117 lines
3.8 KiB
TypeScript
117 lines
3.8 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
Code2,
|
|
Palette,
|
|
Database,
|
|
Cloud,
|
|
Shield,
|
|
Smartphone,
|
|
Layers,
|
|
} from "lucide-react";
|
|
import { TreeCategoryHeader, TreeItemRow } from "@/components/admin";
|
|
import { TechIcon } from "@/components/icons/tech-icon";
|
|
import { Skill } from "@/clients/domains/admin-client";
|
|
|
|
interface SkillsListProps {
|
|
filteredSkillsByCategory: Record<string, Skill[]>;
|
|
expandedCategories: Set<string>;
|
|
onToggleCategory: (category: string) => void;
|
|
onEditSkill: (skill: Skill) => void;
|
|
onDeleteSkill: (skillId: string) => void;
|
|
}
|
|
|
|
export function SkillsList({
|
|
filteredSkillsByCategory,
|
|
expandedCategories,
|
|
onToggleCategory,
|
|
onEditSkill,
|
|
onDeleteSkill,
|
|
}: SkillsListProps) {
|
|
// Fonction pour obtenir l'icône de la catégorie
|
|
const getCategoryIcon = (category: string) => {
|
|
const categoryName = category.toLowerCase();
|
|
if (categoryName.includes("frontend") || categoryName.includes("front"))
|
|
return Code2;
|
|
if (categoryName.includes("backend") || categoryName.includes("back"))
|
|
return Layers;
|
|
if (
|
|
categoryName.includes("design") ||
|
|
categoryName.includes("ui") ||
|
|
categoryName.includes("ux")
|
|
)
|
|
return Palette;
|
|
if (categoryName.includes("data") || categoryName.includes("database"))
|
|
return Database;
|
|
if (categoryName.includes("cloud") || categoryName.includes("devops"))
|
|
return Cloud;
|
|
if (categoryName.includes("security") || categoryName.includes("securité"))
|
|
return Shield;
|
|
if (
|
|
categoryName.includes("mobile") ||
|
|
categoryName.includes("android") ||
|
|
categoryName.includes("ios")
|
|
)
|
|
return Smartphone;
|
|
return Code2; // Par défaut
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{Object.entries(filteredSkillsByCategory).map(
|
|
([category, categorySkills], index) => (
|
|
<div key={category}>
|
|
<TreeCategoryHeader
|
|
category={category}
|
|
isExpanded={expandedCategories.has(category)}
|
|
onToggle={() => onToggleCategory(category)}
|
|
icon={(() => {
|
|
const IconComponent = getCategoryIcon(category);
|
|
return <IconComponent className="w-5 h-5 text-blue-400" />;
|
|
})()}
|
|
itemCount={categorySkills.length}
|
|
itemLabel="skill"
|
|
showSeparator={index > 0}
|
|
/>
|
|
|
|
{/* Liste des skills de la catégorie */}
|
|
{expandedCategories.has(category) && (
|
|
<div className="bg-slate-950/30">
|
|
{categorySkills.map((skill, skillIndex) => (
|
|
<TreeItemRow
|
|
key={skill.id}
|
|
icon={
|
|
<div className="flex items-center gap-3">
|
|
<TechIcon
|
|
iconName={skill.icon}
|
|
className="w-5 h-5 text-green-400"
|
|
fallbackText={skill.name}
|
|
/>
|
|
<div className="p-1 bg-green-500/20 border border-green-500/30 rounded text-xs font-mono text-green-400 min-w-[3rem] text-center shrink-0">
|
|
{skill.icon || "?"}
|
|
</div>
|
|
</div>
|
|
}
|
|
title={skill.name}
|
|
subtitle={skill.description}
|
|
badges={[
|
|
{
|
|
text: `${skill.usageCount} util.`,
|
|
variant: "outline",
|
|
},
|
|
]}
|
|
onEdit={() => onEditSkill(skill)}
|
|
onDelete={() => onDeleteSkill(skill.id)}
|
|
canDelete={skill.usageCount === 0}
|
|
showSeparator={skillIndex > 0}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
)}
|
|
</>
|
|
);
|
|
}
|