Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.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>
|
|
);
|
|
}
|