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:
@@ -4,7 +4,9 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import DashboardLayout from "@/components/DashboardLayout";
|
||||
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, PieChart, Pie, Cell } from "recharts";
|
||||
import { FileText, Users, CheckCircle2, TrendingUp } from "lucide-react";
|
||||
import { FileText, Users, CheckCircle2, TrendingUp, Download } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
|
||||
const COLORS = ["#3b82f6", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#ec4899"];
|
||||
|
||||
@@ -17,6 +19,46 @@ export default function AdminQuestionnaireAnalyse() {
|
||||
const { data: questions } = trpc.questions.list.useQuery({ questionnaireId });
|
||||
const { data: reponsesDetaillees } = trpc.questionnaires.getReponsesDetaillees.useQuery({ id: questionnaireId });
|
||||
|
||||
// Mutations d'export
|
||||
const exportExcelMutation = trpc.questionnaires.exportExcel.useMutation();
|
||||
const exportPDFMutation = trpc.questionnaires.exportPDF.useMutation();
|
||||
|
||||
const handleExportExcel = async () => {
|
||||
try {
|
||||
const result = await exportExcelMutation.mutateAsync({ id: questionnaireId });
|
||||
const blob = new Blob([Uint8Array.from(atob(result.data), c => c.charCodeAt(0))], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = result.filename;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
toast.success('Export Excel réussi');
|
||||
} catch (error) {
|
||||
toast.error('Erreur lors de l\'export Excel');
|
||||
}
|
||||
};
|
||||
|
||||
const handleExportPDF = async () => {
|
||||
try {
|
||||
const result = await exportPDFMutation.mutateAsync({ id: questionnaireId });
|
||||
const blob = new Blob([Uint8Array.from(atob(result.data), c => c.charCodeAt(0))], {
|
||||
type: 'application/pdf'
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = result.filename;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
toast.success('Export PDF réussi');
|
||||
} catch (error) {
|
||||
toast.error('Erreur lors de l\'export PDF');
|
||||
}
|
||||
};
|
||||
|
||||
if (!questionnaire) {
|
||||
return (
|
||||
<DashboardLayout>
|
||||
@@ -96,9 +138,29 @@ export default function AdminQuestionnaireAnalyse() {
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<div className="container mx-auto py-8">
|
||||
<div className="mb-6">
|
||||
<h1 className="text-3xl font-bold">{questionnaire.nom}</h1>
|
||||
<p className="text-muted-foreground mt-1">Analyse des réponses</p>
|
||||
<div className="mb-6 flex justify-between items-start">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">{questionnaire.nom}</h1>
|
||||
<p className="text-muted-foreground mt-1">Analyse des réponses</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleExportExcel}
|
||||
disabled={exportExcelMutation.isPending}
|
||||
>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
{exportExcelMutation.isPending ? "Export..." : "Excel"}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleExportPDF}
|
||||
disabled={exportPDFMutation.isPending}
|
||||
>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
{exportPDFMutation.isPending ? "Export..." : "PDF"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Statistiques globales */}
|
||||
|
||||
Reference in New Issue
Block a user