feat: mentor section on homepage
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
ActionSection,
|
||||
ClientWrapper,
|
||||
WelcomeScreen,
|
||||
MentorSection,
|
||||
} from "@/components/home";
|
||||
|
||||
export default async function HomePage() {
|
||||
@@ -51,8 +52,14 @@ export default async function HomePage() {
|
||||
|
||||
{/* Main Content Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
{/* Radar Chart */}
|
||||
{/* Left Column: Radar + Mentor */}
|
||||
<div className="space-y-8">
|
||||
<RadarSection radarData={radarData} />
|
||||
<MentorSection
|
||||
userEvaluation={userEvaluation}
|
||||
skillCategories={skillCategories}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Category Breakdown */}
|
||||
<CategoryBreakdown
|
||||
|
||||
@@ -7,3 +7,4 @@ export { SkillProgress } from "./skill-progress";
|
||||
export { ActionSection } from "./action-section";
|
||||
export { ClientWrapper } from "./client-wrapper";
|
||||
export { WelcomeScreen } from "./welcome-screen";
|
||||
export { MentorSection } from "./mentor-section";
|
||||
|
||||
202
components/home/mentor-section.tsx
Normal file
202
components/home/mentor-section.tsx
Normal file
@@ -0,0 +1,202 @@
|
||||
import { TechIcon } from "@/components/icons/tech-icon";
|
||||
import { getTechColors } from "@/lib/tech-colors";
|
||||
import { UserEvaluation, SkillCategory } from "@/lib/types";
|
||||
|
||||
interface MentorSectionProps {
|
||||
className?: string;
|
||||
userEvaluation: UserEvaluation;
|
||||
skillCategories: SkillCategory[];
|
||||
}
|
||||
|
||||
export function MentorSection({
|
||||
className = "",
|
||||
userEvaluation,
|
||||
skillCategories,
|
||||
}: MentorSectionProps) {
|
||||
// Récupérer les compétences où l'utilisateur peut être mentor
|
||||
const mentorSkills = userEvaluation.evaluations.flatMap((cat) => {
|
||||
const skillCategory = skillCategories.find(
|
||||
(sc) => sc.category === cat.category
|
||||
);
|
||||
return cat.skills
|
||||
.filter((skill) => skill.canMentor)
|
||||
.map((skill) => {
|
||||
const skillInfo = skillCategory?.skills.find(
|
||||
(s) => s.id === skill.skillId
|
||||
);
|
||||
return {
|
||||
id: skill.skillId,
|
||||
name: skillInfo?.name || skill.skillId,
|
||||
icon: skillInfo?.icon || "fas-code",
|
||||
level: skill.level,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Récupérer les compétences maîtrisées (expert uniquement)
|
||||
const masteredSkills = userEvaluation.evaluations.flatMap((cat) => {
|
||||
const skillCategory = skillCategories.find(
|
||||
(sc) => sc.category === cat.category
|
||||
);
|
||||
return cat.skills
|
||||
.filter((skill) => skill.level === "expert")
|
||||
.map((skill) => {
|
||||
const skillInfo = skillCategory?.skills.find(
|
||||
(s) => s.id === skill.skillId
|
||||
);
|
||||
return {
|
||||
id: skill.skillId,
|
||||
name: skillInfo?.name || skill.skillId,
|
||||
icon: skillInfo?.icon || "fas-code",
|
||||
level: skill.level,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Récupérer les compétences que l'utilisateur veut apprendre
|
||||
const learningSkills = userEvaluation.evaluations.flatMap((cat) => {
|
||||
const skillCategory = skillCategories.find(
|
||||
(sc) => sc.category === cat.category
|
||||
);
|
||||
return cat.skills
|
||||
.filter((skill) => skill.wantsToLearn)
|
||||
.map((skill) => {
|
||||
const skillInfo = skillCategory?.skills.find(
|
||||
(s) => s.id === skill.skillId
|
||||
);
|
||||
return {
|
||||
id: skill.skillId,
|
||||
name: skillInfo?.name || skill.skillId,
|
||||
icon: skillInfo?.icon || "fas-code",
|
||||
level: skill.level,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Fonction pour déterminer la couleur d'une technologie
|
||||
const getTechColor = (techName: string) => {
|
||||
const lowerName = techName.toLowerCase();
|
||||
if (lowerName.includes("react") || lowerName.includes("next"))
|
||||
return "react";
|
||||
if (lowerName.includes("typescript") || lowerName.includes("javascript"))
|
||||
return "typescript";
|
||||
if (lowerName.includes("node")) return "nodejs";
|
||||
if (lowerName.includes("python")) return "python";
|
||||
if (lowerName.includes("docker")) return "docker";
|
||||
if (lowerName.includes("aws")) return "aws";
|
||||
if (lowerName.includes("kubernetes")) return "kubernetes";
|
||||
if (lowerName.includes("git")) return "default";
|
||||
return "default";
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`bg-white/5 border border-white/10 rounded-xl p-6 backdrop-blur-sm ${className}`}
|
||||
>
|
||||
<div className="space-y-6">
|
||||
{/* Technologies maîtrisées */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-3 flex items-center gap-2">
|
||||
<span className="w-2 h-2 bg-green-400 rounded-full"></span>
|
||||
Technologies maîtrisées
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{masteredSkills.length > 0 ? (
|
||||
masteredSkills.map((tech) => {
|
||||
const colors = getTechColors(getTechColor(tech.name));
|
||||
return (
|
||||
<div
|
||||
key={tech.id}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-lg ${colors.bg} ${colors.border} border transition-all hover:scale-105`}
|
||||
>
|
||||
<TechIcon
|
||||
iconName={tech.icon}
|
||||
className="w-4 h-4"
|
||||
fallbackText={tech.name}
|
||||
/>
|
||||
<span className={`text-sm font-medium ${colors.text}`}>
|
||||
{tech.name}
|
||||
</span>
|
||||
<span className="text-xs text-slate-400">Expert</span>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<p className="text-slate-400 text-sm">
|
||||
Aucune technologie maîtrisée
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Peut mentorer */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-3 flex items-center gap-2">
|
||||
<span className="w-2 h-2 bg-blue-400 rounded-full"></span>
|
||||
Peut mentorer
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{mentorSkills.length > 0 ? (
|
||||
mentorSkills.map((tech) => {
|
||||
const colors = getTechColors(getTechColor(tech.name));
|
||||
return (
|
||||
<div
|
||||
key={tech.id}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-lg ${colors.bg} ${colors.border} border transition-all hover:scale-105`}
|
||||
>
|
||||
<TechIcon
|
||||
iconName={tech.icon}
|
||||
className="w-4 h-4"
|
||||
fallbackText={tech.name}
|
||||
/>
|
||||
<span className={`text-sm font-medium ${colors.text}`}>
|
||||
{tech.name}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<p className="text-slate-400 text-sm">
|
||||
Aucune compétence mentor configurée
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Technologies à apprendre */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-white mb-3 flex items-center gap-2">
|
||||
<span className="w-2 h-2 bg-yellow-400 rounded-full"></span>
|
||||
Veux apprendre
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{learningSkills.length > 0 ? (
|
||||
learningSkills.map((tech) => {
|
||||
const colors = getTechColors(getTechColor(tech.name));
|
||||
return (
|
||||
<div
|
||||
key={tech.id}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-lg ${colors.bg} ${colors.border} border transition-all hover:scale-105 opacity-80`}
|
||||
>
|
||||
<TechIcon
|
||||
iconName={tech.icon}
|
||||
className="w-4 h-4"
|
||||
fallbackText={tech.name}
|
||||
/>
|
||||
<span className={`text-sm font-medium ${colors.text}`}>
|
||||
{tech.name}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<p className="text-slate-400 text-sm">
|
||||
Aucun objectif d'apprentissage configuré
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export function RadarSection({ radarData }: RadarSectionProps) {
|
||||
Radar chart représentant votre niveau par catégorie
|
||||
</p>
|
||||
</div>
|
||||
<div className="h-80">
|
||||
<div className="h-96 pb-8">
|
||||
<SkillsRadarChart data={radarData} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user