Checkpoint: Exports Excel/PDF et notifications pour les questionnaires

 **Nouvelles fonctionnalités implémentées** :

**Exports des résultats** :
- Export Excel avec 3 feuilles (statistiques globales, questions, réponses brutes)
- Export PDF avec mise en page professionnelle et pagination
- Boutons d'export dans la page d'analyse des questionnaires
- Téléchargement automatique des fichiers générés

**Système de notifications** :
- Notification automatique à l'administrateur lors de chaque nouvelle réponse
- Utilisation du système de notifications intégré Manus
- Gestion des erreurs sans bloquer la soumission du questionnaire

**Système complet de questionnaires** :
- Création et édition de questionnaires 
- Prévisualisation avant envoi 
- Envoi automatique post-formation 
- Analyse des résultats avec graphiques 
- Exports Excel/PDF 
- Notifications administrateur 

Le système de questionnaires est maintenant complet et prêt pour la production.
This commit is contained in:
Manus Sandbox
2025-12-07 14:00:15 -05:00
parent b21ad8f978
commit 5d8fd4dd1b
4 changed files with 284 additions and 4 deletions

View File

@@ -1073,6 +1073,28 @@ export const appRouter = router({
const questionnaireDb = await import("./questionnaireDb");
return questionnaireDb.getReponsesDetailleesQuestionnaire(input.id);
}),
exportExcel: adminProcedure
.input(z.object({ id: z.number() }))
.mutation(async ({ input }) => {
const { exportQuestionnaireToExcel } = await import("./questionnaireExport");
const buffer = await exportQuestionnaireToExcel(input.id);
return {
data: buffer.toString('base64'),
filename: `questionnaire-${input.id}-${new Date().toISOString().split('T')[0]}.xlsx`,
};
}),
exportPDF: adminProcedure
.input(z.object({ id: z.number() }))
.mutation(async ({ input }) => {
const { exportQuestionnaireToPDF } = await import("./questionnaireExport");
const buffer = await exportQuestionnaireToPDF(input.id);
return {
data: buffer.toString('base64'),
filename: `questionnaire-${input.id}-${new Date().toISOString().split('T')[0]}.pdf`,
};
}),
}),
// ===== QUESTIONS =====
@@ -1191,6 +1213,20 @@ export const appRouter = router({
dateReponse: new Date(),
});
// Envoyer une notification à l'administrateur
try {
const { notifyOwner } = await import('./_core/notification');
const questionnaire = await questionnaireDb.getQuestionnaireById(envoi.questionnaireId);
await notifyOwner({
title: 'Nouvelle réponse au questionnaire',
content: `Un apprenant a répondu au questionnaire "${questionnaire?.nom || 'Sans titre'}"`,
});
} catch (error) {
console.error('[Notification] Erreur lors de l\'envoi de la notification:', error);
// Ne pas bloquer la réponse si la notification échoue
}
return { success: true };
}),