reafctor: pages for management and split components

This commit is contained in:
Julien Froidefond
2025-08-23 08:16:09 +02:00
parent 97d274190d
commit 2e195ca5cf
29 changed files with 1968 additions and 1607 deletions

View File

@@ -0,0 +1,158 @@
"use client";
import { useState } from "react";
import { Plus, Code2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { DialogTrigger } from "@/components/ui/dialog";
import { SkillCategory, Team } from "@/lib/types";
import { TreeViewPage } from "../management/tree-view-page";
import { useTreeView } from "@/hooks/use-tree-view";
import { useFormDialog } from "@/hooks/use-form-dialog";
import { useSkillsManagement } from "@/hooks/use-skills-management";
import { SkillFormDialog } from "./skill-form-dialog";
import { SkillsList } from "./skills-list";
interface SkillsManagementPageProps {
skillCategories: SkillCategory[];
teams: Team[];
}
export function SkillsManagementPage({
skillCategories,
teams,
}: SkillsManagementPageProps) {
const [searchTerm, setSearchTerm] = useState("");
const {
isCreateDialogOpen,
isEditDialogOpen,
openCreateDialog,
closeCreateDialog,
openEditDialog,
closeEditDialog,
} = useFormDialog();
const {
skills,
isLoading,
editingSkill,
skillFormData,
isSubmitting,
setSkillFormData,
resetForm,
handleCreateSkill,
handleEditSkill,
handleUpdateSkill,
handleDeleteSkill,
} = useSkillsManagement(skillCategories);
// Utilisation du hook factorisé pour la vue arborescente
const {
filteredDataByCategory: filteredSkillsByCategory,
expandedCategories,
toggleCategory,
expandAll,
collapseAll,
} = useTreeView({
data: skills,
searchFields: ["name", "description"],
groupBy: (skill) => skill.category,
searchTerm,
onSearchChange: setSearchTerm,
});
const handleCreateSubmit = async () => {
const success = await handleCreateSkill();
if (success) {
closeCreateDialog();
}
};
const handleEditSubmit = async () => {
const success = await handleUpdateSkill();
if (success) {
closeEditDialog();
}
};
const handleOpenCreateDialog = () => {
resetForm();
openCreateDialog();
};
const handleOpenEditDialog = (skill: any) => {
handleEditSkill(skill);
openEditDialog();
};
const headerActions = (
<Button onClick={handleOpenCreateDialog}>
<Plus className="w-4 h-4 mr-2" />
Nouvelle Skill
</Button>
);
const emptyState = (
<div className="text-center py-8">
<Code2 className="w-10 h-10 text-slate-500 mx-auto mb-3" />
<h3 className="text-base font-medium text-slate-400 mb-1">
{searchTerm ? "Aucune skill trouvée" : "Aucune skill"}
</h3>
<p className="text-slate-500 text-sm">
{searchTerm
? "Essayez de modifier vos critères de recherche"
: "Commencez par créer votre première skill"}
</p>
</div>
);
return (
<>
<TreeViewPage
title="Gestion des Skills"
description="Créez, modifiez et supprimez les skills de votre organisation"
searchTerm={searchTerm}
onSearchChange={setSearchTerm}
onExpandAll={expandAll}
onCollapseAll={collapseAll}
searchPlaceholder="Rechercher une skill..."
hasContent={Object.keys(filteredSkillsByCategory).length > 0}
isLoading={isLoading}
loadingMessage="Chargement des skills..."
emptyState={emptyState}
headerActions={headerActions}
>
<SkillsList
filteredSkillsByCategory={filteredSkillsByCategory}
expandedCategories={expandedCategories}
onToggleCategory={toggleCategory}
onEditSkill={handleOpenEditDialog}
onDeleteSkill={handleDeleteSkill}
/>
</TreeViewPage>
{/* Dialog de création */}
<SkillFormDialog
isOpen={isCreateDialogOpen}
onClose={closeCreateDialog}
onSubmit={handleCreateSubmit}
title="Créer une nouvelle skill"
formData={skillFormData}
onFormDataChange={setSkillFormData}
skillCategories={skillCategories}
isSubmitting={isSubmitting}
/>
{/* Dialog d'édition */}
<SkillFormDialog
isOpen={isEditDialogOpen}
onClose={closeEditDialog}
onSubmit={handleEditSubmit}
title="Modifier la skill"
formData={skillFormData}
onFormDataChange={setSkillFormData}
skillCategories={skillCategories}
isSubmitting={isSubmitting}
/>
</>
);
}