Files
peakskills/components/skill-evaluation.tsx
Julien Froidefond dad172157b feat: add multiple skills addition and optimize evaluation handling
- Introduced `addMultipleSkillsToEvaluation` function in `EvaluationClientWrapper` for batch skill addition.
- Updated `SkillEvaluation` and `SkillSelector` components to utilize the new multiple skills addition feature.
- Implemented optimistic UI updates for skill level, mentor status, and learning status changes, enhancing user experience.
- Refactored evaluation state management to improve performance and maintainability.
- Added error handling and rollback mechanisms for better reliability during API interactions.
2025-08-21 15:07:57 +02:00

118 lines
4.0 KiB
TypeScript

"use client";
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";
import { useEvaluationContext } from "./evaluation";
import {
EvaluationHeader,
SkillLevelLegend,
CategoryTabs,
SkillEvaluationGrid,
} from "./evaluation";
interface SkillEvaluationProps {
categories: SkillCategory[];
evaluations: CategoryEvaluation[];
}
export function SkillEvaluation({
categories,
evaluations,
}: SkillEvaluationProps) {
const {
currentEvaluation: contextEvaluation,
updateSkillLevel,
updateSkillMentorStatus,
updateSkillLearningStatus,
addSkillToEvaluation,
addMultipleSkillsToEvaluation,
removeSkillFromEvaluation,
} = useEvaluationContext();
// Utiliser l'évaluation du contexte (avec état optimiste) ou celle des props (SSR)
const activeEvaluations = contextEvaluation?.evaluations || evaluations;
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
);
const currentEvaluation = activeEvaluations.find(
(evaluation) => evaluation.category === selectedCategory
);
if (!currentCategory) {
return <div>Aucune catégorie disponible</div>;
}
return (
<TooltipProvider>
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 relative overflow-hidden">
{/* Background Effects */}
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-blue-900/20 via-slate-900 to-slate-950" />
<div className="absolute inset-0 bg-grid-white/5 bg-[size:50px_50px]" />
<div className="absolute inset-0 bg-gradient-to-t from-slate-950 via-transparent to-transparent" />
<div className="relative z-10 container mx-auto px-6 py-8 max-w-7xl">
<EvaluationHeader />
<CategoryTabs
categories={categories}
selectedCategory={selectedCategory}
onCategoryChange={handleCategoryChange}
/>
<div className="space-y-8">
<SkillSelector
categories={categories}
evaluations={activeEvaluations}
selectedCategory={selectedCategory}
onAddSkill={addSkillToEvaluation}
onAddMultipleSkills={addMultipleSkillsToEvaluation}
onRemoveSkill={removeSkillFromEvaluation}
/>
{currentEvaluation && (
<SkillEvaluationGrid
currentCategory={currentCategory}
currentEvaluation={currentEvaluation}
onUpdateSkill={updateSkillLevel}
onUpdateMentorStatus={updateSkillMentorStatus}
onUpdateLearningStatus={updateSkillLearningStatus}
onRemoveSkill={removeSkillFromEvaluation}
/>
)}
</div>
<SkillLevelLegend />
</div>
</div>
</TooltipProvider>
);
}