diff --git a/DataSentinel/src/pages/Historique/Historique.jsx b/DataSentinel/src/pages/Historique/Historique.jsx index 4849f91..6c07917 100644 --- a/DataSentinel/src/pages/Historique/Historique.jsx +++ b/DataSentinel/src/pages/Historique/Historique.jsx @@ -2,7 +2,7 @@ // Page Historique : filtres + graphique ligne + tableau résumé import { useState, useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; -import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Area, ComposedChart } from 'recharts'; +import { Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Area, ComposedChart } from 'recharts'; import { getMonitorings, getHistorique, getHistoriqueEvolution, getEvolutionGlobal, exportToCSV } from '../../services/api'; import DataTable from '../../components/common/DataTable'; import LoadingSpinner from '../../components/common/LoadingSpinner'; @@ -10,25 +10,66 @@ import ErrorMessage from '../../components/common/ErrorMessage'; import Button from '../../components/common/Button'; import styles from './Historique.module.css'; +/* Formate une date au format attendu par (YYYY-MM-DD). + On lit les composantes en heure locale plutôt que d'utiliser toISOString(), + qui bascule en UTC : un 1er janvier saisi depuis Paris (UTC+1) y devient le + 31 décembre de l'année précédente. */ +function formatDateISO(date) { + const mois = String(date.getMonth() + 1).padStart(2, '0'); + const jour = String(date.getDate()).padStart(2, '0'); + return `${date.getFullYear()}-${mois}-${jour}`; +} + +/* Période affichée par défaut : du 1er janvier de l'année courante à aujourd'hui. */ +function periodeParDefaut() { + const aujourdhui = new Date(); + return { + debut: formatDateISO(new Date(aujourdhui.getFullYear(), 0, 1)), + fin: formatDateISO(aujourdhui), + }; +} + +/* Récupère le tableau d'historique et la série du graphique pour les filtres + donnés. Sans monitoring sélectionné, on prend la courbe globale. + Fonction pure : elle ne touche à aucun état, ce qui permet de l'appeler + aussi bien depuis le bouton « Afficher » que depuis l'effet de montage. */ +async function recupererHistorique(monitoring, debut, fin) { + const [histResult, evolResult] = monitoring + ? await Promise.all([ + getHistorique(monitoring, debut, fin), + getHistoriqueEvolution(monitoring, debut, fin), + ]) + : await Promise.all([ + getHistorique(undefined, debut, fin), + getEvolutionGlobal(debut, fin), + ]); + + return { + hist: Array.isArray(histResult) ? histResult : [], + evol: Array.isArray(evolResult) ? evolResult : [], + }; +} + export default function Historique() { const [searchParams] = useSearchParams(); + + /* Figé au montage : sert à la fois de valeur initiale des filtres et de + paramètres du premier chargement, sans dépendance instable. */ + const [valeursInitiales] = useState(() => ({ + monitoring: searchParams.get('id') || '', + ...periodeParDefaut(), + })); + const [monitorings, setMonitorings] = useState([]); - const [selectedMonitoring, setSelectedMonitoring] = useState(searchParams.get('id') || ''); - const [dateDebut, setDateDebut] = useState(''); - const [dateFin, setDateFin] = useState(''); + const [selectedMonitoring, setSelectedMonitoring] = useState(valeursInitiales.monitoring); + const [dateDebut, setDateDebut] = useState(valeursInitiales.debut); + const [dateFin, setDateFin] = useState(valeursInitiales.fin); const [historiqueData, setHistoriqueData] = useState([]); const [evolutionData, setEvolutionData] = useState([]); - const [loading, setLoading] = useState(false); + /* Un chargement est lancé dès le montage : la page démarre donc en attente. */ + const [loading, setLoading] = useState(true); const [erreur, setErreur] = useState(''); - /* Set default dates to last 5 days */ - useEffect(() => { - const today = new Date(); - const fiveDaysAgo = new Date(today); - fiveDaysAgo.setDate(today.getDate() - 5); - setDateDebut(fiveDaysAgo.toISOString().split('T')[0]); - setDateFin(today.toISOString().split('T')[0]); - }, []); useEffect(() => { async function loadMonitorings() { try { @@ -41,6 +82,31 @@ export default function Historique() { loadMonitorings(); }, []); + /* Premier affichage : on charge la période par défaut, pour que la page ne + s'ouvre pas sur un écran vide en attente d'un clic. Le drapeau `annule` + évite d'écrire dans un composant déjà démonté si l'utilisateur quitte la + page pendant la requête. */ + useEffect(() => { + let annule = false; + + async function chargerAuMontage() { + const { monitoring, debut, fin } = valeursInitiales; + try { + const { hist, evol } = await recupererHistorique(monitoring, debut, fin); + if (annule) return; + setHistoriqueData(hist); + setEvolutionData(evol); + } catch (e) { + if (!annule) setErreur(e.message || 'Erreur lors du chargement de l\'historique.'); + } finally { + if (!annule) setLoading(false); + } + } + + chargerAuMontage(); + return () => { annule = true; }; + }, [valeursInitiales]); + async function handleAfficher() { if (!dateDebut || !dateFin) { setErreur('Veuillez sélectionner des dates.'); @@ -50,25 +116,7 @@ export default function Historique() { setLoading(true); setErreur(''); try { - let hist = []; - let evol = []; - - if (selectedMonitoring) { - const [histResult, evolResult] = await Promise.all([ - getHistorique(selectedMonitoring, dateDebut, dateFin), - getHistoriqueEvolution(selectedMonitoring, dateDebut, dateFin) - ]); - hist = Array.isArray(histResult) ? histResult : []; - evol = Array.isArray(evolResult) ? evolResult : []; - } else { - const [histResult, evolResult] = await Promise.all([ - getHistorique(undefined, dateDebut, dateFin), - getEvolutionGlobal(dateDebut, dateFin) - ]); - hist = Array.isArray(histResult) ? histResult : []; - evol = Array.isArray(evolResult) ? evolResult : []; - } - + const { hist, evol } = await recupererHistorique(selectedMonitoring, dateDebut, dateFin); setHistoriqueData(hist); setEvolutionData(evol); } catch (e) { @@ -189,9 +237,9 @@ export default function Historique() { emptyMessage="Aucune donnée historique." /> - ) : selectedMonitoring && dateDebut && dateFin && !loading ? ( + ) : (

Aucune donnée trouvée pour cette période.

- ) : null} + )} ); } \ No newline at end of file