import { PDFPane } from './PDFPane' import { RecordPane } from './RecordPane' import { useStore } from './store' import logoUrl from './assets/ai-toolstack-logo.svg' interface Props { sessionId: string } export function ReviewDashboard({ sessionId }: Props) { const sessionData = useStore((s) => s.sessionData) const reviewState = useStore((s) => s.reviewState) const verified = Object.values(reviewState).filter((r) => r.action === 'verify').length const overridden = Object.values(reviewState).filter((r) => r.action === 'override').length const provTotal = sessionData?.provenance.length ?? 0 const fieldTotal = sessionData ? _countLeaves(sessionData.record) : 0 return (
{/* ── Top bar ─────────────────────────────────────────────────── */}
AI Tool Stack {/* Divider */} |
PolicyTrace
{sessionId.slice(0, 8)}…
{/* ── 2-column body ───────────────────────────────────────────── */}
) } function StatDivider() { return · } function Stat({ label, value, color = '#374151', }: { label: string value: number color?: string }) { return ( {label}:{' '} {value} ) } /** Recursively count leaf values in any nested object (mirrors backend _count_leaves). */ function _countLeaves(obj: unknown): number { if (Array.isArray(obj)) return obj.reduce((acc, v) => acc + _countLeaves(v), 0) if (obj && typeof obj === 'object') return Object.values(obj).reduce((acc: number, v) => acc + _countLeaves(v), 0) return 1 }