Feat: Stats athlètes fonctionnel

This commit is contained in:
Amaël Kesteman
2026-01-11 21:27:32 +01:00
parent b9e67589ed
commit cbd53ba471
6 changed files with 129 additions and 43 deletions

View File

@@ -1,31 +1,78 @@
import React from "react";
import React, { useEffect, useState } from "react";
import { Athlete, Session } from "../classes";
import { calculStatsAthlete, niveauAlerte, StatsAthlete } from "../utils/athleteUtils"
import { getSessionsByAthleteId, getSessionsOfUserAPI } from "../requetes";
interface AthleteStatsProps {
athlete: Athlete;
}
function StatAthlete({ athlete }: AthleteStatsProps) {
const [dateDebut, setDateDebut] = React.useState(new Date());
const [dateFin, setDateFin] = React.useState(new Date());
const [seuilCritique, setSeuilCritique] = React.useState(0);
const [seuilMax, setSeuilMax] = React.useState(0);
const [stats, setStats] = React.useState<StatsAthlete | null>(null);
console.log("Athlete:", athlete);
console.log("Sessions:", athlete.sessions);
const [sessions, setSessions] = useState<Session[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [dateDebut, setDateDebut] = useState(new Date());
const [dateFin, setDateFin] = useState(new Date());
const [seuilCritique, setSeuilCritique] = useState(0);
const [seuilMax, setSeuilMax] = useState(0);
const [stats, setStats] = useState<StatsAthlete | null>(null);
const dateToDatetimeLocal = (date: Date) => {
const pad = (n: number) => n.toString().padStart(2, "0");
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
};
useEffect(() => {
async function loadSessions() {
if (!athlete.id) {
console.error("Athlete ID is null");
setLoading(false);
return;
}
setLoading(true);
try {
const sessionsData = await getSessionsByAthleteId(athlete.id);
setSessions(sessionsData);
console.log("Sessions chargées:", sessionsData);
console.log("Première session:", sessionsData[0]);
console.log("Athletes de la première session:", sessionsData[0]?.athletes);
} catch (error) {
console.error("Erreur lors du chargement des sessions:", error);
setSessions([]);
} finally {
setLoading(false);
}
}
loadSessions();
}, [athlete.id]);
const handleCalculerStats = () => {
const statsCalculees = calculStatsAthlete(athlete.sessions, athlete, dateDebut, dateFin);
let safeDebut = dateDebut;
let safeFin = dateFin;
if (sessions.length > 0) {
const times = sessions
.map(s => s.creneau?.getTime())
.filter(t => typeof t === 'number') as number[];
if (times.length > 0) {
const min = Math.min(...times);
const max = Math.max(...times);
// if user range is zero-length or inverted, default to sessions span
if (safeDebut.getTime() === safeFin.getTime() || safeDebut.getTime() > safeFin.getTime()) {
safeDebut = new Date(min);
safeFin = new Date(max);
}
}
}
const statsCalculees = calculStatsAthlete(sessions, athlete, safeDebut, safeFin);
setStats(statsCalculees);
};
return (
<div className="creneau-stats">
<div>Nb Session : {athlete.sessions.length};</div>
<div>Nb Session : {sessions.length};</div>
<table>
<tr>
<th>Début :</th>
@@ -52,7 +99,7 @@ function StatAthlete({ athlete }: AthleteStatsProps) {
{stats && (
<div className="stats-display">
<h3>Statistiques de {athlete.nom}</h3>
<h3>Statistiques de {athlete.prenom} {athlete.nom}</h3>
<p><strong>Nombre total de sessions :</strong> {stats.nbSessions}</p>
<p><strong>Sessions par semaine :</strong> {stats.nbSessionsPerWeek.toFixed(2)}</p>
<p><strong>Statut :</strong> {niveauAlerte(stats, seuilCritique, seuilMax)}</p>

View File

@@ -361,3 +361,29 @@ export async function getAllAthlete(): Promise<Athlete[]> {
}
}
export async function getSessionsByAthleteId(athleteId: number): Promise<Session[]> {
try {
const response = await api.get(`/athlete/athlete/${athleteId}/session`);
const sessions: Session[] = [];
const allAthletes = await getAllAthlete();
response.data.forEach((sessionDTO: SessionDTO) => {
const session = new Session(sessionDTO);
if (sessionDTO.athleteIds && sessionDTO.athleteIds.length > 0) {
session.athletes = allAthletes.filter(a =>
sessionDTO.athleteIds.includes(a.id!)
);
}
sessions.push(session);
});
console.log(`Sessions chargées pour l'athlète ${athleteId}:`, sessions);
return sessions;
} catch (error) {
console.error("Error fetching sessions for athlete:", error);
return [];
}
}

View File

@@ -18,7 +18,8 @@ export function calculStatsAthlete(sessions: Session[], athlete: Athlete, debut:
let nb_semaine = 1; //forcément une semaine
const distributions: Map<string, number> = new Map();
const timeDiff = Math.abs(fin.getTime() - debut.getTime());
nb_semaine = Math.ceil(timeDiff / (1000 * 3600 * 24 * 7));
const msPerWeek = 1000 * 3600 * 24 * 7;
nb_semaine = Math.max(1, Math.ceil(timeDiff / msPerWeek));
sessions.forEach(session => {
// verification session dans l'intervalle