Checkpoint: Ajout de la page de gestion des attestations de formation
Nouvelle fonctionnalité complète pour gérer les attestations : - Schéma de base de données : colonnes modeAttestation et modeEnvoi dans formations, colonnes documentUrl, documentS3Key, uploadedBy, uploadedAt dans attestations - Backend : fichier gestionAttestationsDb.ts, procédures tRPC, fonction sendAttestationEmail - Interface : page AdminGestionAttestations avec sélection de formation, configuration des modes, tableau des apprenants, boutons upload/prévisualisation/envoi/suppression - Navigation : lien dans menu Gestion, route /admin/gestion-attestations
This commit is contained in:
@@ -2281,6 +2281,95 @@ export const appRouter = router({
|
||||
return checkAllPresencesValidated(input.inscriptionId);
|
||||
}),
|
||||
}),
|
||||
|
||||
// ===== GESTION DES ATTESTATIONS =====
|
||||
gestionAttestations: router({
|
||||
// Récupérer la configuration d'une formation
|
||||
getFormationConfig: adminProcedure
|
||||
.input(z.object({ formationId: z.number() }))
|
||||
.query(async ({ input }) => {
|
||||
const { getFormationConfig } = await import("./gestionAttestationsDb");
|
||||
return getFormationConfig(input.formationId);
|
||||
}),
|
||||
|
||||
// Mettre à jour la configuration d'une formation
|
||||
updateFormationConfig: adminProcedure
|
||||
.input(z.object({
|
||||
formationId: z.number(),
|
||||
modeAttestation: z.enum(["auto", "manuel"]),
|
||||
modeEnvoi: z.enum(["auto", "manuel"]),
|
||||
}))
|
||||
.mutation(async ({ input }) => {
|
||||
const { updateFormationConfig } = await import("./gestionAttestationsDb");
|
||||
return updateFormationConfig(
|
||||
input.formationId,
|
||||
input.modeAttestation,
|
||||
input.modeEnvoi
|
||||
);
|
||||
}),
|
||||
|
||||
// Récupérer les apprenants avec leur statut d'attestation
|
||||
getApprenantsWithStatus: adminProcedure
|
||||
.input(z.object({ formationId: z.number() }))
|
||||
.query(async ({ input }) => {
|
||||
const { getApprenantsWithAttestationStatus } = await import("./gestionAttestationsDb");
|
||||
return getApprenantsWithAttestationStatus(input.formationId);
|
||||
}),
|
||||
|
||||
// Uploader un document d'attestation
|
||||
uploadDocument: adminProcedure
|
||||
.input(z.object({
|
||||
inscriptionId: z.number(),
|
||||
documentUrl: z.string(),
|
||||
documentS3Key: z.string(),
|
||||
}))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { uploadAttestationDocument } = await import("./gestionAttestationsDb");
|
||||
return uploadAttestationDocument(
|
||||
input.inscriptionId,
|
||||
input.documentUrl,
|
||||
input.documentS3Key,
|
||||
ctx.user.id
|
||||
);
|
||||
}),
|
||||
|
||||
// Supprimer un document d'attestation
|
||||
deleteDocument: adminProcedure
|
||||
.input(z.object({ attestationId: z.number() }))
|
||||
.mutation(async ({ input }) => {
|
||||
const { deleteAttestationDocument } = await import("./gestionAttestationsDb");
|
||||
return deleteAttestationDocument(input.attestationId);
|
||||
}),
|
||||
|
||||
// Envoyer une attestation par email
|
||||
sendAttestation: adminProcedure
|
||||
.input(z.object({
|
||||
attestationId: z.number(),
|
||||
apprenantEmail: z.string(),
|
||||
apprenantNom: z.string(),
|
||||
apprenantPrenom: z.string(),
|
||||
formationNom: z.string(),
|
||||
pdfUrl: z.string(),
|
||||
}))
|
||||
.mutation(async ({ input }) => {
|
||||
const { sendAttestationEmail } = await import("./emailService");
|
||||
const { markAttestationAsSent } = await import("./gestionAttestationsDb");
|
||||
|
||||
// Envoyer l'email
|
||||
await sendAttestationEmail({
|
||||
to: input.apprenantEmail,
|
||||
apprenantNom: input.apprenantNom,
|
||||
apprenantPrenom: input.apprenantPrenom,
|
||||
formationNom: input.formationNom,
|
||||
pdfUrl: input.pdfUrl,
|
||||
});
|
||||
|
||||
// Marquer comme envoyé
|
||||
await markAttestationAsSent(input.attestationId);
|
||||
|
||||
return { success: true };
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export type AppRouter = typeof appRouter;
|
||||
|
||||
Reference in New Issue
Block a user