import { useState, useMemo } from "react";
import type { DirectiveSummary, DirectiveStatus } from "../../lib/api";
import { useSupervisorQuestions } from "../../contexts/SupervisorQuestionsContext";
import { DirectiveContextMenu } from "./DirectiveContextMenu";
const STATUS_BADGE: Record<DirectiveStatus, { color: string; label: string }> = {
draft: { color: "text-[#7788aa] border-[#2a3a5a]", label: "DRAFT" },
active: { color: "text-green-400 border-green-800", label: "ACTIVE" },
idle: { color: "text-yellow-400 border-yellow-800", label: "IDLE" },
paused: { color: "text-orange-400 border-orange-800", label: "PAUSED" },
archived: { color: "text-[#556677] border-[#2a3a5a]", label: "ARCHIVED" },
};
interface DirectiveListProps {
directives: DirectiveSummary[];
selectedId: string | null;
onSelect: (id: string) => void;
onCreate: () => void;
onStart?: (directive: DirectiveSummary) => void;
onPause?: (directive: DirectiveSummary) => void;
onArchive?: (directive: DirectiveSummary) => void;
onDelete?: (directive: DirectiveSummary) => void;
onGoToPR?: (directive: DirectiveSummary) => void;
}
export function DirectiveList({ directives, selectedId, onSelect, onCreate, onStart, onPause, onArchive, onDelete, onGoToPR }: DirectiveListProps) {
const { pendingQuestions } = useSupervisorQuestions();
const [contextMenuPosition, setContextMenuPosition] = useState<{ x: number; y: number } | null>(null);
const [contextMenuDirective, setContextMenuDirective] = useState<DirectiveSummary | null>(null);
const handleContextMenu = (e: React.MouseEvent, directive: DirectiveSummary) => {
e.preventDefault();
setContextMenuPosition({ x: e.clientX, y: e.clientY });
setContextMenuDirective(directive);
};
const closeContextMenu = () => {
setContextMenuPosition(null);
setContextMenuDirective(null);
};
const questionsPerDirective = useMemo(() => {
const counts = new Map<string, number>();
for (const q of pendingQuestions) {
if (q.directiveId) {
counts.set(q.directiveId, (counts.get(q.directiveId) || 0) + 1);
}
}
return counts;
}, [pendingQuestions]);
return (
<div className="flex flex-col h-full">
<div className="flex items-center justify-between px-3 py-2 border-b border-dashed border-[rgba(117,170,252,0.2)]">
<span className="text-[11px] font-mono text-[#9bc3ff] uppercase tracking-wide">
Directives
</span>
<button
type="button"
onClick={onCreate}
className="text-[11px] font-mono text-[#75aafc] hover:text-white bg-transparent border border-[rgba(117,170,252,0.3)] rounded px-2 py-0.5 hover:border-[rgba(117,170,252,0.6)] transition-colors"
>
+ New
</button>
</div>
<div className="flex-1 overflow-y-auto">
{directives.length === 0 ? (
<div className="px-3 py-6 text-center text-[#556677] font-mono text-[11px]">
No directives yet
</div>
) : (
directives.map((d) => {
const badge = STATUS_BADGE[d.status] || STATUS_BADGE.draft;
const progress = d.totalSteps > 0
? Math.round((d.completedSteps / d.totalSteps) * 100)
: 0;
return (
<button
key={d.id}
type="button"
onClick={() => onSelect(d.id)}
onContextMenu={(e) => handleContextMenu(e, d)}
className={`w-full text-left px-3 py-2.5 border-b border-[rgba(117,170,252,0.1)] hover:bg-[rgba(117,170,252,0.05)] transition-colors ${
selectedId === d.id ? "bg-[rgba(117,170,252,0.1)]" : ""
}`}
>
<div className="flex items-center justify-between mb-1">
<span className="text-[12px] font-mono text-white truncate pr-2">
{d.title}
</span>
{questionsPerDirective.has(d.id) && (
<span className="inline-block w-2.5 h-2.5 rounded-full bg-amber-400 animate-pulse shrink-0" title={`${questionsPerDirective.get(d.id)} pending question(s)`} />
)}
<span
className={`text-[9px] font-mono ${badge.color} border rounded px-1.5 py-0.5 shrink-0`}
>
{badge.label}
</span>
</div>
<p className="text-[10px] text-[#7788aa] font-mono truncate mb-1.5">
{d.goal}
</p>
{d.totalSteps > 0 && (
<div className="flex items-center gap-2">
<div className="flex-1 h-1 bg-[#1a2540] rounded overflow-hidden">
<div
className="h-full bg-emerald-600 rounded transition-all"
style={{ width: `${progress}%` }}
/>
</div>
<span className="text-[9px] font-mono text-[#556677] shrink-0">
{d.completedSteps}/{d.totalSteps}
</span>
</div>
)}
</button>
);
})
)}
</div>
{/* Context Menu */}
{contextMenuPosition && contextMenuDirective && (
<DirectiveContextMenu
x={contextMenuPosition.x}
y={contextMenuPosition.y}
directive={contextMenuDirective}
onClose={closeContextMenu}
onStart={() => onStart?.(contextMenuDirective)}
onPause={() => onPause?.(contextMenuDirective)}
onArchive={() => onArchive?.(contextMenuDirective)}
onDelete={() => onDelete?.(contextMenuDirective)}
onGoToPR={() => onGoToPR?.(contextMenuDirective)}
/>
)}
</div>
);
}