'use client' import { useTransition } from 'react' import { useRouter, usePathname } from 'next/navigation' import { Pencil } from 'lucide-react' import { useShallow } from 'zustand/react/shallow' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { CodeBadge } from '@/components/shared/code-badge' import { PanelNavBar } from '@/components/shared/panel-nav-bar' import { PRIORITY_BORDER } from '@/components/backlog/backlog-card' import { useSprintWorkspaceStore } from '@/stores/sprint-workspace/store' import { selectTasksForActiveStory } from '@/stores/sprint-workspace/selectors' import type { SprintWorkspaceTask, SprintWorkspaceTaskDetail, } from '@/stores/sprint-workspace/types' import { updateTaskStatusAction } from '@/actions/tasks' import { DemoTooltip } from '@/components/shared/demo-tooltip' import { debugProps } from '@/lib/debug' import { cn } from '@/lib/utils' const STATUS_CYCLE: Record = { TO_DO: 'IN_PROGRESS', IN_PROGRESS: 'DONE', DONE: 'TO_DO', EXCLUDED: 'TO_DO', } const STATUS_COLORS: Record = { TO_DO: 'bg-status-todo/15 text-status-todo border-status-todo/30', IN_PROGRESS: 'bg-status-in-progress/15 text-status-in-progress border-status-in-progress/30', DONE: 'bg-status-done/15 text-status-done border-status-done/30', EXCLUDED: 'bg-surface-container-low text-muted-foreground border-border', FAILED: 'bg-status-failed/15 text-status-failed border-status-failed/30', REVIEW: 'bg-status-review/15 text-status-review border-status-review/30', } const STATUS_LABELS: Record = { TO_DO: 'To Do', IN_PROGRESS: 'Bezig', REVIEW: 'Review', DONE: 'Klaar', FAILED: 'Mislukt', EXCLUDED: 'Uitgesloten', } // Behouden voor type-compat met SprintBoardClient props (verdwijnt zodra // SprintBoardClient ook geen tasks-prop meer doorgeeft — T-883). export interface Task { id: string code: string | null title: string description: string | null priority: number status: string story_id: string sprint_id: string | null } type WorkspaceTask = SprintWorkspaceTask | SprintWorkspaceTaskDetail interface TaskListProps { sprintId: string productId: string isDemo: boolean } function TaskRow({ task, code, isDemo, onStatusToggle, onEdit, }: { task: WorkspaceTask code: string | null isDemo: boolean onStatusToggle: () => void onEdit: () => void }) { return (
onEdit()} role="button" tabIndex={0} aria-label={`Bewerk taak: ${task.title}`} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault() onEdit() } }} >

{task.title}

{code && }
) } export function TaskList({ sprintId: _sprintId, productId: _productId, isDemo }: TaskListProps) { const storyId = useSprintWorkspaceStore((s) => s.context.activeStoryId) const orderedTasks = useSprintWorkspaceStore( useShallow(selectTasksForActiveStory), ) const [, startTransition] = useTransition() const router = useRouter() const pathname = usePathname() const doneCount = orderedTasks.filter(t => t.status === 'DONE').length function handleStatusToggle(task: WorkspaceTask) { startTransition(async () => { await updateTaskStatusAction(task.id, STATUS_CYCLE[task.status] ?? 'TO_DO') }) } function openCreateDialog() { if (!storyId) return router.push(`${pathname}?newTask=1&storyId=${storyId}`) } function openEditDialog(taskId: string) { useSprintWorkspaceStore.getState().setActiveTask(taskId) } return (
{doneCount}/{orderedTasks.length} klaar } />
{orderedTasks.length === 0 ? (

Geen taken voor deze story.

) : ( <> {orderedTasks.map((task) => ( handleStatusToggle(task)} onEdit={() => openEditDialog(task.id)} /> ))} )}
) }