diff --git a/components/solo/task-detail-dialog.tsx b/components/solo/task-detail-dialog.tsx index d25975c..6da9f74 100644 --- a/components/solo/task-detail-dialog.tsx +++ b/components/solo/task-detail-dialog.tsx @@ -46,16 +46,25 @@ interface TaskDetailContentProps { onClose: () => void } +const VERIFY_RESULT_CONFIG: Record = { + aligned: { label: 'Aligned', className: 'text-status-done' }, + partial: { label: 'Gedeeltelijk', className: 'text-warning' }, + divergent: { label: 'Divergent', className: 'text-error' }, + empty: { label: 'Geen wijzigingen', className: 'text-muted-foreground' }, +} + type SaveState = 'idle' | 'saving' | 'saved' function TaskDetailContent({ task, productId, isDemo, repoUrl, onClose }: TaskDetailContentProps) { - const { updatePlan } = useSoloStore() + const { updatePlan, updateVerifyOnly } = useSoloStore() const job = useSoloStore(s => s.claudeJobsByTaskId[task.id]) const connectedWorkers = useSoloStore(s => s.connectedWorkers) const [localPlan, setLocalPlan] = useState(task.implementation_plan ?? '') + const [localVerifyOnly, setLocalVerifyOnly] = useState(task.verify_only) const [saveState, setSaveState] = useState('idle') const [, startTransition] = useTransition() const [jobPending, startJobTransition] = useTransition() + const [verifyOnlyPending, startVerifyOnlyTransition] = useTransition() const fadeTimer = useRef | null>(null) const savedPlanRef = useRef(task.implementation_plan ?? '') @@ -111,6 +120,31 @@ function TaskDetailContent({ task, productId, isDemo, repoUrl, onClose }: TaskDe }) } + function handleVerifyOnlyToggle() { + if (isDemo) return + const newValue = !localVerifyOnly + setLocalVerifyOnly(newValue) + startVerifyOnlyTransition(async () => { + try { + const res = await fetch(`/api/tasks/${task.id}`, { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + credentials: 'include', + body: JSON.stringify({ verify_only: newValue }), + }) + if (!res.ok) { + setLocalVerifyOnly(!newValue) + toast.error('Verify-only bijwerken mislukt') + return + } + updateVerifyOnly(task.id, newValue) + } catch { + setLocalVerifyOnly(!newValue) + toast.error('Verify-only bijwerken mislukt') + } + }) + } + return ( <> @@ -162,6 +196,30 @@ function TaskDetailContent({ task, productId, isDemo, repoUrl, onClose }: TaskDe +
+ + + + Alleen verifiëren (niet implementeren) +
+
+ Klaar{job.branch && !job.pushed_at ? ` — branch ${job.branch}` : ''} {job.pushed_at && job.branch && repoUrl && ( )} + {job.verify_result && (() => { + const cfg = VERIFY_RESULT_CONFIG[job.verify_result] + return cfg ? ( + + + + ▸ {cfg.label} + + } /> + + {job.verify_result === 'aligned' && 'De implementatie komt overeen met het plan.'} + {job.verify_result === 'partial' && 'De implementatie wijkt gedeeltelijk af van het plan.'} + {job.verify_result === 'divergent' && 'De implementatie wijkt significant af van het plan.'} + {job.verify_result === 'empty' && 'Er zijn geen codewijzigingen gedetecteerd.'} + + + + ) : null + })()} )}