Checkpoint: Ajout de l'authentification formateur et upload logo/signature pour attestations

## Authentification formateur
- Ajout du rôle "formateur" dans l'enum de la table users
- Ajout du champ formateurId pour lier un compte à un formateur
- Mise à jour de l'interface AdminUsers avec sélection du formateur
- Redirection automatique selon le rôle (admin → /admin, formateur → /formateur)
- Badges et filtres mis à jour pour inclure le rôle formateur

## Upload logo et signature
- Création du composant ImageUpload.tsx avec prévisualisation
- Création de l'endpoint /api/upload-image avec multer pour l'upload vers S3
- Intégration dans AdminAttestations.tsx
- Modification du service PDF pour inclure le logo (en haut à droite) et la signature (en bas)
- Mise à jour des procédures tRPC pour accepter logoUrl, logoS3Key, signatureUrl, signatureS3Key
This commit is contained in:
Manus
2026-01-07 10:34:53 -05:00
parent 023711df92
commit 6484e3e892
15 changed files with 2524 additions and 23 deletions

View File

@@ -904,8 +904,9 @@ export const appRouter = router({
email: z.string().email().optional(),
username: z.string().min(3).optional(),
password: z.string().min(6).optional(),
role: z.enum(["user", "admin"]).default("user"),
role: z.enum(["user", "admin", "formateur"]).default("user"),
isActive: z.boolean().default(true),
formateurId: z.number().optional(),
})).mutation(async ({ input }) => {
await db.createUser(input);
return { success: true };
@@ -917,8 +918,9 @@ export const appRouter = router({
email: z.string().email().optional(),
username: z.string().min(3).optional(),
password: z.string().min(6).optional(),
role: z.enum(["user", "admin"]).optional(),
role: z.enum(["user", "admin", "formateur"]).optional(),
isActive: z.boolean().optional(),
formateurId: z.number().optional(),
})).mutation(async ({ input }) => {
const { id, ...data } = input;
await db.updateUser(id, data);
@@ -1821,6 +1823,10 @@ export const appRouter = router({
nomSignataire: z.string().optional(),
fonctionSignataire: z.string().optional(),
texteAttestation: z.string().optional(),
logoUrl: z.string().optional(),
logoS3Key: z.string().optional(),
signatureUrl: z.string().optional(),
signatureS3Key: z.string().optional(),
}))
.mutation(async ({ input }) => {
const { updateConfigAttestation } = await import("./attestationService");