Vinculaciones multi-agencia

This commit is contained in:
2025-06-25 12:38:50 -06:00
parent a830e3a84a
commit c5c698dbe4
62 changed files with 5107 additions and 1454 deletions

View File

@@ -1,11 +1,17 @@
<?php include __DIR__ . '/../partials/sidebar_sistemas.php'; ?>
<?php include __DIR__ . '/../partials/sidebar_administrador.php'; ?>
<html>
<!DOCTYPE html>
<html lang="es">
<head>
<title>Dashboard | Agencia Aduanal</title>
<meta charset="UTF-8">
<title>Dashboard | Administrador</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
@@ -27,12 +33,89 @@
.card { border-radius: 12px; }
.table thead th { background: #343a40; color: #fff; }
</style>
</head>
<body>
<div class="content">
<h4>✅ Agencias Activas</h4>
<h4 class="mb-4">✅ Agencias Activas</h4>
<!-- TABLA DE AGENCIAS -->
<div class="card p-3 shadow-sm">
<div class="table-responsive">
<table class="table table-striped table-hover align-middle" id="tabla-agencias-activas">
<thead>
<tr>
<th>#</th>
<th>Nombre</th>
<th>RFC</th>
<th>Correo</th>
<th>Teléfono</th>
<th>Dirección</th>
<th>Fecha</th>
<th>Administrador</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (!empty($agencias)): ?>
<?php foreach ($agencias as $ag): ?>
<tr>
<td><?= $ag['id_agencia'] ?></td>
<td><?= htmlspecialchars(decrypt($ag['nombre_agencia'])) ?></td>
<td><?= htmlspecialchars($ag['rfc_agencia']) ?></td>
<td><?= htmlspecialchars(decrypt($ag['email'])) ?></td>
<td><?= htmlspecialchars($ag['telefono']) ?></td>
<td><?= htmlspecialchars($ag['direccion']) ?></td>
<td><?= $ag['creado_en'] ? $ag['creado_en']->format('Y-m-d H:i') : '' ?></td>
<td><?= htmlspecialchars($ag['id_administrador']) ?></td>
<td>
<?php if (isset($ag['activo']) && $ag['activo'] == 1): ?>
<a href="/IMPORTADORES/administrador/suspenderAgencia?id=<?= $ag['id_agencia'] ?>&success=1" class="btn btn-sm btn-danger">Suspender</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="8" class="text-center">No hay agencias registradas aún.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('#tabla-agencias-activas').DataTable({
order: [],
language: {
url: 'https://cdn.datatables.net/plug-ins/1.13.4/i18n/es-ES.json'
}
});
});
</script>
<?php if (isset($_GET['success'])): ?>
<script>
<?php if ($_GET['success'] === 'status_deactivated'): ?>
Swal.fire({ icon: 'success', title: 'Usuario desactivado', text: 'El usuario ha sido desactivado correctamente.', confirmButtonColor: '#198754' });
<?php endif; ?>
</script>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<script>
<?php if ($_GET['error'] === 'unauthorized'): ?>
Swal.fire({ icon: 'error', title: 'No autorizado', text: 'No tienes permisos para realizar esta acción.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_id'): ?>
Swal.fire({ icon: 'error', title: 'ID inválido', text: 'El identificador del usuario no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'agencia_not_found'): ?>
Swal.fire({ icon: 'error', title: 'Usuario no encontrado', text: 'No se encontró el usuario especificado.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'update_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al actualizar', text: 'No se pudo actualizar el estado del usuario.', confirmButtonColor: '#dc3545' });
<?php endif; ?>
</script>
<?php endif; ?>
</body>
</html>

View File

@@ -0,0 +1,202 @@
<?php include __DIR__ . '/../partials/sidebar_administrador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Dashboard | Administrador</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
.sidebar .nav-link { font-weight: normal; color: white; transition: all 0.3s ease; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #495057; color: #fff; }
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
.navbar { position: fixed; top: 0; width: 100%; z-index: 1050; }
/* A partir de dispositivos medianos (>=768px), deja espacio lateral */
@media (min-width: 768px) { .content { margin-left: 250px; /* Ancho del sidebar */ } }
/* En móviles, sin margen lateral */
@media (max-width: 767.98px) {
.content { margin-left: 0; }
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
}
.card { border-radius: 12px; }
.table thead th { background: #343a40; color: #fff; }
</style>
</head>
<body>
<!-- 📄 CONTENIDO -->
<div class="content">
<h4 class="mb-4">🏪 Alta de Agencias Aduanales</h4>
<!-- FORMULARIO -->
<div class="card p-4 mb-5 shadow-sm">
<form action="/IMPORTADORES/administrador/guardar_agencia" method="POST" id="formAltaAgencias">
<h5 class="mb-3"> Nueva Agencia Aduanal</h5>
<div class="row g-3">
<div class="col-md-6">
<label for="nombre_agencia" class="form-label">Nombre de la agencia *</label>
<input type="text" class="form-control" name="nombre_agencia" id="nombre_agencia" required>
</div>
<div class="col-md-6">
<label for="rfc_agencia" class="form-label">RFC *</label>
<input type="text" class="form-control" name="rfc_agencia" maxlength="13" id="rfc_agencia" required>
</div>
<div class="col-md-6">
<label for="correo" class="form-label">Correo electrónico *</label>
<input type="email" class="form-control" name="correo" id="correo" required>
</div>
<div class="col-md-6">
<label for="telefono" class="form-label">Teléfono *</label>
<input type="text" class="form-control" name="telefono" maxlength="11" id="telefono" required>
</div>
<div class="col-md-12">
<label for="direccion" class="form-label">Dirección *</label>
<input type="text" class="form-control" name="direccion" id="direccion"
placeholder="Ej: Calle, num.externo, num.interno, colonia, municipio, código postal, estado" required>
</div><hr>
<p><strong>Administrador de la Agencia</strong></p>
<div class="col-md-6">
<label for="nombre_admin" class="form-label">Nombre *</label>
<input type="text" class="form-control" name="nombre_admin" id="nombre_admin" required>
</div>
<div class="col-md-6">
<label for="correo_admin" class="form-label">Correo Administrador *</label>
<input type="email" class="form-control" name="correo_admin" id="correo_admin" required>
</div>
<div class="text-end mt-4">
<button class="btn btn-success px-4">Registrar</button>
</div>
</form>
</div>
</div>
<script>
// Registro de Agencia
document.getElementById('formAltaAgencias').addEventListener('submit', function(e) {
e.preventDefault();
const nombre = document.getElementById('nombre_agencia').value.trim();
const rfc_agencia = document.getElementById('rfc_agencia').value.trim().toUpperCase();
const correo = document.getElementById('correo').value.trim();
const telefono = document.getElementById('telefono').value.trim();
const direccion = document.getElementById('direccion').value.trim();
const nombre_admin = document.getElementById('nombre_admin').value.trim();
const correo_admin = document.getElementById('correo_admin').value.trim();
// Expresiones regulares
const correoRegex = /^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
const rfcRegex = /^[A-ZÑ&]{3,4}\d{6}[A-Z0-9]{3}$/;
const telefonoRegex = /^\d{3}\s\d{7}$/;
// Validación de nombre
if (!nombre) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El nombre es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('nombre_agencia').focus();
return;
}
// Validación de correo
if (!correo) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El correo es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('correo').focus();
return;
}
if (!correoRegex.test(correo)) {
Swal.fire({ icon: 'error', title: 'Correo inválido', text: 'No es una dirección de correo válida.', confirmButtonColor: '#dc3545' });
document.getElementById('correo').focus();
return;
}
// Validación de RFC
if (!rfc_agencia) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El RFC es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('rfc_agencia').focus();
return;
}
if (!rfcRegex.test(rfc_agencia)) {
Swal.fire({ icon: 'error', title: 'RFC inválido', text: 'El RFC debe tener 12 o 13 caracteres con el formato correcto (ej. ABC123456XYZ).', confirmButtonColor: '#dc3545' });
document.getElementById('rfc_agencia').focus();
return;
}
// Validación de teléfono
if (!telefono) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El teléfono es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('telefono').focus();
return;
}
if (!telefonoRegex.test(telefono)) {
Swal.fire({ icon: 'error', title: 'Teléfono inválido', text: 'Debe tener 10 dígitos en el formato: 3 dígitos (LADA), espacio, y 7 dígitos (ej. 123 4567890).', confirmButtonColor: '#dc3545' });
document.getElementById('telefono').focus();
return;
}
// Validación de dirección
if (!direccion) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'La dirección es obligatoria.', confirmButtonColor: '#dc3545' });
document.getElementById('direccion').focus();
return;
}
// Validación de administrador
if (!nombre_admin) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El nombre del administrador es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('nombre_admin').focus();
return;
}
// Validación de correo de administrador
if (!correo_admin) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El correo de administrador es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('correo_admin').focus();
return;
}
if (!correoRegex.test(correo_admin)) {
Swal.fire({ icon: 'error', title: 'Correo inválido', text: 'No es una dirección de correo válida.', confirmButtonColor: '#dc3545' });
document.getElementById('correo_admin').focus();
return;
}
// Si todas las validaciones pasan, el formulario se envía.
this.submit();
});
</script>
<?php if (isset($_GET['success'])): ?>
<script>
<?php if ($_GET['success'] === 'created'): ?>
Swal.fire({ icon: 'success', title: 'Agencia registrada',
text: 'La agencia adunal se ha registrada correctamente y se ha enviado un correo con las credenciales de acceso al administrador.',
confirmButtonColor: '#198754' });
<?php endif; ?>
</script>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<script>
<?php if ($_GET['error'] === 'unauthorized'): ?>
Swal.fire({ icon: 'error', title: 'No autorizado', text: 'No tienes permisos para realizar esta acción.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_id_agencia'): ?>
Swal.fire({ icon: 'error', title: 'ID de agencia inválido', text: 'El identificador la agencia no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_id'): ?>
Swal.fire({ icon: 'error', title: 'ID inválido', text: 'El identificador del usuario no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'save_agencia_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al guardar agencia', text: 'No se pudo guardar la agencia. Inténtalo nuevamente.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'update_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al actualizar', text: 'No se pudo actualizar el estado del usuario.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_data'): ?>
Swal.fire({ icon: 'error', title: 'Datos inválidos', text: 'Por favor, completa todos los campos requeridos correctamente.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'save_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al guardar', text: 'No se pudo guardar el usuario. Inténtalo nuevamente.', confirmButtonColor: '#dc3545' });
<?php endif; ?>
</script>
<?php endif; ?>
</body>
</html>

View File

@@ -1,128 +1,153 @@
<?php include __DIR__ . '/../partials/sidebar_sistemas.php'; ?>
<?php include __DIR__ . '/../partials/sidebar_administrador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Panel de Administración - Usuarios</title>
<title>Dashboard | Administrador</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
.sidebar .nav-link { font-weight: normal; color: white; transition: all 0.3s ease; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #495057; color: #fff; }
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
.navbar { position: fixed; top: 0; width: 100%; z-index: 1050; }
/* A partir de dispositivos medianos (>=768px), deja espacio lateral */
@media (min-width: 768px) { .content { margin-left: 250px; /* Ancho del sidebar */ } }
/* En móviles, sin margen lateral */
@media (max-width: 767.98px) {
.content { margin-left: 0; }
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
}
.card { border-radius: 12px; }
table.dataTable thead th { background:#343a40; color:#fff; }
</style>
</head>
<body>
<!-- 📄 CONTENIDO -->
<div class="content px-4">
<h3 class="mb-4">Administración de Usuarios</h3>
<div class="content">
<h4 class="mb-4">👥 Alta de Usuarios</h4>
<!-- FORMULARIO -->
<form action="/IMPORTADORES/sistemas/guardar_usuario" method="POST" class="card p-4 mb-5 shadow-sm">
<h5 class="mb-3"> Nuevo Usuario</h5>
<div class="row g-3">
<div class="col-md-4">
<input name="nombre" class="form-control" placeholder="Nombre completo" required>
<div class="card p-4 mb-4 shadow-sm bg-white">
<form action="/IMPORTADORES/administrador/guardar_usuario" method="POST">
<h5 class="mb-3"> Nuevo Usuario</h5>
<div class="row g-3">
<div class="col-md-4">
<input name="nombre" type="text" class="form-control" id="nombre" placeholder="Nombre completo" required>
</div>
<div class="col-md-4">
<input name="email" type="email" class="form-control" id="email" placeholder="Correo electrónico" required>
</div>
<div class="col-md-2">
<input name="password" type="password" class="form-control" id="password" placeholder="Contraseña" required>
</div>
<div class="col-md-2">
<select name="tipo_usuario" class="form-select" required>
<option value="">Tipo</option>
<option value="super_admin">Administrador General</option>
<option value="importador">Importador</option>
</select>
</div>
</div>
<div class="col-md-4">
<input name="email" type="email" class="form-control" placeholder="Correo electrónico" required>
<div class="text-end mt-4">
<button class="btn btn-success px-4">Registrar</button>
</div>
<div class="col-md-2">
<input name="password" type="password" class="form-control" placeholder="Contraseña" required>
</div>
<div class="col-md-2">
<select name="tipo_usuario" class="form-select" required>
<option value="">Tipo</option>
<option value="agente_aduanal">Agente Aduanal</option>
<option value="importador">Importador</option>
</select>
</div>
</div>
<div class="text-end mt-4">
<button class="btn btn-success px-4">Registrar</button>
</div>
</form>
</form>
</div>
<!-- TABLA DE USUARIOS -->
<div class="card p-4 shadow-sm">
<h5 class="mb-3">👁️ Usuarios Registrados</h5>
<h4 class="mb-4">✅ Usuarios Activos</h4>
<div class="card p-3 shadow-sm">
<div class="table-responsive">
<table class="table table-striped table-hover align-middle">
<thead>
<table class="table table-striped table-hover align-middle" id="tabla-activos">
<thead class="table-dark">
<tr>
<th>#</th>
<th>Nombre</th>
<th>Correo</th>
<th>Tipo</th>
<th>Estado</th>
<th>Creado por</th>
<th>Fecha Registro</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (!empty($usuarios)): ?>
<?php foreach ($usuarios as $u): ?>
<?php foreach ($usuarios as $u): ?>
<tr>
<td><?= $u['id_usuario'] ?></td>
<td><?= decrypt($u['nombre']) ?></td>
<td><?= decrypt($u['email']) ?></td>
<td><?= ucfirst($u['tipo_usuario']) ?></td>
<td><?= htmlspecialchars(decrypt($u['nombre'])) ?></td>
<td><?= htmlspecialchars(decrypt($u['email'])) ?></td>
<td><?= htmlspecialchars($u['tipo_usuario']) ?></td>
<td><?= htmlspecialchars($u['creado_por']) ?></td>
<td><?= isset($u['creado_en']) && $u['creado_en'] instanceof DateTime ? $u['creado_en']->format('Y-m-d H:i') : '' ?></td>
<td>
<span class="badge <?= $u['activo'] ? 'bg-success' : 'bg-danger' ?>">
<?= $u['activo'] ? 'Activo' : 'Inactivo' ?>
</span>
</td>
<td>
<a href="/IMPORTADORES/sistemas/toggle_estado?id=<?= $u['id_usuario'] ?>" class="btn btn-sm btn-warning">Toggle</a>
<a href="/IMPORTADORES/sistemas/reset_password?id=<?= $u['id_usuario'] ?>" class="btn btn-sm btn-secondary">Reset</a>
<?php if (isset($u['activo']) && $u['activo'] == 1): ?>
<a href="/IMPORTADORES/administrador/suspender?id=<?= $u['id_usuario'] ?>&success=1" class="btn btn-sm btn-danger">Suspender</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="6" class="text-center">No hay usuarios registrados aún.</td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<?php if (isset($_GET['reset'], $_GET['pass'], $_GET['email']) && $_GET['reset'] === 'ok'): ?>
<script>
const nuevaPassword = "<?= htmlspecialchars($_GET["pass"]) ?>";
const emailUsuario = "<?= htmlspecialchars($_GET["email"]) ?>";
Swal.fire({
icon: 'success',
title: 'Contraseña restablecida',
html: `
Nueva contraseña generada:<br>
<strong style="font-size:18px;">${nuevaPassword}</strong>
<div class="mt-3">
<button class="btn btn-outline-primary btn-sm" onclick="copiarPassword()">📋 Copiar</button>
<button class="btn btn-outline-success btn-sm" onclick="enviarPorCorreo()">📧 Enviar por correo</button>
</div>
`,
showConfirmButton: false,
<script>
$(document).ready(function () {
$('#tabla-activos').DataTable({
order: [],
language: {
url: 'https://cdn.datatables.net/plug-ins/1.13.4/i18n/es-ES.json'
}
});
});
</script>
function copiarPassword() {
navigator.clipboard.writeText(nuevaPassword).then(() => {
Swal.fire('Copiado', 'La contraseña fue copiada al portapapeles.', 'success');
});
}
<?php if (isset($_GET['success'])): ?>
<script>
<?php if ($_GET['success'] === 'created'): ?>
Swal.fire({ icon: 'success', title: 'Usuario creado',
text: 'El usuario se ha creado correctamente y se ha enviado un correo con las credenciales.',
confirmButtonColor: '#198754' });
<?php elseif ($_GET['success'] === 'status_deactivated'): ?>
Swal.fire({ icon: 'success', title: 'Usuario desactivado', text: 'El usuario ha sido desactivado correctamente.', confirmButtonColor: '#198754' });
<?php endif; ?>
</script>
<?php endif; ?>
function enviarPorCorreo() {
fetch(`/IMPORTADORES/sistemas/enviar_password?email=${encodeURIComponent(emailUsuario)}&pass=${encodeURIComponent(nuevaPassword)}`)
.then(response => response.text())
.then(data => {
Swal.fire('Enviado', 'La contraseña fue enviada al correo del usuario.', 'success');
})
.catch(() => {
Swal.fire('Error', 'No se pudo enviar el correo.', 'error');
});
}
<?php if (isset($_GET['error'])): ?>
<script>
<?php if ($_GET['error'] === 'unauthorized'): ?>
Swal.fire({ icon: 'error', title: 'No autorizado', text: 'No tienes permisos para realizar esta acción.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_id'): ?>
Swal.fire({ icon: 'error', title: 'ID inválido', text: 'El identificador del usuario no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'user_not_found'): ?>
Swal.fire({ icon: 'error', title: 'Usuario no encontrado', text: 'No se encontró el usuario especificado.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'update_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al actualizar', text: 'No se pudo actualizar el estado del usuario.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_data'): ?>
Swal.fire({ icon: 'error', title: 'Datos inválidos', text: 'Por favor, completa todos los campos requeridos correctamente.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_user_type'): ?>
Swal.fire({ icon: 'error', title: 'Tipo de usuario inválido', text: 'El tipo de usuario seleccionado no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'email_exists'): ?>
Swal.fire({ icon: 'error', title: 'Correo ya registrado', text: 'Este correo electrónico ya está registrado en el sistema.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'save_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al guardar', text: 'No se pudo guardar el usuario. Inténtalo nuevamente.', confirmButtonColor: '#dc3545' });
<?php endif; ?>
</script>
<?php endif; ?>

View File

@@ -0,0 +1,91 @@
<?php include __DIR__ . '/../partials/sidebar_administrador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Dashboard | Administrador</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
.sidebar .nav-link { font-weight: normal; color: white; transition: all 0.3s ease; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #495057; color: #fff; }
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
.navbar { position: fixed; top: 0; width: 100%; z-index: 1050; }
/* A partir de dispositivos medianos (>=768px), deja espacio lateral */
@media (min-width: 768px) { .content { margin-left: 250px; /* Ancho del sidebar */ } }
/* En móviles, sin margen lateral */
@media (max-width: 767.98px) {
.content { margin-left: 0; }
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
}
.card { border-radius: 12px; }
.table thead th { background: #343a40; color: #fff; }
</style>
</head>
<body>
<!-- 📄 CONTENIDO -->
<div class="content">
<h4 class="mb-4">✅ Aprobación de Agencias Aduanales</h4>
<!-- TABLA DE AGENCIAS -->
<div class="card p-3 shadow-sm">
<h5 class="mb-3">🏪 Agencias Solicitantes</h5>
<div class="table-responsive">
<table class="table table-striped table-hover align-middle" id="tabla-agencias-pendientes">
<thead>
<tr>
<th>#</th>
<th>Nombre</th>
<th>RFC</th>
<th>Correo</th>
<th>Teléfono</th>
<th>Dirección</th>
<th>Fecha</th>
<th>Archivo SAT</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (!empty($solicitudes)): ?>
<?php foreach ($solicitudes as $s): ?>
<tr>
<td><?= $s['request_id'] ?></td>
<td><?= htmlspecialchars(decrypt($s['agencia_name'])) ?></td>
<td><?= htmlspecialchars(decrypt($s['rfc'])) ?></td>
<td><?= htmlspecialchars($s['email']) ?></td>
<td><?= htmlspecialchars($s['phone']) ?></td>
<td><?= htmlspecialchars($s['direccion']) ?></td>
<td><?= $s['request_date'] ? $s['request_date']->format('Y-m-d H:i') : '' ?></td>
<td>
<?php if (!empty($s['opinion_file'])): ?>
<a href="/IMPORTADORES/ver_opinion.php?file=<?= urlencode($s['opinion_file']) ?>" target="_blank" class="btn btn-sm btn-outline-secondary">Ver PDF</a>
<?php else: ?>
<span class="text-muted">No adjunto</span>
<?php endif; ?>
</td>
<td>
<a href="/IMPORTADORES/administrador/aprobar_agencia?id=<?= $s['request_id'] ?>" class="btn btn-sm btn-success">Aprobar</a>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="8" class="text-center">No hay agencias registradas aún.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,119 @@
<?php include __DIR__ . '/../partials/sidebar_administrador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Dashboard | Administrador</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
.sidebar .nav-link { font-weight: normal; color: white; transition: all 0.3s ease; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #495057; color: #fff; }
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
.navbar { position: fixed; top: 0; width: 100%; z-index: 1050; }
/* A partir de dispositivos medianos (>=768px), deja espacio lateral */
@media (min-width: 768px) { .content { margin-left: 250px; /* Ancho del sidebar */ } }
/* En móviles, sin margen lateral */
@media (max-width: 767.98px) {
.content { margin-left: 0; }
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
}
.card { border-radius: 12px; }
.table thead th { background: #343a40; color: #fff; }
</style>
</head>
<body>
<!-- 📄 CONTENIDO -->
<div class="content">
<h4 class="mb-4">✅ Aprobación de Usuarios</h4>
<!-- TABLA DE USUARIOS -->
<div class="card p-3 shadow-sm">
<h5 class="mb-3">👥 Usuarios Solicitantes</h5>
<div class="table-responsive">
<table class="table table-striped table-hover align-middle" id="tabla-usuarios-pendientes">
<thead>
<tr>
<th>#</th>
<th>Empresa</th>
<th>RFC</th>
<th>Correo</th>
<th>Teléfono</th>
<th>Fecha</th>
<th>Archivo SAT</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (!empty($solicitudes)): ?>
<?php foreach ($solicitudes as $s): ?>
<tr>
<td><?= $s['request_id'] ?></td>
<td><?= htmlspecialchars(decrypt($s['company_name'])) ?></td>
<td><?= htmlspecialchars(decrypt($s['rfc'])) ?></td>
<td><?= htmlspecialchars($s['email']) ?></td>
<td><?= htmlspecialchars($s['phone']) ?></td>
<td><?= $s['request_date'] ? $s['request_date']->format('Y-m-d H:i') : '' ?></td>
<td>
<?php if (!empty($s['opinion_file'])): ?>
<a href="/IMPORTADORES/ver_opinion.php?file=<?= urlencode($s['opinion_file']) ?>" target="_blank" class="btn btn-sm btn-outline-secondary">Ver PDF</a>
<?php else: ?>
<span class="text-muted">No adjunto</span>
<?php endif; ?>
</td>
<td>
<a href="/IMPORTADORES/administrador/aprobar_usuario?id=<?= $s['request_id'] ?>" class="btn btn-sm btn-success">Aprobar</a>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="8" class="text-center">No hay solicitudes registradas aún.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php if (isset($_GET['success'])): ?>
<script>
<?php if ($_GET['success'] === 'approved'): ?>
Swal.fire({ icon: 'success', title: 'Usuario aprobado',
text: 'El usuario ha sido aprobado correctamente y se ha enviado un correo con las credenciales.',
confirmButtonColor: '#198754' });
<?php endif; ?>
</script>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<script>
<?php if ($_GET['error'] === 'invalid_id'): ?>
Swal.fire({ icon: 'error', title: 'ID inválido', text: 'El identificador del usuario no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'already_approved'): ?>
Swal.fire({ icon: 'warning', title: 'Ya aprobado', text: 'Esta solicitud ya fue aprobada anteriormente.', confirmButtonColor: '#ffc107' });
<?php elseif ($_GET['error'] === 'request_not_found'): ?>
Swal.fire({ icon: 'error', title: 'Solicitud no encontrada', text: 'No se encontró la solicitud especificada.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'save_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al guardar', text: 'No se pudo guardar el usuario. Inténtalo nuevamente.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'update_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al actualizar', text: 'No se pudo actualizar el estado del usuario.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'failed'): ?>
Swal.fire({ icon: 'error', title: 'Error inesperado', text: 'Ha ocurrido un error inesperado. Por favor, inténtalo nuevamente.', confirmButtonColor: '#dc3545' })
<?php else: ?>
Swal.fire({ icon: 'error', title: 'Error', text: 'Ha ocurrido un error inesperado. Por favor, inténtalo nuevamente.', confirmButtonColor: '#dc3545' });
<?php endif; ?>
</script>
<?php endif; ?>
</body>
</html>

View File

@@ -1,50 +0,0 @@
<?php include __DIR__ . '/../partials/sidebar_sistemas.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Panel de Administración - Usuarios</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<div class="content px-4 pt-5 mt-4">
<h4>🕵️ Bitácora de Accesos</h4>
<table class="table table-hover mt-3 align-middle">
<thead class="table-dark">
<tr>
<th>#</th>
<th>ID Usuario</th>
<th>Correo</th>
<th>IP</th>
<th>Fecha</th>
<th>Éxito</th>
<th>Detalle</th>
</tr>
</thead>
<tbody>
<?php foreach ($registros as $r): ?>
<tr>
<td><?= $r['id'] ?></td>
<td><?= $r['id_usuario'] ?></td>
<td><?= htmlspecialchars($r['email']) ?></td>
<td><?= htmlspecialchars($r['ip']) ?></td>
<td><?= $r['fecha'] instanceof DateTime ? $r['fecha']->format('Y-m-d H:i') : htmlspecialchars($r['fecha']) ?></td>
<td>
<span class="badge <?= $r['exito'] ? 'bg-success' : 'bg-danger' ?>">
<?= $r['exito'] ? 'Sí' : 'No' ?>
</span>
</td>
<td><?= htmlspecialchars($r['detalle']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</body>
</html>

View File

@@ -1,42 +0,0 @@
<?php include __DIR__ . '/../partials/sidebar_sistemas.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Panel de Administración - Usuarios</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<div class="content px-4 pt-5 mt-4">
<h4>🛠️ Bitácora de Cambios de Usuario</h4>
<table class="table table-hover mt-3 align-middle">
<thead class="table-dark">
<tr>
<th>#</th>
<th>ID Usuario</th>
<th>Acción</th>
<th>Descripción</th>
<th>Fecha</th>
</tr>
</thead>
<tbody>
<?php foreach ($registros as $r): ?>
<tr>
<td><?= $r['id_bitacora'] ?></td>
<td><?= $r['usuario_id'] ?></td>
<td><strong><?= htmlspecialchars($r['accion']) ?></strong></td>
<td><?= nl2br(htmlspecialchars($r['descripcion'])) ?></td>
<td><?= $r['fecha'] instanceof DateTime ? $r['fecha']->format('Y-m-d H:i') : htmlspecialchars($r['fecha']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,113 @@
<?php include __DIR__ . '/../partials/sidebar_administrador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Dashboard | Administrador</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
.sidebar .nav-link { font-weight: normal; color: white; transition: all 0.3s ease; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #495057; color: #fff; }
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
.navbar { position: fixed; top: 0; width: 100%; z-index: 1050; }
.btn-indigo { background-color: #6610f2; color: white; }
.btn-indigo:hover { background-color: #520dc2; color: white; }
.text-indigo { color: #520dc2; }
.btn-orange { background-color: orangeRed; color: white; }
.btn-orange:hover { background-color: #ff3600; color: white; }
.text-orange { color: orangeRed; }
.btn-teal { background-color: #20c997; color: white; }
.btn-teal:hover { background-color: #4dd4ac; color: black; }
.text-teal { color: #20c997; }
/* A partir de dispositivos medianos (>=768px), deja espacio lateral */
@media (min-width: 768px) { .content { margin-left: 250px; /* Ancho del sidebar */ } }
/* En móviles, sin margen lateral */
@media (max-width: 767.98px) {
.content { margin-left: 0; }
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
}
.card { border-radius: 12px; }
</style>
</head>
<body>
<!-- 📄 CONTENIDO -->
<div class="content">
<h4 class="mb-4">📦 Panel de Administrador</h4>
<div class="row g-4">
<div class="col-md-4">
<div class="card shadow-sm p-3">
<h5 class="text-primary">Aprobar agencias</h5>
<p>Aprueba las agencias que solicitaron un registro.</p>
<a href="/IMPORTADORES/sistemas/aprobarAgencias"
class="btn btn-primary btn-sm mt-2 <?= $_SERVER['REQUEST_URI'] === '/IMPORTADORES/sistemas/aprobarAgencias' ? 'active' : '' ?>">
Ver bitácora</a>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm p-3">
<h5 class="text-success">Alta de agencias</h5>
<p>Da de alta manualmente una agencia.</p>
<a href="/IMPORTADORES/sistemas/altaAgencias"
class="btn btn-success btn-sm mt-2 <?= $_SERVER['REQUEST_URI'] === '/IMPORTADORES/sistemas/altaAgencias' ? 'active' : '' ?>">
Nuevo agente
</a>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm p-3">
<h5 class="text-info">Aprobar de usuarios</h5>
<p>Aprueba los usuarios que solicitaron un registro.</p>
<a href="/IMPORTADORES/sistemas/aprobarUsuarios"
class="btn btn-info btn-sm mt-2 <?= $_SERVER['REQUEST_URI'] === '/IMPORTADORES/sistemas/aprobarUsuarios' ? 'active' : '' ?>">
Ver usuarios
</a>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm p-3">
<h5 class="text-indigo">Alta de usuarios</h5>
<p>Da de alta manualmente a un usuario.</p>
<a href="/IMPORTADORES/sistemas/altaUsuarios"
class="btn btn-indigo btn-sm mt-2 <?= $_SERVER['REQUEST_URI'] === '/IMPORTADORES/sistemas/altaUsuarios' ? 'active' : '' ?>">
Nuevo agente
</a>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm p-3">
<h5 class="text-warning">Configuración</h5>
<p>Administra los datos de tu agencia.</p>
<a href="/IMPORTADORES/sistemas/configuracion"
class="btn btn-warning btn-sm mt-2 <?= $_SERVER['REQUEST_URI'] === '/IMPORTADORES/sistemas/configuracion' ? 'active' : '' ?>">
Configurar
</a>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm p-3">
<h5 class="text-danger">Cerrar sesión</h5>
<p>Salir del sistema de forma segura.</p>
<a href="/IMPORTADORES/sistemas/logout" class="btn btn-danger btn-sm mt-2">Logout</a>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,28 +0,0 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Login Sistemas</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container mt-5" style="max-width: 400px;">
<h4 class="mb-4 text-center">Acceso Administrativo</h4>
<form action="/IMPORTADORES/sistemas/login" method="POST">
<div class="mb-3">
<label class="form-label">Correo</label>
<input type="email" name="email" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Contraseña</label>
<input type="password" name="clave" class="form-control" required>
</div>
<div class="d-grid">
<button class="btn btn-primary">Entrar</button>
</div>
</form>
</div>
</body>
</html>

View File

@@ -0,0 +1,117 @@
<?php include __DIR__ . '/../partials/sidebar_administrador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Dashboard | Administrador</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
.sidebar .nav-link { font-weight: normal; color: white; transition: all 0.3s ease; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #495057; color: #fff; }
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
.navbar { position: fixed; top: 0; width: 100%; z-index: 1050; }
/* A partir de dispositivos medianos (>=768px), deja espacio lateral */
@media (min-width: 768px) { .content { margin-left: 250px; /* Ancho del sidebar */ } }
/* En móviles, sin margen lateral */
@media (max-width: 767.98px) {
.content { margin-left: 0; }
.sidebar .nav-link { font-weight: normal; color: #343a40; background-color: transparent; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #e9ecef; color: #212529; }
}
.card { border-radius: 12px; }
table.dataTable thead th { background:#343a40; color:#fff; }
</style>
</head>
<body>
<!-- 📄 CONTENIDO -->
<div class="content">
<h4 class="mb-4">🚷 Usuarios Inactivos</h4>
<div class="card p-3 shadow-sm">
<div class="table-responsive">
<table class="table table-striped" id="tabla-inactivos">
<thead class="table-dark">
<tr>
<th>#</th>
<th>Nombre</th>
<th>Correo</th>
<th>Tipo</th>
<th>Creado por</th>
<th>Fecha Registro</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php foreach ($usuarios as $u): ?>
<tr>
<td><?= $u['id_usuario'] ?></td>
<td><?= htmlspecialchars(decrypt($u['nombre'])) ?></td>
<td><?= htmlspecialchars(decrypt($u['email'])) ?></td>
<td><?= htmlspecialchars($u['tipo_usuario']) ?></td>
<td><?= htmlspecialchars($u['creado_por']) ?></td>
<td><?= isset($u['creado_en']) && $u['creado_en'] instanceof DateTime ? $u['creado_en']->format('Y-m-d H:i') : '' ?></td>
<td>
<?php if (isset($u['activo']) && $u['activo'] == 0): ?>
<a href="/IMPORTADORES/administrador/activar?id=<?= $u['id_usuario'] ?>&success=1" class="btn btn-sm btn-success">Activar</a>
<a href="/IMPORTADORES/administrador/reset_password?id=<?= $u['id_usuario'] ?>" class="btn btn-sm btn-secondary">Nueva Contraseña</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('#tabla-inactivos').DataTable({
order: [],
language: {
url: 'https://cdn.datatables.net/plug-ins/1.13.4/i18n/es-ES.json'
}
});
});
</script>
<?php if (isset($_GET['success'])): ?>
<script>
<?php if ($_GET['success'] === 'status_activated'): ?>
Swal.fire({ icon: 'success', title: 'Usuario activado', text: 'El usuario ha sido activado correctamente.', confirmButtonColor: '#198754' });
<?php elseif ($_GET['success'] === 'update_success'): ?>
Swal.fire({ icon: 'success', title: 'Contraseña temporal restablecida', text: 'La contraseña de accesso temporal fue restablecida correctamente y se envio al correo del usuario.', confirmButtonColor: '#198754' });
<?php endif; ?>
</script>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<script>
<?php if ($_GET['error'] === 'unauthorized'): ?>
Swal.fire({ icon: 'error', title: 'No autorizado', text: 'No tienes permisos para realizar esta acción.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_id'): ?>
Swal.fire({ icon: 'error', title: 'ID inválido', text: 'El identificador del usuario no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'user_not_found'): ?>
Swal.fire({ icon: 'error', title: 'Usuario no encontrado', text: 'No se encontró el usuario especificado.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'update_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al actualizar', text: 'No se pudo actualizar el estado del usuario.', confirmButtonColor: '#dc3545' });
<?php endif; ?>
</script>
<?php endif; ?>
</body>
</html>