'use client'; import React, { useState, useEffect } from 'react'; import { useTranslations } from 'next-intl'; import { Users, Clock, CalendarCheck, School, AlertTriangle, CheckCircle2, } from 'lucide-react'; import Loader from '@/components/Loader'; import StatCard from '@/components/StatCard'; import EventCard from '@/components/EventCard'; import logger from '@/utils/logger'; import { fetchRegisterForms, fetchAbsences, } from '@/app/actions/subscriptionAction'; import { fetchUpcomingEvents } from '@/app/actions/planningAction'; import { useEstablishment } from '@/context/EstablishmentContext'; import Attendance from '@/components/Grades/Attendance'; import LineChart from '@/components/Charts/LineChart'; import PieChart from '@/components/Charts/PieChart'; const mockCompletionRate = 72; // en pourcentage export default function DashboardPage() { const t = useTranslations('dashboard'); const [isLoading, setIsLoading] = useState(false); const [currentYearRegistrationCount, setCurrentYearRegistrationCount] = useState(0); const [upcomingEvents, setUpcomingEvents] = useState([]); const [absencesToday, setAbsencesToday] = useState([]); const { selectedEstablishmentId, selectedEstablishmentTotalCapacity, } = useEstablishment(); const [statusDistribution, setStatusDistribution] = useState([ { label: 'Non envoyé', value: 0 }, { label: 'En attente', value: 0 }, { label: 'En validation', value: 0 }, { label: 'Validé', value: 0 }, ]); const [monthlyRegistrations, setMonthlyRegistrations] = useState([]); useEffect(() => { if (!selectedEstablishmentId) return; setIsLoading(true); // Début du chargement // Fetch des formulaires d'inscription fetchRegisterForms(selectedEstablishmentId) .then((data) => { logger.info('Pending registrations fetched:', data); setCurrentYearRegistrationCount(data.count || 0); const forms = data.registerForms || []; // Filtrage des statuts const distribution = [ { label: 'Non envoyé', value: forms.filter((f) => f.status === 1).length, }, { label: 'En attente', value: forms.filter((f) => f.status === 2 || f.status === 7).length, }, { label: 'En validation', value: forms.filter((f) => f.status === 3 || f.status === 8).length, }, { label: 'Validé', value: forms.filter((f) => f.status === 5).length, }, ]; setStatusDistribution(distribution); // Calcul des inscriptions validées par mois const validForms = forms.filter( (f) => f.status === 5 && f.formatted_last_update ); // Format attendu : "29-05-2025 09:23" const monthLabels = [ 'Janv', 'Fév', 'Mars', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sept', 'Oct', 'Nov', 'Déc', ]; const monthlyCount = Array(12).fill(0); validForms.forEach((f) => { const [day, month, yearAndTime] = f.formatted_last_update.split('-'); const monthIdx = parseInt(month, 10) - 1; if (monthIdx >= 0 && monthIdx < 12) { monthlyCount[monthIdx]++; } }); const monthlyData = monthLabels.map((label, idx) => ({ month: label, value: monthlyCount[idx], })); setMonthlyRegistrations(monthlyData); }) .catch((error) => { logger.error('Erreur lors du fetch des inscriptions :', error); }); // Fetch des événements à venir fetchUpcomingEvents(selectedEstablishmentId) .then((data) => { setUpcomingEvents(data); }) .catch((error) => { logger.error('Error fetching upcoming events:', error); }); // Fetch absences/retards du jour fetchAbsences(selectedEstablishmentId) .then((data) => { const today = new Date().toISOString().split('T')[0]; const absToday = (data || []).filter((a) => a.day === today); // Mapping pour Attendance setAbsencesToday( absToday.map((a) => ({ id: a.id, date: a.day, type: [1, 2].includes(a.reason) ? 'Absence' : 'Retard', justified: [1, 3].includes(a.reason), commentaire: a.commentaire, student_name: a.student_name, })) ); }) .catch((error) => { logger.error('Erreur lors du fetch des absences du jour:', error); }) .finally(() => { setIsLoading(false); // Fin du chargement }); }, [selectedEstablishmentId]); // Calculs à partir de statusDistribution const totalStudents = statusDistribution.find((s) => s.label === 'Validé')?.value || 0; const pendingRegistrationCount = statusDistribution .filter((s) => s.label !== 'Validé') .reduce((acc, s) => acc + s.value, 0); if (isLoading) return ; return (
{/* Statistiques principales */}
} /> } color="green" /> } color="emerald" /> 0 ? `${((totalStudents / selectedEstablishmentTotalCapacity) * 100).toFixed(2)}%` : 0 } icon={} color="orange" />
{/* Événements et KPIs */}
{/* Colonne de gauche : Graphique des inscriptions + Présence */}
{/* Graphique des inscriptions */}

{t('inscriptionTrends')}

{/* Présence et assiduité */}
{/* Colonne de droite : Événements à venir */}

{t('upcomingEvents')}

{upcomingEvents.map((event, index) => ( ))}
); }