"use client"; import { BriefSummary } from "@tasks/shared/orchestrator"; interface ConvoyDagProps { briefs: Array<{ id: string; briefNumber: number; sliceDependencies: number[]; status: string | null; }>; completedBriefIds: Set; } export function ConvoyDag({ briefs, completedBriefIds }: ConvoyDagProps) { if (briefs.length === 0) return null; const briefByNum = new Map(briefs.map((b) => [b.briefNumber, b])); const nodeSize = 60; const spacing = 180; const startX = 80; const startY = 80; const getPosition = (num: number) => ({ x: startX + ((num - 1) % 4) * spacing, y: startY + Math.floor((num - 1) / 4) * 140, }); const briefsSorted = [...briefs].sort((a, b) => a.briefNumber - b.briefNumber); return (
{briefsSorted.map((brief) => { const pos = getPosition(brief.briefNumber); const isComplete = completedBriefIds.has(brief.id); const isEligible = !isComplete && brief.sliceDependencies.every((dep) => { const depBrief = briefByNum.get(dep); return depBrief && completedBriefIds.has(depBrief.id); }); brief.sliceDependencies.forEach((depNum) => { const dep = briefByNum.get(depNum); if (dep) { const depPos = getPosition(depNum); return ( ); } }); return ( B{brief.briefNumber} {isComplete && ( )} ); })}

Green = Complete | Blue = Ready | Gray = Blocked

); } function getPosition(num: number) { const nodeSize = 60; const spacing = 180; const startX = 80; const startY = 80; return { x: 80 + ((num - 1) % 4) * 180, y: 80 + Math.floor((num - 1) / 4) * 140, }; }