diff --git a/components/admin/admin-client-wrapper.tsx b/components/admin/admin-client-wrapper.tsx
index 4390f60..18d22a1 100644
--- a/components/admin/admin-client-wrapper.tsx
+++ b/components/admin/admin-client-wrapper.tsx
@@ -1,17 +1,13 @@
"use client";
import { useState } from "react";
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
-import { Button } from "@/components/ui/button";
-import { Users, Target, Building2, UserCheck, Filter } from "lucide-react";
import { Team, SkillCategory } from "@/lib/types";
-import {
- TeamStatsCard,
- DirectionOverview,
- MultiSelectFilter,
-} from "@/components/admin";
-import { TeamDetailModal } from "@/components/admin/team-detail-modal";
import { TeamStats, DirectionStats } from "@/services/admin-service";
+import { TeamDetailModal } from "@/components/admin/team-detail-modal";
+import { AdminHeader } from "./admin-header";
+import { AdminOverviewCards } from "./admin-overview-cards";
+import { AdminFilters } from "./admin-filters";
+import { AdminContentTabs } from "./admin-content-tabs";
interface AdminClientWrapperProps {
teams: Team[];
@@ -85,21 +81,6 @@ export function AdminClientWrapper({
return filtered;
};
- // Options pour les filtres
- const directionOptions = Array.from(
- new Set(teams.map((team) => team.direction))
- ).map((direction) => ({
- id: direction,
- label: direction,
- count: teams.filter((team) => team.direction === direction).length,
- }));
-
- const teamOptions = teams.map((team) => ({
- id: team.id,
- label: `${team.name} (${team.direction})`,
- count: teamStats.find((stat) => stat.teamId === team.id)?.totalMembers || 0,
- }));
-
// Fonctions pour les actions des équipes
const handleViewTeamDetails = (team: TeamStats) => {
setSelectedTeamForModal(team);
@@ -142,293 +123,38 @@ export function AdminClientWrapper({
{/* Header */}
-
-
-
-
- Administration
-
-
-
-
- Dashboard Managérial
-
-
-
- Vue d'ensemble des compétences par équipe et direction pour pilotage
- stratégique
-
-
+
{/* Overview Cards */}
-
-
-
-
-
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? "FILTRÉES"
- : "TOTAL"}
-
-
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? getFilteredTeamStats().length
- : teams.length}
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? "Équipes filtrées"
- : "Équipes"}
-
- {(selectedDirections.length > 0 || selectedTeams.length > 0) && (
-
- sur {teams.length} au total
-
- )}
-
-
-
-
-
-
-
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? "FILTRÉS"
- : "TOTAL"}
-
-
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? getFilteredTeamStats().reduce(
- (sum, t) => sum + t.totalMembers,
- 0
- )
- : teamStats.reduce((sum, t) => sum + t.totalMembers, 0)}
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? "Membres filtrés"
- : "Membres"}
-
- {(selectedDirections.length > 0 || selectedTeams.length > 0) && (
-
- sur {teamStats.reduce((sum, t) => sum + t.totalMembers, 0)} au
- total
-
- )}
-
-
-
-
-
-
-
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? "FILTRÉES"
- : "TOTAL"}
-
-
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? getFilteredDirectionStats().length
- : directionStats.length}
-
-
- {selectedDirections.length > 0 || selectedTeams.length > 0
- ? "Directions filtrées"
- : "Directions"}
-
- {(selectedDirections.length > 0 || selectedTeams.length > 0) && (
-
- sur {directionStats.length} au total
-
- )}
-
-
-
-
-
-
-
-
-
- RÉFÉRENTIEL
-
-
-
-
- {skillCategories.reduce(
- (sum, cat) => sum + (cat.skills?.length || 0),
- 0
- )}
-
-
Compétences suivies
-
- {skillCategories.length} catégories
-
-
-
-
+
{/* Filtres */}
-
-
-
-
-
-
- Filtres avancés
-
-
-
-
-
- }
- />
-
-
- }
- />
-
-
- {/* Résumé des filtres actifs */}
- {(selectedDirections.length > 0 || selectedTeams.length > 0) && (
-
-
-
-
-
- {getFilteredTeamStats().reduce(
- (sum, t) => sum + t.totalMembers,
- 0
- )}{" "}
- membres
-
-
-
-
-
- )}
-
-
+
{/* Main Content Tabs */}
-
-
-
-
- Vue par Direction
-
-
- Vue par Équipe
-
-
-
-
-
-
- {getFilteredDirectionStats().length > 0 ? (
- getFilteredDirectionStats().map((direction) => (
-
- ))
- ) : (
-
-
-
-
-
- Aucune direction trouvée
-
-
- Aucune direction ne correspond aux filtres sélectionnés.
-
-
- )}
-
-
-
-
-
- {getFilteredTeamStats().length > 0 ? (
- getFilteredTeamStats().map((team) => (
-
handleViewTeamDetails(team)}
- onViewReport={() => handleExportTeamReport(team)}
- />
- ))
- ) : (
-
-
-
-
-
-
- Aucune équipe trouvée
-
-
- Aucune équipe ne correspond aux filtres sélectionnés.
-
-
-
- )}
-
-
-
+
{/* Modale de détails d'équipe */}
DirectionStats[];
+ getFilteredTeamStats: () => TeamStats[];
+ onViewTeamDetails: (team: TeamStats) => void;
+ onExportTeamReport: (team: TeamStats) => void;
+}
+
+export function AdminContentTabs({
+ getFilteredDirectionStats,
+ getFilteredTeamStats,
+ onViewTeamDetails,
+ onExportTeamReport,
+}: AdminContentTabsProps) {
+ return (
+
+
+
+
+ Vue par Direction
+
+
+ Vue par Équipe
+
+
+
+
+
+
+ {getFilteredDirectionStats().length > 0 ? (
+ getFilteredDirectionStats().map((direction) => (
+
+ ))
+ ) : (
+
+
+
+
+
+ Aucune direction trouvée
+
+
+ Aucune direction ne correspond aux filtres sélectionnés.
+
+
+ )}
+
+
+
+
+
+ {getFilteredTeamStats().length > 0 ? (
+ getFilteredTeamStats().map((team) => (
+
onViewTeamDetails(team)}
+ onViewReport={() => onExportTeamReport(team)}
+ />
+ ))
+ ) : (
+
+
+
+
+
+
+ Aucune équipe trouvée
+
+
+ Aucune équipe ne correspond aux filtres sélectionnés.
+
+
+
+ )}
+
+
+
+ );
+}
diff --git a/components/admin/admin-filters.tsx b/components/admin/admin-filters.tsx
new file mode 100644
index 0000000..9fe5f24
--- /dev/null
+++ b/components/admin/admin-filters.tsx
@@ -0,0 +1,108 @@
+"use client";
+
+import { Button } from "@/components/ui/button";
+import { Users, Target, Building2, Filter } from "lucide-react";
+import { Team } from "@/lib/types";
+import { TeamStats } from "@/services/admin-service";
+import { MultiSelectFilter } from "./multi-select-filter";
+
+interface AdminFiltersProps {
+ teams: Team[];
+ teamStats: TeamStats[];
+ selectedDirections: string[];
+ selectedTeams: string[];
+ onDirectionsChange: (directions: string[]) => void;
+ onTeamsChange: (teams: string[]) => void;
+ getFilteredTeamStats: () => TeamStats[];
+}
+
+export function AdminFilters({
+ teams,
+ teamStats,
+ selectedDirections,
+ selectedTeams,
+ onDirectionsChange,
+ onTeamsChange,
+ getFilteredTeamStats,
+}: AdminFiltersProps) {
+ const hasFilters = selectedDirections.length > 0 || selectedTeams.length > 0;
+
+ const directionOptions = Array.from(
+ new Set(teams.map((team) => team.direction))
+ ).map((direction) => ({
+ id: direction,
+ label: direction,
+ count: teams.filter((team) => team.direction === direction).length,
+ }));
+
+ const teamOptions = teams.map((team) => ({
+ id: team.id,
+ label: `${team.name} (${team.direction})`,
+ count: teamStats.find((stat) => stat.teamId === team.id)?.totalMembers || 0,
+ }));
+
+ const handleReset = () => {
+ onDirectionsChange([]);
+ onTeamsChange([]);
+ };
+
+ return (
+
+
+
+
+
+
Filtres avancés
+
+
+
+
+ }
+ />
+
+
+ }
+ />
+
+
+ {/* Résumé des filtres actifs */}
+ {hasFilters && (
+
+
+
+
+
+ {getFilteredTeamStats().reduce(
+ (sum, t) => sum + t.totalMembers,
+ 0
+ )}{" "}
+ membres
+
+
+
+
+
+ )}
+
+
+ );
+}
diff --git a/components/admin/admin-header.tsx b/components/admin/admin-header.tsx
new file mode 100644
index 0000000..61d89f6
--- /dev/null
+++ b/components/admin/admin-header.tsx
@@ -0,0 +1,23 @@
+"use client";
+
+import { Building2 } from "lucide-react";
+
+export function AdminHeader() {
+ return (
+
+
+
+
+ Administration
+
+
+
+
Dashboard Managérial
+
+
+ Vue d'ensemble des compétences par équipe et direction pour pilotage
+ stratégique
+
+
+ );
+}
diff --git a/components/admin/admin-overview-cards.tsx b/components/admin/admin-overview-cards.tsx
new file mode 100644
index 0000000..58d6fe6
--- /dev/null
+++ b/components/admin/admin-overview-cards.tsx
@@ -0,0 +1,134 @@
+"use client";
+
+import { Users, Target, Building2, UserCheck } from "lucide-react";
+import { Team, SkillCategory } from "@/lib/types";
+import { TeamStats, DirectionStats } from "@/services/admin-service";
+
+interface AdminOverviewCardsProps {
+ teams: Team[];
+ skillCategories: SkillCategory[];
+ teamStats: TeamStats[];
+ directionStats: DirectionStats[];
+ selectedDirections: string[];
+ selectedTeams: string[];
+ getFilteredTeamStats: () => TeamStats[];
+ getFilteredDirectionStats: () => DirectionStats[];
+}
+
+export function AdminOverviewCards({
+ teams,
+ skillCategories,
+ teamStats,
+ directionStats,
+ selectedDirections,
+ selectedTeams,
+ getFilteredTeamStats,
+ getFilteredDirectionStats,
+}: AdminOverviewCardsProps) {
+ const hasFilters = selectedDirections.length > 0 || selectedTeams.length > 0;
+
+ return (
+
+
+
+
+
+
+
+ {hasFilters ? "FILTRÉES" : "TOTAL"}
+
+
+
+
+ {hasFilters ? getFilteredTeamStats().length : teams.length}
+
+
+ {hasFilters ? "Équipes filtrées" : "Équipes"}
+
+ {hasFilters && (
+
+ sur {teams.length} au total
+
+ )}
+
+
+
+
+
+
+
+
+
+ {hasFilters ? "FILTRÉS" : "TOTAL"}
+
+
+
+
+ {hasFilters
+ ? getFilteredTeamStats().reduce(
+ (sum, t) => sum + t.totalMembers,
+ 0
+ )
+ : teamStats.reduce((sum, t) => sum + t.totalMembers, 0)}
+
+
+ {hasFilters ? "Membres filtrés" : "Membres"}
+
+ {hasFilters && (
+
+ sur {teamStats.reduce((sum, t) => sum + t.totalMembers, 0)} au
+ total
+
+ )}
+
+
+
+
+
+
+
+
+
+ {hasFilters ? "FILTRÉES" : "TOTAL"}
+
+
+
+
+ {hasFilters
+ ? getFilteredDirectionStats().length
+ : directionStats.length}
+
+
+ {hasFilters ? "Directions filtrées" : "Directions"}
+
+ {hasFilters && (
+
+ sur {directionStats.length} au total
+
+ )}
+
+
+
+
+
+
+
+ {skillCategories.reduce(
+ (sum, cat) => sum + (cat.skills?.length || 0),
+ 0
+ )}
+
+
Compétences suivies
+
+ {skillCategories.length} catégories
+
+
+
+
+ );
+}
diff --git a/components/admin/index.ts b/components/admin/index.ts
index b86a704..562ca00 100644
--- a/components/admin/index.ts
+++ b/components/admin/index.ts
@@ -3,3 +3,7 @@ export { DirectionOverview } from "./direction-overview";
export { MultiSelectFilter } from "./multi-select-filter";
export { AdminClientWrapper } from "./admin-client-wrapper";
export { TeamDetailClientWrapper } from "./team-detail-client-wrapper";
+export { AdminHeader } from "./admin-header";
+export { AdminOverviewCards } from "./admin-overview-cards";
+export { AdminFilters } from "./admin-filters";
+export { AdminContentTabs } from "./admin-content-tabs";