feat: importance in db and mentorcard home colors
This commit is contained in:
89
components/admin/skills/importance-badge.tsx
Normal file
89
components/admin/skills/importance-badge.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { ChevronDown, Check } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { getImportanceColors } from "@/lib/tech-colors";
|
||||
|
||||
interface ImportanceBadgeProps {
|
||||
importance: string;
|
||||
onImportanceChange: (newImportance: string) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export function ImportanceBadge({
|
||||
importance,
|
||||
onImportanceChange,
|
||||
disabled = false,
|
||||
}: ImportanceBadgeProps) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const colors = getImportanceColors(importance);
|
||||
|
||||
const handleImportanceChange = (newImportance: string) => {
|
||||
onImportanceChange(newImportance);
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
const IMPORTANCE_LABELS = {
|
||||
incontournable: "Incontournable",
|
||||
majeure: "Majeure",
|
||||
standard: "Standard",
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={`h-6 px-2 text-xs font-medium border ${colors.bg} ${
|
||||
colors.text
|
||||
} ${colors.border} hover:opacity-80 transition-all ${
|
||||
disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"
|
||||
}`}
|
||||
disabled={disabled}
|
||||
>
|
||||
<span
|
||||
className={`w-2 h-2 rounded-full ${colors.text.replace(
|
||||
"text-",
|
||||
"bg-"
|
||||
)}`}
|
||||
/>
|
||||
{IMPORTANCE_LABELS[importance as keyof typeof IMPORTANCE_LABELS] ||
|
||||
importance}
|
||||
{!disabled && <ChevronDown className="w-3 h-3 ml-1" />}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
{!disabled && (
|
||||
<DropdownMenuContent align="end" className="w-40">
|
||||
{Object.entries(IMPORTANCE_LABELS).map(([key, label]) => {
|
||||
const itemColors = getImportanceColors(key);
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={key}
|
||||
onClick={() => handleImportanceChange(key)}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<span
|
||||
className={`w-2 h-2 rounded-full ${itemColors.text.replace(
|
||||
"text-",
|
||||
"bg-"
|
||||
)}`}
|
||||
/>
|
||||
{label}
|
||||
{importance === key && <Check className="w-3 h-3 ml-auto" />}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
)}
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { TreeCategoryHeader, TreeItemRow } from "@/components/admin";
|
||||
import { TechIcon } from "@/components/icons/tech-icon";
|
||||
import { Skill } from "@/clients/domains/admin-client";
|
||||
import { ImportanceBadge } from "./importance-badge";
|
||||
|
||||
interface SkillsListProps {
|
||||
filteredSkillsByCategory: Record<string, Skill[]>;
|
||||
@@ -20,6 +21,7 @@ interface SkillsListProps {
|
||||
onEditSkill: (skill: Skill) => void;
|
||||
onDeleteSkill: (skillId: string) => void;
|
||||
onDeleteCategory?: (categoryName: string) => void; // Nouvelle prop
|
||||
onImportanceChange?: (skillId: string, newImportance: string) => void;
|
||||
}
|
||||
|
||||
export function SkillsList({
|
||||
@@ -29,6 +31,7 @@ export function SkillsList({
|
||||
onEditSkill,
|
||||
onDeleteSkill,
|
||||
onDeleteCategory,
|
||||
onImportanceChange,
|
||||
}: SkillsListProps) {
|
||||
// Fonction pour obtenir l'icône de la catégorie
|
||||
const getCategoryIcon = (category: string) => {
|
||||
@@ -108,6 +111,14 @@ export function SkillsList({
|
||||
onDelete={() => onDeleteSkill(skill.id)}
|
||||
canDelete={skill.usageCount === 0}
|
||||
showSeparator={skillIndex > 0}
|
||||
additionalInfo={
|
||||
<ImportanceBadge
|
||||
importance={skill.importance || "standard"}
|
||||
onImportanceChange={(newImportance: string) =>
|
||||
onImportanceChange?.(skill.id, newImportance)
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -51,6 +51,7 @@ export function SkillsManagementPage({
|
||||
handleEditSkill,
|
||||
handleUpdateSkill,
|
||||
handleDeleteSkill,
|
||||
handleImportanceChange,
|
||||
} = useSkillsManagement(skillCategories, initialSkills);
|
||||
|
||||
// Utilisation du hook factorisé pour la vue arborescente
|
||||
@@ -93,6 +94,13 @@ export function SkillsManagementPage({
|
||||
openEditDialog();
|
||||
};
|
||||
|
||||
const handleImportanceChangeWrapper = async (
|
||||
skillId: string,
|
||||
newImportance: string
|
||||
) => {
|
||||
await handleImportanceChange(skillId, newImportance);
|
||||
};
|
||||
|
||||
const headerActions = (
|
||||
<Button onClick={handleOpenCreateDialog}>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
@@ -137,6 +145,7 @@ export function SkillsManagementPage({
|
||||
onEditSkill={handleOpenEditDialog}
|
||||
onDeleteSkill={handleDeleteSkill}
|
||||
onDeleteCategory={handleDeleteCategory}
|
||||
onImportanceChange={handleImportanceChangeWrapper}
|
||||
/>
|
||||
</TreeViewPage>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user