Scrum4Me/components/solo/solo-column.tsx
Madhura68 e1903bc16c feat(ST-356): add solo Kanban board with DnD and Zustand store
- useSoloStore: initTasks, optimisticMove (returns prev status), rollback, updatePlan
- SoloBoard: DndContext with PointerSensor (distance:5), closestCorners, 3 columns
- SoloColumn: useDroppable per status, MD3 status-color headers, task count, empty state
- SoloTaskCard + SoloTaskCardOverlay: useDraggable (disabled for demo), priority left-border
- onDragEnd: optimisticMove → updateTaskStatusAction → rollback + toast on error
- REVIEW tasks mapped to IN_PROGRESS column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 16:54:52 +02:00

64 lines
1.8 KiB
TypeScript

'use client'
import { useDroppable } from '@dnd-kit/core'
import { cn } from '@/lib/utils'
import { SoloTaskCard } from './solo-task-card'
import type { SoloTask } from './solo-board'
export const COLUMN_CONFIG = {
TO_DO: {
label: 'To Do',
headerClass: 'bg-status-todo/15 text-status-todo border-b border-status-todo/20',
},
IN_PROGRESS: {
label: 'Bezig',
headerClass: 'bg-status-in-progress/15 text-status-in-progress border-b border-status-in-progress/20',
},
DONE: {
label: 'Klaar',
headerClass: 'bg-status-done/15 text-status-done border-b border-status-done/20',
},
} as const
export type ColumnStatus = keyof typeof COLUMN_CONFIG
interface SoloColumnProps {
status: ColumnStatus
tasks: SoloTask[]
isDemo: boolean
onTaskClick: (task: SoloTask) => void
}
export function SoloColumn({ status, tasks, isDemo, onTaskClick }: SoloColumnProps) {
const { setNodeRef, isOver } = useDroppable({ id: status })
const config = COLUMN_CONFIG[status]
return (
<div
ref={setNodeRef}
className={cn(
'flex flex-col rounded-lg border border-border overflow-hidden',
isOver && 'ring-2 ring-primary ring-inset',
)}
>
<div className={cn('flex items-center gap-2 px-3 py-2', config.headerClass)}>
<span className="text-sm font-medium">{config.label}</span>
<span className="text-xs opacity-60 ml-auto">{tasks.length}</span>
</div>
<div className="flex-1 flex flex-col gap-2 p-2 overflow-y-auto min-h-[140px]">
{tasks.map(task => (
<SoloTaskCard
key={task.id}
task={task}
isDemo={isDemo}
onClick={() => onTaskClick(task)}
/>
))}
{tasks.length === 0 && (
<p className="text-xs text-muted-foreground text-center py-8">Geen taken</p>
)}
</div>
</div>
)
}