feat: review admin overview and popup details fwith importance

This commit is contained in:
Julien Froidefond
2025-08-27 13:16:39 +02:00
parent 94a18b0ca5
commit e9aecca2a5
5 changed files with 415 additions and 82 deletions

View File

@@ -15,8 +15,17 @@ interface DirectionOverviewProps {
direction: string;
totalMembers: number;
averageSkillLevel: number;
topSkills: Array<{ skillName: string; averageLevel: number }>;
topSkills: Array<{
skillName: string;
averageLevel: number;
importance: "incontournable" | "majeure" | "standard";
coverage: number;
}>;
skillCoverage: number;
criticalSkillsCoverage: {
incontournable: number;
majeure: number;
};
}>;
totalMembers: number;
averageSkillLevel: number;
@@ -81,6 +90,18 @@ export function DirectionOverview({
}: DirectionOverviewProps) {
const colors = getDirectionColors(direction);
// Calculer la moyenne des couvertures des compétences critiques
const averageCriticalCoverage = teams.reduce(
(acc, team) => {
acc.incontournable += team.criticalSkillsCoverage.incontournable;
acc.majeure += team.criticalSkillsCoverage.majeure;
return acc;
},
{ incontournable: 0, majeure: 0 }
);
averageCriticalCoverage.incontournable /= teams.length || 1;
averageCriticalCoverage.majeure /= teams.length || 1;
return (
<div className="bg-gradient-to-br from-slate-800/40 to-slate-700/30 backdrop-blur-sm border border-slate-600/30 rounded-2xl overflow-hidden shadow-xl">
<div
@@ -153,24 +174,76 @@ export function DirectionOverview({
</h4>
</div>
<div className="space-y-3">
{/* Compétences incontournables */}
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-sm text-slate-300">
Maîtrise globale:
Incontournables:
</span>
<span className="text-lg font-bold text-white">
{((averageSkillLevel / 3) * 100).toFixed(0)}%
<span
className={`text-sm font-bold ${
averageCriticalCoverage.incontournable < 75
? "text-red-400"
: "text-green-400"
}`}
>
{averageCriticalCoverage.incontournable.toFixed(0)}%
</span>
</div>
<div className="w-full bg-slate-700/50 rounded-full h-2">
<div className="w-full bg-slate-700/50 rounded-full h-1.5">
<div
className="bg-gradient-to-r from-blue-500 to-blue-400 h-2 rounded-full transition-all shadow-sm"
style={{ width: `${(averageSkillLevel / 3) * 100}%` }}
className={`h-1.5 rounded-full transition-all shadow-sm ${
averageCriticalCoverage.incontournable < 75
? "bg-gradient-to-r from-red-500 to-red-400"
: "bg-gradient-to-r from-green-500 to-green-400"
}`}
style={{
width: `${averageCriticalCoverage.incontournable}%`,
}}
/>
</div>
</div>
<div className="pt-2 text-xs text-slate-400">
Basé sur {teams.length} équipes
{/* Compétences majeures */}
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-sm text-slate-300">Majeures:</span>
<span
className={`text-sm font-bold ${
averageCriticalCoverage.majeure < 60
? "text-orange-400"
: "text-green-400"
}`}
>
{averageCriticalCoverage.majeure.toFixed(0)}%
</span>
</div>
<div className="w-full bg-slate-700/50 rounded-full h-1.5">
<div
className={`h-1.5 rounded-full transition-all shadow-sm ${
averageCriticalCoverage.majeure < 60
? "bg-gradient-to-r from-orange-500 to-orange-400"
: "bg-gradient-to-r from-green-500 to-green-400"
}`}
style={{ width: `${averageCriticalCoverage.majeure}%` }}
/>
</div>
</div>
{/* Niveau global */}
<div className="space-y-2 pt-2 border-t border-slate-600/30">
<div className="flex justify-between">
<span className="text-sm text-slate-300">Niveau global:</span>
<span className="text-sm font-bold text-white">
{((averageSkillLevel / 3) * 100).toFixed(0)}%
</span>
</div>
<div className="w-full bg-slate-700/50 rounded-full h-1.5">
<div
className="bg-gradient-to-r from-blue-500 to-blue-400 h-1.5 rounded-full transition-all shadow-sm"
style={{ width: `${(averageSkillLevel / 3) * 100}%` }}
/>
</div>
</div>
</div>
</div>
@@ -229,6 +302,7 @@ export function DirectionOverview({
averageSkillLevel={team.averageSkillLevel}
topSkills={team.topSkills}
skillCoverage={team.skillCoverage}
criticalSkillsCoverage={team.criticalSkillsCoverage}
onViewDetails={() => onViewTeamDetails(team)}
onViewReport={() => onExportTeamReport(team)}
/>