diff options
Diffstat (limited to 'makima/frontend/src/components/contracts/ContractList.tsx')
| -rw-r--r-- | makima/frontend/src/components/contracts/ContractList.tsx | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/makima/frontend/src/components/contracts/ContractList.tsx b/makima/frontend/src/components/contracts/ContractList.tsx deleted file mode 100644 index 1eee6a3..0000000 --- a/makima/frontend/src/components/contracts/ContractList.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import { useState } from "react"; -import type { ContractSummary, ContractStatus } from "../../lib/api"; -import { PhaseBadge } from "./PhaseBadge"; -import { PhaseProgressBarCompact } from "./PhaseProgressBar"; -import { ContractContextMenu } from "./ContractContextMenu"; - -interface ContractListProps { - contracts: ContractSummary[]; - loading: boolean; - onSelect: (id: string) => void; - onCreate: () => void; - selectedId?: string; - onMarkComplete?: (contract: ContractSummary) => void; - onMarkActive?: (contract: ContractSummary) => void; - onArchive?: (contract: ContractSummary) => void; - onDelete?: (contract: ContractSummary) => void; - onGoToSupervisor?: (contract: ContractSummary) => void; -} - -const statusColors: Record<ContractStatus, string> = { - active: "text-green-400", - completed: "text-blue-400", - archived: "text-[#555]", -}; - -export function ContractList({ - contracts, - loading, - onSelect, - onCreate, - selectedId, - onMarkComplete, - onMarkActive, - onArchive, - onDelete, - onGoToSupervisor, -}: ContractListProps) { - const [filter, setFilter] = useState<ContractStatus | "all">("all"); - const [contextMenuPosition, setContextMenuPosition] = useState<{ x: number; y: number } | null>(null); - const [contextMenuContract, setContextMenuContract] = useState<ContractSummary | null>(null); - - const handleContextMenu = (e: React.MouseEvent, contract: ContractSummary) => { - e.preventDefault(); - setContextMenuPosition({ x: e.clientX, y: e.clientY }); - setContextMenuContract(contract); - }; - - const closeContextMenu = () => { - setContextMenuPosition(null); - setContextMenuContract(null); - }; - - const filteredContracts = - filter === "all" - ? contracts - : contracts.filter((c) => c.status === filter); - - if (loading) { - return ( - <div className="panel h-full flex items-center justify-center"> - <div className="font-mono text-[#9bc3ff] text-sm">Loading...</div> - </div> - ); - } - - return ( - <div className="panel h-full flex flex-col min-h-0"> - {/* Header */} - <div className="p-4 border-b border-dashed border-[rgba(117,170,252,0.35)]"> - <div className="flex items-center justify-between mb-3"> - <h2 className="font-mono text-sm text-[#75aafc] uppercase tracking-wider"> - Contracts - </h2> - <button - onClick={onCreate} - className="px-3 py-1.5 font-mono text-xs text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3] hover:bg-[#153667] transition-colors uppercase" - > - + New - </button> - </div> - - {/* Filter tabs */} - <div className="flex gap-1"> - {(["all", "active", "completed", "archived"] as const).map((status) => ( - <button - key={status} - onClick={() => setFilter(status)} - className={` - px-2 py-1 font-mono text-[10px] uppercase tracking-wider transition-colors - ${ - filter === status - ? "bg-[rgba(117,170,252,0.1)] text-[#9bc3ff] border border-[rgba(117,170,252,0.3)]" - : "text-[#555] hover:text-[#75aafc]" - } - `} - > - {status} - </button> - ))} - </div> - </div> - - {/* Contract list */} - <div className="flex-1 min-h-0 overflow-y-auto"> - {filteredContracts.length === 0 ? ( - <div className="p-4 text-center"> - <p className="font-mono text-sm text-[#555]"> - {filter === "all" - ? "No contracts yet" - : `No ${filter} contracts`} - </p> - </div> - ) : ( - <div className="divide-y divide-[rgba(117,170,252,0.15)]"> - {filteredContracts.map((contract) => ( - <button - key={contract.id} - onClick={() => onSelect(contract.id)} - onContextMenu={(e) => handleContextMenu(e, contract)} - className={` - w-full text-left p-4 transition-colors - ${ - selectedId === contract.id - ? "bg-[rgba(117,170,252,0.1)]" - : "hover:bg-[rgba(117,170,252,0.05)]" - } - `} - > - <div className="flex items-start justify-between gap-2 mb-2"> - <div className="flex items-center gap-2 min-w-0"> - <h3 className="font-mono text-sm text-[#dbe7ff] truncate"> - {contract.name} - </h3> - {contract.localOnly && ( - <span className="px-1.5 py-0.5 font-mono text-[9px] uppercase text-amber-400 border border-amber-400/30 bg-amber-400/10 shrink-0"> - Local - </span> - )} - </div> - <span - className={`text-[10px] font-mono uppercase shrink-0 ${ - statusColors[contract.status] - }`} - > - {contract.status} - </span> - </div> - - {contract.description && ( - <p className="font-mono text-xs text-[#555] mb-2 line-clamp-2"> - {contract.description} - </p> - )} - - <div className="flex items-center justify-between"> - <PhaseProgressBarCompact currentPhase={contract.phase} contractType={contract.contractType} /> - <div className="flex items-center gap-3 text-[10px] font-mono text-[#555]"> - {contract.fileCount > 0 && ( - <span>{contract.fileCount} files</span> - )} - {contract.taskCount > 0 && ( - <span>{contract.taskCount} tasks</span> - )} - {contract.repositoryCount > 0 && ( - <span>{contract.repositoryCount} repos</span> - )} - </div> - </div> - </button> - ))} - </div> - )} - </div> - - {/* Context Menu */} - {contextMenuPosition && contextMenuContract && ( - <ContractContextMenu - x={contextMenuPosition.x} - y={contextMenuPosition.y} - contract={contextMenuContract} - onClose={closeContextMenu} - onMarkComplete={() => onMarkComplete?.(contextMenuContract)} - onMarkActive={() => onMarkActive?.(contextMenuContract)} - onArchive={() => onArchive?.(contextMenuContract)} - onDelete={() => onDelete?.(contextMenuContract)} - onGoToSupervisor={() => onGoToSupervisor?.(contextMenuContract)} - /> - )} - </div> - ); -} - -export function ContractCard({ - contract, - onClick, -}: { - contract: ContractSummary; - onClick: () => void; -}) { - return ( - <button - onClick={onClick} - className="w-full text-left p-4 border border-[rgba(117,170,252,0.2)] hover:border-[rgba(117,170,252,0.4)] transition-colors" - > - <div className="flex items-start justify-between gap-2 mb-2"> - <h3 className="font-mono text-sm text-[#dbe7ff]">{contract.name}</h3> - <PhaseBadge phase={contract.phase} /> - </div> - - {contract.description && ( - <p className="font-mono text-xs text-[#555] mb-3 line-clamp-2"> - {contract.description} - </p> - )} - - <div className="flex items-center gap-4 text-[10px] font-mono text-[#555]"> - <span>{contract.fileCount} files</span> - <span>{contract.taskCount} tasks</span> - <span>{contract.repositoryCount} repos</span> - </div> - </button> - ); -} |
