Checkpoint: Modification du comportement par défaut du menu accordéon : seule la section TABLEAU DE BORD est ouverte à l'ouverture, les sections GESTION, CONFIGURATION et ANALYSES sont fermées par défaut. Ajout d'un système de version (MENU_VERSION = 2) pour forcer la réinitialisation du localStorage avec les nouvelles valeurs par défaut.

This commit is contained in:
Manus Sandbox
2025-12-10 04:20:46 -05:00
parent 74d6b58326
commit 8640c17b3b
2 changed files with 284 additions and 13 deletions

View File

@@ -162,7 +162,12 @@ function DashboardLayoutContent({
// État pour gérer les sections ouvertes/fermées (persisté dans localStorage) // État pour gérer les sections ouvertes/fermées (persisté dans localStorage)
const [openSections, setOpenSections] = useState<Record<string, boolean>>(() => { const [openSections, setOpenSections] = useState<Record<string, boolean>>(() => {
// Essayer de charger depuis localStorage // Version du système de menu (incrémenter pour forcer la réinitialisation)
const MENU_VERSION = 2;
const savedVersion = localStorage.getItem('menuVersion');
// Si la version a changé, ignorer le localStorage existant
if (savedVersion && parseInt(savedVersion) === MENU_VERSION) {
const saved = localStorage.getItem('menuSectionsState'); const saved = localStorage.getItem('menuSectionsState');
if (saved) { if (saved) {
try { try {
@@ -171,11 +176,19 @@ function DashboardLayoutContent({
// En cas d'erreur, utiliser les valeurs par défaut // En cas d'erreur, utiliser les valeurs par défaut
} }
} }
// Valeurs par défaut : toutes les sections ouvertes }
// Valeurs par défaut : seule la section TABLEAU DE BORD est ouverte
const initial: Record<string, boolean> = {}; const initial: Record<string, boolean> = {};
menuSections.forEach(section => { menuSections.forEach(section => {
initial[section.title] = true; // Ouvrir uniquement "Tableau de bord", fermer les autres
initial[section.title] = section.title === "Tableau de bord";
}); });
// Sauvegarder la version et l'état initial
localStorage.setItem('menuVersion', MENU_VERSION.toString());
localStorage.setItem('menuSectionsState', JSON.stringify(initial));
return initial; return initial;
}); });
@@ -277,7 +290,7 @@ function DashboardLayoutContent({
<SidebarContent className="gap-0"> <SidebarContent className="gap-0">
{menuSections.map((section, sectionIndex) => { {menuSections.map((section, sectionIndex) => {
const isOpen = openSections[section.title] ?? true; const isOpen = openSections[section.title] ?? false;
return ( return (
<div key={section.title}> <div key={section.title}>
{sectionIndex > 0 && ( {sectionIndex > 0 && (

264
todo.md
View File

@@ -1,6 +1,259 @@
# Gestion des Formations Manager Itinova - TODO # Gestion des Formations Manager Itinova - TODO
[... contenu existant conservé ...] ## Fonctionnalités principales
- [x] Gestion des formations (CRUD)
- [x] Gestion des séquences avec jusqu'à 4 dates par séquence
- [x] Gestion des apprenants (CRUD)
- [x] Système d'inscription avec validation de capacité
- [x] Génération d'invitations Outlook (.ics)
- [x] Envoi d'emails automatiques (confirmation, teaser, rappels)
- [x] Exports PDF et Excel
- [x] Filtres et recherche sur toutes les pages
- [x] Champ "Fonction" dans la fiche apprenant
- [x] Filtres par fonction sur les pages apprenants et inscrits
- [x] Graphique de répartition par fonction sur le tableau de bord
- [x] Personnalisation des templates d'emails
- [x] Gestion des utilisateurs avec rôles (admin/user)
- [x] Configuration SMTP pour l'envoi d'emails
- [x] Authentification locale avec email/mot de passe
- [x] Cohabitation OAuth Manus + authentification locale
## Champ "Public cible" dans les séquences
- [x] Ajouter le champ "Public cible" dans la table sequences
- [x] Ajouter le champ dans le formulaire de création de séquence
- [x] Ajouter le champ dans le formulaire de modification de séquence
- [x] Afficher le public cible sur la page d'inscription publique
- [x] Ajouter "Tous" dans la liste des publics cible
- [x] Ajouter le badge de public cible dans le tableau des séquences
- [x] Ajouter le filtre par public cible sur la page de gestion des séquences
- [x] Ajouter le public cible dans tous les exports (Excel, PDF)
## Alerte d'incohérence public cible / fonction
- [x] Ajouter une alerte d'information lors de l'inscription
- [x] Afficher l'alerte si le public cible ne correspond pas à la fonction
- [x] Laisser l'inscription se faire (alerte non bloquante)
- [x] Pas d'alerte si le public cible est "Tous"
## Rapport d'analyse public cible
- [x] Créer une page de rapport comparant public cible et fonction des inscrits
- [x] Afficher les écarts entre public cible et fonction réelle
- [x] Ajouter des statistiques et graphiques pour visualiser les écarts
- [x] Ajouter le lien dans le menu de navigation
## Gestion des formateurs
- [x] Créer la table formateurs dans la base de données
- [x] Créer les procédures tRPC (list, create, delete)
- [x] Créer le composant FormateurCombobox avec autocomplétion
- [x] Ajouter le champ formateur dans le formulaire de création de séquence
- [x] Ajouter le champ formateur dans le formulaire de modification de séquence
- [x] Afficher le formateur dans le tableau des séquences
- [x] Afficher le formateur dans les emails d'invitation
- [x] Corriger le stockage pour utiliser formateurId au lieu du nom
## Barre de progression colorée pour les séquences
- [x] Créer le composant CapacityProgressBar
- [x] Afficher "nbInscrits / capacité" avec pourcentage
- [x] Code couleur automatique : vert (<70%), orange (70-90%), rouge (>90%)
- [x] Intégrer dans le tableau des séquences
- [x] Corriger le composant Progress pour supporter indicatorClassName
## Vue calendrier mensuel
- [x] Créer la page AdminCalendrier
- [x] Afficher un calendrier mensuel avec navigation
- [x] Afficher les séquences sur leurs dates respectives
- [x] Ajouter un dialog de détails au clic sur une séquence
- [x] Ajouter le lien "Calendrier" dans le menu de navigation
- [x] Afficher le nom de la formation + nom de la séquence
- [x] Afficher le lieu, le formateur et le nombre d'inscrits
- [x] Corriger le bug de dates (parseISO vs Date)
- [x] Corriger le bug React #31 (clés stables pour les jours)
## Système de rappels automatiques
- [x] Créer la table rappels dans la base de données
- [x] Créer les procédures tRPC (list, create, update, delete)
- [x] Créer la page AdminRappels pour configurer les rappels
- [x] Permettre de configurer des rappels multiples (J-15, J-7, J-1)
- [x] Templates d'emails personnalisables avec variables dynamiques
- [x] Activation/désactivation des rappels
- [x] Infrastructure pour l'envoi automatique (scheduler)
- [x] Ajouter le lien "Rappels" dans le menu de navigation
- [x] Créer les templates J-7 et J-1 avec style Itinova
- [x] Implémenter le scheduler automatique (vérification toutes les heures)
- [x] Corriger le bug d'envois multiples (un seul email par séquence)
## Améliorations diverses
- [x] Réorganisation du menu de navigation en 4 zones (Tableau de bord, Gestion, Configuration, Analyses)
- [x] Couleur bleue pour les titres des zones du menu
- [x] Icône œil en bleu pour la visualisation
- [x] Icône corbeille en rouge pour la suppression
- [x] Badges de couleur pour les fonctions des apprenants
- [x] Badges de couleur pour le public cible des séquences
- [x] Couleurs uniques pour chaque formation dans le tableau des séquences
- [x] Badges Actif/Inactif pour les apprenants
- [x] Page dédiée aux établissements avec statistiques
## Améliorations du calendrier
- [x] Ajout de filtres (formation, lieu, public cible)
- [x] Vues alternatives (semaine, jour) en plus de la vue mensuelle
- [x] Export PDF du calendrier
- [x] Export iCal (.ics) pour import dans Outlook/Google Calendar
## Import Excel pour créer formations et séquences en masse
- [x] Créer le template Excel avec colonnes prédéfinies
- [x] Créer la procédure backend de parsing et validation
- [x] Créer l'interface frontend avec upload et prévisualisation
- [x] Ajouter la documentation utilisateur
- [x] Corriger le bug de conflit de noms (formations vs table formations)
- [x] Corriger le bug de colonne lienInscription → lienUnique
- [x] Corriger le bug de récupération des IDs après insertion
- [x] Ajouter le menu de navigation sur la page Import Excel
- [x] Déplacer le menu Import Excel vers le bloc Configuration
## Corrections décalage horaire
- [x] Correction du décalage horaire dans le formulaire de création de séquence
- [x] Correction du décalage horaire dans le formulaire d'édition de séquence
- [x] Correction du décalage horaire dans l'affichage des séquences
- [x] Correction du décalage horaire dans la page d'inscription publique
- [x] Utilisation des méthodes locales (getHours, getMinutes) au lieu des méthodes UTC
## Scripts de déploiement VPS
- [x] Créer backup-before-update.sh (sauvegarde automatique)
- [x] Créer update-app.sh (mise à jour automatique)
- [x] Créer create-deployment-package.sh (création de package)
- [x] Créer GUIDE_MISE_A_JOUR.md (documentation complète)
- [x] Corriger les chemins pour utiliser formation-manager-itinova
- [x] Corriger le bug "drizzle-kit: not found" (pnpm install sans --prod)
- [x] Créer DEPLOIEMENT-MANUEL.md (guide déploiement sans Git)
- [x] Créer deploy-update-manual.sh (script sans git pull)
- [x] Créer DEPLOIEMENT-TARGZ.md (guide avec archive tar.gz)
- [x] Créer deploy-update-targz.sh (script pour archive)
## Support SMTP Direct (sans Resend)
- [x] Ajouter les champs SMTP dans la table emailConfig
- [x] Créer server/_core/smtpSender.ts avec Nodemailer
- [x] Modifier emailSender.ts pour supporter SMTP et Resend
- [x] Ajouter l'interface de configuration SMTP dans AdminEmailConfig
- [x] Corriger le bug d'enregistrement des champs SMTP
- [x] Corriger la fonction upsertEmailConfig pour éviter les doublons
- [x] Corriger l'affichage du statut (SMTP Direct au lieu de Resend)
## Améliorations emails groupés (teaser et rappel)
- [x] Ajouter des logs serveur détaillés pour l'envoi groupé
- [x] Afficher le nombre d'emails envoyés avec succès et échoués
- [x] Avertir si aucun email n'est envoyé (aucun apprenant confirmé)
- [x] Corriger le remplacement des tags {{nomFormation}}, {{nomSequence}}, etc.
- [x] Ajouter le formateur et le lieu dans l'email de teaser
- [x] Ajouter toutes les variables disponibles dans les templates
## Améliorations templates d'emails
- [x] Ajouter la possibilité de personnaliser le corps du message
- [x] Ajouter un éditeur de texte riche (TipTap) pour formater le contenu
- [x] Ajouter 7 boutons pour insérer rapidement des variables dynamiques
- [x] Afficher la prévisualisation HTML en temps réel
- [x] Implémenter le remplacement automatique des variables lors de l'envoi
- [x] Ajouter un bouton d'aperçu avec données réelles d'un apprenant
- [x] Ajouter le template de rappel J-1 dans la liste
- [x] Corriger les templates J-7 et J-1 pour afficher toutes les dates
- [x] Ajouter la variable {{datesHTML}} pour afficher toutes les dates formatées
- [x] Ajouter le bouton {{datesHTML}} dans l'interface
- [x] Corriger la variable {{datesHTML}} dans l'email de confirmation
## Tableau de bord analytique
- [x] Créer la page AdminTableauBordAnalytique
- [x] Afficher les statistiques globales (cartes)
- [x] Graphique d'évolution des inscriptions par mois
- [x] Graphique du taux de remplissage des séquences
- [x] Top 10 des établissements participants
- [x] Répartition par fonction
- [x] Ajouter des filtres de période (mois, trimestre, année)
- [x] Implémenter l'export Excel des rapports analytiques
- [x] Corriger l'incohérence des statistiques de répartition par fonction
- [x] Ajouter le graphique de répartition par établissement sur le tableau de bord principal
## Améliorations visuelles
- [x] Afficher le taux de remplissage en couleur conditionnelle
- [x] Icône corbeille en rouge pour la suppression
- [x] Icône œil en bleu pour la visualisation
- [x] Couleurs uniques pour chaque formation dans le tableau des séquences
- [x] Badges de couleur pour les fonctions des apprenants
- [x] Badges Actif/Inactif pour les apprenants
## Feuilles de présence améliorées
- [x] Ajouter le logo Itinova en haut à droite (40x15mm)
- [x] Afficher le nom du formateur dans l'en-tête
- [x] Ajouter deux colonnes de signature par apprenant (Matin / Après-midi)
- [x] Générer une page par date de formation
- [x] Ajouter la signature du formateur en bas de page avec date
## Détail par apprenant
- [x] Créer la procédure tRPC apprenants.getInscriptions
- [x] Créer la page AdminApprenantDetail
- [x] Afficher les informations personnelles de l'apprenant
- [x] Afficher le tableau de toutes ses inscriptions
- [x] Ajouter le bouton "Détail" dans la page AdminApprenants
- [x] Ajouter la route /admin/apprenants/:id dans App.tsx
## Correction problème création excessive d'utilisateurs
- [x] Analyser la base de données pour identifier les doublons
- [x] Nettoyer les utilisateurs en double
- [x] Ajouter la contrainte UNIQUE sur la colonne openId
- [x] Vérifier que onDuplicateKeyUpdate fonctionne correctement
## Ajout identifiant de connexion et modification mot de passe
- [x] Ajouter le champ username dans le schéma de la base de données
- [x] Mettre à jour les procédures tRPC create et update
- [x] Implémenter le hashage du mot de passe avec bcryptjs
- [x] Ajouter la colonne "Identifiant" dans le tableau des utilisateurs
- [x] Ajouter les champs dans le formulaire de création
- [x] Ajouter les champs dans le formulaire d'édition
## Utilisateur administrateur spécial
- [x] Créer l'utilisateur "Administrateur" avec identifiant "adminServFormation"
- [x] Désactiver le bouton de suppression pour cet utilisateur
- [x] Rendre les champs nom et identifiant en lecture seule
- [x] Permettre la modification de l'email et du mot de passe uniquement
- [x] Garantir un accès administrateur permanent au système
## Page de connexion locale
- [x] Créer la route d'authentification backend avec hashage bcrypt
- [x] Créer la page Login.tsx avec formulaire username/password
- [x] Implémenter la session JWT
- [x] Tester avec l'utilisateur adminServFormation
- [x] Ajouter la route /login dans App.tsx
- [x] Créer une page de choix de connexion à la racine (/)
- [x] Corriger la redirection après déconnexion vers la page de choix
- [x] Ajouter la détection automatique de l'état de connexion
- [x] Corriger l'authentification locale pour compatibilité avec OAuth
## Guide de configuration HTTPS
- [x] Créer le guide complet de configuration HTTPS avec Let's Encrypt
- [x] Créer le script d'installation automatique
- [x] Créer le template nginx optimisé
## Questionnaires de satisfaction et évaluation des acquis ## Questionnaires de satisfaction et évaluation des acquis
@@ -10,8 +263,8 @@
- [x] Créer l'interface publique de réponse aux questionnaires - [x] Créer l'interface publique de réponse aux questionnaires
- [x] Implémenter l'envoi automatique post-formation - [x] Implémenter l'envoi automatique post-formation
- [x] Créer les tableaux de bord d'analyse avec graphiques (satisfaction par formation/formateur) - [x] Créer les tableaux de bord d'analyse avec graphiques (satisfaction par formation/formateur)
- [ ] Implémenter les exports Excel/PDF des feedbacks - [x] Implémenter les exports Excel/PDF des feedbacks
- [ ] Tester le système complet (création, envoi, réponse, analyse) - [x] Tester le système complet (création, envoi, réponse, analyse)
- [ ] Déployer sur le serveur VPS - [ ] Déployer sur le serveur VPS
## Amélioration : Prévisualisation des questionnaires ## Amélioration : Prévisualisation des questionnaires
@@ -154,3 +407,8 @@
- [x] Supprimer le useEffect problématique (toutes sections ouvertes par défaut) - [x] Supprimer le useEffect problématique (toutes sections ouvertes par défaut)
- [x] Utiliser localStorage pour persister l'état des sections - [x] Utiliser localStorage pour persister l'état des sections
- [x] Tester le comportement en cliquant sur différents items - [x] Tester le comportement en cliquant sur différents items
## Modification comportement par défaut accordéon menu
- [x] Modifier l'initialisation pour ouvrir uniquement TABLEAU DE BORD par défaut
- [x] Fermer GESTION, CONFIGURATION, ANALYSES par défaut
- [x] Tester le comportement à l'ouverture