diff --git a/.manus/db/db-query-1769175779618.json b/.manus/db/db-query-1769175779618.json new file mode 100644 index 0000000..051fdfd --- /dev/null +++ b/.manus/db/db-query-1769175779618.json @@ -0,0 +1,26 @@ +{ + "query": "SELECT df.id, df.sequenceId, df.dateDebut, df.dateFin, df.ordre, s.nom as sequenceNom\nFROM datesFormation df\nJOIN sequences s ON df.sequenceId = s.id\nWHERE s.nom = 'Groupe A'\nORDER BY df.ordre;", + "command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT df.id, df.sequenceId, df.dateDebut, df.dateFin, df.ordre, s.nom as sequenceNom\nFROM datesFormation df\nJOIN sequences s ON df.sequenceId = s.id\nWHERE s.nom = 'Groupe A'\nORDER BY df.ordre;", + "rows": [ + { + "id": "900001", + "sequenceId": "30001", + "dateDebut": "2025-11-20 12:48:00", + "dateFin": "2025-11-21 06:48:00", + "ordre": "1", + "sequenceNom": "Groupe A" + }, + { + "id": "900002", + "sequenceId": "30001", + "dateDebut": "2025-12-17 12:46:00", + "dateFin": "2025-12-17 21:46:00", + "ordre": "2", + "sequenceNom": "Groupe A" + } + ], + "messages": [], + "stdout": "id\tsequenceId\tdateDebut\tdateFin\tordre\tsequenceNom\n900001\t30001\t2025-11-20 12:48:00\t2025-11-21 06:48:00\t1\tGroupe A\n900002\t30001\t2025-12-17 12:46:00\t2025-12-17 21:46:00\t2\tGroupe A\n", + "stderr": "", + "execution_time_ms": 115 +} \ No newline at end of file diff --git a/client/src/pages/AdminSequences.tsx b/client/src/pages/AdminSequences.tsx index 3d9bd92..10a3e95 100644 --- a/client/src/pages/AdminSequences.tsx +++ b/client/src/pages/AdminSequences.tsx @@ -223,6 +223,19 @@ export default function AdminSequences() { return; } + // Valider que chaque date de fin est après la date de début + for (let i = 0; i < formData.dates.length; i++) { + const date = formData.dates[i]; + if (date.dateDebut && date.dateFin) { + const debut = new Date(date.dateDebut); + const fin = new Date(date.dateFin); + if (fin <= debut) { + toast.error(`Date ${i + 1}: La date de fin doit être après la date de début`); + return; + } + } + } + const data = { formationId: parseInt(formData.formationId), nom: formData.nom, diff --git a/server/routers.ts b/server/routers.ts index 7cc5f30..2919a22 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -454,6 +454,18 @@ export const appRouter = router({ })).mutation(async ({ input }) => { const { dates, ...sequenceData } = input; + // Valider que chaque date de fin est après la date de début + for (const date of dates) { + const debut = new Date(date.dateDebut); + const fin = new Date(date.dateFin); + if (fin <= debut) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: 'La date de fin doit être après la date de début pour toutes les dates de formation', + }); + } + } + // Créer la séquence const result = await db.createSequence({ ...sequenceData, @@ -496,6 +508,18 @@ export const appRouter = router({ console.log('[UPDATE SEQUENCE] Input reçu:', JSON.stringify(input, null, 2)); + // Valider que chaque date de fin est après la date de début + for (const date of dates) { + const debut = new Date(date.dateDebut); + const fin = new Date(date.dateFin); + if (fin <= debut) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: 'La date de fin doit être après la date de début pour toutes les dates de formation', + }); + } + } + // Mettre à jour la séquence const updateData: any = { ...sequenceData, diff --git a/todo.md b/todo.md index 9acc43f..ad55baf 100644 --- a/todo.md +++ b/todo.md @@ -1194,3 +1194,6 @@ - [x] Corriger l'erreur 'Aucun rappel actif configuré' lors du test de rappels - [x] Désactiver visuellement le bouton de test pour les séquences sans rappels actifs - [x] Ajouter un badge de compteur sur le bouton de test indiquant le nombre de rappels actifs +- [x] Corriger l'erreur 'Unexpected token' lors de la mutation API sur /admin/sequences +- [ ] Corriger l'erreur dans le fichier ICS qui empêche l'importation dans Outlook +- [ ] Ajouter validation date fin > date début dans la boîte de dialogue de modification des séquences