import { useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useAuthUnified } from "@/hooks/useAuthUnified"; import { useStore } from "@/components/Layout"; import { useToast } from "@/hooks/use-toast"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { Pagination, usePagination } from "@/components/ui/pagination"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { ListTodo, Plus, Search, Circle, Clock, AlertTriangle, CheckCircle, Edit, Trash2 } from "lucide-react"; import { format } from "date-fns"; import { fr } from "date-fns/locale"; import TaskForm from "@/components/tasks/TaskForm"; import { Task } from "@shared/schema"; type TaskWithRelations = Task & { assignedUser: { id: string; username: string; firstName?: string; lastName?: string; }; creator: { id: string; username: string; firstName?: string; lastName?: string; }; group: { id: number; name: string; color: string; }; }; export default function Tasks() { const { user } = useAuthUnified(); const { selectedStoreId } = useStore(); const { toast } = useToast(); const queryClient = useQueryClient(); // États locaux const [searchTerm, setSearchTerm] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); const [priorityFilter, setPriorityFilter] = useState("all"); // Modals const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [showDeleteModal, setShowDeleteModal] = useState(false); const [selectedTask, setSelectedTask] = useState(null); const [taskToDelete, setTaskToDelete] = useState(null); // Fetch tasks const { data: tasks = [], isLoading } = useQuery({ queryKey: ["/api/tasks", selectedStoreId], queryFn: () => { const params = new URLSearchParams(); if (selectedStoreId) { params.append('storeId', selectedStoreId); } return fetch(`/api/tasks?${params.toString()}`, { credentials: 'include' }).then(res => { if (!res.ok) { throw new Error(`HTTP error! status: ${res.status}`); } return res.json(); }); }, enabled: !!user, }); // Fetch users for task assignment const { data: users = [] } = useQuery({ queryKey: ["/api/users"], queryFn: () => fetch('/api/users', { credentials: 'include' }).then(res => { if (!res.ok) { throw new Error(`HTTP error! status: ${res.status}`); } return res.json(); }), enabled: !!user, }); const handleEditTask = (task: TaskWithRelations) => { setSelectedTask(task); setShowEditModal(true); }; const handleCompleteTask = async (taskId: number) => { try { const response = await fetch(`/api/tasks/${taskId}/complete`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, credentials: 'include', body: JSON.stringify({}), }); if (!response.ok) { throw new Error('Erreur lors de la completion de la tâche'); } await queryClient.invalidateQueries({ queryKey: ["/api/tasks"] }); toast({ title: "Succès", description: "Tâche marquée comme terminée", }); } catch (error) { console.error("Error completing task:", error); toast({ title: "Erreur", description: "Impossible de terminer la tâche", variant: "destructive", }); } }; const handleDeleteClick = (task: TaskWithRelations) => { setTaskToDelete(task); setShowDeleteModal(true); }; const handleConfirmDelete = async () => { if (!taskToDelete) return; try { const response = await fetch(`/api/tasks/${taskToDelete.id}`, { method: 'DELETE', credentials: 'include', }); if (!response.ok) { throw new Error('Erreur lors de la suppression'); } await queryClient.invalidateQueries({ queryKey: ["/api/tasks"] }); toast({ title: "Succès", description: "Tâche supprimée avec succès", }); setShowDeleteModal(false); setTaskToDelete(null); } catch (error) { console.error("Error deleting task:", error); toast({ title: "Erreur", description: "Impossible de supprimer la tâche", variant: "destructive", }); } }; // Filtrer les tâches const filteredTasks = tasks.filter((task: TaskWithRelations) => { // Filtre par recherche if (searchTerm && !task.title.toLowerCase().includes(searchTerm.toLowerCase()) && !task.description?.toLowerCase().includes(searchTerm.toLowerCase())) { return false; } // Filtre par statut if (statusFilter !== "all" && task.status !== statusFilter) { return false; } // Filtre par priorité if (priorityFilter !== "all" && task.priority !== priorityFilter) { return false; } return true; }); // Pagination const { currentPage, setCurrentPage, itemsPerPage, setItemsPerPage, totalPages, paginatedData: paginatedTasks, totalItems } = usePagination(filteredTasks, 10); const getPriorityConfig = (priority: string) => { switch (priority) { case 'high': return { color: 'destructive' as const, icon: AlertTriangle, label: 'Élevée' }; case 'medium': return { color: 'default' as const, icon: Clock, label: 'Moyenne' }; case 'low': return { color: 'secondary' as const, icon: Circle, label: 'Faible' }; default: return { color: 'secondary' as const, icon: Circle, label: 'Moyenne' }; } }; const canCreateTasks = user?.role === 'admin' || user?.role === 'manager'; if (isLoading) { return (
); } return (
{/* Header */}

Gestion des Tâches

{totalItems} tâche{totalItems !== 1 ? 's' : ''} trouvée{totalItems !== 1 ? 's' : ''}

{canCreateTasks && ( Créer une nouvelle tâche setShowCreateModal(false)} /> )}
{/* Sidebar avec filtres */}
{/* Filtres */} Filtres {/* Recherche */}
setSearchTerm(e.target.value)} className="pl-10" />
{/* Filtre par statut */}
{/* Filtre par priorité */}
{/* Zone principale avec les tâches */}
{/* Liste des tâches */}
{totalItems === 0 ? (

Aucune tâche

Aucune tâche trouvée avec les filtres sélectionnés.

) : (
{/* Tâches en cours */} {paginatedTasks.filter(task => task.status === 'pending').length > 0 && (

Tâches en cours ({paginatedTasks.filter(task => task.status === 'pending').length})

{paginatedTasks .filter(task => task.status === 'pending') .map((task) => { const priorityConfig = getPriorityConfig(task.priority); const PriorityIcon = priorityConfig.icon; return (
{task.title}
{priorityConfig.label}
{task.description && (

{task.description}

)}
Assigné à: {task.assignedTo} Créée: {format(new Date(task.createdAt), 'dd/MM/yyyy HH:mm', { locale: fr })}
); })}
)} {/* Tâches terminées */} {paginatedTasks.filter(task => task.status === 'completed').length > 0 && (

Tâches terminées ({paginatedTasks.filter(task => task.status === 'completed').length})

{paginatedTasks .filter(task => task.status === 'completed') .map((task) => { const priorityConfig = getPriorityConfig(task.priority); const PriorityIcon = priorityConfig.icon; return (
{task.title}
Terminée
{task.description && (

{task.description}

)}
Assigné à: {task.assignedTo} Créée: {format(new Date(task.createdAt), 'dd/MM/yyyy HH:mm', { locale: fr })} {task.completedAt && ( Terminée: {format(new Date(task.completedAt), 'dd/MM/yyyy HH:mm', { locale: fr })} )}
); })}
)}
)} {/* Pagination */} {totalItems > 0 && ( )}
{/* Modal d'édition */} Modifier la tâche {selectedTask && ( { setShowEditModal(false); setSelectedTask(null); }} /> )} {/* Modal de confirmation de suppression */} Confirmer la suppression

Êtes-vous sûr de vouloir supprimer la tâche "{taskToDelete?.title}" ?

Cette action est irréversible.

); }