diff options
Diffstat (limited to 'makima/frontend/src/components/directives/DirectiveList.tsx')
| -rw-r--r-- | makima/frontend/src/components/directives/DirectiveList.tsx | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/makima/frontend/src/components/directives/DirectiveList.tsx b/makima/frontend/src/components/directives/DirectiveList.tsx new file mode 100644 index 0000000..d0371e0 --- /dev/null +++ b/makima/frontend/src/components/directives/DirectiveList.tsx @@ -0,0 +1,85 @@ +import { useState } from "react"; +import type { DirectiveSummary } from "../../lib/api"; +import { DirectiveListItem } from "./DirectiveListItem"; + +interface DirectiveListProps { + directives: DirectiveSummary[]; + loading: boolean; + onSelect: (id: string) => void; + onCreate: () => void; + selectedId?: string; + onArchive: (directive: DirectiveSummary) => void; +} + +export function DirectiveList({ + directives, + loading, + onSelect, + onCreate, + selectedId, + onArchive, +}: DirectiveListProps) { + const [filter, setFilter] = useState<"all" | "active" | "completed" | "failed">("all"); + + const filteredDirectives = directives.filter((d) => { + if (filter === "all") return true; + if (filter === "active") return ["draft", "planning", "active", "paused"].includes(d.status); + if (filter === "completed") return d.status === "completed"; + if (filter === "failed") return d.status === "failed"; + return true; + }); + + return ( + <div className="panel h-full flex flex-col overflow-hidden"> + <div className="flex items-center justify-between p-3 border-b border-[rgba(117,170,252,0.15)]"> + <h2 className="font-mono text-sm text-[#75aafc] uppercase">Directives</h2> + <button + onClick={onCreate} + className="px-3 py-1 font-mono text-[10px] text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3] hover:bg-[#153667] transition-colors uppercase" + > + + New + </button> + </div> + + {/* Filters */} + <div className="flex gap-1 p-2 border-b border-[rgba(117,170,252,0.1)]"> + {(["all", "active", "completed", "failed"] as const).map((f) => ( + <button + key={f} + onClick={() => setFilter(f)} + className={`px-2 py-1 font-mono text-[10px] uppercase ${ + filter === f + ? "text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3]" + : "text-[#556677] hover:text-[#9bc3ff]" + }`} + > + {f} + </button> + ))} + </div> + + {/* List */} + <div className="flex-1 overflow-y-auto"> + {loading ? ( + <div className="p-4 text-center"> + <p className="font-mono text-xs text-[#556677]">Loading...</p> + </div> + ) : filteredDirectives.length === 0 ? ( + <div className="p-4 text-center"> + <p className="font-mono text-xs text-[#556677]">No directives found</p> + </div> + ) : ( + filteredDirectives.map((d) => ( + <DirectiveListItem + key={d.id} + directive={d} + selected={d.id === selectedId} + onClick={() => onSelect(d.id)} + onArchive={() => onArchive(d)} + /> + )) + )} + </div> + </div> + ); +} |
