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>
48 lines
1.6 KiB
TypeScript
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>
|
|
);
|
|
}
|