import { useEffect, useState, useCallback, useRef } from 'react' import { Columns3, PauseCircle } from 'lucide-react' import type { Task } from '../types' import { fetchTasks, updateTask } from '../api' import { useTaskDrawer } from '../components/TaskDrawer' import { useStatuses } from '../context/StatusesContext' import { PriorityBadge, dueInfo, CategoryFilter } from '../components/shared' export default function BoardView() { const { openTask, changeVersion } = useTaskDrawer() const { statuses } = useStatuses() const [tasks, setTasks] = useState([]) const [error, setError] = useState(null) const [over, setOver] = useState(null) const [categoryFilter, setCategoryFilter] = useState([]) const dragId = useRef(null) const load = useCallback(() => { fetchTasks({}).then(setTasks).catch(e => setError(e.message)) }, []) useEffect(() => { load() }, [load, changeVersion]) async function drop(status: string) { const id = dragId.current dragId.current = null setOver(null) if (id === null) return const task = tasks.find(t => t.id === id) if (!task || task.status === status) return setTasks(ts => ts.map(t => t.id === id ? { ...t, status } : t)) await updateTask(id, { status }).catch(() => load()) load() } const visibleTasks = categoryFilter.length === 0 ? tasks : tasks.filter(t => t.category_id !== null && categoryFilter.includes(t.category_id)) return (

Board

{error &&
{error}
}
{statuses.map(status => { const items = visibleTasks.filter(t => t.status === status.value) return (
{ e.preventDefault(); setOver(status.value) }} onDragLeave={() => setOver(o => o === status.value ? null : o)} onDrop={() => drop(status.value)}>
{status.is_hold && } {status.label} {items.length}
{items.map(t => (
{ dragId.current = t.id }} onClick={() => openTask(t.id)}>
{t.title}
{t.list_name && ( {t.list_name} )} {t.category_name && ( {t.category_name} )} {(() => { const d = dueInfo(t.due_at); return d && {d.label} })()}
))} {items.length === 0 &&
—
}
) })}
) }