// frontend/components/tasks/KanbanView.tsx "use client"; import { useState } from "react"; import { Icon } from "@/components/Icon"; import { cx } from "@/lib/cx"; import { COLUMNS } from "@/lib/tasks/tree"; import type { Person, Project, Status, Task } from "@/lib/types"; import { KanbanCard } from "./KanbanCard"; export function KanbanView({ tasks, people, projects, onOpen, onMove, onAdd, }: { tasks: Task[]; people: Record; projects: Record; onOpen: (id: string) => void; onMove: (id: string, status: Status) => void; onAdd: (status: Status, title: string) => void; }) { const [dragId, setDragId] = useState(null); const [overCol, setOverCol] = useState(null); const [addCol, setAddCol] = useState(null); const [text, setText] = useState(""); const submit = (status: Status) => { if (text.trim()) onAdd(status, text.trim()); setText(""); setAddCol(null); }; return (
{COLUMNS.map((col) => { const items = tasks.filter((t) => t.status === col.id); return (
{ e.preventDefault(); if (overCol !== col.id) setOverCol(col.id); }} onDragLeave={(e) => { if (e.currentTarget === e.target) setOverCol(null); }} onDrop={(e) => { e.preventDefault(); if (dragId) onMove(dragId, col.id as Status); setDragId(null); setOverCol(null); }} >
{col.label} {items.length}
{addCol === col.id && (
setText(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(col.id as Status); if (e.key === "Escape") setAddCol(null); }} onBlur={() => submit(col.id as Status)} />
)} {items.map((t) => ( { setDragId(t.id); e.dataTransfer.effectAllowed = "move"; }} onDragEnd={() => { setDragId(null); setOverCol(null); }} /> ))} {items.length === 0 && addCol !== col.id && (
여기로 작업을 옮겨보세요
)}
); })}
); }