'use client'; import { useRef, useState } from 'react'; import { useTranslations } from 'next-intl'; import { Loader2, Paperclip, Send } from 'lucide-react'; import { DialogCloseButton } from '@/components/ui/shared/DialogCloseButton'; import { Button } from '@/components/ui/shared/Button'; import { Checkbox } from '@/components/ui/shared/Checkbox'; import type { LinkedOrganizationOption, PastTreatment, PastTreatmentCase } from '@/types/treatment'; import { CaseSentLabel } from '@/components/ui/treatment/CaseSentLabel'; import { TreatmentLatestAttachmentPreview } from '@/components/ui/treatment/TreatmentLatestAttachmentPreview'; export type TreatmentPreviewMode = 'readonly' | 'editable'; interface TreatmentPreviewDialogProps { open: boolean; onClose: () => void; treatment: PastTreatment | null; mode: TreatmentPreviewMode; orgs?: LinkedOrganizationOption[]; sendBusyCaseId?: string | null; uploadBusyCaseId?: string | null; onAttach?: (caseKey: string, files: FileList) => void | Promise; onSend?: (caseKey: string, organizationIds: string[]) => void | Promise; getCaseOrgIds?: (caseKey: string) => string[]; onToggleCaseOrg?: (caseKey: string, organizationId: string, checked: boolean) => void; } function caseKey(c: PastTreatmentCase): string { return c.clientId ?? c.id; } const caseActionIconClass = 'inline-flex items-center justify-center rounded-[var(--radius-sm)] p-1.5 text-text-secondary transition-colors hover:bg-background-card/80 hover:text-text-primary disabled:cursor-not-allowed disabled:opacity-40'; const TREATMENT_TYPE_KEYS = { consultation: 'typeConsultation', filling: 'typeFilling', endo: 'typeEndo', visit: 'typeVisit', hygiene: 'typeHygiene', } as const; export function TreatmentPreviewDialog({ open, onClose, treatment, mode, orgs = [], sendBusyCaseId, uploadBusyCaseId, onAttach, onSend, getCaseOrgIds, onToggleCaseOrg, }: TreatmentPreviewDialogProps) { const t = useTranslations('treatment'); const [expandedSendCaseId, setExpandedSendCaseId] = useState(null); const fileInputsRef = useRef>({}); if (!open || !treatment) return null; const editable = mode === 'editable'; const activeOrgs = orgs.filter((o) => o.active); return (

{t('previewDialogTitle')}

{t('previewDialogSubtitle')}

{treatment.title}

{new Date(treatment.treatmentAt).toLocaleDateString()}

{t('statusLabel')} {treatment.status}

{treatment.details.length === 0 ? (

{t('noCases')}

) : (
{treatment.details.map((c, idx) => { const key = caseKey(c); const attachments = c.attachmentMetas ?? []; const latestAttachment = attachments.length > 0 ? attachments[attachments.length - 1] : null; const sent = Boolean(c.sentAt); const actionsEnabled = editable && !sent; const selectedOrgIds = getCaseOrgIds?.(key) ?? (c.destinationOrganizationId ? [c.destinationOrganizationId] : []); const sendExpanded = expandedSendCaseId === key; const comment = c.notes?.trim() ?? ''; const attachBusy = uploadBusyCaseId === key; const sendBusy = sendBusyCaseId === key; const typeKey = TREATMENT_TYPE_KEYS[c.treatmentType as keyof typeof TREATMENT_TYPE_KEYS]; const typeLabel = typeKey ? t(typeKey) : c.treatmentType; return (

{t('caseLabel', { n: idx + 1 })}

{actionsEnabled && (
{ fileInputsRef.current[key] = el; }} type="file" multiple className="sr-only" aria-hidden onChange={(e) => { if (e.target.files?.length) { void onAttach?.(key, e.target.files); } e.target.value = ''; }} />
)}

{t('typeLabel')} {typeLabel}

{t('teethLabel')}{' '} {c.teeth.length ? [...c.teeth].sort().join(', ') : t('teethNone')}

{comment ? (

{t('commentsLabel')} {comment}

) : (

{t('commentsEmpty')}

)}
{sent && ( )}

{t('attachments')}

{sendExpanded && editable && !sent && (

{t('sendToLinkedOrgs')}

{activeOrgs.length === 0 ? (

{t('noActiveOrgs')}

) : (
{activeOrgs.map((o) => ( onToggleCaseOrg?.(key, o.id, checked)} label={o.name} /> ))}
)}
)}
); })}
)}
); }