'use client'; import { useRef, useState } from 'react'; 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'; export function TreatmentPreviewDialog({ open, onClose, treatment, mode, orgs = [], sendBusyCaseId, uploadBusyCaseId, onAttach, onSend, getCaseOrgIds, onToggleCaseOrg, }: TreatmentPreviewDialogProps) { 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 (

Treatment preview

Review cases, attachments, and send destinations.

{treatment.title}

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

Status: {treatment.status}

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

No cases in this treatment.

) : (
{treatment.cases.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.sendToOrganizationIds ?? []; const sendExpanded = expandedSendCaseId === key; const comment = c.notes?.trim() ?? ''; const attachBusy = uploadBusyCaseId === key; const sendBusy = sendBusyCaseId === key; return (

Case {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 = ''; }} />
)}

Type: {c.treatmentType}

Teeth:{' '} {c.teeth.length ? [...c.teeth].sort().join(', ') : 'None selected'}

{comment ? (

Comments: {comment}

) : (

Comments: —

)}
{sent && ( )}

Attachments

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

Send to linked organizations

{activeOrgs.length === 0 ? (

No active linked organizations.

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