'use client'; import { useState, useEffect, useRef } from 'react'; import { createPortal } from 'react-dom'; import { TaskPriority } from '@/lib/types'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; import { useTasksContext } from '@/contexts/TasksContext'; import { getAllPriorities, getPriorityColorHex } from '@/lib/status-config'; import { SORT_OPTIONS } from '@/lib/sort-config'; export interface KanbanFilters { search?: string; tags?: string[]; priorities?: TaskPriority[]; showCompleted?: boolean; compactView?: boolean; swimlanesByTags?: boolean; pinnedTag?: string; // Tag pour les objectifs principaux sortBy?: string; // Clé de l'option de tri sélectionnée } interface KanbanFiltersProps { filters: KanbanFilters; onFiltersChange: (filters: KanbanFilters) => void; } export function KanbanFilters({ filters, onFiltersChange }: KanbanFiltersProps) { const { tags: availableTags } = useTasksContext(); const [isExpanded, setIsExpanded] = useState(false); const [isSortExpanded, setIsSortExpanded] = useState(false); const sortDropdownRef = useRef(null); const sortButtonRef = useRef(null); const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 }); // Fermer le dropdown de tri en cliquant à l'extérieur useEffect(() => { function handleClickOutside(event: MouseEvent) { if (sortDropdownRef.current && !sortDropdownRef.current.contains(event.target as Node)) { setIsSortExpanded(false); } } if (isSortExpanded) { document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); } }, [isSortExpanded]); const handleSearchChange = (search: string) => { onFiltersChange({ ...filters, search: search || undefined }); }; const handleTagToggle = (tagName: string) => { const currentTags = filters.tags || []; const newTags = currentTags.includes(tagName) ? currentTags.filter(t => t !== tagName) : [...currentTags, tagName]; onFiltersChange({ ...filters, tags: newTags.length > 0 ? newTags : undefined }); }; const handlePriorityToggle = (priority: TaskPriority) => { const currentPriorities = filters.priorities || []; const newPriorities = currentPriorities.includes(priority) ? currentPriorities.filter(p => p !== priority) : [...currentPriorities, priority]; onFiltersChange({ ...filters, priorities: newPriorities.length > 0 ? newPriorities : undefined }); }; const handleCompactViewToggle = () => { onFiltersChange({ ...filters, compactView: !filters.compactView }); }; const handleSwimlanesToggle = () => { onFiltersChange({ ...filters, swimlanesByTags: !filters.swimlanesByTags }); }; const handleSortChange = (sortKey: string) => { onFiltersChange({ ...filters, sortBy: sortKey }); }; const handleSortToggle = () => { if (!isSortExpanded && sortButtonRef.current) { const rect = sortButtonRef.current.getBoundingClientRect(); setDropdownPosition({ top: rect.bottom + window.scrollY + 4, left: rect.left + window.scrollX }); } setIsSortExpanded(!isSortExpanded); }; const handleClearFilters = () => { onFiltersChange({}); }; const activeFiltersCount = (filters.tags?.length || 0) + (filters.priorities?.length || 0) + (filters.search ? 1 : 0); const priorityOptions = getAllPriorities().map(priorityConfig => ({ value: priorityConfig.key, label: priorityConfig.label, color: priorityConfig.color })); return (
{/* Header avec recherche et bouton expand */}
handleSearchChange(e.target.value)} placeholder="Rechercher des tâches..." className="bg-slate-800/50 border-slate-600" />
{/* Bouton swimlanes par tags */} {/* Bouton vue compacte */} {/* Bouton de tri */}
{activeFiltersCount > 0 && ( )}
{/* Filtres étendus */} {isExpanded && (
{/* Filtres par priorité */}
{priorityOptions.map((priority) => ( ))}
{/* Filtres par tags */} {availableTags.length > 0 && (
{availableTags.map((tag) => ( ))}
)} {/* Résumé des filtres actifs */} {activeFiltersCount > 0 && (
Filtres actifs
{filters.search && (
Recherche: “{filters.search}”
)} {filters.priorities?.length && (
Priorités: {filters.priorities.join(', ')}
)} {filters.tags?.length && (
Tags: {filters.tags.join(', ')}
)}
)}
)}
{/* Dropdown de tri rendu via portail pour éviter les problèmes de z-index */} {isSortExpanded && typeof window !== 'undefined' && createPortal(
{SORT_OPTIONS.map((option) => ( ))}
, document.body )}
); }