From 87044a747b47bd83249d61a45842c7f7b2eae56d Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 11 Jan 2026 05:52:14 +0000 Subject: Contract system --- .../src/components/contracts/PhaseProgressBar.tsx | 142 +++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 makima/frontend/src/components/contracts/PhaseProgressBar.tsx (limited to 'makima/frontend/src/components/contracts/PhaseProgressBar.tsx') diff --git a/makima/frontend/src/components/contracts/PhaseProgressBar.tsx b/makima/frontend/src/components/contracts/PhaseProgressBar.tsx new file mode 100644 index 0000000..5ee7999 --- /dev/null +++ b/makima/frontend/src/components/contracts/PhaseProgressBar.tsx @@ -0,0 +1,142 @@ +import type { ContractPhase } from "../../lib/api"; + +interface PhaseProgressBarProps { + currentPhase: ContractPhase; + onPhaseClick?: (phase: ContractPhase) => void; + readonly?: boolean; +} + +const phases: ContractPhase[] = ["research", "specify", "plan", "execute", "review"]; + +const phaseLabels: Record = { + research: "Research", + specify: "Specify", + plan: "Plan", + execute: "Execute", + review: "Review", +}; + +const phaseColors: Record = { + research: { + active: "bg-purple-400 border-purple-400", + inactive: "bg-transparent border-purple-400/30", + completed: "bg-purple-400/50 border-purple-400/50", + }, + specify: { + active: "bg-blue-400 border-blue-400", + inactive: "bg-transparent border-blue-400/30", + completed: "bg-blue-400/50 border-blue-400/50", + }, + plan: { + active: "bg-cyan-400 border-cyan-400", + inactive: "bg-transparent border-cyan-400/30", + completed: "bg-cyan-400/50 border-cyan-400/50", + }, + execute: { + active: "bg-yellow-400 border-yellow-400", + inactive: "bg-transparent border-yellow-400/30", + completed: "bg-yellow-400/50 border-yellow-400/50", + }, + review: { + active: "bg-green-400 border-green-400", + inactive: "bg-transparent border-green-400/30", + completed: "bg-green-400/50 border-green-400/50", + }, +}; + +export function PhaseProgressBar({ + currentPhase, + onPhaseClick, + readonly = false, +}: PhaseProgressBarProps) { + const currentIndex = phases.indexOf(currentPhase); + + return ( +
+ {phases.map((phase, index) => { + const isActive = phase === currentPhase; + const isCompleted = index < currentIndex; + const colors = phaseColors[phase]; + const colorClass = isActive + ? colors.active + : isCompleted + ? colors.completed + : colors.inactive; + + const canClick = !readonly && onPhaseClick; + + return ( +
+ {/* Phase node */} + + + {/* Connector line */} + {index < phases.length - 1 && ( +
+ )} +
+ ); + })} +
+ ); +} + +export function PhaseProgressBarCompact({ + currentPhase, +}: { + currentPhase: ContractPhase; +}) { + const currentIndex = phases.indexOf(currentPhase); + + return ( +
+ {phases.map((phase, index) => { + const isActive = phase === currentPhase; + const isCompleted = index < currentIndex; + const colors = phaseColors[phase]; + + return ( +
+ ); + })} +
+ ); +} -- cgit v1.2.3