155 lines
6.8 KiB
JavaScript
155 lines
6.8 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { api } from '../stores/api';
|
|
import PageHeader from '../components/PageHeader';
|
|
import SuccessCheck from '../components/SuccessCheck';
|
|
|
|
export default function RapportRSG() {
|
|
const [rapports, setRapports] = useState([]);
|
|
const [form, setForm] = useState({
|
|
reunion_dist: new Date().toISOString().slice(0, 10),
|
|
decisions_text: '',
|
|
infos_region: '',
|
|
sujets_groupe: '',
|
|
});
|
|
const [loading, setLoading] = useState(true);
|
|
const [success, setSuccess] = useState(false);
|
|
const [viewRapport, setViewRapport] = useState(null);
|
|
const [error, setError] = useState('');
|
|
|
|
useEffect(() => {
|
|
api.get('/rapports-rsg/').then((data) => {
|
|
setRapports(data);
|
|
setLoading(false);
|
|
}).catch(() => setLoading(false));
|
|
}, []);
|
|
|
|
const handleSubmit = async () => {
|
|
if (!form.decisions_text.trim() && !form.infos_region.trim() && !form.sujets_groupe.trim()) {
|
|
setError('Au moins une section doit être remplie');
|
|
return;
|
|
}
|
|
setError('');
|
|
try {
|
|
const decisionsList = form.decisions_text
|
|
.split('\n')
|
|
.map((d) => d.trim())
|
|
.filter((d) => d.length > 0);
|
|
|
|
await api.post('/rapports-rsg/', {
|
|
reunion_dist: form.reunion_dist,
|
|
decisions: decisionsList.length > 0 ? decisionsList : null,
|
|
infos_region: form.infos_region.trim() || null,
|
|
sujets_groupe: form.sujets_groupe.trim() || null,
|
|
});
|
|
setSuccess(true);
|
|
} catch (e) { setError(e.message); }
|
|
};
|
|
|
|
if (success) return <SuccessCheck message="Rapport RSG enregistré ✓" />;
|
|
|
|
// Vue lecture
|
|
if (viewRapport) {
|
|
return (
|
|
<div className="min-h-screen bg-gray-100">
|
|
<div className="bg-aa-blue text-white p-4 flex items-center gap-3">
|
|
<button onClick={() => setViewRapport(null)} className="text-2xl">←</button>
|
|
<div>
|
|
<h1 className="text-lg font-bold">Rapport RSG</h1>
|
|
<p className="text-blue-200 text-xs">Réunion du {viewRapport.reunion_dist}</p>
|
|
</div>
|
|
</div>
|
|
<div className="p-4 space-y-4">
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<p className="text-xs text-gray-400 mb-1">Rédigé par {viewRapport.redacteur_prenom}</p>
|
|
</div>
|
|
{viewRapport.decisions && viewRapport.decisions.length > 0 && (
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<h3 className="font-bold text-gray-700 mb-2">Décisions du district</h3>
|
|
{viewRapport.decisions.map((d, i) => (
|
|
<div key={i} className="py-2 border-b border-gray-100 last:border-0">
|
|
<p className="text-sm text-gray-800">• {d}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
{viewRapport.infos_region && (
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<h3 className="font-bold text-gray-700 mb-2">Informations de la région</h3>
|
|
<p className="text-sm text-gray-600 whitespace-pre-wrap">{viewRapport.infos_region}</p>
|
|
</div>
|
|
)}
|
|
{viewRapport.sujets_groupe && (
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<h3 className="font-bold text-gray-700 mb-2">Sujets pour le groupe</h3>
|
|
<p className="text-sm text-gray-600 whitespace-pre-wrap">{viewRapport.sujets_groupe}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-100">
|
|
<PageHeader titre="Rapport du RSG" sousTitre="M3 — Réunion de district" />
|
|
|
|
<div className="p-4 space-y-4">
|
|
{/* Rapports existants */}
|
|
{rapports.length > 0 && (
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<h2 className="text-xs font-bold text-gray-400 uppercase tracking-wider mb-2">Rapports récents</h2>
|
|
{rapports.slice(0, 5).map((r) => (
|
|
<button key={r.id} onClick={() => setViewRapport(r)}
|
|
className="w-full flex items-center justify-between py-2 border-b border-gray-50 last:border-0 active:bg-gray-50">
|
|
<div>
|
|
<p className="font-medium text-sm text-gray-800">Réunion du {r.reunion_dist}</p>
|
|
<p className="text-xs text-gray-400">Par {r.redacteur_prenom}</p>
|
|
</div>
|
|
<span className="text-gray-300">→</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{/* Nouveau rapport */}
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<label className="text-xs text-gray-400 block mb-1">Date de la réunion de district</label>
|
|
<input type="date" value={form.reunion_dist}
|
|
onChange={(e) => setForm({ ...form, reunion_dist: e.target.value })}
|
|
className="w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue" />
|
|
</div>
|
|
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<label className="text-xs text-gray-400 block mb-1">Décisions du district (une par ligne)</label>
|
|
<textarea value={form.decisions_text}
|
|
onChange={(e) => setForm({ ...form, decisions_text: e.target.value })} rows={4}
|
|
placeholder="Vote sur le budget annuel approuvé Nouveau format d'atelier proposé Date du prochain congrès confirmée"
|
|
className="w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue resize-none text-sm" />
|
|
</div>
|
|
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<label className="text-xs text-gray-400 block mb-1">Informations de la région 87</label>
|
|
<textarea value={form.infos_region}
|
|
onChange={(e) => setForm({ ...form, infos_region: e.target.value })} rows={3}
|
|
placeholder="Nouvelles de l'assemblée régionale, rapports..."
|
|
className="w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue resize-none text-sm" />
|
|
</div>
|
|
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<label className="text-xs text-gray-400 block mb-1">Sujets à rapporter au groupe</label>
|
|
<textarea value={form.sujets_groupe}
|
|
onChange={(e) => setForm({ ...form, sujets_groupe: e.target.value })} rows={3}
|
|
placeholder="Points à discuter à la prochaine réunion d'affaires..."
|
|
className="w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue resize-none text-sm" />
|
|
</div>
|
|
|
|
{error && <p className="text-red-500 text-sm text-center bg-red-50 p-3 rounded-lg">{error}</p>}
|
|
|
|
<button onClick={handleSubmit}
|
|
className="w-full p-5 bg-blue-700 text-white rounded-2xl text-xl font-bold disabled:opacity-40 active:scale-[0.97] transition shadow-lg">
|
|
📨 Enregistrer le rapport
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|