"use client"; import { useMemo, useState } from "react"; import { TaskCard } from "@/components/molecules/TaskCard"; import { cn } from "@/lib/utils"; type Task = { id: string; title: string; status: string; priority: string; description?: string | null; due_at?: string | null; assigned_agent_id?: string | null; assignee?: string; approvalsPendingCount?: number; }; type TaskBoardProps = { tasks: Task[]; onTaskSelect?: (task: Task) => void; onTaskMove?: (taskId: string, status: string) => void; }; const columns = [ { title: "Inbox", status: "inbox", dot: "bg-slate-400", accent: "hover:border-slate-400 hover:bg-slate-50", text: "group-hover:text-slate-700 text-slate-500", badge: "bg-slate-100 text-slate-600", }, { title: "In Progress", status: "in_progress", dot: "bg-purple-500", accent: "hover:border-purple-400 hover:bg-purple-50", text: "group-hover:text-purple-600 text-slate-500", badge: "bg-purple-100 text-purple-700", }, { title: "Review", status: "review", dot: "bg-indigo-500", accent: "hover:border-indigo-400 hover:bg-indigo-50", text: "group-hover:text-indigo-600 text-slate-500", badge: "bg-indigo-100 text-indigo-700", }, { title: "Done", status: "done", dot: "bg-green-500", accent: "hover:border-green-400 hover:bg-green-50", text: "group-hover:text-green-600 text-slate-500", badge: "bg-emerald-100 text-emerald-700", }, ]; const formatDueDate = (value?: string | null) => { if (!value) return undefined; const date = new Date(value); if (Number.isNaN(date.getTime())) return undefined; return date.toLocaleDateString(undefined, { month: "short", day: "numeric", }); }; export function TaskBoard({ tasks, onTaskSelect, onTaskMove, }: TaskBoardProps) { const [draggingId, setDraggingId] = useState(null); const [activeColumn, setActiveColumn] = useState(null); const grouped = useMemo(() => { const buckets: Record = {}; for (const column of columns) { buckets[column.status] = []; } tasks.forEach((task) => { const bucket = buckets[task.status] ?? buckets.inbox; bucket.push(task); }); return buckets; }, [tasks]); const handleDragStart = (task: Task) => (event: React.DragEvent) => { setDraggingId(task.id); event.dataTransfer.effectAllowed = "move"; event.dataTransfer.setData( "text/plain", JSON.stringify({ taskId: task.id, status: task.status }), ); }; const handleDragEnd = () => { setDraggingId(null); setActiveColumn(null); }; const handleDrop = (status: string) => (event: React.DragEvent) => { event.preventDefault(); setActiveColumn(null); const raw = event.dataTransfer.getData("text/plain"); if (!raw) return; try { const payload = JSON.parse(raw) as { taskId?: string; status?: string }; if (!payload.taskId || !payload.status) return; if (payload.status === status) return; onTaskMove?.(payload.taskId, status); } catch { // Ignore malformed payloads. } }; const handleDragOver = (status: string) => (event: React.DragEvent) => { event.preventDefault(); if (activeColumn !== status) { setActiveColumn(status); } }; const handleDragLeave = (status: string) => () => { if (activeColumn === status) { setActiveColumn(null); } }; return (
{columns.map((column) => { const columnTasks = grouped[column.status] ?? []; return (

{column.title}

{columnTasks.length}
{columnTasks.map((task) => ( onTaskSelect?.(task)} draggable isDragging={draggingId === task.id} onDragStart={handleDragStart(task)} onDragEnd={handleDragEnd} /> ))}
); })}
); }