import { useMemo } from 'react' import type { FieldEntry, GoldenRecord } from './types' import { useStore } from './store' import { FieldRow } from './FieldRow' interface Props { sessionId: string } const SECTION_LABELS: Record = { policy_header: 'Policy Header', vehicle_details: 'Vehicle Details', driver_details: 'Drivers', cover_and_excesses: 'Cover & Excesses', financial_summary: 'Financial Summary', additional_risk_data: 'Additional Risk Data', } export function RecordPane({ sessionId }: Props) { const sessionData = useStore((s) => s.sessionData) const reviewState = useStore((s) => s.reviewState) const activeFieldPath = useStore((s) => s.activeFieldPath) const setActiveField = useStore((s) => s.setActiveField) const fieldsBySection = useMemo(() => { if (!sessionData) return [] return flattenRecord(sessionData.record, sessionData.provenance.reduce( (acc, p) => { acc[p.field_path] = p; return acc }, {} as Record, )) }, [sessionData]) if (!sessionData) return null const conflicts = sessionData.conflicts ?? [] return (
{/* Header */}

Golden Record

Select a field to see its source in the PDF

{/* Scrollable field list */}
{conflicts.length > 0 && (

{conflicts.length} cross-document conflict{conflicts.length > 1 ? 's' : ''} · resolved by authority rules

    {conflicts.map((c) => (
  • {c.field} Winner: {c.winner} Schedule: {c.schedule_value ?? '—'} {' · '}Certificate: {c.certificate_value ?? '—'}
  • ))}
)} {fieldsBySection.map(({ section, entries }) => (

{SECTION_LABELS[section] ?? section}

{entries.filter((e) => e.provenance).length}/{entries.length} located
{entries.map((entry) => ( setActiveField(activeFieldPath === entry.fieldPath ? null : entry) } /> ))}
))}
) } // ── Field flattening helpers ─────────────────────────────────────────────── interface SectionGroup { section: string entries: FieldEntry[] } function flattenRecord( record: GoldenRecord, provenanceMap: Record, ): SectionGroup[] { const groups: SectionGroup[] = [] for (const [sectionKey, sectionValue] of Object.entries(record)) { if (sectionValue == null) continue const entries: FieldEntry[] = [] if (Array.isArray(sectionValue)) { // driver_details sectionValue.forEach((item: Record, idx: number) => { walkObject( item, `${sectionKey}[${idx}]`, `Driver ${idx + 1}`, entries, provenanceMap, ) }) } else if (typeof sectionValue === 'object') { walkObject( sectionValue as Record, sectionKey, '', entries, provenanceMap, ) } else { entries.push({ fieldPath: sectionKey, label: formatLabel(sectionKey), value: String(sectionValue), section: sectionKey, provenance: provenanceMap[sectionKey], }) } if (entries.length > 0) { groups.push({ section: sectionKey, entries }) } } return groups } function walkObject( obj: Record, pathPrefix: string, _labelPrefix: string, out: FieldEntry[], provenanceMap: Record, ) { for (const [key, val] of Object.entries(obj)) { const path = `${pathPrefix}.${key}` if (val == null) continue if (typeof val === 'object' && !Array.isArray(val)) { walkObject(val as Record, path, key, out, provenanceMap) } else if (Array.isArray(val)) { val.forEach((item, i) => { if (item == null) return const iPath = `${path}[${i}]` if (typeof item === 'object') { walkObject(item as Record, iPath, key, out, provenanceMap) } else { out.push({ fieldPath: iPath, label: `${formatLabel(key)} [${i}]`, value: String(item), section: pathPrefix.split('.')[0], provenance: provenanceMap[iPath], }) } }) } else { out.push({ fieldPath: path, label: driverPrefix(pathPrefix) + formatLabel(key), value: String(val), section: pathPrefix.split('.')[0], provenance: provenanceMap[path], }) } } } const LABELS: Record = { vrm: 'Registration (VRM)', dob: 'Date of Birth', license_type: 'Licence Type', is_main_driver: 'Main Driver', has_security_device: 'Security Device', overnight_postcode: 'Overnight Postcode', standard_compulsory: 'Compulsory Excess', total_accidental_damage: 'Accidental Damage Excess', own_repairer_additional_excess: 'Own Repairer Excess', years: 'NCD Years', protected: 'NCD Protected', } function formatLabel(key: string): string { return LABELS[key] ?? key .replace(/_/g, ' ') .replace(/\b\w/g, (c) => c.toUpperCase()) } function driverPrefix(pathPrefix: string): string { const m = pathPrefix.match(/^driver_details\[(\d+)\]$/) return m ? `Driver ${Number(m[1]) + 1} · ` : '' }