summaryrefslogtreecommitdiff
path: root/makima/frontend/src/components/directives/DirectiveListItem.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'makima/frontend/src/components/directives/DirectiveListItem.tsx')
-rw-r--r--makima/frontend/src/components/directives/DirectiveListItem.tsx83
1 files changed, 83 insertions, 0 deletions
diff --git a/makima/frontend/src/components/directives/DirectiveListItem.tsx b/makima/frontend/src/components/directives/DirectiveListItem.tsx
new file mode 100644
index 0000000..6ff82e4
--- /dev/null
+++ b/makima/frontend/src/components/directives/DirectiveListItem.tsx
@@ -0,0 +1,83 @@
+import type { DirectiveSummary } from "../../lib/api";
+
+interface DirectiveListItemProps {
+ directive: DirectiveSummary;
+ selected: boolean;
+ onClick: () => void;
+ onArchive: () => void;
+}
+
+export function DirectiveListItem({ directive, selected, onClick, onArchive }: DirectiveListItemProps) {
+ const progress = directive.totalSteps > 0
+ ? Math.round((directive.completedSteps / directive.totalSteps) * 100)
+ : 0;
+
+ const statusColor = {
+ draft: "text-[#556677]",
+ planning: "text-yellow-400",
+ active: "text-green-400",
+ paused: "text-yellow-400",
+ completed: "text-[#75aafc]",
+ archived: "text-[#556677]",
+ failed: "text-red-400",
+ }[directive.status] || "text-[#556677]";
+
+ const confidenceColor = {
+ green: "bg-green-500",
+ yellow: "bg-yellow-500",
+ red: "bg-red-500",
+ }[directive.currentConfidence !== null && directive.currentConfidence >= 0.8
+ ? "green"
+ : directive.currentConfidence !== null && directive.currentConfidence >= 0.5
+ ? "yellow"
+ : "red"] || "bg-[#556677]";
+
+ return (
+ <div
+ onClick={onClick}
+ className={`p-3 cursor-pointer border-b border-[rgba(117,170,252,0.1)] hover:bg-[rgba(117,170,252,0.05)] ${
+ selected ? "bg-[rgba(117,170,252,0.1)]" : ""
+ }`}
+ >
+ <div className="flex items-start justify-between gap-2">
+ <div className="flex-1 min-w-0">
+ <div className="font-mono text-sm text-[#dbe7ff] truncate">
+ {directive.title || directive.goal.slice(0, 50)}
+ </div>
+ <div className="flex items-center gap-2 mt-1">
+ <span className={`font-mono text-[10px] uppercase ${statusColor}`}>
+ {directive.status}
+ </span>
+ <span className="font-mono text-[10px] text-[#556677]">
+ {directive.completedSteps}/{directive.totalSteps} steps
+ </span>
+ </div>
+ </div>
+ <div className="flex flex-col items-end gap-1">
+ {directive.currentConfidence !== null && (
+ <div className={`w-2 h-2 rounded-full ${confidenceColor}`} title={`Confidence: ${Math.round(directive.currentConfidence * 100)}%`} />
+ )}
+ <button
+ onClick={(e) => {
+ e.stopPropagation();
+ onArchive();
+ }}
+ className="font-mono text-[10px] text-[#556677] hover:text-red-400"
+ >
+ Archive
+ </button>
+ </div>
+ </div>
+
+ {/* Progress bar */}
+ {directive.totalSteps > 0 && (
+ <div className="mt-2 h-1 bg-[rgba(117,170,252,0.1)] overflow-hidden">
+ <div
+ className="h-full bg-[#75aafc] transition-all duration-300"
+ style={{ width: `${progress}%` }}
+ />
+ </div>
+ )}
+ </div>
+ );
+}