Files
stack/apps/web/src/components/tasks/kanban-board.tsx
Jason Woltje c0b798daf3 feat(web): task management with list view and kanban board
Add task management page with dual view modes (list table and kanban
columns). Tasks are fetched from the gateway API and displayed with
status badges, priority indicators, and due dates. Kanban columns
map to task statuses: not-started, in-progress, blocked, done.

Components: TaskCard, KanbanBoard, TaskListView
Types: Task, TaskStatus, TaskPriority, Project, ProjectStatus

Refs #29

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:27:38 -05:00

48 lines
1.6 KiB
TypeScript

'use client';
import type { Task, TaskStatus } from '@/lib/types';
import { TaskCard } from './task-card';
interface KanbanBoardProps {
tasks: Task[];
onTaskClick: (task: Task) => void;
}
const columns: { id: TaskStatus; label: string }[] = [
{ id: 'not-started', label: 'Not Started' },
{ id: 'in-progress', label: 'In Progress' },
{ id: 'blocked', label: 'Blocked' },
{ id: 'done', label: 'Done' },
];
export function KanbanBoard({ tasks, onTaskClick }: KanbanBoardProps): React.ReactElement {
return (
<div className="flex gap-4 overflow-x-auto pb-4">
{columns.map((col) => {
const columnTasks = tasks.filter((t) => t.status === col.id);
return (
<div
key={col.id}
className="flex w-72 shrink-0 flex-col rounded-lg border border-surface-border bg-surface-elevated"
>
<div className="flex items-center justify-between border-b border-surface-border px-3 py-2">
<h3 className="text-sm font-medium text-text-secondary">{col.label}</h3>
<span className="rounded-full bg-surface-card px-2 py-0.5 text-xs text-text-muted">
{columnTasks.length}
</span>
</div>
<div className="flex-1 space-y-2 p-2">
{columnTasks.length === 0 && (
<p className="py-4 text-center text-xs text-text-muted">No tasks</p>
)}
{columnTasks.map((task) => (
<TaskCard key={task.id} task={task} onClick={onTaskClick} />
))}
</div>
</div>
);
})}
</div>
);
}