diff --git a/client/src/pages/AdminSessionInscrits.tsx b/client/src/pages/AdminSessionInscrits.tsx index c53d7f1..790300e 100644 --- a/client/src/pages/AdminSessionInscrits.tsx +++ b/client/src/pages/AdminSessionInscrits.tsx @@ -4,8 +4,11 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { trpc } from "@/lib/trpc"; -import { ArrowLeft, Download, Mail } from "lucide-react"; +import { ArrowLeft, Download, Mail, Search, SlidersHorizontal } from "lucide-react"; import { useLocation, useRoute } from "wouter"; +import { useState, useMemo } from "react"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; import { Skeleton } from "@/components/ui/skeleton"; import { toast } from "sonner"; @@ -13,6 +16,12 @@ export default function AdminSessionInscrits() { const [, setLocation] = useLocation(); const [, params] = useRoute("/admin/sessions/:id/inscrits"); const sessionId = params?.id ? parseInt(params.id) : 0; + + // États pour les filtres + const [searchTerm, setSearchTerm] = useState(""); + const [filterStatut, setFilterStatut] = useState("all"); + const [filterEtablissement, setFilterEtablissement] = useState("all"); + const [sortBy, setSortBy] = useState<"date" | "nom">("date"); const utils = trpc.useUtils(); const { data: session, isLoading: loadingSession } = trpc.sessions.getById.useQuery({ id: sessionId }); @@ -115,6 +124,49 @@ export default function AdminSessionInscrits() { return formations?.find(f => f.id === formationId)?.nom || "Formation inconnue"; }; + // Extraire les codes établissement uniques + const uniqueEtablissements = useMemo(() => { + if (!inscriptions) return []; + const codes = inscriptions + .filter(i => i.apprenant) + .map(i => i.apprenant!.codeEtablissement); + return Array.from(new Set(codes)).sort(); + }, [inscriptions]); + + // Filtrer et trier les inscriptions + const filteredAndSortedInscriptions = useMemo(() => { + if (!inscriptions) return []; + + let filtered = inscriptions.filter(inscription => { + // Filtre par recherche (nom, prénom, email) + const matchesSearch = searchTerm === "" || + inscription.apprenant?.nom.toLowerCase().includes(searchTerm.toLowerCase()) || + inscription.apprenant?.prenom.toLowerCase().includes(searchTerm.toLowerCase()) || + inscription.apprenant?.email.toLowerCase().includes(searchTerm.toLowerCase()); + + // Filtre par statut + const matchesStatut = filterStatut === "all" || inscription.inscription.statut === filterStatut; + + // Filtre par établissement + const matchesEtablissement = filterEtablissement === "all" || + inscription.apprenant?.codeEtablissement === filterEtablissement; + + return matchesSearch && matchesStatut && matchesEtablissement; + }); + + // Tri + filtered.sort((a, b) => { + if (sortBy === "date") { + return new Date(b.inscription.dateInscription).getTime() - new Date(a.inscription.dateInscription).getTime(); + } else if (sortBy === "nom") { + return (a.apprenant?.nom || "").localeCompare(b.apprenant?.nom || ""); + } + return 0; + }); + + return filtered; + }, [inscriptions, searchTerm, filterStatut, filterEtablissement, sortBy]); + const getStatutBadge = (statut: string) => { const styles = { confirmee: "bg-green-100 text-green-800", @@ -149,10 +201,88 @@ export default function AdminSessionInscrits() {

{getFormationName(session.formationId)} - {session.nom}

- )} - + )} + {/* Filtres et recherche */} + + + + + Filtres et recherche + + + +
+ {/* Recherche */} +
+ +
+ + setSearchTerm(e.target.value)} + className="pl-8" + /> +
+
+ + {/* Filtre par statut */} +
+ + +
+ + {/* Filtre par établissement */} +
+ + +
+ + {/* Tri */} +
+ + +
+
+ + {/* Compteur de résultats */} +
+ {filteredAndSortedInscriptions.length} inscrit(s) trouvé(s) sur {inscriptions?.length || 0} total +
+
+
+ {loadingSession || loadingInscriptions ? (
@@ -239,7 +369,7 @@ export default function AdminSessionInscrits() { - {inscriptions && inscriptions.length > 0 ? ( + {filteredAndSortedInscriptions && filteredAndSortedInscriptions.length > 0 ? ( @@ -253,7 +383,7 @@ export default function AdminSessionInscrits() { - {inscriptions.map((item) => ( + {filteredAndSortedInscriptions.map((item) => ( {item.apprenant?.nom} {item.apprenant?.prenom} diff --git a/todo.md b/todo.md index f76bb73..0f5be5b 100644 --- a/todo.md +++ b/todo.md @@ -67,3 +67,5 @@ - [x] Ajouter des filtres de tri sur la page des sessions (date, lieu, places restantes) - [x] Ajouter des filtres de recherche sur la page des formations - [x] Ajouter des filtres de recherche sur la page des apprenants + +- [x] Ajouter des filtres complets sur la page de gestion des inscrits (recherche, statut, établissement, tri par date)