groupe-meditation/frontend/src/pages/Rapports.jsx

82 lines
3.1 KiB
React
Raw Normal View History

2026-03-04 14:01:00 -05:00
import React, { useState, useEffect } from 'react';
import { api } from '../stores/api';
import PageHeader from '../components/PageHeader';
export default function Rapports() {
2026-04-17 04:04:04 -04:00
const [anneesResolutions, setAnneesResolutions] = useState([]);
2026-03-04 14:01:00 -05:00
const [loading, setLoading] = useState(true);
const [generating, setGenerating] = useState(null);
useEffect(() => {
api.get('/rapports/resolutions/annees').then((annees) => {
2026-04-17 04:04:04 -04:00
setAnneesResolutions(annees);
2026-03-04 14:01:00 -05:00
setLoading(false);
}).catch(() => setLoading(false));
}, []);
2026-04-17 04:04:04 -04:00
const telecharger = async (path, key, filename) => {
2026-03-04 14:01:00 -05:00
setGenerating(key);
try {
const token = api.getToken();
2026-04-17 04:04:04 -04:00
const res = await fetch(`/api/rapports/${path}`, {
2026-03-04 14:01:00 -05:00
headers: { Authorization: `Bearer ${token}` },
});
if (!res.ok) throw new Error('Erreur de génération');
const blob = await res.blob();
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
2026-04-17 04:04:04 -04:00
a.download = filename;
2026-03-04 14:01:00 -05:00
a.click();
URL.revokeObjectURL(a.href);
} catch (e) {
alert(`Erreur: ${e.message}`);
}
setGenerating(null);
};
const vide = anneesResolutions.length === 0;
2026-04-17 04:04:04 -04:00
2026-03-04 14:01:00 -05:00
return (
<div className="min-h-screen bg-gray-100">
2026-04-17 04:04:04 -04:00
<PageHeader titre="Rapports PDF" sousTitre="C1 — Finances, réunions, résolutions" />
2026-03-04 14:01:00 -05:00
<div className="p-4 space-y-4">
{loading ? (
<p className="text-center text-gray-400 py-8">Chargement...</p>
2026-04-17 04:04:04 -04:00
) : vide ? (
2026-03-04 14:01:00 -05:00
<div className="text-center py-12">
<p className="text-4xl mb-2">📄</p>
<p className="text-gray-500">Aucun rapport disponible</p>
<p className="text-gray-400 text-sm mt-1">Les rapports apparaîtront après les premières saisies</p>
</div>
) : (
2026-04-17 04:04:04 -04:00
<>
{/* Registre des résolutions */}
{anneesResolutions.length > 0 && (
<div className="bg-white rounded-2xl p-4 shadow-sm">
<h3 className="font-bold text-gray-800 mb-3">📜 Registre des résolutions</h3>
<div className="grid gap-2">
{anneesResolutions.map((a) => (
<button key={a.annee}
onClick={() => telecharger(`resolutions/${a.annee}`, `res-${a.annee}`, `registre_resolutions_${a.annee}.pdf`)}
disabled={generating === `res-${a.annee}`}
className="flex items-center gap-3 p-3 bg-orange-50 rounded-xl text-left active:scale-[0.98] transition border border-orange-200"
>
<span className="text-xl">📜</span>
<div className="flex-1">
<p className="font-bold text-orange-800 text-sm">Résolutions {a.annee}</p>
2026-05-25 17:39:38 -04:00
<p className="text-xs text-orange-600">Décisions prises en Groupe</p>
2026-04-17 04:04:04 -04:00
</div>
<span className="text-orange-400">{generating === `res-${a.annee}` ? '⏳' : '↓'}</span>
</button>
))}
</div>
2026-03-04 14:01:00 -05:00
</div>
2026-04-17 04:04:04 -04:00
)}
</>
2026-03-04 14:01:00 -05:00
)}
</div>
</div>
);
}