diff options
| author | soryu <soryu@soryu.co> | 2026-01-11 05:52:14 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-01-15 00:21:16 +0000 |
| commit | 87044a747b47bd83249d61a45842c7f7b2eae56d (patch) | |
| tree | ef2000ce79ffcc2723ef841acef5aa1deb1d5378 /makima/frontend/src/components/workflow/PhaseColumn.tsx | |
| parent | 077820c4167c168072d217a1b01df840463a12a8 (diff) | |
| download | soryu-87044a747b47bd83249d61a45842c7f7b2eae56d.tar.gz soryu-87044a747b47bd83249d61a45842c7f7b2eae56d.zip | |
Contract system
Diffstat (limited to 'makima/frontend/src/components/workflow/PhaseColumn.tsx')
| -rw-r--r-- | makima/frontend/src/components/workflow/PhaseColumn.tsx | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/makima/frontend/src/components/workflow/PhaseColumn.tsx b/makima/frontend/src/components/workflow/PhaseColumn.tsx new file mode 100644 index 0000000..ddea85f --- /dev/null +++ b/makima/frontend/src/components/workflow/PhaseColumn.tsx @@ -0,0 +1,123 @@ +import { useState } from "react"; +import type { ContractSummary, ContractPhase } from "../../lib/api"; +import { WorkflowContractCard } from "./WorkflowContractCard"; + +interface PhaseColumnProps { + phase: ContractPhase; + contracts: ContractSummary[]; + onContractClick: (contractId: string) => void; + onDrop: (contractId: string, phase: ContractPhase) => void; +} + +const phaseConfig: Record< + ContractPhase, + { label: string; color: string; bgColor: string; borderColor: string } +> = { + research: { + label: "Research", + color: "text-purple-400", + bgColor: "bg-purple-400/10", + borderColor: "border-purple-400/30", + }, + specify: { + label: "Specify", + color: "text-blue-400", + bgColor: "bg-blue-400/10", + borderColor: "border-blue-400/30", + }, + plan: { + label: "Plan", + color: "text-cyan-400", + bgColor: "bg-cyan-400/10", + borderColor: "border-cyan-400/30", + }, + execute: { + label: "Execute", + color: "text-yellow-400", + bgColor: "bg-yellow-400/10", + borderColor: "border-yellow-400/30", + }, + review: { + label: "Review", + color: "text-green-400", + bgColor: "bg-green-400/10", + borderColor: "border-green-400/30", + }, +}; + +export function PhaseColumn({ + phase, + contracts, + onContractClick, + onDrop, +}: PhaseColumnProps) { + const [isDragOver, setIsDragOver] = useState(false); + const config = phaseConfig[phase]; + + const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); + setIsDragOver(true); + }; + + const handleDragLeave = () => { + setIsDragOver(false); + }; + + const handleDrop = (e: React.DragEvent) => { + e.preventDefault(); + setIsDragOver(false); + const contractId = e.dataTransfer.getData("contractId"); + if (contractId) { + onDrop(contractId, phase); + } + }; + + return ( + <div + className={` + flex flex-col min-w-[220px] flex-1 border border-[rgba(117,170,252,0.15)] + ${isDragOver ? "bg-[rgba(117,170,252,0.05)]" : "bg-transparent"} + transition-colors + `} + onDragOver={handleDragOver} + onDragLeave={handleDragLeave} + onDrop={handleDrop} + > + {/* Column header */} + <div + className={` + p-3 border-b ${config.borderColor} ${config.bgColor} + flex items-center justify-between + `} + > + <span className={`font-mono text-xs uppercase tracking-wider ${config.color}`}> + {config.label} + </span> + <span className="font-mono text-[10px] text-[#555]"> + ({contracts.length}) + </span> + </div> + + {/* Cards container */} + <div className="flex-1 overflow-y-auto p-2 space-y-2"> + {contracts.length === 0 ? ( + <div className="p-4 text-center font-mono text-[10px] text-[#555]"> + No contracts + </div> + ) : ( + contracts.map((contract) => ( + <WorkflowContractCard + key={contract.id} + contract={contract} + onClick={() => onContractClick(contract.id)} + onDragStart={(e) => { + e.dataTransfer.setData("contractId", contract.id); + e.dataTransfer.effectAllowed = "move"; + }} + /> + )) + )} + </div> + </div> + ); +} |
