diff --git a/app/api/skills/route.ts b/app/api/skills/route.ts
new file mode 100644
index 0000000..413b75f
--- /dev/null
+++ b/app/api/skills/route.ts
@@ -0,0 +1,41 @@
+import { NextResponse } from "next/server";
+import fs from "fs";
+import path from "path";
+import { SkillCategory } from "@/lib/types";
+
+export async function GET() {
+ try {
+ const dataDir = path.join(process.cwd(), "data", "skills");
+
+ const categories = [
+ "frontend",
+ "backend",
+ "devops",
+ "mobile",
+ "data",
+ "cloud",
+ "security",
+ "design",
+ ];
+
+ const skillCategories: SkillCategory[] = [];
+
+ for (const category of categories) {
+ const filePath = path.join(dataDir, `${category}.json`);
+
+ if (fs.existsSync(filePath)) {
+ const fileContent = fs.readFileSync(filePath, "utf-8");
+ const data = JSON.parse(fileContent);
+ skillCategories.push(data);
+ }
+ }
+
+ return NextResponse.json(skillCategories);
+ } catch (error) {
+ console.error("Error loading skills:", error);
+ return NextResponse.json(
+ { error: "Failed to load skills" },
+ { status: 500 }
+ );
+ }
+}
diff --git a/app/api/teams/route.ts b/app/api/teams/route.ts
new file mode 100644
index 0000000..f4a0730
--- /dev/null
+++ b/app/api/teams/route.ts
@@ -0,0 +1,25 @@
+import { NextResponse } from "next/server";
+import fs from "fs";
+import path from "path";
+import { Team } from "@/lib/types";
+
+export async function GET() {
+ try {
+ const filePath = path.join(process.cwd(), "data", "teams.json");
+
+ if (!fs.existsSync(filePath)) {
+ return NextResponse.json({ teams: [] });
+ }
+
+ const fileContent = fs.readFileSync(filePath, "utf-8");
+ const data = JSON.parse(fileContent);
+
+ return NextResponse.json(data.teams as Team[]);
+ } catch (error) {
+ console.error("Error loading teams:", error);
+ return NextResponse.json(
+ { error: "Failed to load teams" },
+ { status: 500 }
+ );
+ }
+}
diff --git a/app/page.tsx b/app/page.tsx
index cddd84f..1bbec66 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -20,6 +20,43 @@ import Link from "next/link";
import { Code2, ChevronDown, ChevronRight, ExternalLink } from "lucide-react";
import { getCategoryIcon } from "@/lib/category-icons";
+// Fonction pour déterminer la couleur du badge selon le niveau moyen
+function getScoreColors(score: number) {
+ if (score >= 2.5) {
+ // Expert/Maîtrise (violet)
+ return {
+ bg: "bg-violet-500/20",
+ border: "border-violet-500/30",
+ text: "text-violet-400",
+ gradient: "from-violet-500 to-violet-400",
+ };
+ } else if (score >= 1.5) {
+ // Autonome (vert)
+ return {
+ bg: "bg-green-500/20",
+ border: "border-green-500/30",
+ text: "text-green-400",
+ gradient: "from-green-500 to-green-400",
+ };
+ } else if (score >= 0.5) {
+ // Non autonome (orange/amber)
+ return {
+ bg: "bg-amber-500/20",
+ border: "border-amber-500/30",
+ text: "text-amber-400",
+ gradient: "from-amber-500 to-amber-400",
+ };
+ } else {
+ // Jamais pratiqué (rouge)
+ return {
+ bg: "bg-red-500/20",
+ border: "border-red-500/30",
+ text: "text-red-400",
+ gradient: "from-red-500 to-red-400",
+ };
+ }
+}
+
export default function HomePage() {
const { userEvaluation, skillCategories, teams, loading, updateProfile } =
useEvaluation();
@@ -186,26 +223,53 @@ export default function HomePage() {
{category.category}
-
-
- {category.score.toFixed(1)}/3
-
-
+ {skillsCount > 0 ? (
+ (() => {
+ const colors = getScoreColors(category.score);
+ return (
+
+
+ {Math.round((category.score / 3) * 100)}%
+
+
+ );
+ })()
+ ) : (
+
+
+ Aucune
+
+
+ )}
- {evaluatedCount}/{skillsCount} compétences sélectionnées
- évaluées
-
-
-
+ {skillsCount > 0
+ ? `${evaluatedCount}/${skillsCount} compétences sélectionnées évaluées`
+ : "Aucune compétence sélectionnée"}
+ {skillsCount > 0 ? (
+
+ {(() => {
+ const colors = getScoreColors(category.score);
+ return (
+
+ );
+ })()}
+
+ ) : (
+
+ )}
{/* Expanded Skills */}
diff --git a/hooks/use-evaluation.ts b/hooks/use-evaluation.ts
index 9730718..1c5d8b9 100644
--- a/hooks/use-evaluation.ts
+++ b/hooks/use-evaluation.ts
@@ -16,6 +16,40 @@ import {
} from "@/lib/evaluation-utils";
import { loadSkillCategories, loadTeams } from "@/lib/data-loader";
+// Fonction pour migrer une évaluation existante avec de nouvelles catégories
+function migrateEvaluation(
+ evaluation: UserEvaluation,
+ allCategories: SkillCategory[]
+): UserEvaluation {
+ const existingCategoryNames = evaluation.evaluations.map((e) => e.category);
+ const missingCategories = allCategories.filter(
+ (cat) => !existingCategoryNames.includes(cat.category)
+ );
+
+ if (missingCategories.length === 0) {
+ return evaluation; // Pas de migration nécessaire
+ }
+
+ console.log(
+ "🔄 Migrating evaluation with new categories:",
+ missingCategories.map((c) => c.category)
+ );
+
+ const newCategoryEvaluations: CategoryEvaluation[] = missingCategories.map(
+ (category) => ({
+ category: category.category,
+ skills: [],
+ selectedSkillIds: [],
+ })
+ );
+
+ return {
+ ...evaluation,
+ evaluations: [...evaluation.evaluations, ...newCategoryEvaluations],
+ lastUpdated: new Date().toISOString(),
+ };
+}
+
export function useEvaluation() {
const [userEvaluation, setUserEvaluation] = useState(
null
@@ -39,7 +73,10 @@ export function useEvaluation() {
// Try to load existing evaluation
const saved = loadUserEvaluation();
if (saved) {
- setUserEvaluation(saved);
+ // Migrate evaluation to include new categories if needed
+ const migratedEvaluation = migrateEvaluation(saved, categories);
+ setUserEvaluation(migratedEvaluation);
+ saveUserEvaluation(migratedEvaluation); // Save the migrated version
}
} catch (error) {
console.error("Failed to initialize data:", error);
diff --git a/lib/data-loader.ts b/lib/data-loader.ts
index f48ee96..b833bb9 100644
--- a/lib/data-loader.ts
+++ b/lib/data-loader.ts
@@ -1,29 +1,27 @@
import { SkillCategory, Team } from "./types";
-// Import direct des données JSON depuis le dossier /data
-import frontendData from "@/data/skills/frontend.json";
-import backendData from "@/data/skills/backend.json";
-import devopsData from "@/data/skills/devops.json";
-import mobileData from "@/data/skills/mobile.json";
-import dataData from "@/data/skills/data.json";
-import cloudData from "@/data/skills/cloud.json";
-import securityData from "@/data/skills/security.json";
-import designData from "@/data/skills/design.json";
-import teamsData from "@/data/teams.json";
-
export async function loadSkillCategories(): Promise {
- return [
- frontendData,
- backendData,
- devopsData,
- mobileData,
- dataData,
- cloudData,
- securityData,
- designData,
- ] as SkillCategory[];
+ try {
+ const response = await fetch("/api/skills");
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ return await response.json();
+ } catch (error) {
+ console.error("Failed to load skill categories:", error);
+ return [];
+ }
}
export async function loadTeams(): Promise {
- return teamsData.teams as Team[];
-}
\ No newline at end of file
+ try {
+ const response = await fetch("/api/teams");
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ return await response.json();
+ } catch (error) {
+ console.error("Failed to load teams:", error);
+ return [];
+ }
+}