"use client"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { TeamMemberProfile, SkillGap } from "@/lib/team-review-types"; import { UserCheck, GraduationCap } from "lucide-react"; import { TechIcon } from "@/components/icons/tech-icon"; import { getImportanceColors } from "@/lib/tech-colors"; import { isCoverageBelowObjective } from "@/lib/evaluation-utils"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; interface SkillMatrixProps { members: TeamMemberProfile[]; skillGaps: SkillGap[]; } export function SkillMatrix({ members, skillGaps }: SkillMatrixProps) { // Filtrer les skills valides et les organiser par catégorie const validSkillGaps = skillGaps.filter( (skill) => skill.skillId && skill.skillName && skill.category ); // Fonction de tri par importance const sortByImportance = (a: SkillGap, b: SkillGap) => { const importanceOrder = { incontournable: 2, majeure: 1, standard: 0, }; const importanceDiff = importanceOrder[b.importance] - importanceOrder[a.importance]; if (importanceDiff !== 0) return importanceDiff; // Si même importance, trier par couverture (ascendant) return (a.coverage || 0) - (b.coverage || 0); }; const skillsByCategory = validSkillGaps.reduce((acc, skill) => { if (!acc[skill.category]) { acc[skill.category] = []; } acc[skill.category].push(skill); return acc; }, {} as Record); // Trier les compétences par importance dans chaque catégorie Object.values(skillsByCategory).forEach((skills) => { skills.sort(sortByImportance); }); const getLevelBadge = (level: string | null) => { const colors = { never: "bg-white/5 text-slate-300", "not-autonomous": "bg-yellow-500/20 text-yellow-200", autonomous: "bg-green-500/20 text-green-200", expert: "bg-blue-500/20 text-blue-200", }; return level ? ( {level} ) : ( - ); }; // Vérifier si nous avons des données valides if (validSkillGaps.length === 0 || members.length === 0) { return ( Matrice des compétences

Aucune donnée disponible pour la matrice des compétences.

); } return ( Matrice des compétences Toutes {Object.keys(skillsByCategory).map((category) => ( {category} ))}
Compétence Catégorie {members.map((member) => ( {member.member.firstName} {member.member.lastName} ))} Couverture {validSkillGaps.sort(sortByImportance).map((skill) => { const colors = getImportanceColors(skill.importance); return (
{skill.skillName} {skill.risk === "high" && ( Risque )}
{skill.category} {members.map((member) => { const memberSkill = member.skills.find( (s) => s.skillId === skill.skillId ); return (
{getLevelBadge(memberSkill?.level || null)} {memberSkill?.canMentor && ( Mentor )} {memberSkill?.wantsToLearn && ( Apprenant )}
); })}
= 75 ? "bg-green-500/50" : (skill.coverage || 0) >= 50 ? "bg-yellow-500/50" : "bg-red-500/50" }`} style={{ width: `${Math.max( 0, Math.min(100, skill.coverage || 0) )}%`, }} />
= 75 ? "text-green-400" : (skill.coverage || 0) >= 50 ? "text-yellow-400" : "text-red-400" }`} > {Math.round(skill.coverage || 0)}%
); })}
{Object.entries(skillsByCategory).map(([category, skills]) => (
Compétence {members.map((member) => ( {member.member.firstName} {member.member.lastName} ))} Couverture {skills.map((skill) => { const colors = getImportanceColors(skill.importance); return (
{skill.skillName} {skill.risk === "high" && ( Risque )}
{members.map((member) => { const memberSkill = member.skills.find( (s) => s.skillId === skill.skillId ); return (
{getLevelBadge(memberSkill?.level || null)} {memberSkill?.canMentor && ( Mentor )} {memberSkill?.wantsToLearn && ( Apprenant )}
); })}
= 75 ? "bg-green-500/50" : (skill.coverage || 0) >= 50 ? "bg-yellow-500/50" : "bg-red-500/50" }`} style={{ width: `${Math.max( 0, Math.min(100, skill.coverage || 0) )}%`, }} />
= 75 ? "text-green-400" : (skill.coverage || 0) >= 50 ? "text-yellow-400" : "text-red-400" }`} > {Math.round(skill.coverage || 0)}%
); })}
))}
); }