From 1a5ed8b65d13a877fec237ba629d56c42d473fe2 Mon Sep 17 00:00:00 2001 From: Alexeer Date: Mon, 7 Jul 2025 15:53:01 -0600 Subject: [PATCH] Correcciones - registro --- app/controllers/administrador.php | 14 +- app/controllers/registro.php | 2 +- views/admin/alta_agencias.php | 24 +-- views/admin/alta_usuarios.php | 192 ++++++++++++++++++++-- views/registro/form.php | 10 +- views/transportes/crear.php | 215 ++++++++++++++++++++----- views/transportistas/alta.php | 259 +++++++++++++++++++++++++----- 7 files changed, 597 insertions(+), 119 deletions(-) diff --git a/app/controllers/administrador.php b/app/controllers/administrador.php index 81225c9..c0c017f 100644 --- a/app/controllers/administrador.php +++ b/app/controllers/administrador.php @@ -85,9 +85,9 @@ function aprobar_usuario() } // Preparar datos con validación - $nombre = !empty($solicitud['company_name']) ? decrypt($solicitud['company_name']) : null; - $email = $solicitud['email'] ?? null; - $rfc = !empty($solicitud['rfc']) ? decrypt($solicitud['rfc']) : null; + $nombre = !empty($solicitud['company_name']) ? decrypt($solicitud['company_name']) : null; + $email = $solicitud['email'] ?? null; + $rfc = !empty($solicitud['rfc']) ? decrypt($solicitud['rfc']) : null; $telefono = $solicitud['phone'] ?? null; // Validar datos requeridos @@ -106,9 +106,9 @@ function aprobar_usuario() $email_encrypt = encrypt($email); // Insertar en usuarios_sistema y obtener ID en la misma consulta - $sqlInsert = "INSERT INTO usuarios_sistema (nombre, email, password_hash, tipo_usuario, activo, creado_en, dos_factores, creado_por, preferencias_catalogos) - OUTPUT INSERTED.id_usuario - VALUES (?, ?, ?, ?, 1, GETDATE(), 0, ?, 1)"; + $sqlInsert = "INSERT INTO usuarios_sistema (nombre, email, password_hash, tipo_usuario, activo, creado_en, dos_factores, creado_por, preferencias_catalogos) + OUTPUT INSERTED.id_usuario + VALUES (?, ?, ?, ?, 1, GETDATE(), 0, ?, 1)"; $stmtInsert = sqlsrv_query($conn, $sqlInsert, [ $nombre_encrypt, $email_encrypt, $password_hash, $tipo, $_SESSION['usuario_id'] @@ -120,7 +120,7 @@ function aprobar_usuario() // Obtener el ID directamente del OUTPUT $idUsuarioRow = sqlsrv_fetch_array($stmtInsert, SQLSRV_FETCH_ASSOC); - $id_usuario = $idUsuarioRow['id_usuario'] ?? null; + $id_usuario = $idUsuarioRow['id_usuario'] ?? null; if (!$id_usuario) { throw new Exception("No se pudo obtener el ID del usuario creado. ID obtenido: " . var_export($idUsuarioRow, true)); diff --git a/app/controllers/registro.php b/app/controllers/registro.php index e07e2f6..cf07584 100644 --- a/app/controllers/registro.php +++ b/app/controllers/registro.php @@ -265,7 +265,7 @@ function enviarSoliAgencia() // Sanitizar y obtener datos $agencia = trim($_POST['nombre_agencia'] ?? ''); - $rfc = trim($_POST['rfc'] ?? ''); + $rfc = trim($_POST['rfc_agencia'] ?? ''); $correo = trim($_POST['correo'] ?? ''); $telefono = trim($_POST['telefono'] ?? ''); $direccion = trim($_POST['direccion'] ?? ''); diff --git a/views/admin/alta_agencias.php b/views/admin/alta_agencias.php index ec6a7e0..f3b472c 100644 --- a/views/admin/alta_agencias.php +++ b/views/admin/alta_agencias.php @@ -134,54 +134,58 @@
➕ Nueva Agencia Aduanal
+
-
+
+ -
+ -
+ -
+ -
+
+ -
-
+ +

Administrador de la Agencia

+
+ -
+
+ -
diff --git a/views/admin/alta_usuarios.php b/views/admin/alta_usuarios.php index 4fb211d..234dab8 100644 --- a/views/admin/alta_usuarios.php +++ b/views/admin/alta_usuarios.php @@ -62,6 +62,111 @@ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: left 0.5s; } .btn-animated:hover::before { left: 100%; } table.dataTable thead th { background:#343a40; color:#fff; } + /* ========== ANIMACIONES PARA INPUTS ========== */ + /* 1. Animación al hacer focus */ + .form-control { transition: all 0.3s ease; border: 2px solid #dee2e6; position: relative; } + .form-control:focus { border-color: #0d6efd; box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25), 0 0 20px rgba(13, 110, 253, 0.3); transform: translateY(-2px); } + /* 2. Animación al escribir */ + .form-control:not(:placeholder-shown) { border-color: #198754; background-color: #f8fff9; } + /* 3. Efecto de shake en validación */ + .form-control.shake { animation: shake 0.5s ease-in-out; } + @keyframes shake { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-5px); } + 75% { transform: translateX(5px); } + } + /* 4. Floating labels con animación */ + .form-floating-custom { position: relative; margin-bottom: 1.5rem; } + .form-floating-custom .form-control { padding: 1rem 0.75rem 0.5rem 0.75rem; height: auto; } + .form-floating-custom .form-label { position: absolute; top: 0.75rem; left: 0.75rem; transition: all 0.3s ease; pointer-events: none; color: #6c757d; z-index: 2; } + .form-floating-custom .form-control:focus ~ .form-label, + .form-floating-custom .form-control:not(:placeholder-shown) ~ .form-label { top: 0.25rem; font-size: 0.75rem; color: #0d6efd; font-weight: 600; } + /* 5. Efecto de pulso en hover */ + .input-pulse:hover { animation: inputPulse 0.6s ease-in-out; } + @keyframes inputPulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.02); } + 100% { transform: scale(1); } + } + /* 6. Gradiente animado en el borde */ + .input-gradient { position: relative; overflow: hidden; } + .input-gradient::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; + background: linear-gradient(90deg, transparent, rgba(13, 110, 253, 0.3), transparent); transition: left 0.5s; pointer-events: none; z-index: 1; } + .input-gradient:focus::before { left: 100%; } + /* 7. Efecto de brillo en validación exitosa */ + .form-control.valid { border-color: #198754; background: linear-gradient(45deg, #fff, #f8fff9); animation: successGlow 1s ease-in-out; } + @keyframes successGlow { + 0% { box-shadow: 0 0 5px rgba(25, 135, 84, 0.5); } + 50% { box-shadow: 0 0 20px rgba(25, 135, 84, 0.8); } + 100% { box-shadow: 0 0 5px rgba(25, 135, 84, 0.5); } + } + /* 8. Typing effect simulation */ + .input-typing { position: relative; } + .input-typing::after { content: '|'; position: absolute; right: 10px; top: 50%; transform: translateY(-50%); opacity: 0; animation: blink 1s infinite; color: #0d6efd; } + .input-typing:focus::after { opacity: 1; } + @keyframes blink { + 0%, 50% { opacity: 1; } + 51%, 100% { opacity: 0; } + } + /* 9. Efecto de ondas */ + .input-ripple { position: relative; overflow: hidden; } + .input-ripple::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: rgba(13, 110, 253, 0.2); + border-radius: 50%; transform: translate(-50%, -50%); transition: width 0.3s, height 0.3s; pointer-events: none; } + .input-ripple:focus::before { width: 300px; height: 300px; } + /* 10. Slide-up animation para los campos */ + .form-group-animated { opacity: 0; transform: translateY(20px); animation: slideUp 0.6s ease-out forwards; } + .form-group-animated:nth-child(1) { animation-delay: 0.1s; } + .form-group-animated:nth-child(2) { animation-delay: 0.2s; } + .form-group-animated:nth-child(3) { animation-delay: 0.3s; } + .form-group-animated:nth-child(4) { animation-delay: 0.4s; } + .form-group-animated:nth-child(5) { animation-delay: 0.5s; } + .form-group-animated:nth-child(6) { animation-delay: 0.6s; } + .form-group-animated:nth-child(7) { animation-delay: 0.7s; } + .form-group-animated:nth-child(8) { animation-delay: 0.8s; } + @keyframes slideUp { to { opacity: 1; transform: translateY(0); } } + /* ========== ANIMACIONES PARA SELECT ========== */ + /* 1. Estilos base para select */ + .form-select {transition: all 0.3s ease; border: 2px solid #dee2e6; position: relative; cursor: pointer; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 6 7 7 7-7'/%3e%3c/svg%3e"); + background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 16px 12px; } + /* 2. Animación al hacer focus */ + .form-select:focus { border-color: #0d6efd; box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25), 0 0 20px rgba(13, 110, 253, 0.3); transform: translateY(-2px); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%230d6efd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 6 7 7 7-7'/%3e%3c/svg%3e"); } + /* 3. Animación cuando tiene valor seleccionado */ + .form-select:not([value=""]):not(:invalid) { border-color: #198754; background-color: #f8fff9; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23198754' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 6 7 7 7-7'/%3e%3c/svg%3e"); padding: 1rem 2.5rem 0.5rem 0.75rem; height: auto; min-height: 3.5rem; } + .form-floating-custom .form-select:focus ~ .form-label, + .form-floating-custom .form-select:not([value=""]) ~ .form-label { top: 0.25rem; font-size: 0.75rem; color: #0d6efd; font-weight: 600; } + /* 5. Efecto de shake en validación para select */ + .form-select.shake { animation: shake 0.5s ease-in-out; } + /* 6. Efecto de pulso en hover para select */ + .select-pulse:hover { animation: inputPulse 0.6s ease-in-out; } + /* 7. Gradiente animado para select */ + .select-gradient { position: relative; overflow: hidden; } + .select-gradient::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(13, 110, 253, 0.3), transparent); transition: left 0.5s; pointer-events: none; z-index: 1; } + .select-gradient:focus::before { left: 100%; } + /* 8. Efecto de brillo en validación exitosa para select */ + .form-select.valid { border-color: #198754; background-color: #f8fff9; animation: successGlow 1s ease-in-out; } + /* 9. Efecto de rotación de la flecha al abrir */ + .select-arrow-rotate { transition: all 0.3s ease; } + .select-arrow-rotate:focus { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%230d6efd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 10 7-7 7 7'/%3e%3c/svg%3e"); } + /* 10. Efecto de ondas para select */ + .select-ripple { position: relative; overflow: hidden; } + .select-ripple::after { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; + background: rgba(13, 110, 253, 0.2); border-radius: 50%; transform: translate(-50%, -50%); transition: width 0.3s, height 0.3s; pointer-events: none; } + .select-ripple:focus::after { width: 300px; height: 300px; } + /* 11. Efecto de scale suave */ + .select-scale { transition: transform 0.2s ease; } + .select-scale:hover { transform: scale(1.02); } + .select-scale:focus { transform: scale(1.02) translateY(-2px); } + /* 12. Personalización de opciones (limitado en algunos navegadores) */ + .form-select option { padding: 0.5rem; transition: all 0.2s ease; } + .form-select option:hover { background-color: #f8f9fa; } + /* 13. Indicador de estado */ + .select-status { position: relative; } + .select-status::after { content: ''; position: absolute; right: 2.5rem; top: 50%; transform: translateY(-50%); + width: 8px; height: 8px; border-radius: 50%; background-color: #dc3545; opacity: 0; transition: opacity 0.3s ease; } .select-status.valid::after { background-color: #198754; opacity: 1; } + .select-status:invalid::after { background-color: #dc3545; opacity: 1; } @@ -71,24 +176,36 @@

👥 Alta de Usuarios

-
+
➕ Nuevo Usuario
-
- +
+
+ + +
-
- +
+
+ + +
-
- +
+
+ + +
-
- +
+
+ + +
@@ -144,6 +261,55 @@ } }); }); + + // Script para manejar las animaciones de validación + document.addEventListener('DOMContentLoaded', function() { + const inputs = document.querySelectorAll('.form-control'); + + inputs.forEach(input => { + // Validación en tiempo real + input.addEventListener('input', function() { + if (this.checkValidity()) { + this.classList.remove('shake'); + this.classList.add('valid'); + } else { + this.classList.remove('valid'); + } + }); + + // Efecto shake en campos inválidos + input.addEventListener('invalid', function() { + this.classList.add('shake'); + setTimeout(() => { + this.classList.remove('shake'); + }, 500); + }); + }); + + // Validación del formulario + document.getElementById('formAltaUsuarios').addEventListener('submit', function(e) { + e.preventDefault(); + + let isValid = true; + inputs.forEach(input => { + if (!input.checkValidity()) { + input.classList.add('shake'); + isValid = false; + } + }); + + if (isValid) { + // Aquí puedes agregar tu lógica de envío + Swal.fire({ + icon: 'success', + title: '¡Éxito!', + text: 'Agencia registrada correctamente', + showConfirmButton: false, + timer: 1500 + }); + } + }); + }); diff --git a/views/registro/form.php b/views/registro/form.php index 96be6a3..b685cfd 100644 --- a/views/registro/form.php +++ b/views/registro/form.php @@ -48,6 +48,7 @@ $color2 = explode(',', $config['colores_primarios'] ?? '#003366,#0055A5') .form-container.active { display: block; } .form-title { text-align: center; margin-bottom: 2rem; color: #333; } .transition-fade { transition: opacity 0.3s ease-in-out; } + .alert { bottom: 30px; } @@ -159,7 +160,8 @@ $color2 = explode(',', $config['colores_primarios'] ?? '#003366,#0055A5')
-

+
+

Administrador de la Agencia

@@ -183,7 +185,7 @@ $color2 = explode(',', $config['colores_primarios'] ?? '#003366,#0055A5')
-
+
-