import { useState, useEffect, useMemo } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Calendar, ArrowLeft, Users } from "lucide-react"; import { useNavigate, useParams } from "react-router-dom"; import { toast } from "sonner"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; interface Membre { id: number; nom: string; email: string; role: string; soldeCP: number; soldeRTT: number; typeContrat?: string; Actif?: number; } interface Equipe { Id: number; nomService: string; nombreMembres: number; demandesEnAttente: number; campus: string; } const TeamDetail = () => { const navigate = useNavigate(); const { id } = useParams<{ id: string }>(); const [equipe, setEquipe] = useState(null); const [membres, setMembres] = useState([]); const [loadingEquipe, setLoadingEquipe] = useState(true); const [loadingMembres, setLoadingMembres] = useState(true); useEffect(() => { if (id) { chargerEquipe(parseInt(id)); chargerMembres(parseInt(id)); } }, [id]); const chargerEquipe = async (equipeId: number) => { setLoadingEquipe(true); try { const token = localStorage.getItem('token'); const response = await fetch(`/api/equipes/${equipeId}`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) throw new Error('Équipe non trouvée'); const data = await response.json(); setEquipe(data); } catch (error) { toast.error("Erreur lors du chargement de l'équipe"); setEquipe(null); } finally { setLoadingEquipe(false); } }; const chargerMembres = async (equipeId: number) => { setLoadingMembres(true); try { const token = localStorage.getItem('token'); const response = await fetch(`/api/equipes/${equipeId}/membres`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) throw new Error('Impossible de récupérer les membres'); const data = await response.json(); console.log('📊 Données membres reçues en frontend:', data); data.forEach((m: Membre) => { console.log(` - ${m.nom}: CP=${m.soldeCP} (type: ${typeof m.soldeCP}), RTT=${m.soldeRTT} (type: ${typeof m.soldeRTT})`); }); setMembres(data); } catch (error) { console.error('❌ Erreur chargement membres:', error); toast.error("Erreur lors du chargement des membres"); setMembres([]); } finally { setLoadingMembres(false); } }; const getRoleBadge = (role: string) => { switch (role) { case 'Admin': return {role}; case 'RH': return {role}; case 'Validateur': return {role}; case 'Directeur de campus': return {role}; default: return {role}; } }; // ✅ Fonction pour détecter si un membre est apprenti const estApprenti = (membre: Membre): boolean => { return membre.typeContrat === 'Apprentissage' || membre.role === 'Apprenti' || membre.role?.toLowerCase().includes('apprenti'); }; // ✅ CORRECTION: Utiliser useMemo pour recalculer les totaux à chaque changement de membres const totaux = useMemo(() => { if (!membres || membres.length === 0) { console.log('⚠️ Aucun membre pour calculer les totaux'); return { totalCP: 0, totalRTT: 0 }; } console.log('🧮 Calcul des totaux pour', membres.length, 'membres'); const totalCP = membres.reduce((sum, m) => { const solde = parseFloat(String(m.soldeCP)) || 0; console.log(` - ${m.nom}: CP=${m.soldeCP} (${typeof m.soldeCP}) → ajout de ${solde}`); return sum + solde; }, 0); // ✅ Exclure les apprentis du calcul des RTT const totalRTT = membres.reduce((sum, m) => { if (estApprenti(m)) { console.log(` - ${m.nom}: RTT=0 (Apprenti - pas de RTT)`); return sum; } const solde = parseFloat(String(m.soldeRTT)) || 0; console.log(` - ${m.nom}: RTT=${m.soldeRTT} (${typeof m.soldeRTT}) → ajout de ${solde}`); return sum + solde; }, 0); console.log('✅ Totaux calculés: CP=', totalCP, 'RTT=', totalRTT); return { totalCP, totalRTT }; }, [membres]); // ✅ Recalculer quand membres change if (loadingEquipe) { return (

Chargement de l'équipe...

); } if (!equipe) { return (

Équipe introuvable

); } return (

{equipe.nomService}

{equipe.campus}

Membres

{equipe.nombreMembres}

Demandes en attente

{equipe.demandesEnAttente}

Total CP

{totaux.totalCP.toFixed(1)}j

Total RTT

{totaux.totalRTT.toFixed(1)}j

Membres de l'équipe {membres.length} membre{membres.length > 1 ? 's' : ''} {loadingMembres ? (

Chargement des membres...

) : membres.length > 0 ? (
Nom Email Rôle CP restants RTT restants {membres.map((membre) => { const isApprenti = estApprenti(membre); return (
{membre.nom} {isApprenti && ( Apprenti )}
{membre.email} {getRoleBadge(membre.role)} {parseFloat(String(membre.soldeCP || 0)).toFixed(1)}j {isApprenti ? ( N/A ) : ( {parseFloat(String(membre.soldeRTT || 0)).toFixed(1)}j )}
); })}
) : (

Aucun membre dans cette équipe

)}
); }; export default TeamDetail;