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

113 lines
3.8 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';
const STATUTS = {
en_attente: { label: 'En attente', bg: 'bg-yellow-100', text: 'text-yellow-800', emoji: '⏳' },
en_cours: { label: 'En cours', bg: 'bg-blue-100', text: 'text-blue-800', emoji: '🔄' },
complete: { label: 'Complété', bg: 'bg-green-100', text: 'text-green-800', emoji: '✓' },
};
function Badge({ statut }) {
const s = STATUTS[statut] || STATUTS.en_attente;
return (
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-bold ${s.bg} ${s.text}`}>
{s.emoji} {s.label}
</span>
);
}
export default function Decisions() {
const [decisions, setDecisions] = useState([]);
const [filtre, setFiltre] = useState('ouvertes'); // ouvertes | toutes
const [loading, setLoading] = useState(true);
const charger = async () => {
setLoading(true);
try {
let url = '/decisions/';
if (filtre === 'ouvertes') {
// Charger en_attente et en_cours
const [att, enc] = await Promise.all([
api.get('/decisions/?statut=en_attente'),
api.get('/decisions/?statut=en_cours'),
]);
setDecisions([...enc, ...att]);
} else {
const data = await api.get(url);
setDecisions(data);
}
} catch (e) {
console.error(e);
}
setLoading(false);
};
useEffect(() => { charger(); }, [filtre]);
return (
<div className="min-h-screen bg-gray-100">
<PageHeader titre="Décisions en cours" sousTitre="C5 — Suivi réunion d'affaires" />
{/* Filtres */}
<div className="p-4 pb-0">
<div className="flex gap-2">
{[
{ key: 'ouvertes', label: 'Ouvertes' },
{ key: 'toutes', label: 'Toutes' },
].map((f) => (
<button
key={f.key}
onClick={() => setFiltre(f.key)}
className={`px-4 py-2 rounded-full text-sm font-bold transition ${
filtre === f.key
? 'bg-aa-blue text-white'
: 'bg-white text-gray-600 border border-gray-200'
}`}
>
{f.label}
</button>
))}
</div>
</div>
{/* Liste */}
<div className="p-4 space-y-3">
{loading ? (
<p className="text-center text-gray-400 py-8">Chargement...</p>
) : decisions.length === 0 ? (
<div className="text-center py-12">
<p className="text-4xl mb-2">📌</p>
<p className="text-gray-500">Aucune décision {filtre === 'ouvertes' ? 'ouverte' : ''}</p>
</div>
) : (
decisions.map((d) => (
<div key={d.id} className="bg-white rounded-2xl p-4 shadow-sm">
<div className="flex items-start justify-between gap-3">
<div className="flex-1">
<p className="font-bold text-gray-800">{d.sujet}</p>
{d.description && (
<p className="text-sm text-gray-500 mt-1">{d.description}</p>
)}
<div className="flex flex-wrap items-center gap-2 mt-2">
<Badge statut={d.statut} />
{d.responsable_prenom && (
<span className="text-xs text-gray-400">→ {d.responsable_prenom}</span>
)}
<span className="text-xs text-gray-300">{d.date_decision}</span>
</div>
{d.proposeur && (
<p className="text-xs text-gray-400 mt-1">
Proposé par {d.proposeur}{d.secondeur ? `, secondé par ${d.secondeur}` : ''}
</p>
)}
</div>
</div>
</div>
))
)}
</div>
</div>
);
}