2026-05-19 23:43:43 +03:30
|
|
|
'use client';
|
|
|
|
|
|
2026-06-20 14:51:43 +03:30
|
|
|
import { useTranslations } from 'next-intl';
|
2026-05-19 23:43:43 +03:30
|
|
|
import { Button } from '@/components/ui/shared/Button';
|
|
|
|
|
import type { PastTreatment } from '@/types/treatment';
|
|
|
|
|
|
2026-06-20 14:51:43 +03:30
|
|
|
const TREATMENT_TYPE_KEYS = {
|
|
|
|
|
consultation: 'typeConsultation',
|
|
|
|
|
filling: 'typeFilling',
|
|
|
|
|
endo: 'typeEndo',
|
|
|
|
|
visit: 'typeVisit',
|
|
|
|
|
hygiene: 'typeHygiene',
|
|
|
|
|
} as const;
|
|
|
|
|
|
2026-05-19 23:43:43 +03:30
|
|
|
interface TreatmentPreviewCardProps {
|
|
|
|
|
draft: PastTreatment | null;
|
|
|
|
|
disabled?: boolean;
|
|
|
|
|
onPreview: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function TreatmentPreviewCard({ draft, disabled, onPreview }: TreatmentPreviewCardProps) {
|
2026-06-20 14:51:43 +03:30
|
|
|
const t = useTranslations('treatment');
|
|
|
|
|
|
|
|
|
|
const attachmentCount = draft
|
2026-06-28 15:34:56 +03:30
|
|
|
? draft.details.reduce((n, c) => n + (c.attachmentMetas?.length ?? 0), 0)
|
2026-06-20 14:51:43 +03:30
|
|
|
: 0;
|
|
|
|
|
|
2026-05-19 23:43:43 +03:30
|
|
|
return (
|
|
|
|
|
<div className="surface-card p-4 space-y-3">
|
|
|
|
|
<div className="flex items-center justify-between gap-2">
|
2026-06-20 14:51:43 +03:30
|
|
|
<h3 className="text-sm font-semibold text-text-primary">{t('previewTitle')}</h3>
|
2026-05-19 23:43:43 +03:30
|
|
|
<Button type="button" variant="primary" disabled={disabled || !draft} onClick={onPreview}>
|
2026-06-20 14:51:43 +03:30
|
|
|
{t('previewDraft')}
|
2026-05-19 23:43:43 +03:30
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
{!draft ? (
|
2026-06-20 14:51:43 +03:30
|
|
|
<p className="text-sm text-text-muted">{t('selectAppointment')}</p>
|
2026-05-19 23:43:43 +03:30
|
|
|
) : (
|
|
|
|
|
<div className="border border-border/70 rounded-[var(--radius-md)] p-3 bg-background-secondary/40 space-y-2">
|
|
|
|
|
<div className="flex items-start justify-between gap-2">
|
|
|
|
|
<p className="text-sm font-medium text-text-primary">{draft.title}</p>
|
|
|
|
|
<span className="text-xs text-text-muted tabular-nums shrink-0 capitalize">{draft.status}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<p className="text-xs text-text-secondary">
|
2026-06-28 15:34:56 +03:30
|
|
|
{t('caseCount', { n: draft.details.length })} ·{' '}
|
2026-06-20 14:51:43 +03:30
|
|
|
{t('attachmentCount', { n: attachmentCount })}
|
2026-05-19 23:43:43 +03:30
|
|
|
</p>
|
|
|
|
|
<div className="space-y-2">
|
2026-06-28 15:34:56 +03:30
|
|
|
{draft.details.slice(0, 2).map((c, idx) => {
|
2026-06-20 14:51:43 +03:30
|
|
|
const typeKey = TREATMENT_TYPE_KEYS[c.treatmentType as keyof typeof TREATMENT_TYPE_KEYS];
|
|
|
|
|
const typeLabel = typeKey ? t(typeKey) : c.treatmentType;
|
|
|
|
|
return (
|
2026-05-19 23:43:43 +03:30
|
|
|
<div
|
|
|
|
|
key={c.id}
|
|
|
|
|
className="rounded-[var(--radius-sm)] border border-border/60 px-2.5 py-2 text-xs text-text-secondary"
|
|
|
|
|
>
|
|
|
|
|
<span className="text-text-primary font-medium capitalize">
|
2026-06-20 14:51:43 +03:30
|
|
|
{t('caseSummary', { n: idx + 1, type: typeLabel })}
|
2026-05-19 23:43:43 +03:30
|
|
|
</span>
|
|
|
|
|
{c.teeth.length > 0 && (
|
2026-06-20 14:51:43 +03:30
|
|
|
<span className="ml-1 tabular-nums">
|
|
|
|
|
{t('teethPrefix')} {[...c.teeth].sort().join(', ')}
|
|
|
|
|
</span>
|
2026-05-19 23:43:43 +03:30
|
|
|
)}
|
|
|
|
|
</div>
|
2026-06-20 14:51:43 +03:30
|
|
|
);
|
|
|
|
|
})}
|
2026-06-28 15:34:56 +03:30
|
|
|
{draft.details.length > 2 && (
|
|
|
|
|
<p className="text-xs text-text-muted">{t('moreCases', { n: draft.details.length - 2 })}</p>
|
2026-05-19 23:43:43 +03:30
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|