// src/pages/Users/Users.jsx // Page Utilisateurs : gestion réelle des utilisateurs via l'API admin import { useState, useEffect, useCallback } from 'react'; import { Plus, Edit, Trash2, KeyRound } from 'lucide-react'; import DataTable from '../../components/common/DataTable'; import Button from '../../components/common/Button'; import LoadingSpinner from '../../components/common/LoadingSpinner'; import ErrorMessage from '../../components/common/ErrorMessage'; import { getUsers, createUser, updateUser, deleteUser, resetUserPassword, } from '../../services/api'; import styles from './Users.module.css'; /* Rôles disponibles côté backend */ const ROLES = ['Admin', 'Superviseur', 'Consultant']; export default function Users() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [erreur, setErreur] = useState(''); /* Modale active : 'create' | 'edit' | 'reset' | null */ const [modal, setModal] = useState(null); const [selected, setSelected] = useState(null); const [form, setForm] = useState({}); const [formError, setFormError] = useState(''); const [submitting, setSubmitting] = useState(false); const charger = useCallback(async () => { setLoading(true); setErreur(''); try { const data = await getUsers(); setUsers(Array.isArray(data) ? data : []); } catch (e) { setErreur(e.message || 'Erreur lors du chargement des utilisateurs.'); } finally { setLoading(false); } }, []); /* Chargement initial. Le drapeau `annule` évite d'écrire dans un composant déjà démonté si l'utilisateur quitte la page pendant la requête. */ useEffect(() => { let annule = false; async function chargerAuMontage() { try { const data = await getUsers(); if (!annule) setUsers(Array.isArray(data) ? data : []); } catch (e) { if (!annule) setErreur(e.message || 'Erreur lors du chargement des utilisateurs.'); } finally { if (!annule) setLoading(false); } } chargerAuMontage(); return () => { annule = true; }; }, []); /* Ouverture des modales */ function ouvrirCreation() { setSelected(null); setForm({ username: '', email: '', password: '', role: 'Consultant' }); setFormError(''); setModal('create'); } function ouvrirEdition(user) { setSelected(user); setForm({ email: user.email ?? '', role: user.role ?? 'Consultant', actif: !!user.actif }); setFormError(''); setModal('edit'); } function ouvrirReset(user) { setSelected(user); setForm({ password: '' }); setFormError(''); setModal('reset'); } function fermerModale() { setModal(null); setSelected(null); setForm({}); setFormError(''); } /* Suppression (soft delete) avec confirmation */ async function handleDelete(user) { if (!window.confirm(`Désactiver l'utilisateur "${user.username}" ?`)) { return; } try { await deleteUser(user.id_user); await charger(); } catch (e) { setErreur(e.message || 'Erreur lors de la suppression.'); } } /* Soumission de la modale courante */ async function handleSubmit(e) { e.preventDefault(); setFormError(''); setSubmitting(true); try { if (modal === 'create') { await createUser({ username: form.username, email: form.email, password: form.password, role: form.role, }); } else if (modal === 'edit') { await updateUser(selected.id_user, { email: form.email, role: form.role, actif: form.actif, }); } else if (modal === 'reset') { await resetUserPassword(selected.id_user, form.password); } fermerModale(); await charger(); } catch (e) { setFormError(e.message || 'Une erreur est survenue.'); } finally { setSubmitting(false); } } const columns = [ { key: 'username', label: 'Identifiant' }, { key: 'email', label: 'Email' }, { key: 'role', label: 'Rôle' }, { key: 'actif', label: 'Statut', render: (val) => (val ? 'Actif' : 'Inactif'), }, { key: 'actions', label: 'Actions', render: (val, row) => (