From 8640c17b3b4ab82bc91f958846aa46ec4c5fcb1c Mon Sep 17 00:00:00 2001 From: Manus Sandbox Date: Wed, 10 Dec 2025 04:20:46 -0500 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Modification=20du=20comportement?= =?UTF-8?q?=20par=20d=C3=A9faut=20du=20menu=20accord=C3=A9on=20:=20seule?= =?UTF-8?q?=20la=20section=20TABLEAU=20DE=20BORD=20est=20ouverte=20=C3=A0?= =?UTF-8?q?=20l'ouverture,=20les=20sections=20GESTION,=20CONFIGURATION=20e?= =?UTF-8?q?t=20ANALYSES=20sont=20ferm=C3=A9es=20par=20d=C3=A9faut.=20Ajout?= =?UTF-8?q?=20d'un=20syst=C3=A8me=20de=20version=20(MENU=5FVERSION=20=3D?= =?UTF-8?q?=202)=20pour=20forcer=20la=20r=C3=A9initialisation=20du=20local?= =?UTF-8?q?Storage=20avec=20les=20nouvelles=20valeurs=20par=20d=C3=A9faut.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/DashboardLayout.tsx | 33 ++- todo.md | 264 +++++++++++++++++++++- 2 files changed, 284 insertions(+), 13 deletions(-) diff --git a/client/src/components/DashboardLayout.tsx b/client/src/components/DashboardLayout.tsx index 7a36daa..730d01c 100644 --- a/client/src/components/DashboardLayout.tsx +++ b/client/src/components/DashboardLayout.tsx @@ -162,20 +162,33 @@ function DashboardLayoutContent({ // État pour gérer les sections ouvertes/fermées (persisté dans localStorage) const [openSections, setOpenSections] = useState>(() => { - // Essayer de charger depuis localStorage - const saved = localStorage.getItem('menuSectionsState'); - if (saved) { - try { - return JSON.parse(saved); - } catch { - // En cas d'erreur, utiliser les valeurs par défaut + // 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'); + if (saved) { + try { + return JSON.parse(saved); + } catch { + // 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 = {}; 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; }); @@ -277,7 +290,7 @@ function DashboardLayoutContent({ {menuSections.map((section, sectionIndex) => { - const isOpen = openSections[section.title] ?? true; + const isOpen = openSections[section.title] ?? false; return (
{sectionIndex > 0 && ( diff --git a/todo.md b/todo.md index 0f58008..0d17840 100644 --- a/todo.md +++ b/todo.md @@ -1,6 +1,259 @@ # 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 @@ -10,8 +263,8 @@ - [x] Créer l'interface publique de réponse aux questionnaires - [x] Implémenter l'envoi automatique post-formation - [x] Créer les tableaux de bord d'analyse avec graphiques (satisfaction par formation/formateur) -- [ ] Implémenter les exports Excel/PDF des feedbacks -- [ ] Tester le système complet (création, envoi, réponse, analyse) +- [x] Implémenter les exports Excel/PDF des feedbacks +- [x] Tester le système complet (création, envoi, réponse, analyse) - [ ] Déployer sur le serveur VPS ## Amélioration : Prévisualisation des questionnaires @@ -154,3 +407,8 @@ - [x] Supprimer le useEffect problématique (toutes sections ouvertes par défaut) - [x] Utiliser localStorage pour persister l'état des sections - [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