"use client"; import React, { useState, useEffect } from "react"; import { TeamStats, TeamMember } from "@/lib/admin-types"; import { TeamDetailHeader } from "./team-detail-header"; import { TeamMetricsCards } from "./team-metrics-cards"; import { TeamDetailTabs } from "./team-detail-tabs"; import { TeamMemberModal } from "@/components/admin"; import { COVERAGE_OBJECTIVES, isCoverageBelowObjective, } from "@/lib/evaluation-utils"; interface TeamDetailClientWrapperProps { team: TeamStats; teamId: string; } interface SkillAnalysis { skillName: string; category: string; importance: "incontournable" | "majeure" | "standard"; experts: Array<{ name: string; level: number; canMentor: boolean; }>; learners: Array<{ name: string; currentLevel: number; }>; averageLevel: number; totalEvaluations: number; expertCount: number; learnerCount: number; proficiencyRate: number; coverage: number; } interface TeamInsights { averageTeamLevel: number; totalExperts: number; totalLearners: number; skillGaps: { incontournable: number; majeure: number; standard: number; }; strongSkills: { incontournable: number; majeure: number; standard: number; }; criticalSkillsCoverage: { incontournable: number; majeure: number; }; } export function TeamDetailClientWrapper({ team, teamId, }: TeamDetailClientWrapperProps) { const [skillAnalysis, setSkillAnalysis] = useState([]); const [selectedMember, setSelectedMember] = useState(null); const [isMemberModalOpen, setIsMemberModalOpen] = useState(false); useEffect(() => { // Analyser les compétences avec les vraies données const skillMap = new Map(); // Créer un Map pour stocker les infos d'importance des skills const skillImportanceMap = new Map(); team.topSkills.forEach((skill) => { skillImportanceMap.set(skill.skillName, skill.importance); }); team.members.forEach((member) => { member.skills.forEach((skill) => { if (!skillMap.has(skill.skillName)) { skillMap.set(skill.skillName, { skillName: skill.skillName, category: skill.category, importance: skillImportanceMap.get(skill.skillName) || "standard", experts: [], learners: [], averageLevel: 0, totalEvaluations: 0, coverage: 0, }); } const skillData = skillMap.get(skill.skillName); skillData.totalEvaluations++; skillData.averageLevel += skill.level; if (skill.level >= 2) { skillData.experts.push({ name: `${member.firstName} ${member.lastName}`, level: skill.level, canMentor: skill.canMentor, }); } if (skill.wantsToLearn) { skillData.learners.push({ name: `${member.firstName} ${member.lastName}`, currentLevel: skill.level, }); } }); }); const skills = Array.from(skillMap.values()) .map( (skill): SkillAnalysis => ({ ...skill, averageLevel: skill.averageLevel / skill.totalEvaluations, expertCount: skill.experts.length, learnerCount: skill.learners.length, proficiencyRate: (skill.experts.length / skill.totalEvaluations) * 100, coverage: (skill.experts.length / team.totalMembers) * 100, }) ) .sort((a, b) => { // D'abord par importance const importanceOrder = { incontournable: 2, majeure: 1, standard: 0 }; const importanceDiff = importanceOrder[b.importance] - importanceOrder[a.importance]; if (importanceDiff !== 0) return importanceDiff; // Ensuite par niveau moyen return b.averageLevel - a.averageLevel; }); setSkillAnalysis(skills); }, [team]); const handleExportReport = () => { const reportData = { team: team.teamName, direction: team.direction, exportDate: new Date().toLocaleDateString(), detailedStats: { totalMembers: team.totalMembers, averageSkillLevel: team.averageSkillLevel, skillCoverage: team.skillCoverage, }, members: team.members.map((member) => ({ name: `${member.firstName} ${member.lastName}`, joinDate: member.joinDate, skillCount: member.skills.length, skills: member.skills, })), skillAnalysis, }; const dataStr = JSON.stringify(reportData, null, 2); const dataUri = "data:application/json;charset=utf-8," + encodeURIComponent(dataStr); const exportFileDefaultName = `rapport-detaille-${team.teamName.toLowerCase()}-${ new Date().toISOString().split("T")[0] }.json`; const linkElement = document.createElement("a"); linkElement.setAttribute("href", dataUri); linkElement.setAttribute("download", exportFileDefaultName); linkElement.click(); }; const teamInsights: TeamInsights = { averageTeamLevel: team.members.reduce((sum, member) => { const memberAvg = member.skills.reduce((s, skill) => s + skill.level, 0) / member.skills.length; return sum + memberAvg; }, 0) / team.members.length, totalExperts: team.members.reduce( (sum, member) => sum + member.skills.filter((s) => s.level >= 2 && s.canMentor).length, 0 ), totalLearners: team.members.reduce( (sum, member) => sum + member.skills.filter((s) => s.wantsToLearn).length, 0 ), skillGaps: { incontournable: skillAnalysis.filter( (s) => s.importance === "incontournable" && isCoverageBelowObjective(s.coverage, s.importance) ).length, majeure: skillAnalysis.filter( (s) => s.importance === "majeure" && isCoverageBelowObjective(s.coverage, s.importance) ).length, standard: skillAnalysis.filter( (s) => s.importance === "standard" && s.averageLevel < 1.5 ).length, }, strongSkills: { incontournable: skillAnalysis.filter( (s) => s.importance === "incontournable" && !isCoverageBelowObjective(s.coverage, s.importance) ).length, majeure: skillAnalysis.filter( (s) => s.importance === "majeure" && !isCoverageBelowObjective(s.coverage, s.importance) ).length, standard: skillAnalysis.filter( (s) => s.importance === "standard" && s.averageLevel >= 2.5 ).length, }, criticalSkillsCoverage: team.criticalSkillsCoverage, }; return (
{/* Background Effects */}
{/* Header */} {/* Métriques principales */} {/* Contenu principal avec onglets */} { setSelectedMember(member); setIsMemberModalOpen(true); }} /> {/* Modal détail membre */} setIsMemberModalOpen(false)} member={selectedMember} />
); }