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 [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] = await Promise.all([ api.get('/membres/actifs'), api.get(`/collectes/?mois=${mois}&annee=${annee}&limite=50`), ]); setMembres(mbrs); setCollectesMois(cols); if (membre && !detenteurId) setDetenteurId(membre.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 MOIS_NOMS = ['', 'janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']; // 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 dates = []; const d = new Date(); for (let i = 0; i < 12; i++) { const test = new Date(d); test.setDate(d.getDate() - i); if (test.getDay() === jourReunion) { dates.push(test.toISOString().slice(0, 10)); } } // Aussi vérifier les 30 jours suivants dans le passé for (let i = 12; i < 60; i++) { const test = new Date(d); test.setDate(d.getDate() - i); if (test.getDay() === jourReunion) { dates.push(test.toISOString().slice(0, 10)); } } return dates; }; const datesReunion = getDatesReunion(); return (
{msg &&
{msg}
} {error &&
{error}
}
{tab === 'mois' && ( <>

Total {MOIS_NOMS[mois]} {annee}

{totalMois.toFixed(2)} $

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

{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' && (
{datesReunion.length > 0 ? ( ) : ( setDateCollecte(e.target.value)} max={new Date().toISOString().slice(0, 10)} className="w-full p-3 bg-gray-50 rounded-xl text-lg border-0 focus:ring-2 focus:ring-aa-blue" /> )}

Saisie rétroactive permise aux dates de réunion

$ 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 />
)}
); }