import type { ReactNode } from 'react'; import { useI18n, type Key } from '../lib/i18n'; import { usePhoto } from '../lib/usePhoto'; import type { UserReport } from '../lib/types'; import { Icon, VettingSummary } from './ui'; interface Props { report: UserReport; /** Queue view: the place is the heading and the claim sits below it. Place view: the claim is the heading. */ placeName?: string | undefined; headingLevel?: 'h2' | 'h3'; /** Show the full automatic assessment (city panel) instead of the short tags. */ detailed?: boolean; children?: ReactNode; } const STATUS_TAG = { pending: 'bg-base-lighter text-ink', accepted: 'bg-success-dark text-white', rejected: 'bg-error-dark text-white', } as const; /** One layout for every user report, with or without a photo, in the place view and in the city inbox. */ export function ReportCard({ report: r, placeName, headingLevel = 'h3', detailed = false, children }: Props) { const { t, date } = useI18n(); const photo = usePhoto(r.photoId); const Heading = headingLevel; const claim = ( <> {t(`rep.attr.${r.attr}` as Key)}: {typeof r.value === 'number' ? `${r.value} ${t('unit.cm')}` : t(`rep.${r.value}` as Key)} ); const status = r.status ?? 'pending'; return (
{photo ? ( {t('rep.photo.alt')} ) : ( <> {t('vet.flag.no-photo')} )}
{placeName ?? claim} {t(status === 'pending' ? 'detail.reports.pending' : (`dash.queue.status.${status}` as Key))}
{placeName &&

{claim}

}

{date(r.createdAt.slice(0, 10))} {r.demo && {t('detail.reports.demo')}}

{r.measure && (

{t(`vet.measure.${r.measure.kind}` as Key)}: {r.measure.value} {r.measure.unit === 'cm' ? 'cm' : '%'} ({t(`vet.method.${r.measure.method}` as Key)})

)} {r.note &&

{r.note}

} {children &&
{children}
}
); }