Add classified evidence presentations

This commit is contained in:
2026-08-22 19:28:06 +02:00
parent dc0147aebc
commit 10dcd567c6
18 changed files with 414 additions and 45 deletions
+28 -1
View File
@@ -1,6 +1,6 @@
import type { ComponentType } from 'react'
import { BadgeCheck, BookOpen, Building2, CalendarClock, FileText, Image as ImageIcon, Pencil, UserRound } from 'lucide-react'
import type { CaseDocument, DocumentExhibit, Evidence, Exhibit, ExhibitRelation, ExhibitType, SourceFileType, TemporalFact } from './types'
import type { CaseDocument, DocumentCaptureKind, DocumentExhibit, Evidence, Exhibit, ExhibitRelation, ExhibitType, SourceFileType, TemporalFact } from './types'
export type WidgetCommand =
| { type: 'open-document'; documentId: string }
@@ -135,5 +135,32 @@ export const documentWidgetRegistry:Record<SourceFileType,DocumentWidgetDefiniti
}
export function documentWidget(type:SourceFileType) { return documentWidgetRegistry[type] || documentWidgetRegistry.file }
export type DocumentCaptureDefinition = {
label:string
description:string
defaultSize:{ width:number;height:number }
}
export const documentCaptureRegistry:Record<DocumentCaptureKind,DocumentCaptureDefinition> = {
unclassified:{ label:'Not sure',description:'Keep the standard evidence card for now.',defaultSize:{width:174,height:145} },
photo:{ label:'Mugshot',description:'A portrait or identifying photograph.',defaultSize:{width:188,height:240} },
scene:{ label:'Image',description:'A place, situation, object, or event is shown.',defaultSize:{width:244,height:200} },
clipping:{ label:'Clip',description:'An extract captured from a larger source.',defaultSize:{width:210,height:194} },
full_page:{ label:'Document',description:'A complete page or formal document view.',defaultSize:{width:205,height:294} },
}
export function documentCapture(kind:DocumentCaptureKind) { return documentCaptureRegistry[kind] || documentCaptureRegistry.unclassified }
/** Context-sensitive starter copy. A Party is never treated as proof by default. */
export function defaultConnectionLabel(first:Exhibit,second:Exhibit) {
const types = new Set([first.type,second.type])
if (types.has('party') && types.has('claim')) return 'Subject of claim'
const document = first.type === 'document' ? first : second.type === 'document' ? second : null
if (document && types.has('party')) {
if (document.captureKind === 'photo') return 'Depicts…'
if (document.captureKind === 'scene') return 'Shows…'
return 'Concerns…'
}
return 'Proof that…'
}
export function documentExhibits(exhibits:Exhibit[]):DocumentExhibit[] { return exhibits.filter((exhibit):exhibit is DocumentExhibit => exhibit.type === 'document') }
export function evidenceExhibits(exhibits:Exhibit[]):Evidence[] { return exhibits.filter((exhibit):exhibit is Evidence => exhibit.type !== 'document') }