Checkpoint: Implémentation de trois fonctionnalités majeures :

1. Personnalisation des templates d'emails avec variables {{lieu}} et {{formateur}} (déjà disponible)
2. Aperçu avant envoi avec données réelles d'un apprenant (modal avec iframe)
3. Email de rappel J-1 avec bouton d'envoi et d'aperçu

Les templates personnalisés supportent maintenant toutes les variables disponibles.
L'aperçu permet de vérifier le rendu final avant l'envoi groupé.
Le rappel J-1 complète le système de communication avec les apprenants.
This commit is contained in:
Manus Sandbox
2025-11-30 13:33:32 -05:00
parent 9e1d574d2e
commit d73db2820c
5 changed files with 401 additions and 9 deletions

View File

@@ -493,10 +493,7 @@ export const appRouter = router({
return { success: true };
}),
sendGroupEmail: adminProcedure.input(z.object({
sequenceId: z.number(),
type: z.enum(['teaser', 'rappel']),
})).mutation(async ({ input }) => {
sendGroupEmail: adminProcedure.input(z.object({ sequenceId: z.number(), type: z.enum(['teaser', 'rappel', 'rappel_j1']) })).mutation(async ({ input }) => {
const sequence = await db.getSequenceById(input.sequenceId);
if (!sequence) {
throw new TRPCError({ code: 'NOT_FOUND', message: 'Séquence introuvable' });
@@ -553,6 +550,17 @@ export const appRouter = router({
};
}),
emailPreview: adminProcedure
.input(z.object({
sequenceId: z.number(),
type: z.enum(['teaser', 'rappel', 'rappel_j1']),
apprenantId: z.number().optional(),
}))
.query(async ({ input }) => {
const { generateEmailPreview } = await import('./emailPreview');
return await generateEmailPreview(input);
}),
exportExcel: adminProcedure.input(z.object({ sequenceId: z.number() })).mutation(async ({ input }) => {
const sequence = await db.getSequenceById(input.sequenceId);
if (!sequence) throw new TRPCError({ code: 'NOT_FOUND', message: 'Séquence introuvable' });