Files
Front-DataSentinel/DataSentinel/src/pages/Admin/Admin.jsx
T
2026-05-20 10:43:18 +02:00

230 lines
7.0 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// src/pages/Admin/Admin.jsx
// Page Administration : onglets pour gérer monitorings, services, catégories, contacts
import { useState, useEffect } 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 styles from './Admin.module.css';
/* Modale générique pour ajouter/modifier */
function Modal({ isOpen, onClose, title, children }) {
if (!isOpen) return null;
return (
<div className={styles.modalOverlay} onClick={onClose}>
<div className={styles.modal} onClick={e => e.stopPropagation()}>
<div className={styles.modalHeader}>
<h2>{title}</h2>
<button className={styles.closeBtn} onClick={onClose}>×</button>
</div>
<div className={styles.modalBody}>
{children}
</div>
</div>
</div>
);
}
export default function Admin() {
const [activeTab, setActiveTab] = useState('monitorings');
const [data, setData] = useState({});
const [loading, setLoading] = useState(true);
const [erreur, setErreur] = useState('');
const [modalOpen, setModalOpen] = useState(false);
const [editingItem, setEditingItem] = useState(null);
useEffect(() => {
async function loadData() {
setLoading(true);
setErreur('');
try {
const [monitorings, services, categories, contacts] = await Promise.all([
getMonitorings(),
getServices(),
getCategories(),
getContacts()
]);
setData({
monitorings: Array.isArray(monitorings) ? monitorings : [],
services: Array.isArray(services) ? services : [],
categories: Array.isArray(categories) ? categories : [],
contacts: Array.isArray(contacts) ? contacts : []
});
} catch (e) {
setErreur(e.message || 'Erreur lors du chargement des données administratives.');
} finally {
setLoading(false);
}
}
loadData();
}, []);
function handleAdd() {
setEditingItem(null);
setModalOpen(true);
}
function handleEdit(item) {
setEditingItem(item);
setModalOpen(true);
}
function handleDelete(item) {
// Simulation de suppression (pas d'API pour ça)
console.log('Supprimer', item);
}
const tabs = [
{ key: 'monitorings', label: 'Monitorings' },
{ key: 'services', label: 'Services' },
{ key: 'categories', label: 'Catégories' },
{ key: 'contacts', label: 'Contacts' }
];
const columns = {
monitorings: [
{ key: 'monito_intitule', label: 'Nom' },
{ key: 'id_service', label: 'Service' },
{ key: 'id_categorie', label: 'Catégorie' },
{ key: 'bdd_source', label: 'Source' },
{ key: 'table_source', label: 'Table' },
{
key: 'actions',
label: 'Actions',
render: (val, row) => (
<div className={styles.actions}>
<button className={styles.actionBtn} onClick={() => handleEdit(row)}>
<Edit size={14} />
Modifier
</button>
<button className={styles.actionBtn} onClick={() => handleDelete(row)}>
<Trash2 size={14} />
Désactiver
</button>
</div>
)
}
],
services: [
{ key: 'nom_service', label: 'Nom' },
{
key: 'actions',
label: 'Actions',
render: (val, row) => (
<div className={styles.actions}>
<button className={styles.actionBtn} onClick={() => handleEdit(row)}>
<Edit size={14} />
Modifier
</button>
<button className={styles.actionBtn} onClick={() => handleDelete(row)}>
<Trash2 size={14} />
Désactiver
</button>
</div>
)
}
],
categories: [
{ key: 'intitule_categorie', label: 'Nom' },
{
key: 'actions',
label: 'Actions',
render: (val, row) => (
<div className={styles.actions}>
<button className={styles.actionBtn} onClick={() => handleEdit(row)}>
<Edit size={14} />
Modifier
</button>
<button className={styles.actionBtn} onClick={() => handleDelete(row)}>
<Trash2 size={14} />
Désactiver
</button>
</div>
)
}
],
contacts: [
{ key: 'intitule_contact', label: 'Intitulé' },
{ key: 'nom', label: 'Nom' },
{ key: 'prenom', label: 'Prénom' },
{ key: 'mail', label: 'Email' },
{ key: 'id_service', label: 'Service' },
{
key: 'actions',
label: 'Actions',
render: (val, row) => (
<div className={styles.actions}>
<button className={styles.actionBtn} onClick={() => handleEdit(row)}>
<Edit size={14} />
Modifier
</button>
<button className={styles.actionBtn} onClick={() => handleDelete(row)}>
<Trash2 size={14} />
Désactiver
</button>
</div>
)
}
]
};
if (loading) return <LoadingSpinner message="Chargement des données administratives..." />;
if (erreur) return <ErrorMessage message={erreur} />;
return (
<div className={styles.page}>
<h1 className={styles.title}>Administration</h1>
{/* Onglets */}
<div className={styles.tabs}>
{tabs.map(tab => (
<button
key={tab.key}
className={`${styles.tab} ${activeTab === tab.key ? styles.active : ''}`}
onClick={() => setActiveTab(tab.key)}
>
{tab.label}
</button>
))}
</div>
{/* Contenu de l'onglet actif */}
<div className={styles.tabContent}>
<div className={styles.header}>
<h2>{tabs.find(t => t.key === activeTab)?.label}</h2>
<Button variant="primary" onClick={handleAdd}>
<Plus size={14} />
Ajouter
</Button>
</div>
<DataTable
columns={columns[activeTab]}
data={data[activeTab] || []}
pageSize={50}
emptyMessage={`Aucun ${activeTab.slice(0, -1)} trouvé.`}
/>
</div>
{/* Modale */}
<Modal
isOpen={modalOpen}
onClose={() => setModalOpen(false)}
title={`${editingItem ? 'Modifier' : 'Ajouter'} ${tabs.find(t => t.key === activeTab)?.label.slice(0, -1)}`}
>
<p>Formulaire à implémenter selon les besoins.</p>
<div className={styles.modalActions}>
<Button variant="secondary" onClick={() => setModalOpen(false)}>
Annuler
</Button>
<Button variant="primary" onClick={() => setModalOpen(false)}>
Enregistrer
</Button>
</div>
</Modal>
</div>
);
}