/** * @file dashboard/KanbanBoard.tsx * @description Client component wrapping the kanban columns grid, tracking individual task update/deletion states, and handling asynchronous mutations via API. */ "use client"; import { useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import KanbanColumn from "./KanbanColumn"; import { KANBAN_COLUMNS, Task, TaskStatus } from "@/types/tasks"; import KanbanBoardHeader from "./components/KanbanBoardHeader"; /** * Renders the responsive grid container of kanban columns, coordinating state tracking * for active task updates/deletions and triggering mutation API requests. * * @param {Object} props - The component props. * @param {Task[]} props.tasks - The array of task items displayed across the board. * @returns {JSX.Element} The rendered kanban board component. */ export default function KanbanBoard({ tasks }: { tasks: Task[] }) { const router = useRouter(); const [, startTransition] = useTransition(); const [updatingTaskIds, setUpdatingTaskIds] = useState>( new Set(), ); /** * Updates the status of a specific task by sending a PATCH request to the API, * managing loading states, and refreshing the router upon success. * * @param {string} taskId - The unique identifier of the task to update. * @param {TaskStatus} targetStatus - The new target status for the task. */ const updateTaskStatus = (taskId: string, targetStatus: TaskStatus) => { setUpdatingTaskIds((prev) => new Set(prev).add(taskId)); startTransition(async () => { try { const response = await fetch(`/api/tasks/${taskId}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status: targetStatus }), }); if (!response.ok) { throw new Error("Failed to update task status"); } await router.refresh(); } catch (error) { console.error("Error during task status update:", error); } finally { setUpdatingTaskIds((prev) => { const next = new Set(prev); next.delete(taskId); return next; }); } }); }; /** * Deletes a specific task by sending a DELETE request to the API, * managing loading states, and refreshing the router upon success. * * @param {string} taskId - The unique identifier of the task to delete. */ const deleteTask = (taskId: string) => { setUpdatingTaskIds((prev) => new Set(prev).add(taskId)); startTransition(async () => { try { const response = await fetch(`/api/tasks/${taskId}`, { method: "DELETE", }); if (!response.ok) throw new Error("Failed to delete task"); await router.refresh(); } catch (error) { console.error("Error during task deletion:", error); } finally { setUpdatingTaskIds((prev) => { const next = new Set(prev); next.delete(taskId); return next; }); } }); }; return (
{/* Workspace Header */} {/* Kanban Columns Grid */}
{KANBAN_COLUMNS.map((col) => { const columnTasks = tasks.filter((t) => t.status === col.id); return ( ); })}
); }