feat: review admin teams views for importance inclusion
This commit is contained in:
@@ -7,6 +7,7 @@ import { Badge } from "@/components/ui/badge";
|
||||
interface SkillAnalysis {
|
||||
skillName: string;
|
||||
category: string;
|
||||
importance: "incontournable" | "majeure" | "standard";
|
||||
experts: Array<{
|
||||
name: string;
|
||||
level: number;
|
||||
@@ -21,6 +22,7 @@ interface SkillAnalysis {
|
||||
expertCount: number;
|
||||
learnerCount: number;
|
||||
proficiencyRate: number;
|
||||
coverage: number;
|
||||
}
|
||||
|
||||
interface TeamSkillsTabProps {
|
||||
@@ -95,101 +97,156 @@ export function TeamSkillsTab({ skillAnalysis }: TeamSkillsTabProps) {
|
||||
</div>
|
||||
|
||||
{/* Liste des compétences détaillée */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">
|
||||
{filteredSkills.map((skill, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="bg-white/5 border border-white/10 rounded-lg p-3 hover:bg-white/10 transition-colors"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="min-w-0 flex-1">
|
||||
<h4 className="font-medium text-white text-sm truncate">
|
||||
{skill.skillName}
|
||||
</h4>
|
||||
<p className="text-xs text-slate-400">{skill.category}</p>
|
||||
</div>
|
||||
<div
|
||||
className={`px-2 py-1 border rounded text-center ml-2 flex-shrink-0 ${getSkillLevelBadgeClasses(
|
||||
skill.averageLevel
|
||||
)}`}
|
||||
>
|
||||
<span className="text-xs font-medium">
|
||||
{getSkillLevelLabel(skill.averageLevel)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl">
|
||||
<div className="overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="border-b border-white/10">
|
||||
<th className="text-left py-2 px-4 text-xs font-medium text-slate-400">
|
||||
Compétence
|
||||
</th>
|
||||
<th className="text-center py-2 px-2 text-xs font-medium text-slate-400">
|
||||
Niveau
|
||||
</th>
|
||||
<th className="text-center py-2 px-2 text-xs font-medium text-slate-400">
|
||||
Experts
|
||||
</th>
|
||||
<th className="text-center py-2 px-2 text-xs font-medium text-slate-400">
|
||||
Appren.
|
||||
</th>
|
||||
<th className="text-center py-2 px-2 text-xs font-medium text-slate-400">
|
||||
Couv.
|
||||
</th>
|
||||
<th className="text-center py-2 px-4 text-xs font-medium text-slate-400">
|
||||
Mentors
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{filteredSkills.map((skill, idx) => {
|
||||
const target =
|
||||
skill.importance === "incontournable"
|
||||
? 75
|
||||
: skill.importance === "majeure"
|
||||
? 60
|
||||
: 0;
|
||||
const isUnderTarget = target > 0 && skill.coverage < target;
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-xs text-slate-300">Niveau:</span>
|
||||
<span className="text-white font-semibold text-sm">
|
||||
{skill.averageLevel.toFixed(1)}/3
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="w-full bg-white/10 rounded-full h-1.5">
|
||||
<div
|
||||
className={`h-1.5 rounded-full transition-all ${getSkillLevelColor(
|
||||
skill.averageLevel
|
||||
)
|
||||
.replace("bg-", "bg-gradient-to-r from-")
|
||||
.replace("-500", "-500 to-")
|
||||
.replace("500 to-", "400")}`}
|
||||
style={{ width: `${(skill.averageLevel / 3) * 100}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-3 gap-1 text-xs">
|
||||
<div className="text-center">
|
||||
<div className="text-white font-semibold">
|
||||
{skill.totalEvaluations}
|
||||
</div>
|
||||
<div className="text-slate-400 text-xs">Éval.</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-green-300 font-semibold">
|
||||
{skill.expertCount}
|
||||
</div>
|
||||
<div className="text-slate-400 text-xs">Experts</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-blue-300 font-semibold">
|
||||
{skill.learnerCount}
|
||||
</div>
|
||||
<div className="text-slate-400 text-xs">Appren.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{skill.experts.filter((e) => e.canMentor).length > 0 && (
|
||||
<div className="pt-2 border-t border-white/10">
|
||||
<div className="text-xs text-slate-400 mb-1">Mentors:</div>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{skill.experts
|
||||
.filter((e) => e.canMentor)
|
||||
.slice(0, 2)
|
||||
.map((expert, i) => (
|
||||
<Badge
|
||||
key={i}
|
||||
variant="outline"
|
||||
className="text-xs text-green-300 border-green-500/30 px-1 py-0.5"
|
||||
return (
|
||||
<tr
|
||||
key={idx}
|
||||
className={`border-b border-white/5 hover:bg-white/5 ${
|
||||
skill.importance === "incontournable"
|
||||
? "bg-red-500/5"
|
||||
: skill.importance === "majeure"
|
||||
? "bg-blue-500/5"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<td className="py-2 px-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div
|
||||
className={`w-1 h-6 rounded-sm ${
|
||||
skill.importance === "incontournable"
|
||||
? "bg-red-500"
|
||||
: skill.importance === "majeure"
|
||||
? "bg-blue-500"
|
||||
: "bg-slate-500"
|
||||
}`}
|
||||
/>
|
||||
<div>
|
||||
<div className="text-sm text-slate-200">
|
||||
{skill.skillName}
|
||||
</div>
|
||||
<div className="text-xs text-slate-400">
|
||||
{skill.category}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-2 px-2">
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<div
|
||||
className={`text-sm font-medium ${getSkillLevelBadgeClasses(
|
||||
skill.averageLevel
|
||||
)}`}
|
||||
>
|
||||
{expert.name.split(" ")[0]}
|
||||
</Badge>
|
||||
))}
|
||||
{skill.experts.filter((e) => e.canMentor).length > 2 && (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="text-xs text-slate-400 border-slate-500/30 px-1 py-0.5"
|
||||
>
|
||||
+{skill.experts.filter((e) => e.canMentor).length - 2}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{skill.averageLevel.toFixed(1)}
|
||||
</div>
|
||||
<div className="w-12 bg-white/10 rounded-full h-1">
|
||||
<div
|
||||
className={`h-1 rounded-full ${getSkillLevelColor(
|
||||
skill.averageLevel
|
||||
)}`}
|
||||
style={{
|
||||
width: `${(skill.averageLevel / 3) * 100}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-2 px-2 text-center">
|
||||
<span className="text-sm text-green-400 font-medium">
|
||||
{skill.expertCount}
|
||||
</span>
|
||||
</td>
|
||||
<td className="py-2 px-2 text-center">
|
||||
<span className="text-sm text-blue-400 font-medium">
|
||||
{skill.learnerCount}
|
||||
</span>
|
||||
</td>
|
||||
<td className="py-2 px-2">
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<div
|
||||
className={`text-sm font-medium ${
|
||||
isUnderTarget ? "text-red-400" : "text-green-400"
|
||||
}`}
|
||||
>
|
||||
{skill.coverage.toFixed(0)}%
|
||||
</div>
|
||||
<div className="w-12 bg-white/10 rounded-full h-1">
|
||||
<div
|
||||
className={`h-1 rounded-full ${
|
||||
isUnderTarget ? "bg-red-500" : "bg-green-500"
|
||||
}`}
|
||||
style={{ width: `${skill.coverage}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-2 px-4">
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
{skill.experts
|
||||
.filter((e) => e.canMentor)
|
||||
.slice(0, 2)
|
||||
.map((expert, i) => (
|
||||
<Badge
|
||||
key={i}
|
||||
variant="outline"
|
||||
className="text-[10px] text-green-300 border-green-500/30 px-1"
|
||||
>
|
||||
{expert.name.split(" ")[0]}
|
||||
</Badge>
|
||||
))}
|
||||
{skill.experts.filter((e) => e.canMentor).length >
|
||||
2 && (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="text-[10px] text-slate-400 border-slate-500/30 px-1"
|
||||
>
|
||||
+
|
||||
{skill.experts.filter((e) => e.canMentor).length -
|
||||
2}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user