// src/pages/Admin/Admin.jsx // Page Administration : CRUD sur les référentiels (monitorings, services, // catégories, contacts). Réservée au rôle Admin côté API. import { useState, useEffect, useCallback } from 'react'; import { Plus, Edit, Trash2 } from 'lucide-react'; import { getMonitorings, getServices, getCategories, getContacts } from '../../services/api'; import DataTable from '../../components/common/DataTable'; import LoadingSpinner from '../../components/common/LoadingSpinner'; import ErrorMessage from '../../components/common/ErrorMessage'; import Button from '../../components/common/Button'; import Modal from '../../components/common/Modal'; import ReferentielForm from './ReferentielForm'; import { REFERENTIELS, LIBELLES_REFERENTIEL } from './referentielsConfig'; import styles from './Admin.module.css'; async function chargerReferentiels() { const [monitorings, services, categories, contacts] = await Promise.all([ getMonitorings(), getServices(), getCategories(), getContacts(), ]); return { monitorings: Array.isArray(monitorings) ? monitorings : [], services: Array.isArray(services) ? services : [], categories: Array.isArray(categories) ? categories : [], contacts: Array.isArray(contacts) ? contacts : [], }; } export default function Admin() { const [ongletActif, setOngletActif] = useState(REFERENTIELS[0].key); const [donnees, setDonnees] = useState({}); const [loading, setLoading] = useState(true); const [erreur, setErreur] = useState(''); const [modaleOuverte, setModaleOuverte] = useState(false); const [elementEnEdition, setElementEnEdition] = useState(null); const recharger = useCallback(async () => { setErreur(''); try { setDonnees(await chargerReferentiels()); } catch (e) { setErreur(e.message || 'Erreur lors du chargement des données administratives.'); } }, []); useEffect(() => { let annule = false; async function chargerAuMontage() { try { const resultat = await chargerReferentiels(); if (!annule) setDonnees(resultat); } catch (e) { if (!annule) setErreur(e.message || 'Erreur lors du chargement des données administratives.'); } finally { if (!annule) setLoading(false); } } chargerAuMontage(); return () => { annule = true; }; }, []); const referentiel = REFERENTIELS.find(r => r.key === ongletActif); function ouvrirCreation() { setElementEnEdition(null); setModaleOuverte(true); } function ouvrirEdition(element) { setElementEnEdition(element); setModaleOuverte(true); } async function handleEnregistrer(corps) { if (elementEnEdition) { await referentiel.modifier(elementEnEdition[referentiel.idField], corps); } else { await referentiel.creer(corps); } setModaleOuverte(false); await recharger(); } async function handleSupprimer(element) { const action = referentiel.suppressionEstDesactivation ? 'Désactiver' : 'Supprimer'; const nom = element[referentiel.colonnes[0].key]; if (!window.confirm(`${action} « ${nom} » ?`)) return; setErreur(''); try { await referentiel.supprimer(element[referentiel.idField]); await recharger(); } catch (e) { setErreur(e.message || 'La suppression a échoué.'); } } /* Affiche le libellé d'un référentiel lié plutôt que son identifiant brut. */ function libelleLie(nomReferentiel, id) { const { idField, labelField } = LIBELLES_REFERENTIEL[nomReferentiel]; const trouve = (donnees[nomReferentiel] || []).find(item => item[idField] === id); return trouve ? trouve[labelField] : id; } const colonnes = [ ...referentiel.colonnes.map(colonne => ({ key: colonne.key, label: colonne.label, render: colonne.referentiel ? val => libelleLie(colonne.referentiel, val) : undefined, })), { key: 'actions', label: 'Actions', render: (val, row) => (