feat: enhance Kanban components with new UI elements

- Added `ColumnHeader`, `EmptyState`, and `DropZone` components to improve the Kanban UI structure and user experience.
- Refactored `KanbanColumn` to utilize the new components, enhancing readability and maintainability.
- Updated `Card` component to support flexible props for shadow, border, and background, allowing for better customization across the application.
- Adjusted `SwimlanesBase` to incorporate the new `ColumnHeader` for consistent column representation.
This commit is contained in:
Julien Froidefond
2025-09-28 22:10:12 +02:00
parent 5a3d825b8e
commit 687d02ff3a
9 changed files with 499 additions and 97 deletions

View File

@@ -1,12 +1,11 @@
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 { Card, CardHeader, CardContent, ColumnHeader, EmptyState, DropZone } from '@/components/ui';
import { CreateTaskData } from '@/clients/tasks-client';
import { useState } from 'react';
import { useDroppable } from '@dnd-kit/core';
import { getStatusConfig, getTechStyle, getBadgeVariant } from '@/lib/status-config';
import { getStatusConfig, getTechStyle } from '@/lib/status-config';
interface KanbanColumnProps {
id: TaskStatus;
@@ -27,41 +26,23 @@ export function KanbanColumn({ id, tasks, onCreateTask, onEditTask, compactView
// 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="column"
className={`h-full flex flex-col transition-all duration-200 ${
isOver ? 'ring-2 ring-[var(--primary)]/50 bg-[var(--card-hover)]' : ''
}`}
>
<CardHeader className="pb-4">
<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-[var(--card-hover)] transition-colors flex items-center justify-center text-xs font-mono`}
title="Ajouter une tâche rapide"
>
+
</button>
)}
</div>
</div>
</CardHeader>
<div className="flex-shrink-0 w-72 md:w-72 lg:w-80 h-full">
<DropZone ref={setNodeRef} isOver={isOver}>
<Card variant="column" className="h-full flex flex-col">
<CardHeader className="pb-4">
<ColumnHeader
title={statusConfig.label}
icon={statusConfig.icon}
count={tasks.length}
color={style.accent.replace('text-', '')}
accentColor={style.accent}
borderColor={style.border}
showAddButton={!!onCreateTask}
onAddClick={() => setShowQuickAdd(true)}
/>
</CardHeader>
<CardContent className="flex-1 p-4 h-[calc(100vh-220px)] overflow-y-auto">
<div className="space-y-3">
@@ -78,15 +59,11 @@ export function KanbanColumn({ id, tasks, onCreateTask, onEditTask, compactView
)}
{tasks.length === 0 && !showQuickAdd ? (
<div className="text-center py-20">
<div className={`w-16 h-16 mx-auto mb-4 rounded-full bg-[var(--card)] 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-[var(--muted-foreground)] 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>
<EmptyState
icon={statusConfig.icon}
accentColor={style.accent}
borderColor={style.border}
/>
) : (
tasks.map((task) => (
<TaskCard key={task.id} task={task} onEdit={onEditTask} compactView={compactView} />
@@ -94,7 +71,8 @@ export function KanbanColumn({ id, tasks, onCreateTask, onEditTask, compactView
)}
</div>
</CardContent>
</Card>
</Card>
</DropZone>
</div>
);
}