import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import type { FunnelResponse, FunnelStage } from '../../types/labeleval'; import { SectionCard, fmtInt, fmtPct } from './shared'; function StageBar({ stage, max, color }: { stage: FunnelStage; max: number; color: string }) { const width = max > 0 ? Math.max(2, (stage.count / max) * 100) : 2; return ( {stage.stage.replace(/_/g, ' ')} {fmtInt(stage.count)} · {fmtPct(stage.pct_of_input)} ); } export default function VerificationFunnel({ funnel }: { funnel: FunnelResponse | null }) { if (!funnel || (funnel.main_path.length === 0 && funnel.side_path.length === 0)) { return ( No funnel data yet — run the evaluation pipeline to populate it. ); } const maxMain = Math.max(1, ...funnel.main_path.map((s) => s.count)); const maxSide = Math.max(1, ...funnel.side_path.map((s) => s.count)); return ( MAIN PATH {funnel.main_path.map((s) => ( ))} SIDE BRANCH — FLAGGED → HITL → RE-LABEL → RE-VALIDATION → VERIFIED {funnel.side_path.map((s) => ( ))} ); }