import React, { useState, useEffect } from 'react'; import { api } from '../stores/api'; import { useStore } from '../stores/store'; import PageHeader from '../components/PageHeader'; 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 } = 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 dateLocale = (d = new Date()) => { const an = d.getFullYear(); const mo = String(d.getMonth() + 1).padStart(2, '0'); const jo = String(d.getDate()).padStart(2, '0'); return `${an}-${mo}-${jo}`; }; const labelDate = (d, avecAnnee = false) => { const dt = new Date(d + 'T12:00:00'); return dt.toLocaleDateString('fr-CA', { weekday: 'long', day: 'numeric', month: 'long', ...(avecAnnee ? { year: 'numeric' } : {}), }); }; // Calculer les dernières dates de réunion pour le sélecteur const joursSemaine = { 'lundi': 1, 'mardi': 2, 'mercredi': 3, 'jeudi': 4, 'vendredi': 5, 'samedi': 6, 'dimanche': 0 }; const jourReunion = groupe?.jour_reunion ? joursSemaine[groupe.jour_reunion.toLowerCase()] : null; const getDatesReunion = () => { if (jourReunion === null) return []; const datesAvecCollecte = new Set(collectesToutes.map((c) => c.date_collecte)); const dates = []; const d = new Date(); for (let i = 0; i < 180; i++) { const test = new Date(d); test.setDate(d.getDate() - i); const valeur = dateLocale(test); if (test.getDay() === jourReunion) { if (!datesAvecCollecte.has(valeur)) dates.push(valeur); } } return dates; }; const datesReunion = getDatesReunion(); useEffect(() => { if (datesReunion.length > 0 && !datesReunion.includes(dateCollecte)) { setDateCollecte(datesReunion[0]); } }, [collectesToutes, groupe?.jour_reunion]); return (
Total {MOIS_NOMS[mois]} {annee}
{totalMois.toFixed(2)} $
{collectesMois.length} collecte{collectesMois.length > 1 ? 's' : ''}
{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}
)}💰
Aucune collecte ce mois-ci
{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}
}Seuls les {groupe?.jour_reunion || 'jours de réunion'} sans collecte enregistrée sont proposés.