"use client"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { TeamReviewData } from "@/lib/team-review-types"; import { Progress } from "@/components/ui/progress"; import { Badge } from "@/components/ui/badge"; import { AlertTriangle } from "lucide-react"; import { getImportanceColors } from "@/lib/tech-colors"; import { COVERAGE_OBJECTIVES, isCoverageBelowObjective, } from "@/lib/evaluation-utils"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; interface TeamOverviewProps { team: TeamReviewData["team"]; stats: TeamReviewData["stats"]; members: TeamReviewData["members"]; categoryCoverage: TeamReviewData["categoryCoverage"]; skillGaps: TeamReviewData["skillGaps"]; } export function TeamOverview({ team, stats, members, categoryCoverage, skillGaps, }: TeamOverviewProps) { // Trouver les top contributeurs const topContributors = [...members] .sort((a, b) => b.expertSkills - a.expertSkills) .slice(0, 3); // Trouver les catégories les plus fortes const strongestCategories = [...categoryCoverage] .sort((a, b) => b.coverage - a.coverage) .slice(0, 2); // Trouver les catégories qui nécessitent de l'attention const categoriesNeedingAttention = [...categoryCoverage] .map((cat) => { // Pour chaque catégorie, on identifie : // 1. Les compétences incontournables sous-couvertes const uncoveredIncontournables = skillGaps.filter( (gap) => gap.category === cat.category && gap.importance === "incontournable" && isCoverageBelowObjective(gap.coverage, gap.importance) ); // 2. Les compétences majeures sous-couvertes const uncoveredMajeures = skillGaps.filter( (gap) => gap.category === cat.category && gap.importance === "majeure" && isCoverageBelowObjective(gap.coverage, gap.importance) ); // Une catégorie nécessite de l'attention si : const needsAttention = uncoveredIncontournables.length > 0 || // Il y a des compétences incontournables sous-couvertes uncoveredMajeures.length > 0 || // OU des compétences majeures sous-couvertes (cat.experts < 2 && stats.totalMembers > 5); // OU pas assez d'experts dans une équipe significative if (!needsAttention) return null; // Calculer un score d'attention pour trier les catégories const attentionScore = // Les incontournables pèsent plus lourd uncoveredIncontournables.length * 3 + // Les majeures un peu moins uncoveredMajeures.length * 2 + // Manque d'experts est un facteur aggravant (cat.experts < 2 && stats.totalMembers > 5 ? 1 : 0); return { ...cat, // On combine les deux types pour l'affichage criticalSkills: [...uncoveredIncontournables, ...uncoveredMajeures], attentionScore, }; }) .filter((cat): cat is NonNullable => cat !== null) .sort((a, b) => b.attentionScore - a.attentionScore) .slice(0, 3); return ( Vue d'ensemble
{/* Points forts */}

Points forts

{strongestCategories.map((cat) => (

{cat.category}

{cat.coverage.toFixed(0)}%

{cat.experts} experts • {cat.mentors} mentors

))}
{/* Top contributeurs */}

Top contributeurs

{topContributors.map((member) => (

{member.member.firstName} {member.member.lastName}

{member.expertSkills} expertises {member.mentorSkills > 0 && ( {member.mentorSkills} mentorats )}
))}
{/* Points d'attention */}

Besoins prioritaires

{categoriesNeedingAttention.map((cat) => (

{cat.category}

{cat.experts} exp • {cat.mentors} ment
{/* Compétences sous-couvertes */} {cat.criticalSkills.length > 0 && (
{cat.criticalSkills .sort((a, b) => { if ( a.importance === "incontournable" && b.importance !== "incontournable" ) return -1; if ( a.importance !== "incontournable" && b.importance === "incontournable" ) return 1; return a.coverage - b.coverage; }) .map((skill) => { const colors = getImportanceColors(skill.importance); const target = COVERAGE_OBJECTIVES[skill.importance]; return (
{skill.skillName} {skill.coverage.toFixed(0)}%

{skill.importance === "incontournable" ? "Compétence incontournable" : "Compétence majeure"}

Objectif : {target}% de couverture
Actuel : {skill.coverage.toFixed(0)}%
{isCoverageBelowObjective( skill.coverage, skill.importance ) ? `Manque ${( target - skill.coverage ).toFixed(0)}%` : "Objectif atteint"}

); })}
)}
))} {stats.learningNeeds > 0 && (

{stats.learningNeeds} compétences sans expert ni mentor

)}
); }