From b0fcb4d57359a31905be0abdaf432b565ab9636a Mon Sep 17 00:00:00 2001 From: Manus Date: Thu, 8 Jan 2026 10:37:10 -0500 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Ajout=20d'une=20colonne=20"Rappel?= =?UTF-8?q?s=20configur=C3=A9s"=20dans=20le=20tableau=20de=20gestion=20des?= =?UTF-8?q?=20s=C3=A9quences=20permettant=20de=20visualiser=20instantan?= =?UTF-8?q?=C3=A9ment=20les=20rappels=20automatiques=20associ=C3=A9s=20?= =?UTF-8?q?=C3=A0=20chaque=20date=20de=20formation.=20Modification=20backe?= =?UTF-8?q?nd=20:=20cr=C3=A9ation=20de=20la=20fonction=20getRappelsByDateF?= =?UTF-8?q?ormation()=20dans=20db.ts=20qui=20r=C3=A9cup=C3=A8re=20les=20ra?= =?UTF-8?q?ppels=20sp=C3=A9cifiques=20=C3=A0=20une=20date=20ainsi=20que=20?= =?UTF-8?q?les=20rappels=20globaux=20(sans=20dates=20sp=C3=A9cifiques).=20?= =?UTF-8?q?Modification=20du=20router=20sequences.list=20pour=20inclure=20?= =?UTF-8?q?les=20rappels=20dans=20les=20donn=C3=A9es=20des=20s=C3=A9quence?= =?UTF-8?q?s=20via=20Promise.all.=20Interface=20frontend=20:=20ajout=20de?= =?UTF-8?q?=20la=20colonne=20entre=20"Dates"=20et=20"Lieu"=20avec=20badges?= =?UTF-8?q?=20violets=20(bg-purple-50,=20text-purple-700,=20border-purple-?= =?UTF-8?q?300)=20et=20ic=C3=B4ne=20Bell=20pour=20chaque=20rappel,=20organ?= =?UTF-8?q?is=C3=A9s=20par=20date=20avec=20labels=20"Date=201:",=20"Date?= =?UTF-8?q?=202:",=20etc.=20Affichage=20"Aucun=20rappel"=20en=20italique?= =?UTF-8?q?=20gris=20pour=20les=20dates=20sans=20rappels.=20Cette=20foncti?= =?UTF-8?q?onnalit=C3=A9=20am=C3=A9liore=20consid=C3=A9rablement=20la=20vi?= =?UTF-8?q?sibilit=C3=A9=20de=20la=20configuration=20des=20rappels=20et=20?= =?UTF-8?q?facilite=20la=20gestion=20globale=20des=20communications=20auto?= =?UTF-8?q?matiques.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/AdminSequences.tsx | 29 +++++++++++++++++++++++- server/db.ts | 35 +++++++++++++++++++++++++++++ server/routers.ts | 11 ++++++++- todo.md | 5 +++++ 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/client/src/pages/AdminSequences.tsx b/client/src/pages/AdminSequences.tsx index 11d6ed8..4febfd5 100644 --- a/client/src/pages/AdminSequences.tsx +++ b/client/src/pages/AdminSequences.tsx @@ -7,8 +7,9 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { Badge } from "@/components/ui/badge"; import { trpc } from "@/lib/trpc"; -import { Calendar, Edit, Eye, Plus, Trash2, X } from "lucide-react"; +import { Calendar, Edit, Eye, Plus, Trash2, X, Bell } from "lucide-react"; import FormateurCombobox from "@/components/FormateurCombobox"; import CapacityProgressBar from "@/components/CapacityProgressBar"; import { toast } from "sonner"; @@ -675,6 +676,7 @@ export default function AdminSequences() { Formation Nom Dates + Rappels configurés Lieu Formateur Public cible @@ -698,6 +700,31 @@ export default function AdminSequences() { ))} + +
+ {sequence.dates.map((date: any) => ( +
+
Date {date.ordre}:
+
+ {date.rappels && date.rappels.length > 0 ? ( + date.rappels.map((rappel: any) => ( + + + {rappel.nom} + + )) + ) : ( + Aucun rappel + )} +
+
+ ))} +
+
{sequence.lieu} {sequence.formateur?.nom || "-"} diff --git a/server/db.ts b/server/db.ts index 075738f..324147e 100644 --- a/server/db.ts +++ b/server/db.ts @@ -1113,6 +1113,41 @@ export async function updateRappelExecution(id: number) { }).where(eq(rappels.id, id)); } +export async function getRappelsByDateFormation(dateFormationId: number) { + const db = await getDb(); + if (!db) return []; + + // Récupérer les IDs des rappels associés à cette date + const rappelDatesResults = await db.select().from(rappelDates).where(eq(rappelDates.dateFormationId, dateFormationId)); + const rappelIds = rappelDatesResults.map(rd => rd.rappelId); + + if (rappelIds.length === 0) { + // Retourner tous les rappels actifs qui n'ont pas de dates spécifiques (rappels globaux) + const allRappels = await db.select().from(rappels).where(eq(rappels.actif, true)); + const globalRappels = []; + + for (const rappel of allRappels) { + const dates = await getRappelDates(rappel.id); + if (dates.length === 0) { + globalRappels.push(rappel); + } + } + + return globalRappels; + } + + // Récupérer les détails des rappels + const rappelsResults = await Promise.all( + rappelIds.map(async (id) => { + const rappelResult = await db.select().from(rappels).where(eq(rappels.id, id)).limit(1); + return rappelResult.length > 0 ? rappelResult[0] : null; + }) + ); + + // Filtrer les null et retourner + return rappelsResults.filter((r): r is Rappel => r !== null); +} + // ==================== UTILISATEURS ADMIN ==================== diff --git a/server/routers.ts b/server/routers.ts index bde77f4..ecd8d5f 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -258,7 +258,16 @@ export const appRouter = router({ seqs.map(async (seq) => { const dates = await db.getDatesBySequence(seq.id); const nbInscrits = await db.countInscriptionsBySequence(seq.id, 'confirmee'); - return { ...seq, dates, nbInscrits }; + + // Récupérer les rappels associés à chaque date + const datesAvecRappels = await Promise.all( + dates.map(async (date) => { + const rappels = await db.getRappelsByDateFormation(date.id); + return { ...date, rappels }; + }) + ); + + return { ...seq, dates: datesAvecRappels, nbInscrits }; }) ); return sequencesAvecDates; diff --git a/todo.md b/todo.md index 00b8f10..5643610 100644 --- a/todo.md +++ b/todo.md @@ -585,3 +585,8 @@ - [x] Ajouter des badges colorés pour distinguer formations, séquences et dates - [x] Utiliser des icônes pour identifier chaque type d'élément - [x] Améliorer la hiérarchie typographique pour faciliter la lecture + +## Colonne Rappels configurés dans la gestion des séquences +- [x] Modifier le backend pour récupérer les rappels associés à chaque date +- [x] Ajouter la colonne "Rappels configurés" dans le tableau des séquences +- [x] Afficher les rappels avec badges visuels similaires à la page des rappels