Files
vt-fe/src/routes/_sidebar/kanban.tsx

161 lines
4.8 KiB
TypeScript

import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Kanban, KanbanBoard, KanbanColumn, KanbanColumnHandle, KanbanItem, KanbanOverlay } from '@/components/ui/kanban'
import { createFileRoute } from '@tanstack/react-router'
import { GripVertical } from 'lucide-react'
import { useState } from 'react'
export const Route = createFileRoute('/_sidebar/kanban')({
component: RouteComponent,
beforeLoad: () => {
return {
breadcrumb: 'Kanban',
}
},
})
const kanbanboard = {
columns: [
{
id: 0,
name: 'Backlog'
},
{
id: 1,
name: 'Todo'
},
{
id: 2,
name: 'Doing'
},
{
id: 3,
name: 'Done'
},
{
id: 4,
name: 'Backlog'
},
{
id: 5,
name: 'Todo'
},
{
id: 6,
name: 'Doing'
},
{
id: 7,
name: 'Done'
},
],
}
interface Task {
id: string;
title: string;
priority: "low" | "medium" | "high";
assignee?: string;
dueDate?: string;
}
const COLUMN_TITLES: Record<string, string> = {
backlog: "Backlog",
inProgress: "In Progress",
done: "Done",
};
function RouteComponent() {
// const [columns, setColumns] = useState(kanbanboard.columns)
const [columns, setColumns] = useState<string[]>([
"backlog",
"inProgress",
"done",
"sprintbacl",
"toStart",
"notDone",
]);
return (
<div className="h-full w-full">
<Kanban value={columns} onValueChange={setColumns} getItemValue={(c) => c.id}>
<KanbanBoard className="flex min-w-full overflow-scroll">
{Object.entries(columns).map(([columnValue]) => (
<KanbanColumn key={columnValue} value={columnValue} className='min-w-md'>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span className="font-semibold text-sm">
{COLUMN_TITLES[columnValue]}
</span>
<Badge
variant="secondary"
className="pointer-events-none rounded-sm"
>
0
</Badge>
</div>
<KanbanColumnHandle asChild>
<Button variant="ghost" size="icon">
<GripVertical className="h-4 w-4" />
</Button>
</KanbanColumnHandle>
</div>
<div className="flex flex-col gap-2 p-0.5">
{/* List Tasks using Tanstack Query
{tasks.map((task) => (
<KanbanItem key={task.id} value={task.id} asHandle asChild>
<div className="rounded-md border bg-card p-3 shadow-xs">
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between gap-2">
<span className="line-clamp-1 font-medium text-sm">
{task.title}
</span>
<Badge
variant={
task.priority === "high"
? "destructive"
: task.priority === "medium"
? "default"
: "secondary"
}
className="pointer-events-none h-5 rounded-sm px-1.5 text-[11px] capitalize"
>
{task.priority}
</Badge>
</div>
<div className="flex items-center justify-between text-muted-foreground text-xs">
{task.assignee && (
<div className="flex items-center gap-1">
<div className="size-2 rounded-full bg-primary/20" />
<span className="line-clamp-1">
{task.assignee}
</span>
</div>
)}
{task.dueDate && (
<time className="text-[10px] tabular-nums">
{task.dueDate}
</time>
)}
</div>
</div>
</div>
</KanbanItem>
))}
*/}
</div>
</KanbanColumn>
))}
</KanbanBoard>
<KanbanOverlay>
<div className="size-full rounded-md bg-primary/10" />
</KanbanOverlay>
</Kanban>
</div>
)
}