Checkpoint: Intégration des signatures tactiles dans les feuilles de présence PDF :

 Modifications implémentées :
- Interface ApprenantPresence étendue pour inclure les présences avec signatures
- Fonction generateFeuillePresence modifiée pour charger et afficher les images de signatures
- Hook didDrawCell ajouté pour insérer les images dans les cellules du tableau PDF
- Procédure exportFeuillePresence modifiée pour récupérer toutes les présences avec signatures
- Signatures chargées depuis le système de fichiers local (uploads/signatures/)
- Gestion automatique des cas où la signature n'existe pas (cellule vide)
- Hauteur des cellules augmentée (minCellHeight: 15) pour accommoder les signatures

📋 Fonctionnement :
- Lors de l'export PDF, le système récupère toutes les présences de la séquence
- Pour chaque apprenant, les signatures sont associées à leurs dates respectives
- Les images PNG sont chargées depuis le disque et converties en base64
- Les signatures sont insérées dans les colonnes Matin/Après-midi correspondantes
- Si aucune signature n'existe, la cellule reste vide pour signature manuscrite

🔧 Technique :
- Utilisation de jsPDF avec jspdf-autotable
- Chargement des images avec fs.readFileSync
- Conversion en data URL base64 pour insertion dans le PDF
- Gestion des erreurs avec console.warn si fichier manquant
This commit is contained in:
Manus
2026-01-28 05:21:57 -05:00
parent a0141e3f71
commit 8f808980dc
3 changed files with 79 additions and 15 deletions

View File

@@ -1147,14 +1147,29 @@ export const appRouter = router({
}
}
// Récupérer toutes les présences avec signatures pour cette séquence
const { getPresencesBySequence } = await import("./presenceDb");
const presences = await getPresencesBySequence(input.sequenceId);
const data = inscriptions
.filter(i => i.inscription.statut === 'confirmee' && i.apprenant)
.map(i => ({
nom: i.apprenant!.nom,
prenom: i.apprenant!.prenom,
codeEtablissement: i.apprenant!.codeEtablissement,
fonction: i.apprenant!.fonction,
}));
.map(i => {
// Récupérer les présences de cet apprenant
const apprenantPresences = presences
.filter(p => p.inscriptionId === i.inscription.id)
.map(p => ({
dateFormationId: p.dateFormationId,
signatureUrl: p.signatureUrl,
}));
return {
nom: i.apprenant!.nom,
prenom: i.apprenant!.prenom,
codeEtablissement: i.apprenant!.codeEtablissement,
fonction: i.apprenant!.fonction,
presences: apprenantPresences,
};
});
const buffer = await generateFeuillePresence({
formationNom: formation.nom,