Checkpoint: Implémentation complète de la fonctionnalité "Gestion des plans de formations" :

- Schéma DB : 3 nouvelles tables (catalogueFormation, planFormation, planFormationItem)
- Backend tRPC : routers catalogue et planFormation (CRUD, import bulk CSV, suggestions, toggle validée Itinova)
- Frontend : page Plans de formation (liste par établissement/année, CRUD, soumission/validation)
- Frontend : page Détail plan (items, liaison catalogue, suggestions automatiques)
- Frontend : page Catalogue de formation (liste, filtres thème/Itinova/OPCO, import CSV, badges)
- Menu sidebar : nouvelle section "Plans de formations" avec sous-menus
- Tests unitaires : 13 tests (scoring suggestions, validation données, parsing CSV)
This commit is contained in:
Manus
2026-05-27 16:39:18 +00:00
parent 54159fd872
commit 6952ae6907
14 changed files with 5295 additions and 2 deletions

View File

@@ -21,7 +21,7 @@ import {
} from "@/components/ui/sidebar";
import { APP_LOGO, APP_TITLE, getLoginUrl } from "@/const";
import { useIsMobile } from "@/hooks/useMobile";
import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, CalendarDays, Bell, BarChart3, UserCog, Mail, Settings, TrendingUp, Building2, FileSpreadsheet, ClipboardList, ChevronDown, User, FileText, QrCode, Shield } from "lucide-react";
import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, CalendarDays, Bell, BarChart3, UserCog, Mail, Settings, TrendingUp, Building2, FileSpreadsheet, ClipboardList, ChevronDown, User, FileText, QrCode, Shield, BookOpen, Library } from "lucide-react";
import { CSSProperties, useEffect, useRef, useState } from "react";
import { useLocation } from "wouter";
import { DashboardLayoutSkeleton } from './DashboardLayoutSkeleton';
@@ -36,6 +36,7 @@ const getCategoryColor = (sectionTitle: string) => {
"Traçabilité": "text-purple-500",
"Analyses": "text-pink-500",
"Gestion technique": "text-red-500",
"Plans de formations": "text-teal-600",
};
return colors[sectionTitle] || "text-gray-500";
};
@@ -48,6 +49,7 @@ const getCategoryGradient = (sectionTitle: string) => {
"Traçabilité": "from-purple-300 to-purple-400",
"Analyses": "from-pink-300 to-pink-400",
"Gestion technique": "from-red-300 to-red-400",
"Plans de formations": "from-teal-300 to-teal-400",
};
return gradients[sectionTitle] || "from-gray-300 to-gray-400";
};
@@ -60,6 +62,7 @@ const getCategoryBgColor = (sectionTitle: string) => {
"Traçabilité": "bg-purple-50/80 hover:bg-purple-100/90",
"Analyses": "bg-pink-50/80 hover:bg-pink-100/90",
"Gestion technique": "bg-red-50/80 hover:bg-red-100/90",
"Plans de formations": "bg-teal-50/80 hover:bg-teal-100/90",
};
return bgColors[sectionTitle] || "bg-gray-50/80 hover:bg-gray-100/90";
};
@@ -114,6 +117,13 @@ const menuSections = [
{ icon: BarChart3, label: "Statistiques des rappels", path: "/admin/rappels/statistiques" },
]
},
{
title: "Plans de formations",
items: [
{ icon: BookOpen, label: "Plans de formations", path: "/admin/plans-formation" },
{ icon: Library, label: "Catalogue de formation", path: "/admin/catalogue-formation" },
]
},
{
title: "Gestion technique",
items: [