feat: my team page
This commit is contained in:
152
components/team-review/learning-section.tsx
Normal file
152
components/team-review/learning-section.tsx
Normal file
@@ -0,0 +1,152 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user