<?php require_once '../includes/config.php'; require_once '../includes/auth.php'; // Vérification de l'authentification if (!Auth::check()) { header('Location: login.php'); exit; } // Vérification des privilèges administrateur (premier utilisateur uniquement) if (!Auth::isAdmin()) { header('Location: index.php'); exit; } $success = ''; $error = ''; // Traitement de l'ajout ou modification d'un utilisateur if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { try { $config = Config::load(); // Traitement selon l'action switch ($_POST['action']) { case 'add': // Validation $userId = trim($_POST['user_id'] ?? ''); $password = $_POST['password'] ?? ''; $confirmPassword = $_POST['confirm_password'] ?? ''; $comment = trim($_POST['comment'] ?? ''); $role = $_POST['role'] ?? 'editor'; if (strlen($userId) < 3) { throw new Exception('L\'identifiant doit faire au moins 3 caractères'); } if (strlen($password) < 8) { throw new Exception('Le mot de passe doit faire au moins 8 caractères'); } if ($password !== $confirmPassword) { throw new Exception('Les mots de passe ne correspondent pas'); } // Vérification de l'unicité de l'identifiant foreach ($config['users'] as $user) { if ($user['id'] === $userId) { throw new Exception('Cet identifiant est déjà utilisé'); } } // Ajout de l'utilisateur $config['users'][] = [ 'id' => $userId, 'password' => password_hash($password, PASSWORD_DEFAULT), 'role' => $role, 'comment' => $comment ]; $success = 'Utilisateur ajouté avec succès'; break; case 'edit': // Validation $userId = trim($_POST['user_id'] ?? ''); $newUserId = trim($_POST['new_user_id'] ?? ''); $password = $_POST['password'] ?? ''; $comment = trim($_POST['comment'] ?? ''); $role = $_POST['role'] ?? 'editor'; if ($newUserId && strlen($newUserId) < 3) { throw new Exception('Le nouvel identifiant doit faire au moins 3 caractères'); } if ($password && strlen($password) < 8) { throw new Exception('Le mot de passe doit faire au moins 8 caractères'); } // Recherche de l'utilisateur à modifier $userFound = false; foreach ($config['users'] as &$user) { if ($user['id'] === $userId) { // Vérification que le premier compte ne perde pas ses privilèges admin if ($user === reset($config['users']) && $role !== 'admin') { throw new Exception('Le premier compte doit conserver le rôle d\'administrateur'); } // Mise à jour des informations if ($newUserId && $newUserId !== $userId) { // Vérification de l'unicité du nouvel identifiant foreach ($config['users'] as $existingUser) { if ($existingUser['id'] === $newUserId) { throw new Exception('Ce nouvel identifiant est déjà utilisé'); } } $user['id'] = $newUserId; } if ($password) { $user['password'] = password_hash($password, PASSWORD_DEFAULT); } $user['comment'] = $comment; $user['role'] = $role; $userFound = true; break; } } if (!$userFound) { throw new Exception('Utilisateur non trouvé'); } $success = 'Utilisateur modifié avec succès'; break; case 'delete': // Validation $userId = trim($_POST['user_id'] ?? ''); // Empêcher la suppression du premier utilisateur if ($userId === reset($config['users'])['id']) { throw new Exception('Le compte administrateur principal ne peut pas être supprimé'); } // Recherche et suppression de l'utilisateur $userIndex = -1; foreach ($config['users'] as $index => $user) { if ($user['id'] === $userId) { $userIndex = $index; break; } } if ($userIndex === -1) { throw new Exception('Utilisateur non trouvé'); } array_splice($config['users'], $userIndex, 1); $success = 'Utilisateur supprimé avec succès'; break; } // Sauvegarde de la configuration Config::save($config); } catch (Exception $e) { $error = $e->getMessage(); } } // Chargement de la configuration $config = Config::load(); ?> <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Gestion des utilisateurs - Administration</title> <?php if (file_exists(__DIR__ . '/../assets/images/site/favicon.png')): ?> <link rel="icon" type="image/png" href="../assets/images/site/favicon.png"> <?php endif; ?> <link rel="stylesheet" href="../assets/css/main.css"> </head> <body> <nav class="admin-nav"> <div class="nav-brand"> <?php if (!empty($config['site']['logo'])): ?> <img src="<?= htmlspecialchars('../' . $config['site']['logo']) ?>" alt="<?= htmlspecialchars($config['site']['name']) ?>"> <?php endif; ?> <span>Administration</span> </div> <div class="nav-menu"> <a href="index.php" class="button tooltip" data-tooltip="Retour"> <i class="fas fa-arrow-left"></i> </a> </div> </nav> <main class="admin-main"> <h1>Gestion des utilisateurs</h1> <?php if ($success): ?> <div class="success-message"><?= htmlspecialchars($success) ?></div> <?php endif; ?> <?php if ($error): ?> <div class="error-message"><?= htmlspecialchars($error) ?></div> <?php endif; ?> <!-- Liste des utilisateurs existants --> <section class="users-section"> <h2>Utilisateurs existants</h2> <div class="users-list"> <?php foreach ($config['users'] as $index => $user): ?> <div class="user-item <?= $index === 0 ? 'admin-user' : '' ?>"> <div class="user-info"> <h3><?= htmlspecialchars($user['id']) ?></h3> <p class="user-role"> Rôle : <span><?= htmlspecialchars($user['role'] ?? 'editor') ?></span> </p> <?php if (!empty($user['comment'])): ?> <p class="user-comment"><?= htmlspecialchars($user['comment']) ?></p> <?php endif; ?> </div> <div class="user-actions"> <button type="button" class="button tooltip edit-user" data-tooltip="Modifier" data-user-id="<?= htmlspecialchars($user['id']) ?>" data-user-comment="<?= htmlspecialchars($user['comment'] ?? '') ?>" data-user-role="<?= htmlspecialchars($user['role'] ?? 'editor') ?>"> <i class="fas fa-edit"></i> </button> <?php if ($index !== 0): ?> <button type="button" class="button tooltip delete-user" data-tooltip="Supprimer" data-user-id="<?= htmlspecialchars($user['id']) ?>"> <i class="fas fa-trash-alt"></i> </button> <?php endif; ?> </div> </div> <?php endforeach; ?> </div> <button type="button" id="addUserBtn" class="button tooltip" data-tooltip="Ajouter un utilisateur"> <i class="fas fa-user-plus"></i> <span class="tooltip-text">Ajouter un utilisateur</span> </button> </section> <!-- Formulaire d'ajout d'utilisateur (modal) --> <div id="addUserModal" class="modal"> <div class="modal-content"> <div class="modal-header"> <h2>Ajouter un utilisateur</h2> </div> <form method="POST" id="addUserForm"> <input type="hidden" name="action" value="add"> <div class="form-group"> <label for="user_id">Identifiant</label> <input type="text" id="user_id" name="user_id" required minlength="3"> </div> <div class="form-group"> <label for="password">Mot de passe</label> <input type="password" id="password" name="password" required minlength="8"> </div> <div class="form-group"> <label for="confirm_password">Confirmation du mot de passe</label> <input type="password" id="confirm_password" name="confirm_password" required> </div> <div class="form-group"> <label for="role">Rôle</label> <select id="role" name="role"> <option value="editor">Éditeur</option> <option value="admin">Administrateur</option> </select> </div> <div class="form-group"> <label for="comment">Commentaire (optionnel)</label> <textarea id="comment" name="comment" rows="3"></textarea> </div> <div class="modal-footer"> <button type="button" class="button dark cancel-btn">Annuler</button> <button type="submit" class="button">Ajouter</button> </div> </form> </div> </div> <!-- Formulaire d'édition d'utilisateur (modal) --> <div id="editUserModal" class="modal"> <div class="modal-content"> <div class="modal-header"> <h2>Modifier un utilisateur</h2> </div> <form method="POST" id="editUserForm"> <input type="hidden" name="action" value="edit"> <input type="hidden" id="edit_user_id" name="user_id"> <div class="form-group"> <label for="new_user_id">Nouvel identifiant (laisser vide pour ne pas modifier)</label> <input type="text" id="new_user_id" name="new_user_id" minlength="3"> </div> <div class="form-group"> <label for="edit_password">Nouveau mot de passe (laisser vide pour ne pas modifier)</label> <input type="password" id="edit_password" name="password" minlength="8"> </div> <div class="form-group"> <label for="edit_role">Rôle</label> <select id="edit_role" name="role"> <option value="editor">Éditeur</option> <option value="admin">Administrateur</option> </select> </div> <div class="form-group"> <label for="edit_comment">Commentaire</label> <textarea id="edit_comment" name="comment" rows="3"></textarea> </div> <div class="modal-footer"> <button type="button" class="button dark cancel-btn"> <i class="fas fa-times"></i> <span class="button-text">Annuler</span> </button> <button type="submit" class="button"> <i class="fas fa-save"></i> <span class="button-text">Enregistrer</span> </button> </div> </form> </div> </div> <!-- Formulaire de suppression (caché) --> <form id="deleteUserForm" method="POST" style="display: none;"> <input type="hidden" name="action" value="delete"> <input type="hidden" id="delete_user_id" name="user_id"> </form> </main> <script> document.addEventListener('DOMContentLoaded', function() { // Gestion des modales const addUserModal = document.getElementById('addUserModal'); const editUserModal = document.getElementById('editUserModal'); // Boutons d'ouverture des modales const addUserBtn = document.getElementById('addUserBtn'); // Boutons de fermeture des modales const cancelBtns = document.querySelectorAll('.cancel-btn'); // Ouverture de la modale d'ajout addUserBtn.addEventListener('click', function() { addUserModal.style.display = 'block'; document.getElementById('addUserForm').reset(); }); // Ouverture de la modale d'édition document.querySelectorAll('.edit-user').forEach(button => { button.addEventListener('click', function() { const userId = this.dataset.userId; const userComment = this.dataset.userComment; const userRole = this.dataset.userRole; document.getElementById('edit_user_id').value = userId; document.getElementById('new_user_id').value = ''; document.getElementById('edit_password').value = ''; document.getElementById('edit_comment').value = userComment; // Sélectionner la bonne option dans le select const roleSelect = document.getElementById('edit_role'); for (let i = 0; i < roleSelect.options.length; i++) { if (roleSelect.options[i].value === userRole) { roleSelect.selectedIndex = i; break; } } // Si c'est le premier utilisateur, désactiver le changement de rôle if (userId === '<?= htmlspecialchars(reset($config['users'])['id']) ?>') { roleSelect.disabled = true; } else { roleSelect.disabled = false; } editUserModal.style.display = 'block'; }); }); // Fermeture des modales avec les boutons Annuler cancelBtns.forEach(button => { button.addEventListener('click', function() { addUserModal.style.display = 'none'; editUserModal.style.display = 'none'; }); }); // Fermeture des modales en cliquant à l'extérieur window.addEventListener('click', function(event) { if (event.target === addUserModal) { addUserModal.style.display = 'none'; } else if (event.target === editUserModal) { editUserModal.style.display = 'none'; } }); // Validation du formulaire d'ajout document.getElementById('addUserForm').addEventListener('submit', function(e) { const password = document.getElementById('password').value; const confirmPassword = document.getElementById('confirm_password').value; if (password !== confirmPassword) { e.preventDefault(); alert('Les mots de passe ne correspondent pas'); } }); // Suppression d'un utilisateur document.querySelectorAll('.delete-user').forEach(button => { button.addEventListener('click', function() { const userId = this.dataset.userId; confirmDialog.show({ title: 'Suppression d\'utilisateur', message: `Voulez-vous vraiment supprimer l'utilisateur "${userId}" ? Cette action est irréversible.`, confirmText: 'Supprimer', confirmClass: 'danger', onConfirm: () => { document.getElementById('delete_user_id').value = userId; document.getElementById('deleteUserForm').submit(); } }); }); }); }); </script> <link rel="stylesheet" href="../assets/css/dialog.css"> <script src="../assets/js/dialog.js"></script> <style> /* Styles spécifiques à la page utilisateurs */ .users-list { display: flex; flex-direction: column; gap: var(--spacing-md); margin: var(--spacing-lg) 0; } .user-item { background: var(--bg-tertiary); padding: var(--spacing-lg); border-radius: var(--radius-md); border: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: center; } .user-item.admin-user { background: linear-gradient(135deg, var(--bg-tertiary), #57433a); position: relative; } .user-item.admin-user::after { content: 'Admin principal'; position: absolute; top: 0.5rem; right: 0.5rem; background: var(--accent-primary); color: var(--text-tertiary); padding: 0.2rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.8rem; } .user-info h3 { margin: 0 0 var(--spacing-xs) 0; color: var(--text-primary); } .user-role { color: var(--text-secondary); margin: 0 0 var(--spacing-xs) 0; } .user-role span { color: var(--accent-primary); } .user-comment { font-style: italic; color: var(--text-secondary); margin: 0; font-size: 0.9rem; } .user-actions { display: flex; gap: var(--spacing-sm); } .user-actions .button { padding: var(--spacing-sm) var(--spacing-md); } .delete-user { background-color: var(--bg-secondary); } .delete-user:hover { background-color: var(--error-color); } /* Responsiveness */ @media (max-width: 768px) { .user-item { flex-direction: column; align-items: stretch; } .user-actions { margin-top: var(--spacing-md); justify-content: flex-end; } .modal-content { width: 95%; max-width: 600px; height: auto; max-height: 90vh; overflow-y: auto; } } </style> </body> </html>