197 lines
5.5 KiB
TypeScript
197 lines
5.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { Plus, Building2 } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { SkillCategory, Team as TeamType } from "@/lib/types";
|
|
import { TeamStats } from "@/lib/admin-types";
|
|
import { TreeViewPage } from "../management/tree-view-page";
|
|
import { useTreeView } from "@/hooks/use-tree-view";
|
|
import { useFormDialog } from "@/hooks/use-form-dialog";
|
|
import { useTeamsManagement } from "@/hooks/use-teams-management";
|
|
import { TeamFormDialog } from "./team-form-dialog";
|
|
import { TeamsList } from "./teams-list";
|
|
import { TeamMembersModal } from "../management/team-members-modal";
|
|
|
|
interface TeamsManagementPageProps {
|
|
teams: TeamType[];
|
|
teamStats: TeamStats[];
|
|
}
|
|
|
|
export function TeamsManagementPage({
|
|
teams,
|
|
teamStats,
|
|
}: TeamsManagementPageProps) {
|
|
const [searchTerm, setSearchTerm] = useState("");
|
|
const [isMembersModalOpen, setIsMembersModalOpen] = useState(false);
|
|
const [selectedTeam, setSelectedTeam] = useState<TeamType | null>(null);
|
|
|
|
const {
|
|
isCreateDialogOpen,
|
|
isEditDialogOpen,
|
|
openCreateDialog,
|
|
closeCreateDialog,
|
|
openEditDialog,
|
|
closeEditDialog,
|
|
} = useFormDialog();
|
|
|
|
const {
|
|
teams: localTeams,
|
|
teamStats: localTeamStats,
|
|
editingTeam,
|
|
teamFormData,
|
|
isSubmitting,
|
|
directions,
|
|
setTeamFormData,
|
|
resetForm,
|
|
getTeamStats,
|
|
getDirectionStats,
|
|
handleCreateTeam,
|
|
handleEditTeam,
|
|
handleUpdateTeam,
|
|
handleDeleteTeam,
|
|
handleDeleteDirection,
|
|
} = useTeamsManagement(teams, teamStats);
|
|
|
|
// Utilisation du hook factorisé pour la vue arborescente
|
|
const {
|
|
filteredDataByCategory: filteredTeamsByDirection,
|
|
expandedCategories: expandedDirections,
|
|
toggleCategory: toggleDirection,
|
|
expandAll,
|
|
collapseAll,
|
|
} = useTreeView({
|
|
data: localTeams,
|
|
searchFields: ["name"],
|
|
groupBy: (team) => team.direction,
|
|
searchTerm,
|
|
onSearchChange: setSearchTerm,
|
|
});
|
|
|
|
const handleCreateSubmit = async () => {
|
|
const success = await handleCreateTeam();
|
|
if (success) {
|
|
closeCreateDialog();
|
|
}
|
|
};
|
|
|
|
const handleEditSubmit = async () => {
|
|
const success = await handleUpdateTeam();
|
|
if (success) {
|
|
closeEditDialog();
|
|
}
|
|
};
|
|
|
|
const handleOpenCreateDialog = () => {
|
|
resetForm();
|
|
openCreateDialog();
|
|
};
|
|
|
|
const handleOpenEditDialog = (team: TeamType) => {
|
|
handleEditTeam(team);
|
|
openEditDialog();
|
|
};
|
|
|
|
const handleViewMembers = (team: TeamType) => {
|
|
setSelectedTeam(team);
|
|
setIsMembersModalOpen(true);
|
|
};
|
|
|
|
// Fonction pour mettre à jour les stats d'une équipe après suppression d'un membre
|
|
const updateTeamStatsAfterMemberRemoval = (teamId: string) => {
|
|
// Cette logique sera gérée par le hook useTeamsManagement
|
|
};
|
|
|
|
const headerActions = (
|
|
<Button onClick={handleOpenCreateDialog}>
|
|
<Plus className="w-4 h-4 mr-2" />
|
|
Nouvelle Équipe
|
|
</Button>
|
|
);
|
|
|
|
const emptyState = (
|
|
<div className="text-center py-8">
|
|
<Building2 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 équipe trouvée" : "Aucune équipe"}
|
|
</h3>
|
|
<p className="text-sm text-slate-500">
|
|
{searchTerm
|
|
? "Essayez de modifier vos critères de recherche"
|
|
: "Commencez par créer votre première équipe"}
|
|
</p>
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<TreeViewPage
|
|
title="Gestion des Teams"
|
|
description="Créez, modifiez et supprimez les équipes de votre organisation"
|
|
searchTerm={searchTerm}
|
|
onSearchChange={setSearchTerm}
|
|
onExpandAll={expandAll}
|
|
onCollapseAll={collapseAll}
|
|
searchPlaceholder="Rechercher une équipe..."
|
|
hasContent={Object.keys(filteredTeamsByDirection).length > 0}
|
|
emptyState={emptyState}
|
|
headerActions={headerActions}
|
|
>
|
|
<TeamsList
|
|
filteredTeamsByDirection={filteredTeamsByDirection}
|
|
expandedDirections={expandedDirections}
|
|
onToggleDirection={toggleDirection}
|
|
onEditTeam={handleOpenEditDialog}
|
|
onDeleteTeam={handleDeleteTeam}
|
|
onDeleteDirection={handleDeleteDirection}
|
|
onViewMembers={handleViewMembers}
|
|
getTeamStats={getTeamStats}
|
|
getDirectionStats={getDirectionStats}
|
|
/>
|
|
</TreeViewPage>
|
|
|
|
{/* Dialog de création */}
|
|
<TeamFormDialog
|
|
isOpen={isCreateDialogOpen}
|
|
onClose={closeCreateDialog}
|
|
onSubmit={handleCreateSubmit}
|
|
title="Créer une nouvelle équipe"
|
|
formData={teamFormData}
|
|
onFormDataChange={setTeamFormData}
|
|
directions={directions}
|
|
isSubmitting={isSubmitting}
|
|
/>
|
|
|
|
{/* Dialog d'édition */}
|
|
<TeamFormDialog
|
|
isOpen={isEditDialogOpen}
|
|
onClose={closeEditDialog}
|
|
onSubmit={handleEditSubmit}
|
|
title="Modifier l'équipe"
|
|
formData={teamFormData}
|
|
onFormDataChange={setTeamFormData}
|
|
directions={directions}
|
|
isSubmitting={isSubmitting}
|
|
/>
|
|
|
|
{/* Modal des membres d'équipe */}
|
|
{selectedTeam && (
|
|
<TeamMembersModal
|
|
teamId={selectedTeam.id}
|
|
teamName={selectedTeam.name}
|
|
isOpen={isMembersModalOpen}
|
|
onClose={() => {
|
|
setIsMembersModalOpen(false);
|
|
setSelectedTeam(null);
|
|
}}
|
|
onMemberRemoved={() => {
|
|
if (selectedTeam) {
|
|
updateTeamStatsAfterMemberRemoval(selectedTeam.id);
|
|
}
|
|
}}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|