Angelicahg
Gamma
Verificado
Verificación en dos pasos activada
Verificado por Whatsapp
Verificado por Binance
		Hola, estoy haciendo una web como de prueba, aprendiendo. Y estoy bastante avanzada, pero estoy estancada en una opcion de Eliminar Usuarios masivamente.
Tengo una lista de usuarios que, selecciono todos y el boton de eliminar seleccionados no sirve (Si sirve, eliminar uno por uno) pero eliminar masivamente no.
		
	
		
	
Aquí mis codigos:
usuarios.js
	
	
	
		
eliminar_masivo.php
	
	
	
		
usuarios.php
	
	
	
		
Cabe destacatar que no me deja hacer clic en el boton "Eliminar Seleccionados", asi que no se si eliminan masivamente o no, pq aja no deja hacer la accion no se si me explico, ya intente solucionarlo tambien con chatgpt pero cada vez me arruina más 🤣, si alguien sabe se lo agradezco tengo 2 dias en esto y no he avanzando nada mas por esa funcion
	
		
			
		
		
	
				
			Tengo una lista de usuarios que, selecciono todos y el boton de eliminar seleccionados no sirve (Si sirve, eliminar uno por uno) pero eliminar masivamente no.
Aquí mis codigos:
usuarios.js
		JavaScript:
	
	document.addEventListener('DOMContentLoaded', () => {
  // Obtener el token CSRF desde el meta tag
  const csrf_token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
 
  const createPopup = document.getElementById("create-user-popup");
  const editPopup = document.getElementById("edit-user-popup");
  const overlay = document.getElementById("popup-overlay");
  // Abrir popup de crear usuario
  document.getElementById("create-user-btn")?.addEventListener("click", () => {
    createPopup.style.display = "flex";
    overlay.style.display = "block";
  });
  // Cerrar popups al hacer clic en el overlay
  overlay?.addEventListener('click', (e) => {
    if (e.target === overlay) {
      closeAllPopups();
    }
  });
  // Botón de cerrar popup tipo "–"
  document.querySelectorAll(".close-popup")?.forEach(btn => {
    btn.addEventListener("click", () => {
      closeAllPopups();
    });
  });
  function closeAllPopups() {
    createPopup.style.display = "none";
    editPopup.style.display = "none";
    overlay.style.display = "none";
  }
  // Mostrar/ocultar contraseña (crear)
  document.getElementById("mostrar-password")?.addEventListener("click", () => {
    const input = document.getElementById("password");
    const icon = document.querySelector("#mostrar-password i");
    input.type = input.type === "password" ? "text" : "password";
    icon.classList.toggle("fa-eye");
    icon.classList.toggle("fa-eye-slash");
  });
  // Generar contraseña (crear)
  document.getElementById("generar-password")?.addEventListener("click", () => {
    const input = document.getElementById("password");
    const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&";
    input.value = Array.from({ length: 10 }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
  });
  // Abrir popup de editar usuario
  document.querySelectorAll('.editar-usuario-btn').forEach(btn => {
    btn.addEventListener("click", async (e) => {
      const id = e.currentTarget.dataset.id;
      try {
        const res = await fetch(`controllers/obtener_usuario.php?id=${id}`);
        const usuario = await res.json();
        document.getElementById("edit_usuario_id").value = usuario.id;
        document.getElementById("edit_username").value = usuario.username;
        document.getElementById("edit_password").value = "";
        document.getElementById("edit_rol").value = usuario.role;
        editPopup.style.display = "flex";
        overlay.style.display = "block";
      } catch (error) {
        mostrarSnackbar("❌ Error al cargar usuario", "error");
        console.error(error);
      }
    });
  });
  // Form crear usuario
  document.getElementById("form-crear-usuario")?.addEventListener("submit", async (e) => {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    try {
      const response = await fetch('controllers/crear_usuario.php', {
        method: "POST",
        body: formData,
      });
      const result = await response.json();
      if (result.success) {
        mostrarSnackbar(result.message || "✅ Usuario creado correctamente");
        closeAllPopups();
        form.reset();
        location.reload();
      } else {
        mostrarSnackbar(result.message || "⚠️ Algo salió mal", "error");
      }
    } catch (err) {
      mostrarSnackbar("❌ Error en el servidor", "error");
      console.error(err);
    }
  });
  // Form editar usuario
  document.getElementById("form-editar-usuario")?.addEventListener("submit", async (e) => {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    try {
      const response = await fetch('controllers/editar_usuario.php', {
        method: "POST",
        body: formData,
      });
      const result = await response.json();
      if (result.success) {
        mostrarSnackbar(result.message || "✅ Usuario actualizado");
        closeAllPopups();
        form.reset();
        location.reload();
      } else {
        mostrarSnackbar(result.message || "⚠️ Algo salió mal", "error");
      }
    } catch (err) {
      mostrarSnackbar("❌ Error en el servidor", "error");
      console.error(err);
    }
  });
  // Cambiar rol
  document.querySelectorAll('.select-rol').forEach(select => {
    select.addEventListener('change', async (e) => {
      const userId = e.target.dataset.id;
      const nuevoRol = e.target.value;
      try {
        const response = await fetch('controllers/cambiar_rol.php', {
          method: 'POST',
          body: new URLSearchParams({ id: userId, rol: nuevoRol })
        });
        const result = await response.json();
        if (result.success) {
          mostrarSnackbar("✅ Rol actualizado");
        } else {
          mostrarSnackbar("⚠️ No se pudo actualizar el rol", "error");
        }
      } catch (err) {
        mostrarSnackbar("❌ Error al actualizar", "error");
      }
    });
  });
 
  // Selección múltiple
  const checkboxes = document.querySelectorAll('.checkbox-usuario');
  const barraAcciones = document.querySelector('.acciones-masivas');
  function actualizarAcciones() {
    const seleccionados = [...checkboxes].filter(c => c.checked);
    const cantidad = seleccionados.length;
    barraAcciones.style.display = cantidad > 1 ? 'flex' : 'none';
    document.querySelectorAll('.tarjeta-usuario').forEach(tarjeta => {
      const cb = tarjeta.querySelector('.checkbox-usuario');
      const acciones = tarjeta.querySelector('.acciones-usuario');
      if (cb.checked) {
        tarjeta.classList.add('seleccionado');
        acciones.style.display = cantidad === 1 ? 'flex' : 'none';
      } else {
        tarjeta.classList.remove('seleccionado');
        acciones.style.display = 'none';
      }
    });
  }
  checkboxes.forEach(cb => {
    cb.addEventListener('change', actualizarAcciones);
  });
 
  // Eliminar usuarios
  document.querySelectorAll('.eliminar-usuario-btn').forEach(btn => {
    btn.addEventListener('click', async (e) => {
      e.preventDefault();  // Prevenir la acción por defecto
      const id = btn.dataset.id;
      console.log("ID del usuario a eliminar:", id); // Verifica si el ID es correcto
      if (confirm("¿Eliminar este usuario?")) {
        try {
          // Enviar la solicitud AJAX
          const res = await fetch('controllers/eliminar_usuario.php?id=' + id + '&token=' + csrf_token, {
            method: "GET",
          });
          const result = await res.json();  // Obtener respuesta JSON
          console.log(result);  // Verifica la respuesta de eliminación
          if (result.success) {
            mostrarSnackbar(result.message, 'success');  // Mostrar mensaje de éxito
            btn.closest('.tarjeta-usuario').remove();  // Eliminar el usuario de la interfaz
          } else {
            mostrarSnackbar(result.message, 'error');  // Mostrar mensaje de error
          }
        } catch (err) {
          mostrarSnackbar("❌ Error al eliminar", 'error');  // Mostrar mensaje de error si ocurre un fallo
          console.error(err);
        }
      }
    });
  });
 
  //Eliminar masivo
  document.addEventListener('DOMContentLoaded', () => {
    const checkboxes = document.querySelectorAll('.checkbox-usuario');
    const barraAcciones = document.querySelector('.acciones-masivas');
    const btnEliminarSeleccionados = document.getElementById('btnEliminarSeleccionados');
    const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
    // Función para actualizar la visibilidad de las acciones masivas
    function actualizarAcciones() {
        const seleccionados = [...checkboxes].filter(c => c.checked);
        const cantidad = seleccionados.length;
        // Mostrar u ocultar la barra de acciones masivas
        barraAcciones.style.display = cantidad > 0 ? 'flex' : 'none';
    }
    // Evento de selección de checkboxes
    checkboxes.forEach(checkbox => {
        checkbox.addEventListener('change', actualizarAcciones);
    });
    // Función para eliminar los usuarios seleccionados
    btnEliminarSeleccionados.addEventListener('click', () => {
        const seleccionados = [...checkboxes].filter(c => c.checked);
        const idsSeleccionados = seleccionados.map(c => c.dataset.id);
        if (idsSeleccionados.length === 0) {
            alert('Selecciona al menos un usuario para eliminar.');
            return;
        }
        // Realizar la solicitud AJAX para eliminar usuarios
        fetch('<?= BASE_URL ?>wp-content/novu-admin/controllers/eliminar-masivo.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                usuarios: idsSeleccionados,
                csrf_token: csrfToken,
            }),
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                alert(data.success);
                location.reload(); // Recargar la página para actualizar la lista
            } else {
                alert(data.error);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            alert('Hubo un error al eliminar los usuarios.');
        });
    });
});
});
	eliminar_masivo.php
		PHP:
	
	<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../config/db.php';
// Verificar si el CSRF token es válido
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    echo json_encode(['error' => 'Token CSRF inválido']);
    exit;
}
$pdo = DB::connect();
if (!$pdo) {
    die("Error de conexión");
}
if (isset($_POST['usuarios'])) {
    $usuarios = $_POST['usuarios']; // Array con los IDs de los usuarios seleccionados
    
    // Crear una lista de placeholders para los IDs
    $placeholders = implode(',', array_fill(0, count($usuarios), '?'));
    // Preparar la consulta para eliminar los usuarios seleccionados
    $stmt = $pdo->prepare("DELETE FROM users WHERE id IN ($placeholders)");
    
    // Ejecutar la consulta con los IDs de los usuarios seleccionados
    $stmt->execute($usuarios);
    // Verificar si la eliminación fue exitosa
    if ($stmt->rowCount() > 0) {
        echo json_encode(['success' => 'Usuarios eliminados correctamente']);
    } else {
        echo json_encode(['error' => 'No se pudo eliminar ningún usuario']);
    }
} else {
    echo json_encode(['error' => 'No se enviaron usuarios para eliminar']);
}
	usuarios.php
		PHP:
	
	<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../config/db.php';
// Funci贸n para registrar errores en un archivo de log
function log_error($message) {
    $log_file = __DIR__ . '/../logs/error_log.txt';  // Ruta al archivo de log
    $date = date('Y-m-d H:i:s');
    $log_message = "[$date] ERROR: $message" . PHP_EOL;
    file_put_contents($log_file, $log_message, FILE_APPEND);
}
$pdo = DB::connect();
if (!$pdo) {
    log_error('Error de conexi贸n a la base de datos.');
    die("Error de conexi贸n");
}
function obtenerUsuarios() {
    global $pdo;
    $stmt = $pdo->prepare("SELECT id, username, role FROM users");
    $stmt->execute();
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
$usuarios = obtenerUsuarios();
?>
<div class="usuarios-wrapper">
  <div class="usuarios-layout">
  <!-- SIDEBAR IZQUIERDO -->
  <aside class="sidebar-usuarios">
    <div class="sidebar-superior">
      <button id="create-user-btn" class="btn-crear-evento">
        <i class="fa-solid fa-plus"></i> CREAR
      </button>
      <div class="separador-crear"></div>
    </div>
    <div class="sidebar-inferior">
      <nav class="sidebar-nav">
        <a href="#" class="filter-option" data-filter="archivados"><i class="fa-solid fa-inbox"></i> Archivados</a>
        <a href="#" class="filter-option" data-filter="papelera"><i class="fa-solid fa-trash"></i> Papelera</a>
        <a href="#" class="filter-option" data-filter="favoritos"><i class="fa-solid fa-star"></i> Favoritos</a>
      </nav>
    </div>
  </aside>
  <!-- CONTENEDOR PRINCIPAL -->
  <div class="panel-eventos">
    <!-- BARRA DE ACCIONES -->
    <div class="barra-acciones">
      <div class="acciones-izquierda">
        <div class="acciones-masivas" style="display: none;">
          <button id="btnEliminarSeleccionados" class="btn-accion-masiva">
    <i class="fa-solid fa-trash"></i> Eliminar seleccionados
</button>
          <button id="btnFavoritos" class="btn-accion-masiva">
            <i class="fa-solid fa-star"></i> Favoritos
          </button>
        </div>
      </div>
      <div class="acciones-derecha filtros-busqueda">
        <select id="filtroRol">
          <option value="">Todos los roles</option>
          <option value="admin">Administrador</option>
          <option value="cliente">Cliente</option>
        </select>
        <select id="ordenarPor">
          <option value="az">Nombre A-Z</option>
          <option value="za">Nombre Z-A</option>
        </select>
        <div class="input-busqueda">
          <i class="fa-solid fa-magnifying-glass"></i>
          <input type="text" id="buscarUsuario" placeholder="Buscar usuario...">
        </div>
        <button id="resetFiltros" class="btn-reset">
          <i class="fa-solid fa-rotate-right"></i>
        </button>
      </div>
    </div>
    <!-- LISTA DE USUARIOS -->
    <div class="lista-usuarios-card">
      <div class="tarjeta-lista">
        <?php foreach ($usuarios as $usuario): ?>
          <div class="tarjeta-usuario">
            <div class="icono-usuario">
              <input type="checkbox" class="checkbox-usuario" data-id="<?= $usuario['id'] ?>">
              <i class="fa-regular fa-star estrella-favorito" data-id="<?= $usuario['id'] ?>"></i>
              <i class="fa-solid fa-user-circle"></i>
            </div>
            <div class="contenido-usuario">
              <h3><?= htmlspecialchars($usuario['username']) ?></h3>
              <div class="rol-select">
                <label for="rol-<?= $usuario['id'] ?>" class="visually-hidden"></label>
                <select class="select-rol" data-id="<?= $usuario['id'] ?>" id="rol-<?= $usuario['id'] ?>">
                  <option value="admin" <?= $usuario['role'] === 'admin' ? 'selected' : '' ?>>Administrador</option>
                  <option value="cliente" <?= $usuario['role'] === 'cliente' ? 'selected' : '' ?>>Cliente</option>
                </select>
              </div>
            </div>
            <div class="acciones-usuario">
              <button class="btn editar-usuario-btn" data-id="<?= $usuario['id'] ?>" title="Editar">
                <i class="fa-solid fa-pen-to-square"></i>
              </button>
              <button class="btn eliminar-usuario-btn" data-id="<?= $usuario['id'] ?>" title="Eliminar">
                <i class="fa-solid fa-trash-can"></i>
              </button>
            </div>
          </div>
        <?php endforeach; ?>
      </div>
    </div>
  </div>
</div>
<!-- Agregar el CSRF Token en meta tag -->
<meta name="csrf-token" content="<?= $_SESSION['csrf_token']; ?>"> <!-- Asegúrate de que esto esté en el <head> -->
<!-- POPUPS -->
<?php
  if (file_exists(__DIR__ . '/popup-crear-usuario.php')) {
    include __DIR__ . '/popup-crear-usuario.php';
  } else {
    echo "<!-- popup-crear-usuario.php no encontrado -->";
  }
  if (file_exists(__DIR__ . '/popup-editar-usuario.php')) {
    include __DIR__ . '/popup-editar-usuario.php';
  } else {
    echo "<!-- popup-editar-usuario.php no encontrado -->";
  }
?>
<!-- OVERLAY GLOBAL -->
<div id="popup-overlay" class="popup-overlay" style="display: none;"></div>
<div id="snackbar-container"></div>
<!-- JS -->
<script src="<?= BASE_URL ?>wp-content/novu-admin/public/assets/js/global.js"></script>
<script src="<?= BASE_URL ?>wp-content/novu-admin/public/assets/js/escritorio/usuarios.js"></script>
	Cabe destacatar que no me deja hacer clic en el boton "Eliminar Seleccionados", asi que no se si eliminan masivamente o no, pq aja no deja hacer la accion no se si me explico, ya intente solucionarlo tambien con chatgpt pero cada vez me arruina más 🤣, si alguien sabe se lo agradezco tengo 2 dias en esto y no he avanzando nada mas por esa funcion