'use client'; import { Task, TaskStatus } from '@/lib/types'; import { TaskCard } from './TaskCard'; import { QuickAddTask } from './QuickAddTask'; import { CreateTaskForm } from '@/components/forms/CreateTaskForm'; import { Button } from '@/components/ui/Button'; import { CreateTaskData } from '@/clients/tasks-client'; import { useState } from 'react'; import { useColumnVisibility } from '@/hooks/useColumnVisibility'; import { getAllStatuses } from '@/lib/status-config'; import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, closestCenter, PointerSensor, useSensor, useSensors, } from '@dnd-kit/core'; import { SortableContext, verticalListSortingStrategy, } from '@dnd-kit/sortable'; import { useDroppable } from '@dnd-kit/core'; // Composant pour les colonnes droppables function DroppableColumn({ status, tasks, onDeleteTask, onEditTask, onUpdateTitle, compactView, onCreateTask, showQuickAdd, onToggleQuickAdd }: { status: TaskStatus; tasks: Task[]; onDeleteTask?: (taskId: string) => Promise; onEditTask?: (task: Task) => void; onUpdateTitle?: (taskId: string, newTitle: string) => Promise; compactView: boolean; onCreateTask?: (data: CreateTaskData) => Promise; showQuickAdd?: boolean; onToggleQuickAdd?: () => void; }) { const { setNodeRef } = useDroppable({ id: status, }); return (
t.id)} strategy={verticalListSortingStrategy}>
{tasks.map(task => ( ))}
{/* QuickAdd pour cette colonne */} {onCreateTask && (
{showQuickAdd ? ( {})} /> ) : ( )}
)}
); } // Interface pour une swimlane export interface SwimlaneData { key: string; label: string; icon?: string; color?: string; tasks: Task[]; } interface SwimlanesBaseProps { tasks: Task[]; title: string; swimlanes: SwimlaneData[]; onCreateTask?: (data: CreateTaskData) => Promise; onDeleteTask?: (taskId: string) => Promise; onEditTask?: (task: Task) => void; onUpdateTitle?: (taskId: string, newTitle: string) => Promise; onUpdateStatus?: (taskId: string, newStatus: TaskStatus) => Promise; compactView?: boolean; visibleStatuses?: TaskStatus[]; loading?: boolean; } export function SwimlanesBase({ tasks, title, swimlanes, onCreateTask, onDeleteTask, onEditTask, onUpdateTitle, onUpdateStatus, compactView = false, visibleStatuses, loading = false }: SwimlanesBaseProps) { const [activeTask, setActiveTask] = useState(null); const [collapsedSwimlanes, setCollapsedSwimlanes] = useState>(new Set()); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [showQuickAdd, setShowQuickAdd] = useState<{ [key: string]: boolean }>({}); // Gestion de la visibilité des colonnes const { getVisibleStatuses } = useColumnVisibility(); const allStatuses = getAllStatuses(); const statusesToShow = visibleStatuses || getVisibleStatuses(allStatuses.map(s => ({ id: s.key }))).map(s => s.id); // Configuration des sensors pour le drag & drop const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 8, }, }) ); // Handlers pour le drag & drop const handleDragStart = (event: DragStartEvent) => { const task = tasks.find(t => t.id === event.active.id); setActiveTask(task || null); }; 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; // Vérifier si le statut a changé const task = tasks.find(t => t.id === taskId); if (task && task.status !== newStatus) { await onUpdateStatus(taskId, newStatus); } }; // Basculer l'état d'une swimlane const toggleSwimlane = (swimlaneKey: string) => { const newCollapsed = new Set(collapsedSwimlanes); if (newCollapsed.has(swimlaneKey)) { newCollapsed.delete(swimlaneKey); } else { newCollapsed.add(swimlaneKey); } setCollapsedSwimlanes(newCollapsed); }; // Handlers pour la création de tâches const handleCreateTask = async (data: CreateTaskData) => { if (onCreateTask) { await onCreateTask(data); setIsCreateModalOpen(false); } }; const handleQuickAdd = async (data: CreateTaskData, columnId: string) => { if (onCreateTask) { await onCreateTask(data); setShowQuickAdd(prev => ({ ...prev, [columnId]: false })); } }; const toggleQuickAdd = (columnId: string) => { setShowQuickAdd(prev => ({ ...prev, [columnId]: !prev[columnId] })); }; return (
{/* Header */}

{title}

{onCreateTask && ( )}
{/* Headers des colonnes visibles */}
{statusesToShow.map(status => { const statusConfig = allStatuses.find(s => s.key === status); return (

{statusConfig?.icon} {statusConfig?.label}

); })}
{/* Swimlanes */}
{swimlanes.map(swimlane => { const isCollapsed = collapsedSwimlanes.has(swimlane.key); return (
{/* Header de la swimlane */}
{/* Contenu de la swimlane */} {!isCollapsed && (
{statusesToShow.map(status => { const statusTasks = swimlane.tasks.filter(task => task.status === status); const columnId = `${swimlane.key}-${status}`; return ( handleQuickAdd(data, columnId) : undefined} showQuickAdd={showQuickAdd[columnId] || false} onToggleQuickAdd={() => toggleQuickAdd(columnId)} /> ); })}
)}
); })}
{/* Drag overlay */} {activeTask && ( )} {/* Modal de création complète */} {onCreateTask && ( setIsCreateModalOpen(false)} onSubmit={handleCreateTask} loading={loading} /> )}
); }