/** * @file dashboard/KanbanColumn.tsx * @description Client component rendering an single kanban column container supporting drag-and-drop task reordering, status updates, and interactive card layouts. */ "use client"; import { useState, useTransition } from "react"; import { Plus } from "lucide-react"; import { useRouter } from "next/navigation"; import KanbanCard from "./KanbanCard"; import { KanbanColumnProps, TaskStatus } from "@/types/tasks"; /** * Renders a kanban column with title indicators, task counters, drag-and-drop event handlers, * and lists of nested KanbanCard items. * * @param {KanbanColumnProps} props - The component props including column ID, title, count, tasks, and color configuration. * @returns {JSX.Element} The rendered kanban column component. */ export default function KanbanColumn(props: KanbanColumnProps) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const [isDraggingOver, setIsDraggingOver] = useState(false); const indicatorColor = props.color ?? "bg-primary"; /** * Updates the status of a task via a state transition and refreshes the router data. * * @param {string} taskId - The unique identifier of the task being updated. * @param {TaskStatus} targetStatus - The new target status category for the task. */ const updateTaskStatus = (taskId: string, targetStatus: TaskStatus) => { startTransition(async () => { try { // TODO: Implement actual API endpoint for updating task status console.log(`Successfully moved task ${taskId} to ${targetStatus}`); router.refresh(); } catch (error) { console.error("Error during task status update:", error); } }); }; /** * Handles the drag-over event to allow dropping items onto the column. * * @param {React.DragEvent} e - The drag event object. */ const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); setIsDraggingOver(true); }; /** * Handles the drag-leave event when a dragged item leaves the column bounds. */ const handleDragLeave = () => { setIsDraggingOver(false); }; /** * Initiates the drag action on a task card, storing its ID and current status in the data transfer payload. * * @param {React.DragEvent} e - The drag event object. * @param {string} taskId - The identifier of the task being dragged. * @param {TaskStatus} currentStatus - The original status category of the task. */ const handleDragStart = ( e: React.DragEvent, taskId: string, currentStatus: TaskStatus, ) => { e.dataTransfer.setData("text/plain", taskId); e.dataTransfer.setData("sourceStatus", currentStatus); }; /** * Handles dropping a task card onto the column, triggering status updates if valid. * * @param {React.DragEvent} e - The drop event object. */ const handleDrop = (e: React.DragEvent) => { e.preventDefault(); setIsDraggingOver(false); const taskId = e.dataTransfer.getData("text/plain"); const sourceStatus = e.dataTransfer.getData("sourceStatus") as TaskStatus; if (!taskId || sourceStatus === props.id) return; updateTaskStatus(taskId, props.id); }; return (
{/* Column Header */}

{props.title}

{props.count}
{/* Card List */}
{props.tasks.length === 0 ? (
No tasks
) : ( props.tasks.map((task) => (
handleDragStart(e, task.id, task.status)} className="group relative bg-card/40 border border-border/80 hover:border-primary/60 p-4 rounded-2xl shadow-sm hover:shadow-xl transition-all duration-300 space-y-3 cursor-grab active:cursor-grabbing hover:-translate-y-0.5" >
)) )}
); }