'use client'; import { Task, TaskStatus } from '@/lib/types'; import { KanbanColumn } from './Column'; import { Button } from '@/components/ui/Button'; import { CreateTaskForm } from '@/components/forms/CreateTaskForm'; import { CreateTaskData } from '@/clients/tasks-client'; import { useMemo, useState } from 'react'; import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, PointerSensor, useSensor, useSensors, } from '@dnd-kit/core'; import { TaskCard } from './TaskCard'; interface KanbanBoardProps { tasks: Task[]; onCreateTask?: (data: CreateTaskData) => Promise; onDeleteTask?: (taskId: string) => Promise; onEditTask?: (task: Task) => void; onUpdateTitle?: (taskId: string, newTitle: string) => Promise; onUpdateStatus?: (taskId: string, newStatus: TaskStatus) => Promise; loading?: boolean; compactView?: boolean; } export function KanbanBoard({ tasks, onCreateTask, onDeleteTask, onEditTask, onUpdateTitle, onUpdateStatus, loading = false, compactView = false }: KanbanBoardProps) { const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [activeTask, setActiveTask] = useState(null); // Configuration des capteurs pour le drag & drop const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 8, // Évite les clics accidentels }, }) ); // Organiser les tâches par statut const tasksByStatus = useMemo(() => { const grouped = tasks.reduce((acc, task) => { if (!acc[task.status]) { acc[task.status] = []; } acc[task.status].push(task); return acc; }, {} as Record); return grouped; }, [tasks]); // Configuration des colonnes const columns: Array<{ id: TaskStatus; title: string; color: string; tasks: Task[]; }> = [ { id: 'todo', title: 'À faire', color: 'gray', tasks: tasksByStatus.todo || [] }, { id: 'in_progress', title: 'En cours', color: 'blue', tasks: tasksByStatus.in_progress || [] }, { id: 'done', title: 'Terminé', color: 'green', tasks: tasksByStatus.done || [] }, { id: 'cancelled', title: 'Annulé', color: 'red', tasks: tasksByStatus.cancelled || [] } ]; const handleCreateTask = async (data: CreateTaskData) => { if (onCreateTask) { await onCreateTask(data); } }; // Gestion du début du drag const handleDragStart = (event: DragStartEvent) => { const { active } = event; const task = tasks.find(t => t.id === active.id); setActiveTask(task || null); }; // Gestion de la fin du drag const handleDragEnd = async (event: DragEndEvent) => { const { active, over } = event; setActiveTask(null); if (!over || !onUpdateStatus) return; const taskId = active.id as string; const newStatus = over.id as TaskStatus; // Trouver la tâche actuelle const task = tasks.find(t => t.id === taskId); if (!task || task.status === newStatus) return; // Mettre à jour le statut await onUpdateStatus(taskId, newStatus); }; return (
{/* Header avec bouton nouvelle tâche */}

Kanban Board

{onCreateTask && ( )}
{/* Board tech dark */}
{columns.map((column) => ( ))}
{/* Modal de création */} {onCreateTask && ( setIsCreateModalOpen(false)} onSubmit={handleCreateTask} loading={loading} /> )}
{/* Overlay pour le drag & drop */} {activeTask ? (
) : null}
); }