import { useState } from "react"; import { trpc } from "@/lib/trpc"; import DashboardLayout from "@/components/DashboardLayout"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { format } from "date-fns"; import { fr } from "date-fns/locale"; import { Mail, CheckCircle2, XCircle, TrendingUp, Send, AlertCircle, Filter, RefreshCw, BarChart3, } from "lucide-react"; const notificationTypeLabels: Record = { remerciement: "Remerciement post-formation", notification_formateur_inscription: "Notification formateur (inscription)", notification_formateur_annulation: "Notification formateur (annulation)", alerte_capacite: "Alerte capacité atteinte", notification_liste_attente: "Notification liste d'attente", }; const notificationTypeColors: Record = { remerciement: "bg-blue-100 text-blue-800", notification_formateur_inscription: "bg-green-100 text-green-800", notification_formateur_annulation: "bg-orange-100 text-orange-800", alerte_capacite: "bg-red-100 text-red-800", notification_liste_attente: "bg-purple-100 text-purple-800", }; export default function AdminNotifications() { const [filters, setFilters] = useState({ type: "", statut: "", email: "", dateDebut: "", dateFin: "", }); const [page, setPage] = useState(0); const limit = 20; const { data: historiqueData, isLoading: isLoadingHistorique, refetch, error: historiqueError } = trpc.notifications.historique.useQuery({ type: filters.type as any || undefined, statut: filters.statut as any || undefined, email: filters.email || undefined, dateDebut: filters.dateDebut || undefined, dateFin: filters.dateFin || undefined, limit, offset: page * limit, }); const { data: statsData, isLoading: isLoadingStats, error: statsError } = trpc.notifications.statistiques.useQuery({ dateDebut: filters.dateDebut || undefined, dateFin: filters.dateFin || undefined, }); const totalPages = Math.ceil((historiqueData?.total || 0) / limit); const handleFilterChange = (key: string, value: string) => { // Convertir 'all' en chaîne vide pour les filtres const actualValue = value === "all" ? "" : value; setFilters((prev) => ({ ...prev, [key]: actualValue })); setPage(0); }; const resetFilters = () => { setFilters({ type: "", statut: "", email: "", dateDebut: "", dateFin: "", }); setPage(0); }; return (

Tableau de bord des Notifications

Historique et statistiques de tous les emails envoyés

Historique Statistiques {isLoadingStats ? (
Chargement...
) : statsError ? (

Erreur lors du chargement des statistiques

{statsError.message}

) : statsData ? ( <> {/* Cartes de statistiques globales */}
Total envoyés
{statsData.global.total}
Réussis
{statsData.global.success}
Échoués
{statsData.global.failed}
Taux de succès
{statsData.global.tauxSucces}%
{/* Statistiques par type */} Répartition par type de notification Nombre d'emails envoyés par catégorie Type Total Réussis Échoués Taux de succès {statsData.parType.map((stat) => ( {notificationTypeLabels[stat.type] || stat.type} {stat.total} {stat.success} {stat.failed} {stat.total > 0 ? Math.round((stat.success / stat.total) * 100) : 0}% ))} {statsData.parType.length === 0 && ( Aucune donnée disponible )}
{/* Évolution par jour */} Évolution des envois Nombre d'emails envoyés par jour Date Total Réussis Échoués {statsData.evolutionParJour.map((jour) => ( {format(new Date(jour.date), "EEEE d MMMM yyyy", { locale: fr })} {jour.total} {jour.success} {jour.failed} ))} {statsData.evolutionParJour.length === 0 && ( Aucune donnée disponible )}
) : (
Aucune statistique disponible
)}
{/* Filtres */} Filtres
handleFilterChange("email", e.target.value)} />
handleFilterChange("dateDebut", e.target.value)} />
handleFilterChange("dateFin", e.target.value)} />
{/* Tableau historique */} Historique des envois {historiqueData?.total || 0} notification(s) trouvée(s) {isLoadingHistorique ? (
Chargement...
) : historiqueError ? (

Erreur lors du chargement de l'historique

{historiqueError.message}

) : historiqueData?.logs.length === 0 ? (
Aucune notification trouvée
) : ( <> Date Type Destinataire Sujet Formation / Séquence Statut {historiqueData?.logs.map((log) => ( {format(new Date(log.dateEnvoi), "dd/MM/yyyy HH:mm", { locale: fr })} {notificationTypeLabels[log.type] || log.type}
{log.emailDestinataire} {log.apprenantNom && log.apprenantPrenom && ( {log.apprenantPrenom} {log.apprenantNom} )} {log.formateurNom && ( Formateur: {log.formateurNom} )}
{log.sujet} {log.formationNom && log.sequenceNom ? (
{log.formationNom} {log.sequenceNom}
) : ( - )}
{log.statut === "success" ? ( Envoyé ) : (
Échec {log.messageErreur && ( {log.messageErreur.substring(0, 50)}... )}
)}
))}
{/* Pagination */} {totalPages > 1 && (

Page {page + 1} sur {totalPages}

)} )}
); }