import type { ComponentType } from 'react' import { BookOpen, Building2, CalendarClock, FileText, Folder, FolderOpen, Image as ImageIcon, Pencil, UserRound } from 'lucide-react' import type { CaseDocument, Evidence, EvidenceType, SourceFileType } from './types' import { folderIsOpen } from './boardDomain' export type ExhibitWidgetProps = { exhibit: Evidence documents: CaseDocument[] onOpenSource: (id: string) => void onToggleFolder: (id: string) => void onEditFolder: (id: string) => void onEditEvent: (id: string) => void onEditParty: (id: string) => void } export type ExhibitWidgetDefinition = { visualType: Exclude heading: (exhibit: Evidence, documents: CaseDocument[]) => string connectionPoint: (exhibit: Evidence) => { x: number; y: number } Component: ComponentType } function FolderWidget({ exhibit, documents, onOpenSource, onToggleFolder, onEditFolder }: ExhibitWidgetProps) { return

{exhibit.title}

{exhibit.content}

{!folderIsOpen(exhibit) &&
{documents.slice(0, 3).map(document => )}{documents.length > 3 && + {documents.length - 3} MORE FILES}
}
} function StandardWidget({ exhibit, onOpenSource }: ExhibitWidgetProps) { return

{exhibit.title}

{exhibit.content}

{exhibit.eventDate && } {exhibit.sourceDocumentId && }
} function EventWidget({ exhibit, onEditEvent }: ExhibitWidgetProps) { const supportCount = exhibit.supportingEvidenceIds?.length || 0 return

{exhibit.title}

{exhibit.content}

{exhibit.eventDate && }
{supportCount} SUPPORTING EXHIBIT{supportCount === 1 ? '' : 'S'}
} function PartyWidget({ exhibit, onEditParty }: ExhibitWidgetProps) { const person = exhibit.partyKind === 'person' return
{person ? : }

{exhibit.title}

{person ? 'PERSON' : (exhibit.organizationKind || 'ORGANIZATION').replaceAll('_', ' ').toUpperCase()}

{exhibit.content || 'No dossier summary yet.'}

{(exhibit.aliases?.length || 0) > 0 &&
AKA · {exhibit.aliases!.join(' · ')}
}
{exhibit.relatedEvidenceIds?.length || 0} ASSOCIATED EXHIBITS
} const standardPoint = (exhibit: Evidence) => ({ x: exhibit.x + exhibit.width / 2, y: exhibit.y + 68 }) const folderDefinition: ExhibitWidgetDefinition = { visualType: 'folder', heading: (_exhibit, documents) => `EVIDENCE FOLDER / ${documents.length}`, connectionPoint: standardPoint, Component: FolderWidget, } export const exhibitWidgetRegistry: Record = { folder: folderDefinition, evidence: folderDefinition, note: { visualType: 'note', heading: () => 'INVESTIGATOR / NOTE', connectionPoint: exhibit => ({ x: exhibit.x + 54, y: exhibit.y + 12 }), Component: StandardWidget }, event: { visualType: 'event', heading: () => 'EVENT / THIS HAPPENED', connectionPoint: standardPoint, Component: EventWidget }, party: { visualType: 'party', heading: exhibit => exhibit.partyKind === 'person' ? 'PARTY / PERSON DOSSIER' : 'PARTY / ORGANIZATION DOSSIER', connectionPoint: standardPoint, Component: PartyWidget }, } export function exhibitWidget(type: EvidenceType) { return exhibitWidgetRegistry[type] || exhibitWidgetRegistry.note } type DocumentWidgetProps = { document: CaseDocument; source: string } export type DocumentWidgetDefinition = { label: string Preview: ComponentType Asset: ComponentType } function ImagePreview({ document, source }: DocumentWidgetProps) { return document.assetId ? : } function GenericPreview({ document }: DocumentWidgetProps) { return
{document.kind}
} function ImageAsset({ document, source }: DocumentWidgetProps) { return {document.fileName } function FrameAsset({ document, source }: DocumentWidgetProps) { return