153 lines
5.8 KiB
TypeScript
153 lines
5.8 KiB
TypeScript
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { TeamMemberProfile, SkillGap } from "@/lib/team-review-types";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
|
import { GraduationCap } from "lucide-react";
|
|
|
|
interface LearningSectionProps {
|
|
members: TeamMemberProfile[];
|
|
skillGaps: SkillGap[];
|
|
}
|
|
|
|
export function LearningSection({ members, skillGaps }: LearningSectionProps) {
|
|
// Trouver les apprenants
|
|
const learners = members.filter((member) => member.learningSkills > 0);
|
|
|
|
// Organiser les besoins d'apprentissage par apprenant
|
|
const learningNeeds = learners.map((learner) => {
|
|
const needs = learner.skills
|
|
.filter((skill) => skill.wantsToLearn)
|
|
.map((skill) => {
|
|
const gap = skillGaps.find((g) => g.skillId === skill.skillId);
|
|
if (!gap) return null;
|
|
|
|
const mentors = members.filter((member) =>
|
|
member.skills.some(
|
|
(s) =>
|
|
s.skillId === skill.skillId &&
|
|
s.canMentor &&
|
|
["autonomous", "expert"].includes(s.level)
|
|
)
|
|
);
|
|
|
|
return {
|
|
skill: skill.skillName,
|
|
category: skill.category,
|
|
currentLevel: skill.level,
|
|
mentors,
|
|
isHighRisk: gap.risk === "high",
|
|
};
|
|
})
|
|
.filter(Boolean);
|
|
|
|
return {
|
|
learner,
|
|
needs,
|
|
};
|
|
});
|
|
|
|
const getLevelColor = (level: string) => {
|
|
const colors = {
|
|
never: "bg-white/5 text-slate-300 border-white/20",
|
|
"not-autonomous": "bg-yellow-500/20 text-yellow-200 border-yellow-500/30",
|
|
autonomous: "bg-green-500/20 text-green-200 border-green-500/30",
|
|
expert: "bg-blue-500/20 text-blue-200 border-blue-500/30",
|
|
};
|
|
return colors[level as keyof typeof colors];
|
|
};
|
|
|
|
return (
|
|
<Card className="bg-white/5 border-white/10 backdrop-blur">
|
|
<CardHeader>
|
|
<CardTitle className="text-slate-200">Besoins en formation</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ScrollArea className="h-[400px]">
|
|
<div className="space-y-6">
|
|
{learningNeeds.map(({ learner, needs }) => (
|
|
<div key={learner.member.uuid} className="space-y-4">
|
|
<div className="flex items-center gap-3">
|
|
<Avatar className="bg-white/10 border border-white/20">
|
|
<AvatarFallback className="text-slate-200 bg-transparent">
|
|
{learner.member.firstName[0]}
|
|
{learner.member.lastName[0]}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
<div>
|
|
<h3 className="font-semibold text-slate-200">
|
|
{learner.member.firstName} {learner.member.lastName}
|
|
</h3>
|
|
<p className="text-sm text-slate-400">
|
|
{learner.learningSkills} compétences à développer
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="pl-12 space-y-3">
|
|
{needs.map(
|
|
(need, idx) =>
|
|
need && (
|
|
<div key={idx} className="space-y-2">
|
|
<div className="flex items-center gap-2">
|
|
<Badge
|
|
variant="outline"
|
|
className="bg-white/5 text-slate-300 border-white/20"
|
|
>
|
|
{need.category}
|
|
</Badge>
|
|
<span className="font-medium text-slate-300">
|
|
{need.skill}
|
|
</span>
|
|
{need.isHighRisk && (
|
|
<Badge
|
|
variant="outline"
|
|
className="bg-red-500/20 text-red-200 border-red-500/30"
|
|
>
|
|
Prioritaire
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<span className="text-slate-400">
|
|
Niveau actuel :
|
|
</span>
|
|
<Badge
|
|
variant="secondary"
|
|
className={getLevelColor(need.currentLevel)}
|
|
>
|
|
{need.currentLevel}
|
|
</Badge>
|
|
</div>
|
|
{need.mentors.length > 0 && (
|
|
<div className="pl-4">
|
|
<p className="text-sm text-slate-400 mb-2">
|
|
Mentors disponibles :
|
|
</p>
|
|
<div className="flex flex-wrap gap-2">
|
|
{need.mentors.map((mentor) => (
|
|
<Badge
|
|
key={mentor.member.uuid}
|
|
variant="outline"
|
|
className="bg-green-500/10 text-green-200 border-green-500/30"
|
|
>
|
|
{mentor.member.firstName}{" "}
|
|
{mentor.member.lastName}
|
|
</Badge>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
)}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</ScrollArea>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|