- Added `cancelled` and `freeze` statuses to `TasksResponse`, `HomePageClientProps`, and `useTasks` for comprehensive task tracking. - Updated task forms to dynamically load statuses using `getAllStatuses`, enhancing maintainability and reducing hardcoded values. - Refactored Kanban components to utilize centralized status configuration, improving consistency across the application. - Adjusted visibility toggle and swimlanes to reflect new status options, ensuring a seamless user experience.
103 lines
4.2 KiB
TypeScript
103 lines
4.2 KiB
TypeScript
import { Task, TaskStatus } from '@/lib/types';
|
|
import { TaskCard } from './TaskCard';
|
|
import { QuickAddTask } from './QuickAddTask';
|
|
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
|
import { Badge } from '@/components/ui/Badge';
|
|
import { CreateTaskData } from '@/clients/tasks-client';
|
|
import { useState } from 'react';
|
|
import { useDroppable } from '@dnd-kit/core';
|
|
import { getStatusConfig, getTechStyle, getBadgeVariant } from '@/lib/status-config';
|
|
|
|
interface KanbanColumnProps {
|
|
id: TaskStatus;
|
|
tasks: Task[];
|
|
onCreateTask?: (data: CreateTaskData) => Promise<void>;
|
|
onDeleteTask?: (taskId: string) => Promise<void>;
|
|
onEditTask?: (task: Task) => void;
|
|
onUpdateTitle?: (taskId: string, newTitle: string) => Promise<void>;
|
|
compactView?: boolean;
|
|
}
|
|
|
|
export function KanbanColumn({ id, tasks, onCreateTask, onDeleteTask, onEditTask, onUpdateTitle, compactView = false }: KanbanColumnProps) {
|
|
const [showQuickAdd, setShowQuickAdd] = useState(false);
|
|
|
|
// Configuration de la zone droppable
|
|
const { setNodeRef, isOver } = useDroppable({
|
|
id: id,
|
|
});
|
|
|
|
// Récupération de la config du statut
|
|
const statusConfig = getStatusConfig(id);
|
|
const style = getTechStyle(statusConfig.color);
|
|
const badgeVariant = getBadgeVariant(statusConfig.color);
|
|
|
|
return (
|
|
<div className="flex-shrink-0 w-80 md:w-1/4 md:flex-1 h-full">
|
|
<Card
|
|
ref={setNodeRef}
|
|
variant="elevated"
|
|
className={`h-full flex flex-col transition-all duration-200 ${
|
|
isOver ? 'ring-2 ring-cyan-400/50 bg-slate-800/60' : ''
|
|
}`}
|
|
>
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
<div className={`w-2 h-2 rounded-full ${style.accent.replace('text-', 'bg-')} animate-pulse`}></div>
|
|
<h3 className={`font-mono text-sm font-bold ${style.accent} uppercase tracking-wider`}>
|
|
{statusConfig.label} {statusConfig.icon}
|
|
</h3>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<Badge variant={badgeVariant} size="sm">
|
|
{String(tasks.length).padStart(2, '0')}
|
|
</Badge>
|
|
{onCreateTask && (
|
|
<button
|
|
onClick={() => setShowQuickAdd(true)}
|
|
className={`w-5 h-5 rounded-full border border-dashed ${style.border} ${style.accent} hover:bg-slate-800/50 transition-colors flex items-center justify-center text-xs font-mono`}
|
|
title="Ajouter une tâche rapide"
|
|
>
|
|
+
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</CardHeader>
|
|
|
|
<CardContent className="flex-1 p-4 h-[calc(100vh-220px)] overflow-y-auto">
|
|
<div className="space-y-3">
|
|
{/* Quick Add Task */}
|
|
{showQuickAdd && onCreateTask && (
|
|
<QuickAddTask
|
|
status={id}
|
|
onSubmit={async (data) => {
|
|
await onCreateTask(data);
|
|
// Ne pas fermer automatiquement pour permettre la création en série
|
|
}}
|
|
onCancel={() => setShowQuickAdd(false)}
|
|
/>
|
|
)}
|
|
|
|
{tasks.length === 0 && !showQuickAdd ? (
|
|
<div className="text-center py-20">
|
|
<div className={`w-16 h-16 mx-auto mb-4 rounded-full bg-slate-800 border-2 border-dashed ${style.border} flex items-center justify-center`}>
|
|
<span className={`text-2xl ${style.accent} opacity-50`}>{statusConfig.icon}</span>
|
|
</div>
|
|
<p className="text-xs font-mono text-slate-500 uppercase tracking-wide">NO DATA</p>
|
|
<div className="mt-2 flex justify-center">
|
|
<div className={`w-8 h-0.5 ${style.accent.replace('text-', 'bg-')} opacity-30`}></div>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
tasks.map((task) => (
|
|
<TaskCard key={task.id} task={task} onDelete={onDeleteTask} onEdit={onEditTask} onUpdateTitle={onUpdateTitle} compactView={compactView} />
|
|
))
|
|
)}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|