diff --git a/app/page.tsx b/app/page.tsx index c909dc9..1af26c8 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { useEvaluation } from "@/hooks/use-evaluation"; import { ProfileForm } from "@/components/profile-form"; import { SkillsRadarChart } from "@/components/radar-chart"; @@ -15,14 +15,17 @@ import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { generateRadarData } from "@/lib/evaluation-utils"; import { useUser } from "@/hooks/use-user-context"; +import { getTechIcon } from "@/components/icons/tech-icons"; import Link from "next/link"; -import { Code2 } from "lucide-react"; +import { Code2, ChevronDown, ChevronRight, ExternalLink } from "lucide-react"; +import { getCategoryIcon } from "@/lib/category-icons"; export default function HomePage() { const { userEvaluation, skillCategories, teams, loading, updateProfile } = useEvaluation(); const { setUserInfo } = useUser(); + const [expandedCategory, setExpandedCategory] = useState(null); // Update user info in navigation when user evaluation is loaded useEffect(() => { @@ -148,36 +151,124 @@ export default function HomePage() { const evaluatedCount = categoryEval?.skills.filter((s) => s.level !== null).length || 0; + const isExpanded = expandedCategory === category.category; + const currentSkillCategory = skillCategories.find( + (sc) => sc.category === category.category + ); + const CategoryIcon = currentSkillCategory + ? getCategoryIcon(currentSkillCategory.icon) + : null; return (
-
-

- {category.category} -

-
- - {category.score.toFixed(1)}/3 - +
+ setExpandedCategory( + isExpanded ? null : category.category + ) + } + > +
+
+ {isExpanded ? ( + + ) : ( + + )} + {CategoryIcon && ( + + )} +

+ {category.category} +

+
+
+ + {category.score.toFixed(1)}/3 + +
+
+
+ {evaluatedCount}/{skillsCount} compétences sélectionnées + évaluées +
+
+
-
- {evaluatedCount}/{skillsCount} compétences sélectionnées - évaluées -
-
-
-
+ + {/* Expanded Skills */} + {isExpanded && categoryEval && currentSkillCategory && ( +
+
+ {categoryEval.selectedSkillIds.map((skillId) => { + const skill = currentSkillCategory.skills.find( + (s) => s.id === skillId + ); + if (!skill) return null; + + const skillEval = categoryEval.skills.find( + (s) => s.skillId === skillId + ); + const TechIcon = getTechIcon(skill.id); + + return ( +
+
+ + + {skill.name} + +
+
+ {skillEval?.level && ( + + {skillEval.level === "never" && + "Jamais utilisé"} + {skillEval.level === "not-autonomous" && + "Non autonome"} + {skillEval.level === "autonomous" && + "Autonome"} + {skillEval.level === "expert" && "Expert"} + + )} +
+
+ ); + })} +
+ +
+ +
+
+ )}
); })} diff --git a/components/evaluation/category-tabs.tsx b/components/evaluation/category-tabs.tsx index d092106..dbc9b7f 100644 --- a/components/evaluation/category-tabs.tsx +++ b/components/evaluation/category-tabs.tsx @@ -1,5 +1,6 @@ import { ChevronRight } from "lucide-react"; import { SkillCategory } from "@/lib/types"; +import { getCategoryIcon } from "@/lib/category-icons"; interface CategoryTabsProps { categories: SkillCategory[]; @@ -16,12 +17,13 @@ export function CategoryTabs({
{categories.map((category) => { const isActive = selectedCategory === category.category; + const CategoryIcon = getCategoryIcon(category.icon); return ( - - -

{label}

-
- +
+ + onUpdateSkill(skill.id, levelValue)} + > + {label} + +
); })} diff --git a/components/evaluation/skill-evaluation-grid.tsx b/components/evaluation/skill-evaluation-grid.tsx index ca9d92e..767be2a 100644 --- a/components/evaluation/skill-evaluation-grid.tsx +++ b/components/evaluation/skill-evaluation-grid.tsx @@ -37,7 +37,7 @@ export function SkillEvaluationGrid({
-
+
{currentEvaluation.selectedSkillIds.map((skillId) => { const skill = currentCategory.skills.find((s) => s.id === skillId); if (!skill) return null; diff --git a/components/skill-evaluation.tsx b/components/skill-evaluation.tsx index 4829cc7..c48365c 100644 --- a/components/skill-evaluation.tsx +++ b/components/skill-evaluation.tsx @@ -1,6 +1,7 @@ "use client"; -import { useState } from "react"; +import { useState, useEffect } from "react"; +import { useSearchParams, useRouter } from "next/navigation"; import { TooltipProvider } from "@/components/ui/tooltip"; import { SkillCategory, SkillLevel, CategoryEvaluation } from "@/lib/types"; import { SkillSelector } from "./skill-selector"; @@ -26,10 +27,31 @@ export function SkillEvaluation({ onAddSkill, onRemoveSkill, }: SkillEvaluationProps) { + const searchParams = useSearchParams(); + const router = useRouter(); + const categoryParam = searchParams.get("category"); + const [selectedCategory, setSelectedCategory] = useState( categories[0]?.category || "" ); + const handleCategoryChange = (category: string) => { + setSelectedCategory(category); + // Update URL without page reload + const newUrl = new URL(window.location.href); + newUrl.searchParams.set("category", category); + router.replace(newUrl.pathname + newUrl.search); + }; + + // Update selected category when URL param changes or categories load + useEffect(() => { + if (categoryParam && categories.some((c) => c.category === categoryParam)) { + setSelectedCategory(categoryParam); + } else if (categories.length > 0 && !selectedCategory) { + setSelectedCategory(categories[0].category); + } + }, [categoryParam, categories]); // Remove selectedCategory from deps to avoid loop + const currentCategory = categories.find( (cat) => cat.category === selectedCategory ); @@ -55,7 +77,7 @@ export function SkillEvaluation({
diff --git a/data/skills/backend.json b/data/skills/backend.json index 27a600d..07f9bdd 100644 --- a/data/skills/backend.json +++ b/data/skills/backend.json @@ -1,5 +1,6 @@ { "category": "Backend", + "icon": "server", "skills": [ { "id": "nodejs", diff --git a/data/skills/devops.json b/data/skills/devops.json index 2aba133..c94161b 100644 --- a/data/skills/devops.json +++ b/data/skills/devops.json @@ -1,5 +1,6 @@ { "category": "DevOps", + "icon": "settings", "skills": [ { "id": "docker", diff --git a/data/skills/frontend.json b/data/skills/frontend.json index 3147a09..349fa21 100644 --- a/data/skills/frontend.json +++ b/data/skills/frontend.json @@ -1,5 +1,6 @@ { "category": "Frontend", + "icon": "monitor", "skills": [ { "id": "react", diff --git a/data/skills/mobile.json b/data/skills/mobile.json index 24ee601..cf1d130 100644 --- a/data/skills/mobile.json +++ b/data/skills/mobile.json @@ -1,5 +1,6 @@ { "category": "Mobile", + "icon": "smartphone", "skills": [ { "id": "reactnative", diff --git a/lib/category-icons.ts b/lib/category-icons.ts new file mode 100644 index 0000000..137d7bf --- /dev/null +++ b/lib/category-icons.ts @@ -0,0 +1,18 @@ +import { + Monitor, + Server, + Settings, + Smartphone, + LucideIcon +} from "lucide-react"; + +const CATEGORY_ICON_MAP: Record = { + monitor: Monitor, + server: Server, + settings: Settings, + smartphone: Smartphone, +}; + +export function getCategoryIcon(iconName: string): LucideIcon { + return CATEGORY_ICON_MAP[iconName] || Settings; // Settings as fallback +} diff --git a/lib/types.ts b/lib/types.ts index 092909c..c5c2819 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -28,6 +28,7 @@ export interface Skill { export interface SkillCategory { category: string; + icon: string; skills: Skill[]; } diff --git a/public/data/skills/backend.json b/public/data/skills/backend.json index 27a600d..07f9bdd 100644 --- a/public/data/skills/backend.json +++ b/public/data/skills/backend.json @@ -1,5 +1,6 @@ { "category": "Backend", + "icon": "server", "skills": [ { "id": "nodejs", diff --git a/public/data/skills/devops.json b/public/data/skills/devops.json index 2aba133..c94161b 100644 --- a/public/data/skills/devops.json +++ b/public/data/skills/devops.json @@ -1,5 +1,6 @@ { "category": "DevOps", + "icon": "settings", "skills": [ { "id": "docker", diff --git a/public/data/skills/frontend.json b/public/data/skills/frontend.json index 3147a09..349fa21 100644 --- a/public/data/skills/frontend.json +++ b/public/data/skills/frontend.json @@ -1,5 +1,6 @@ { "category": "Frontend", + "icon": "monitor", "skills": [ { "id": "react", diff --git a/public/data/skills/mobile.json b/public/data/skills/mobile.json index 24ee601..cf1d130 100644 --- a/public/data/skills/mobile.json +++ b/public/data/skills/mobile.json @@ -1,5 +1,6 @@ { "category": "Mobile", + "icon": "smartphone", "skills": [ { "id": "reactnative",