133 lines
5.1 KiB
JavaScript
133 lines
5.1 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { api } from '../stores/api';
|
|
import { useStore } from '../stores/store';
|
|
import PageHeader from '../components/PageHeader';
|
|
|
|
const CATEGORIES = {
|
|
executif: { label: 'Exécutif', bg: 'bg-blue-100', text: 'text-blue-700' },
|
|
service: { label: 'Service', bg: 'bg-purple-100', text: 'text-purple-700' },
|
|
physique: { label: 'Physique', bg: 'bg-green-100', text: 'text-green-700' },
|
|
};
|
|
|
|
export default function Calendrier() {
|
|
const { groupeId } = useStore();
|
|
const [entries, setEntries] = useState([]);
|
|
const [detailGroupe, setDetailGroupe] = useState(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
api.get('/calendrier/').then((data) => {
|
|
setEntries(data);
|
|
setLoading(false);
|
|
}).catch(() => setLoading(false));
|
|
}, []);
|
|
|
|
// Grouper par groupe
|
|
const parGroupe = {};
|
|
entries.forEach((e) => {
|
|
if (!parGroupe[e.groupe_nom]) {
|
|
parGroupe[e.groupe_nom] = { nom: e.groupe_nom, id: e.groupe_id, jour: e.jour_reunion, serviteurs: [] };
|
|
}
|
|
parGroupe[e.groupe_nom].serviteurs.push(e);
|
|
});
|
|
const groupes = Object.values(parGroupe);
|
|
|
|
const voirDetail = async (gId) => {
|
|
try {
|
|
const data = await api.get(`/calendrier/groupe/${gId}`);
|
|
setDetailGroupe(data);
|
|
} catch {}
|
|
};
|
|
|
|
if (detailGroupe) {
|
|
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={() => setDetailGroupe(null)} className="text-2xl active:opacity-60">←</button>
|
|
<div>
|
|
<h1 className="text-lg font-bold">{detailGroupe.groupe?.nom}</h1>
|
|
<p className="text-blue-200 text-xs">
|
|
{detailGroupe.groupe?.jour_reunion ? `Réunion le ${detailGroupe.groupe.jour_reunion}` : 'Calendrier'}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="p-4 space-y-2">
|
|
{detailGroupe.groupe?.adresse && (
|
|
<div className="bg-white rounded-2xl p-4 shadow-sm">
|
|
<p className="text-xs text-gray-400">Adresse</p>
|
|
<p className="text-gray-700">{detailGroupe.groupe.adresse}</p>
|
|
</div>
|
|
)}
|
|
{detailGroupe.serviteurs?.map((s, i) => {
|
|
const cat = CATEGORIES[s.categorie] || CATEGORIES.physique;
|
|
return (
|
|
<div key={i} className="bg-white rounded-2xl p-4 shadow-sm flex items-center justify-between">
|
|
<div>
|
|
<p className="font-bold text-gray-800">{s.poste}</p>
|
|
<p className="text-sm text-gray-500">{s.prenom}</p>
|
|
</div>
|
|
<span className={`text-xs px-2 py-1 rounded-full font-bold ${cat.bg} ${cat.text}`}>
|
|
{cat.label}
|
|
</span>
|
|
</div>
|
|
);
|
|
})}
|
|
{(!detailGroupe.serviteurs || detailGroupe.serviteurs.length === 0) && (
|
|
<p className="text-center text-gray-400 py-8">Aucun serviteur assigné</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-100">
|
|
<PageHeader titre="Calendrier district" sousTitre="C2 — Serviteurs du district 87-16" />
|
|
|
|
<div className="p-4 space-y-4">
|
|
{loading ? (
|
|
<p className="text-center text-gray-400 py-8">Chargement...</p>
|
|
) : groupes.length === 0 ? (
|
|
<div className="text-center py-12">
|
|
<p className="text-4xl mb-2">📅</p>
|
|
<p className="text-gray-500">Aucune donnée de calendrier</p>
|
|
</div>
|
|
) : (
|
|
groupes.map((g) => {
|
|
const isMon = g.id === groupeId;
|
|
return (
|
|
<button
|
|
key={g.id}
|
|
onClick={() => voirDetail(g.id)}
|
|
className={`w-full text-left rounded-2xl p-4 shadow-sm active:scale-[0.98] transition ${
|
|
isMon ? 'bg-blue-50 border-2 border-blue-300' : 'bg-white border border-gray-100'
|
|
}`}
|
|
>
|
|
<div className="flex items-center justify-between mb-2">
|
|
<div className="flex items-center gap-2">
|
|
{isMon && <span className="text-yellow-500">⭐</span>}
|
|
<h3 className="font-bold text-gray-800">{g.nom}</h3>
|
|
</div>
|
|
<span className="text-gray-300 text-lg">→</span>
|
|
</div>
|
|
{g.jour && (
|
|
<p className="text-xs text-gray-400 mb-2">Réunion le {g.jour}</p>
|
|
)}
|
|
<div className="flex flex-wrap gap-1">
|
|
{g.serviteurs.slice(0, 4).map((s, i) => (
|
|
<span key={i} className="text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded-full">
|
|
{s.poste_nom}: {s.membre_prenom}
|
|
</span>
|
|
))}
|
|
{g.serviteurs.length > 4 && (
|
|
<span className="text-xs text-gray-400 px-2 py-1">+{g.serviteurs.length - 4}</span>
|
|
)}
|
|
</div>
|
|
</button>
|
|
);
|
|
})
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|