import React, { useState, useEffect } from 'react'; import { api } from '../stores/api'; import { useStore } from '../stores/store'; import PageHeader from '../components/PageHeader'; import { dateLocale, dernieresDatesReunion, indexJourReunion, labelDateReunion } from '../utils/datesReunion'; const STATUT = { en_attente: { label: 'À confirmer', cls: 'bg-yellow-100 text-yellow-700' }, confirmee: { label: 'Confirmée', cls: 'bg-blue-100 text-blue-700' }, recu: { label: '✓ Reçue', cls: 'bg-green-100 text-green-700' }, }; export default function Collecte() { const { membre, groupe, estSysadmin } = useStore(); const [montant, setMontant] = useState(''); const [dateCollecte, setDateCollecte] = useState(new Date().toISOString().slice(0, 10)); const [detenteurId, setDetenteurId] = useState(''); const [membres, setMembres] = useState([]); const [collectesMois, setCollectesMois] = useState([]); const [collectesToutes, setCollectesToutes] = useState([]); const [collecteSelectionneeId, setCollecteSelectionneeId] = useState(''); const [tab, setTab] = useState('mois'); const [loading, setLoading] = useState(false); const [msg, setMsg] = useState(''); const [error, setError] = useState(''); const aujourdhui = new Date(); const mois = aujourdhui.getMonth() + 1; const annee = aujourdhui.getFullYear(); const charger = async () => { try { const [mbrs, cols, toutes] = await Promise.all([ api.get('/membres/actifs'), api.get(`/collectes/?mois=${mois}&annee=${annee}&limite=50`), api.get('/collectes/?limite=500'), ]); setMembres(mbrs); setCollectesMois(cols); setCollectesToutes(toutes); if (membre && !detenteurId) setDetenteurId(membre.id); if (!collecteSelectionneeId && toutes.length > 0) setCollecteSelectionneeId(toutes[0].id); } catch (e) { setError(e.message); } }; useEffect(() => { charger(); }, []); const flash = (m) => { setMsg(m); setTimeout(() => setMsg(''), 2500); }; const handleSubmit = async () => { if (!montant || parseFloat(montant) <= 0) { setError('Entrez un montant valide'); return; } if (!detenteurId) { setError("Sélectionnez qui a l'argent"); return; } if (!dateCollecte) { setError("Sélectionnez une date"); return; } setLoading(true); setError(''); try { await api.post('/collectes/', { date_collecte: dateCollecte, montant: parseFloat(montant), detenteur_id: detenteurId, }); setMontant(''); flash('Collecte enregistrée ✓'); setTab('mois'); await charger(); } catch (e) { setError(e.message); } setLoading(false); }; const confirmer = async (id) => { setError(''); try { await api.post(`/collectes/${id}/confirmer`); flash('Montant confirmé ✓'); await charger(); } catch (e) { setError(e.message); } }; const totalMois = collectesMois.reduce((sum, c) => sum + parseFloat(c.montant), 0); const collecteSelectionnee = collectesToutes.find((c) => c.id === collecteSelectionneeId); const MOIS_NOMS = ['', 'janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']; const labelDate = (d, avecAnnee = false) => { return labelDateReunion(d, avecAnnee); }; const jourReunion = indexJourReunion(groupe); const datesAvecCollecte = new Set(collectesToutes.map((c) => c.date_collecte)); const datesReunion = dernieresDatesReunion(groupe, { nombre: 52, exclure: datesAvecCollecte }); useEffect(() => { if (!estSysadmin && datesReunion.length > 0 && !datesReunion.includes(dateCollecte)) { setDateCollecte(datesReunion[0]); } }, [collectesToutes, groupe?.jour_reunion, estSysadmin]); return (
{msg &&
{msg}
} {error &&
{error}
}
{tab === 'mois' && ( <>

Total {MOIS_NOMS[mois]} {annee}

{totalMois.toFixed(2)} $

{collectesMois.length} collecte{collectesMois.length > 1 ? 's' : ''}

{collectesToutes.length > 0 && (
{collecteSelectionnee && (

{labelDate(collecteSelectionnee.date_collecte, true)}

{STATUT[collecteSelectionnee.statut]?.label || collecteSelectionnee.statut}

{parseFloat(collecteSelectionnee.montant).toFixed(2)} $

Saisi par {collecteSelectionnee.saisi_par_prenom || '—'} · Chez {collecteSelectionnee.detenteur_prenom || '—'}

{collecteSelectionnee.confirme_par_prenom && (

Confirmé par {collecteSelectionnee.confirme_par_prenom}

)} {collecteSelectionnee.recu_par_prenom && (

Reçu par {collecteSelectionnee.recu_par_prenom}

)}
)}
)} {collectesMois.length === 0 ? (

💰

Aucune collecte ce mois-ci

) : (
{collectesMois.map((c) => { const st = STATUT[c.statut] || STATUT.en_attente; const peutConfirmer = c.statut === 'en_attente' && c.saisi_par_prenom !== membre?.prenom; return (

{parseFloat(c.montant).toFixed(2)} $

📅 {c.date_collecte}

Saisi par {c.saisi_par_prenom} {' · '}Chez {c.detenteur_prenom}

{c.confirme_par_prenom &&

Confirmé par {c.confirme_par_prenom}

} {c.recu_par_prenom &&

Reçu par {c.recu_par_prenom}

}
{st.label}
{peutConfirmer && ( )}
); })}
)} )} {tab === 'saisie' && (
{estSysadmin ? ( setDateCollecte(e.target.value)} className="w-full p-3 bg-gray-50 rounded-xl text-lg border-0 focus:ring-2 focus:ring-aa-blue" /> ) : datesReunion.length > 0 ? ( ) : (
{jourReunion === null ? "Configurez d'abord le jour de réunion dans les paramètres du groupe." : `Aucune des 52 dernières rencontres n'est sans collecte enregistrée.`}
)}

{estSysadmin ? 'Le sysadmin peut renseigner une date antérieure.' : 'Seules les dates des 52 dernières rencontres sans collecte enregistrée sont proposées.'}

$ setMontant(e.target.value)} className="w-full p-4 pl-10 bg-gray-50 rounded-xl text-3xl font-bold text-center border-0 focus:ring-2 focus:ring-green-500" autoFocus />
)}
); }