Herramientas Informaticas

Categoría: CURSOS PHP Página 1 de 3

🚀 La Gran Transformación Visual: Modernización Integral de la Autenticación con Glassmorphism para Sistemas de Ventas

Entrada fija

En el mundo del desarrollo de software empresarial, a menudo se comete el error de relegar la apariencia visual a un segundo plano. Durante décadas ha imperado la noción de que un sistema de punto de venta (POS), un control de inventarios o un software de facturación administrativa únicamente debe cumplir con ser funcional, robusto y rápido. Sin embargo, la experiencia de usuario moderna (UX) y el diseño de interfaces limpias (UI) han demostrado ser factores determinantes en la productividad de los equipos de trabajo, en la reducción del estrés operativo cotidiano y, sobre todo, en la percepción de calidad y confianza que proyecta una plataforma corporativa.

Hoy presentamos una actualización visual y estructural profunda dirigida a transformar la puerta de entrada de cualquier sistema comercial: el módulo de autenticación. A través de la integración de la estética Glassmorphism (efecto cristal translúcido), la suavización de geometrías mediante bordes curvados de 25 píxeles, la creación de campos de texto inmersivos y el uso inteligente de fondos híbridos, convertimos una interfaz estática tradicional en una experiencia sofisticada, atractiva y de clase mundial.

Todo este desarrollo se encuentra montado y optimizado sobre el popular paquete para CodeIgniter 4 alojado en el repositorio oficial julio101290/boilerplate, integrando los estándares de seguridad de autenticación con las técnicas más avanzadas de diseño CSS moderno.

A lo largo de este extenso artículo exploraremos la justificación psicológica y técnica de este rediseño, desglosaremos cada una de las tres vistas transformadas (Inicio de Sesión, Recuperación de Contraseña y Registro de Nuevos Usuarios), analizaremos las propiedades CSS detrás del efecto visual y detallaremos cómo puedes implementar esta solución en tus propios proyectos de software.

🎨 1. La Importancia de la Primera Impresión en el Software de Negocios

El inicio de sesión no es un simple trámite técnico; es el umbral de bienvenida para cajeros, supervisores, gerentes, contadores y directores de sucursales. Es la primera pantalla que se ilumina en los monitores cada mañana al iniciar una jornada comercial y la última que se cierra al realizar el corte de caja por la noche.

🧠 Psicología visual y seguridad percibida

Cuando un usuario interactúa con un panel de inicio de sesión visualmente descuidado, plano o heredado de tecnologías de hace veinte años, subconscientemente asume que el software detrás es arcaico, lento y propenso a fallas. Por el contrario, cuando un empleado o cliente visualiza una interfaz pulcra, con contrastes balanceados, animaciones sutiles y efectos de profundidad cristalina, la percepción cambia radicalmente:

  • 🛡️ Confianza inmediata: El usuario siente que sus credenciales y los datos de su empresa están resguardados por una herramienta moderna y profesional.
  • ⚡ Reducción de la fatiga cognitiva: Un diseño libre de saturaciones de color estridentes permite que los ojos descansen durante turnos laborales prolongados.
  • 🏢 Identidad de marca: La capacidad de colocar una fotografía de alta resolución de la oficina, almacén o tienda física en el fondo del login vincula emocionalmente la herramienta digital con el entorno físico del negocio.

💎 2. ¿Qué es Glassmorphism y por qué es Ideal para este Proyecto?

El concepto de Glassmorphism se fundamenta en imitar las propiedades físicas del vidrio deslustrado o cristal esmerilado sobre un plano digital. A diferencia de las interfaces planas (Flat Design) o del realismo tridimensional hiperbólico (Neumorphism), el efecto cristal introduce una dimensión visual basada en capas superpuestas donde el fondo nunca desaparece por completo, sino que se transforma en un lienzo difuminado con profundidad espacial.

📐 Las tres reglas de oro del Glassmorphism implementadas:

  1. Translucidez óptica (rgba): En lugar de utilizar fondos blancos sólidos (#ffffff) que bloquean la escena posterior, empleamos valores alfa reducidos como rgba(255, 255, 255, 0.15). Esto permite que la luz, los contrastes y las siluetas del fondo atraviesen la tarjeta.
  2. Desenfoque de lente posterior (backdrop-filter: blur): La translucidez por sí sola causaría ruido visual y problemas de legibilidad, ya que el texto del formulario competiría con los detalles de la fotografía trasera. Al inyectar un filtro de desenfoque gaussiano de 15px directamente sobre lo que subyace a la tarjeta, se eliminan los bordes duros de la imagen de fondo, generando una superficie suave y legible similar al vidrio satinado.
  3. Borde refractivo sutil (1px solid rgba(255, 255, 255, 0.2)): Los cristales reales reflejan la luz en sus cantos. Añadir un borde milimétrico con un tono blanco ligeramente más brillante define la silueta de la tarjeta sin necesidad de emplear líneas negras agresivas o sombras excesivas.

🛠️ 3. El Motor del Proyecto: CodeIgniter 4 y el Repositorio Boilerplate

Para comprender el contexto operativo de este código, es fundamental conocer la arquitectura sobre la que se construye. Este diseño ha sido elaborado para integrarse de forma nativa en julio101290/boilerplate, un paquete especializado que proporciona un panel de control empresarial completo basado en AdminLTE 3, dotado de gestión de roles, permisos, usuarios y utilidades operativas para CodeIgniter 4.

📁 Directorio de Vistas de Autenticación en Boilerplate:
└── app/ (o vendor/julio101290/boilerplate/src/)
    └── Views/
        └── Authentication/
            ├── index.php            <- Plantilla maestra contenedora
            ├── login.php            <- Vista principal de inicio de sesión
            ├── forgot.php           <- Vista de reseteo de credenciales
            ├── register.php         <- Vista de alta de usuarios
            └── message_block.php    <- Renderizado de alertas y errores flash

🧩 Mecanismo de herencia de vistas

El código hace uso intensivo de la directiva:

PHP

<?= $this->extend('julio101290\boilerplate\Views\Authentication\index') ?>
<?= $this->section('content') ?>

Esto asegura que el marco HTML base (<!DOCTYPE html>, etiquetas <head>, inclusión de fuentes FontAwesome y scripts de Bootstrap) permanezca modularizado. El archivo hijo simplemente inyecta el contenido central dentro del contenedor universal, manteniendo el proyecto limpio, mantenible y libre de código duplicado.

🔍 4. Desglose Arquitectónico del Módulo 1: Inicio de Sesión (login.php)

El formulario de inicio de sesión es el núcleo primordial del sistema de ventas. Requiere recibir el correo electrónico o nombre de usuario, la contraseña secreta, ofrecer la opción de recordar sesión y dar acceso a los enlaces secundarios de recuperación y registro.

A continuación, analizamos la estructura técnica de este archivo:

PHP

<?= $this->extend('julio101290\boilerplate\Views\Authentication\index') ?>
<?= $this->section('content') ?>

<style>
    body.login-page {
        background: 
        <?php if (file_exists(FCPATH . 'img/back.png')): ?>
            url('<?= base_url('img/back.png') ?>') no-repeat center center fixed,
        <?php endif; ?>
            radial-gradient(circle at top left, #1e3c72, transparent 60%),
            radial-gradient(circle at bottom right, #2a5298, transparent 60%),
            linear-gradient(135deg, #0f2027, #203a43, #2c5364);
        background-size: cover;
        min-height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .login-box {
        animation: fadeSlide .6s ease-out;
        width: 360px;
    }

    @keyframes fadeSlide {
        from {
            opacity: 0;
            transform: translateY(20px);
        }
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }

    .login-logo {
        font-size: 2.1rem;
        font-weight: 300;
        color: #fff;
        text-align: center;
        margin-bottom: 1.5rem;
        text-shadow: 0 2px 4px rgba(0,0,0,.4);
    }
    
    .login-logo a {
        color: #fff;
    }

    .card {
        background: rgba(255, 255, 255, 0.15); 
        -webkit-backdrop-filter: blur(15px);
        backdrop-filter: blur(15px);
        border-radius: 25px; 
        box-shadow: 0 15px 35px rgba(0,0,0,.2);
        border: 1px solid rgba(255, 255, 255, 0.2); 
        overflow: hidden;
    }

    .login-card-body {
        background: transparent;
        padding: 2.5rem 2rem;
    }

    .login-card-body, .login-box-msg, .custom-control-label, .icheck-primary label {
        color: #ffffff;
        text-shadow: 0 1px 2px rgba(0,0,0,0.3);
    }

    .login-box-msg {
        color: #eeeeee;
        margin: 0;
        padding: 0 20px 20px;
        text-align: center;
    }

    .form-control {
        background: rgba(255, 255, 255, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.3);
        border-right: none;
        color: #fff;
        border-radius: 25px 0 0 25px;
    }

    .form-control::placeholder {
        color: rgba(255, 255, 255, 0.7);
    }

    .form-control:focus {
        background: rgba(255, 255, 255, 0.3);
        border-color: rgba(255, 255, 255, 0.5);
        color: #fff;
        box-shadow: none;
    }
    
    .form-control.is-invalid {
        border-color: #ffcccc;
        background-image: none;
    }

    .input-group-text {
        background: rgba(255, 255, 255, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.3);
        border-left: none;
        color: rgba(255, 255, 255, 0.8);
        border-radius: 0 25px 25px 0;
        cursor: pointer;
    }

    .btn-primary {
        background-color: #4a90e2;
        border-color: #4a90e2;
        border-radius: 25px;
        font-weight: 600;
        letter-spacing: .5px;
        transition: all 0.3s ease;
    }

    .btn-primary:hover {
        background-color: #357abd;
        border-color: #357abd;
        transform: translateY(-2px);
        box-shadow: 0 5px 15px rgba(0,0,0,.3);
    }

    .card a:not(.btn) {
        color: #ffffff;
        opacity: 0.8;
        transition: opacity 0.3s;
    }

    .card a:not(.btn):hover {
        opacity: 1;
        text-decoration: underline;
    }
    
    .card hr {
        border-top: 1px solid rgba(255, 255, 255, 0.2);
    }

    @media (max-width: 576px) {
        .login-box {
            width: 90%;
        }
        .login-card-body {
            padding: 2rem 1.5rem;
        }
    }
</style>

<div class="login-box">
    <div class="login-logo">
        <a href="<?= base_url() ?>"><b><?= lang('Auth.loginTitle') ?></b></a>
    </div>

    <div class="card">
        <div class="card-body login-card-body">
            <?= $this->include('julio101290\boilerplate\Views\Authentication\message_block') ?>

            <form action="<?= base_url(route_to('login')) ?>" method="post">
                <?= csrf_field() ?>

                <div class="input-group mb-4">
                    <input
                        type="<?= $config->validFields === ['email'] ? 'email' : 'text' ?>"
                        name="login"
                        class="form-control <?= session('errors.login') ? 'is-invalid' : '' ?>"
                        placeholder="<?= $config->validFields === ['email']
                            ? lang('Auth.email')
                            : lang('Auth.emailOrUsername') ?>"
                        value="<?= old('login') ?>"
                        autocomplete="off">
                    <div class="input-group-append">
                        <div class="input-group-text">
                            <span class="fas fa-user"></span>
                        </div>
                    </div>
                    <?php if (session('errors.login')) : ?>
                        <div class="invalid-feedback">
                            <?= session('errors.login') ?>
                        </div>
                    <?php endif ?>
                </div>

                <div class="input-group mb-3">
                    <input
                        type="password"
                        name="password"
                        id="password"
                        class="form-control <?= session('errors.password') ? 'is-invalid' : '' ?>"
                        placeholder="<?= lang('Auth.password') ?>">
                    <div class="input-group-append">
                        <div class="input-group-text" onclick="togglePassword()">
                            <span id="toggleIcon" class="fas fa-eye"></span>
                        </div>
                    </div>
                    <?php if (session('errors.password')) : ?>
                        <div class="invalid-feedback">
                            <?= session('errors.password') ?>
                        </div>
                    <?php endif ?>
                </div>

                <div class="row mb-3 align-items-center">
                    <?php if ($config->allowRemembering) { ?>
                        <div class="col-7">
                            <div class="icheck-primary d-inline">
                                <input type="checkbox"
                                       id="remember"
                                       name="remember"
                                       <?= old('remember') ? 'checked' : '' ?>>
                                <label for="remember">
                                    <?= lang('Auth.rememberMe') ?>
                                </label>
                            </div>
                        </div>
                    <?php } ?>
                    <div class="col-5">
                        <button type="submit" class="btn btn-primary btn-block">
                            <?= lang('Auth.signIn') ?>
                        </button>
                    </div>
                </div>
            </form>

            <hr>

            <p class="mb-1 text-center">
                <a href="<?= route_to('forgot') ?>">
                    <?= lang('Auth.forgotYourPassword') ?>
                </a>
            </p>

            <?php if ($config->allowRegistration) { ?>
                <p class="mb-0 text-center">
                    <a href="<?= route_to('register') ?>">
                        <?= lang('Auth.needAnAccount') ?>
                    </a>
                </p>
            <?php } ?>
        </div>
    </div>
</div>

<script>
function togglePassword() {
    const input = document.getElementById('password');
    const icon  = document.getElementById('toggleIcon');
    if (input.type === 'password') {
        input.type = 'text';
        icon.classList.remove('fa-eye');
        icon.classList.add('fa-eye-slash');
    } else {
        input.type = 'password';
        icon.classList.remove('fa-eye-slash');
        icon.classList.add('fa-eye');
    }
}
</script>
<?= $this->endSection() ?>

📋 Aspectos técnicos sobresalientes del Login:

  • 🛡️ Comprobación dinámica de imagen con fallback (file_exists): Mediante PHP evaluamos si el archivo public/img/back.png existe físicamente en el servidor con FCPATH. Si está presente, lo monta como fondo primario fijado (fixed); si no existe, activa un degradado radial y lineal de tonalidades azules profundas (#0f2027 a #2c5364), garantizando que la aplicación jamás falle ni muestre un fondo blanco roto.
  • 👁️ Alternador interactivo de visibilidad de contraseña: La función JavaScript nativa togglePassword() conmuta el atributo type entre password y text, actualizando al mismo tiempo el icono de FontAwesome de fa-eye a fa-eye-slash. Esto mejora la ergonomía en teclados de puntos de venta y dispositivos móviles donde equivocarse de carácter al teclear es recurrente.
  • 🔒 Protección CSRF activa: La inclusión de <?= csrf_field() ?> genera el token criptográfico contra falsificación de peticiones en sitios cruzados, fundamental en cualquier entorno de pagos o cobros.

🔑 5. Desglose Arquitectónico del Módulo 2: Recuperación de Credenciales (forgot.php)

En los entornos comerciales, el olvido de credenciales por parte de cajeros de nuevo ingreso o empleados que rotan turnos es una de las incidencias operativas más frecuentes. Una pantalla de reseteo confusa provoca demoras innecesarias y saturación en los canales de soporte de TI.

La interfaz de recuperación de contraseña fue adaptada minuciosamente para mantener una coherencia visual milimétrica con la pantalla principal:

PHP

<?= $this->extend('julio101290\boilerplate\Views\Authentication\index') ?>
<?= $this->section('content') ?>

<style>
    body.login-page {
        background: 
        <?php if (file_exists(FCPATH . 'img/back.png')): ?>
            url('<?= base_url('img/back.png') ?>') no-repeat center center fixed,
        <?php endif; ?>
            radial-gradient(circle at top left, #1e3c72, transparent 60%),
            radial-gradient(circle at bottom right, #2a5298, transparent 60%),
            linear-gradient(135deg, #0f2027, #203a43, #2c5364);
        background-size: cover;
        min-height: 100vh;
    }

    .login-box {
        animation: fadeSlide .6s ease-out;
    }

    @keyframes fadeSlide {
        from {
            opacity: 0;
            transform: translateY(20px);
        }
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }

    .card {
        background: rgba(255, 255, 255, 0.15);
        -webkit-backdrop-filter: blur(15px);
        backdrop-filter: blur(15px);
        border-radius: 25px;
        box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.2);
        overflow: hidden;
    }

    .login-card-body {
        background: transparent;
        padding: 2.5rem 2rem;
        color: #ffffff;
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
    }

    .login-box-msg {
        color: #ffffff;
        font-weight: 400;
        text-align: center;
        padding: 0 10px 15px;
    }

    .form-control {
        background: rgba(255, 255, 255, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.3);
        border-right: none;
        color: #ffffff;
        border-radius: 25px 0 0 25px;
    }

    .form-control::placeholder {
        color: rgba(255, 255, 255, 0.7);
    }

    .form-control:focus {
        background: rgba(255, 255, 255, 0.3);
        border-color: rgba(255, 255, 255, 0.5);
        color: #ffffff;
        box-shadow: none;
    }

    .form-control.is-invalid {
        border-color: #ffcccc;
        background-image: none;
    }

    .input-group-text {
        background: rgba(255, 255, 255, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.3);
        border-left: none;
        color: rgba(255, 255, 255, 0.85);
        border-radius: 0 25px 25px 0;
    }

    .btn-primary {
        background-color: #4a90e2;
        border-color: #4a90e2;
        border-radius: 25px;
        font-weight: 600;
        letter-spacing: .5px;
        transition: all 0.3s ease;
    }

    .btn-primary:hover {
        background-color: #357abd;
        border-color: #357abd;
        transform: translateY(-2px);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    }

    .card a:not(.btn) {
        color: #ffffff;
        opacity: 0.85;
        transition: opacity 0.3s;
    }

    .card a:not(.btn):hover {
        opacity: 1;
        text-decoration: underline;
    }

    @media (max-width: 576px) {
        .login-card-body {
            padding: 2rem 1.5rem;
        }
    }
</style>

<div class="card">
  <div class="card-body login-card-body">
    <p class="login-box-msg"><?= lang('Auth.forgotPassword') ?></p>
    <p class="login-box-msg"><?= lang('Auth.enterEmailForInstructions') ?></p>
    
    <?= $this->include('julio101290\boilerplate\Views\Authentication\message_block') ?>
    
    <form action="<?= base_url(route_to('forgot')) ?>" method="post">
      <?= csrf_field() ?>
      <div class="input-group mb-4">
        <input type="email" name="email"
          class="form-control <?= session('errors.email') ? 'is-invalid' : '' ?>"
          placeholder="<?= lang('Auth.email') ?>"
          value="<?= old('email') ?>">
        <div class="input-group-append">
          <div class="input-group-text">
            <span class="fas fa-envelope"></span>
          </div>
        </div>
        <?php if (session('errors.email')) : ?>
          <div class="invalid-feedback">
            <?= session('errors.email') ?>
          </div>
        <?php endif ?>
      </div>

      <div class="row mb-3">
        <div class="col-12">
          <button type="submit" class="btn btn-primary btn-block">
            <?= lang('Auth.sendInstructions') ?>
          </button>
        </div>
      </div>
    </form>

    <hr style="border-top: 1px solid rgba(255, 255, 255, 0.2);">

    <p class="mt-2 mb-1 text-center">
      <a href="<?= base_url(route_to('login')) ?>"><?= lang('Auth.signIn') ?></a>
    </p>

    <?php if ($config->allowRegistration) { ?>
    <p class="mb-0 text-center">
      <a href="<?= base_url(route_to('register')) ?>">
        <?= lang('Auth.needAnAccount') ?>
      </a>
    </p>
    <?php } ?>
  </div>
</div>
<?= $this->endSection() ?>

📋 Claves ergonómicas de la pantalla de recuperación:

  • ✉️ Entrada focalizada: Al contar con un único campo principal (correo electrónico), se maximiza el margen vertical mediante mb-4, permitiendo que el botón principal de acción abarque el 100% del ancho con btn-block.
  • 💡 Instrucciones legibles: Las etiquetas de texto descriptivo lang('Auth.enterEmailForInstructions') cuentan con una sombra sutil (text-shadow: 0 1px 2px rgba(0,0,0,0.3)), lo cual garantiza su lectura clara sin importar si el fondo proyecta colores claros o luminiscencias del rascacielos corporativo.

📝 6. Desglose Arquitectónico del Módulo 3: Registro de Nuevos Usuarios (register.php)

El alta de usuarios en un sistema de ventas exige campos adicionales para garantizar la integridad de las cuentas: nombre de usuario único, correo corporativo, contraseña y confirmación de la misma. Al ser un formulario con mayor densidad de campos verticales, el reto de diseño radica en evitar que la tarjeta abrume la pantalla.

Aquí radica la importancia de los inputs translúcidos con radio asimétrico:

PHP

<?= $this->extend('julio101290\boilerplate\Views\Authentication\index') ?>
<?= $this->section('content') ?>

<style>
    body.login-page {
        background: 
        <?php if (file_exists(FCPATH . 'img/back.png')): ?>
            url('<?= base_url('img/back.png') ?>') no-repeat center center fixed,
        <?php endif; ?>
            radial-gradient(circle at top left, #1e3c72, transparent 60%),
            radial-gradient(circle at bottom right, #2a5298, transparent 60%),
            linear-gradient(135deg, #0f2027, #203a43, #2c5364);
        background-size: cover;
        min-height: 100vh;
    }

    .login-box {
        animation: fadeSlide .6s ease-out;
    }

    @keyframes fadeSlide {
        from {
            opacity: 0;
            transform: translateY(20px);
        }
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }

    .card {
        background: rgba(255, 255, 255, 0.15);
        -webkit-backdrop-filter: blur(15px);
        backdrop-filter: blur(15px);
        border-radius: 25px;
        box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.2);
        overflow: hidden;
    }

    .register-card-body {
        background: transparent;
        padding: 2.5rem 2rem;
        color: #ffffff;
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
    }

    .login-box-msg {
        color: #ffffff;
        font-weight: 500;
        text-align: center;
        padding: 0 10px 15px;
    }

    .form-control {
        background: rgba(255, 255, 255, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.3);
        border-right: none;
        color: #ffffff;
        border-radius: 25px 0 0 25px;
    }

    .form-control::placeholder {
        color: rgba(255, 255, 255, 0.7);
    }

    .form-control:focus {
        background: rgba(255, 255, 255, 0.3);
        border-color: rgba(255, 255, 255, 0.5);
        color: #ffffff;
        box-shadow: none;
    }

    .form-control.is-invalid {
        border-color: #ffcccc;
        background-image: none;
    }

    .input-group-text {
        background: rgba(255, 255, 255, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.3);
        border-left: none;
        color: rgba(255, 255, 255, 0.85);
        border-radius: 0 25px 25px 0;
    }

    .btn-primary {
        background-color: #4a90e2;
        border-color: #4a90e2;
        border-radius: 25px;
        font-weight: 600;
        letter-spacing: .5px;
        transition: all 0.3s ease;
    }

    .btn-primary:hover {
        background-color: #357abd;
        border-color: #357abd;
        transform: translateY(-2px);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    }

    .card a:not(.btn) {
        color: #ffffff;
        opacity: 0.85;
        transition: opacity 0.3s;
    }

    .card a:not(.btn):hover {
        opacity: 1;
        text-decoration: underline;
    }

    @media (max-width: 576px) {
        .register-card-body {
            padding: 2rem 1.5rem;
        }
    }
</style>

<div class="card">
  <div class="card-body register-card-body">
    <p class="login-box-msg"><?= lang('Auth.register') ?></p>

    <?= $this->include('julio101290\boilerplate\Views\Authentication\message_block') ?>

    <form action="<?= base_url(route_to('register')) ?>" method="post">
      <?= csrf_field() ?>

      <div class="input-group mb-3">
        <input type="text" name="username"
          class="form-control <?= session('errors.username') ? 'is-invalid' : '' ?>"
          placeholder="<?= lang('Auth.username') ?>" value="<?= old('username') ?>"
          autocomplete="off">
        <div class="input-group-append">
          <div class="input-group-text">
            <span class="fas fa-user"></span>
          </div>
        </div>
        <?php if (session('errors.username')) : ?>
          <div class="invalid-feedback">
            <?= session('errors.username') ?>
          </div>
        <?php endif ?>
      </div>

      <div class="input-group mb-3">
        <input type="email" name="email"
          class="form-control <?= session('errors.email') ? 'is-invalid' : '' ?>"
          placeholder="<?= lang('Auth.email') ?>" value="<?= old('email') ?>"
          autocomplete="off">
        <div class="input-group-append">
          <div class="input-group-text">
            <span class="fas fa-envelope"></span>
          </div>
        </div>
        <?php if (session('errors.email')) : ?>
          <div class="invalid-feedback">
            <?= session('errors.email') ?>
          </div>
        <?php endif ?>
      </div>

      <div class="input-group mb-3">
        <input type="password" name="password"
          class="form-control <?= session('errors.password') ? 'is-invalid' : '' ?>"
          placeholder="<?= lang('Auth.password') ?>" autocomplete="new-password">
        <div class="input-group-append">
          <div class="input-group-text">
            <span class="fas fa-lock"></span>
          </div>
        </div>
        <?php if (session('errors.password')) : ?>
          <div class="invalid-feedback">
            <?= session('errors.password') ?>
          </div>
        <?php endif ?>
      </div>

      <div class="input-group mb-4">
        <input type="password" name="pass_confirm"
          class="form-control <?= session('errors.pass_confirm') ? 'is-invalid' : '' ?>"
          placeholder="<?= lang('Auth.repeatPassword') ?>" autocomplete="new-password">
        <div class="input-group-append">
          <div class="input-group-text">
            <span class="fas fa-lock"></span>
          </div>
        </div>
        <?php if (session('errors.pass_confirm')) : ?>
          <div class="invalid-feedback">
            <?= session('errors.pass_confirm') ?>
          </div>
        <?php endif ?>
      </div>

      <div class="row mb-3">
        <div class="col-12">
          <button type="submit" class="btn btn-primary btn-block">
            <?= lang('Auth.register') ?>
          </button>
        </div>
      </div>
    </form>

    <hr style="border-top: 1px solid rgba(255, 255, 255, 0.2);">

    <p class="mt-2 mb-0 text-center">
      <?= lang('Auth.alreadyRegistered') ?>
      <a href="<?= base_url(route_to('login')) ?>" class="font-weight-bold">
        <?= lang('Auth.signIn') ?>
      </a>
    </p>
  </div>
</div>
<?= $this->endSection() ?>

⚙️ 7. Análisis Exhaustivo de los Estilos CSS Clave

Para comprender por qué este diseño luce consistente en diferentes navegadores, es indispensable analizar los detalles de implementación técnica:

1. La anatomía del grupo de campos (Input Groups)

En el HTML tradicional de Bootstrap, los campos con iconos se dividen en dos bloques contiguos: el elemento <input> a la izquierda y el contenedor .input-group-append con el .input-group-text a la derecha.

Si aplicáramos bordes redondeados estándar (border-radius: 25px) a ambos, obtendríamos dos píldoras separadas con una línea divisoria rota en el medio. Para solucionar esto y lograr una apariencia unificada, aplicamos una división matemática de curvatura:

CSS

/* Curva únicamente el extremo izquierdo (superior e inferior) */
.form-control {
    border-radius: 25px 0 0 25px;
    border-right: none;
}

/* Curva únicamente el extremo derecho (superior e inferior) */
.input-group-text {
    border-radius: 0 25px 25px 0;
    border-left: none;
}

De este modo, ambos elementos se fusionan visualmente formando una única cápsula aerodinámica, eliminando la frontera visual entre el texto que escribe el usuario y el icono descriptivo.

2. Microinteracciones y aceleración por GPU

Un buen diseño no es solo estático; debe responder con gracia a las interacciones del cursor humano. El botón primario .btn-primary implementa dos propiedades de rendimiento:

CSS

.btn-primary {
    transition: all 0.3s ease;
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

Al emplear transform: translateY(-2px) en lugar de modificar márgenes superiores (margin-top), el navegador delega la animación directamente a la tarjeta gráfica (GPU) mediante la composición de capas. El resultado es una interacción a 60 fotogramas por segundo (FPS), libre de parpadeos o tirones (jank).

3. La animación de entrada: fadeSlide

Para otorgar dinamismo al cargar la página, se implementó una animación de entrada suave:

CSS

@keyframes fadeSlide {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

Esta transición de 0.6 segundos produce la sensación visual de que la tarjeta de cristal levita suavemente desde la profundidad de la pantalla hacia el frente del usuario, aportando modernidad sin retrasar el tiempo de carga interactivo (Time to Interactive).

📈 8. Comparativa: Diseño Clásico vs. Estilo Glassmorphism Redondeado

Para apreciar el salto de calidad que aporta esta actualización en un software comercial, observemos la comparativa de atributos:

Criterio de DiseñoEnfoque Clásico (AdminLTE plano)Enfoque Renovado (Glassmorphism 2026)
Fondo de la tarjeta#ffffff sólido opaco al 100%rgba(255, 255, 255, 0.15) translúcido con filtro desenfoque
Radio de esquina4px a 8px (geometría dura rectangular)25px en tarjeta, botones y cajas de texto (forma de cápsula suave)
Contraste de InputsBlanco liso con bordes grises duros (#ced4da)Semitransparente con borde sutil al 30% y texto blanco puro
Integración con MarcaEl fondo no interactúa con el formularioEl fondo corporativo define los reflejos y matices de la tarjeta
Manejo de ContraseñaCampo ciego estándar sin visualizadorIcono interactivo en tiempo real con alternancia visual
Comportamiento MóvilTarjeta ancha con desbordamiento ocasionalAncho elástico al 90% con ajuste dinámico de relleno interno

💻 9. Optimización Técnica y Rendimiento: ¿Cómo Gestionar los Fondos?

El uso de imágenes en fondos de autenticación plantea un reto crítico: el peso de descarga. Si un usuario abre el sistema de ventas desde una sucursal con conexión a internet limitada, cargar una imagen de 10 Megabytes generará una pantalla congelada durante varios segundos.

Para garantizar un rendimiento sobresaliente, recomendamos seguir las siguientes prácticas de optimización:

Formatos y compresión recomendada

  1. Compresión PNG o WebP: Si utilizas el comando de conversión que vimos previamente con ImageMagick o FFmpeg, asegúrate de comprimir la imagen original:Bash# Conversión y optimización en Linux / macOS con ImageMagick magick input.jpg -resize 1920x1080\> -strip -quality 82 public/img/back.png
  2. Dimensiones ideales: La resolución recomendada para la imagen de fondo es de 1920 × 1080 píxeles (Full HD). En pantallas de mayor resolución (como 2K o 4K), la propiedad CSS background-size: cover; escala la imagen de forma limpia, mientras que el desenfoque blur(15px) de la tarjeta de login ocultará cualquier leve pérdida de nitidez en la zona central.
  3. El comodín del Degradado CSS: En caso de que el archivo back.png sea eliminado por mantenimiento o no se encuentre disponible, el código PHP ejecutará instantáneamente el respaldo de degradado radial:CSSradial-gradient(circle at top left, #1e3c72, transparent 60%), radial-gradient(circle at bottom right, #2a5298, transparent 60%), linear-gradient(135deg, #0f2027, #203a43, #2c5364); Este degradado consume exactamente cero peticiones HTTP, se procesa en microsegundos y mantiene una estética corporativa impecable.

📱 10. Ergonomía en Dispositivos Móviles y Terminales Punto de Venta (POS)

Un sistema de ventas actual ya no opera exclusivamente en ordenadores de sobremesa. En la práctica encontramos:

  • 📲 Vendedores en ruta levantando pedidos desde teléfonos Android y iPhone.
  • 📟 Tabletas montadas en mostradores de cobro en tiendas minoristas y restaurantes.
  • 🖥️ Terminales táctiles integradas tipo All-in-One en cajas registradoras.

Para estos casos de uso, se implementaron reglas específicas dentro de la directiva @media (max-width: 576px):

  • Se flexibilizó el ancho fijo de 360px a un dinámico 90%, evitando que la tarjeta choque con los marcos de pantallas móviles estrechas.
  • Se reajustó el espaciado interior (padding) de 2.5rem 2rem a 2rem 1.5rem, maximizando el espacio útil para que el teclado virtual en pantalla no oculte los botones de acción al desplegarse.
  • La altura de los inputs y botones supera los 44 píxeles, cumpliendo con los estándares de accesibilidad táctil recomendados por las guías de diseño de Apple y Google.

🏢 11. Casos de Aplicación Práctica en Negocios Reales

Este diseño ha sido pensado para adaptarse de forma camaleónica a cualquier sector comercial. A continuación te presentamos ideas de cómo personalizar la temática cambiando únicamente la imagen de fondo back.png:

  • 🛍️ Supermercados y tiendas de conveniencia: Coloca una fotografía de pasillos iluminados con carritos de compra y productos en exhibición; los tonos claros transmitirán abundancia y frescura.
  • 💊 Farmacias y clínicas de salud: Utiliza una imagen de fondo con mobiliario blanco y azul médico; la transparencia de la tarjeta aportará una atmósfera de esterilidad, tecnología y precisión médica.
  • 🍽️ Restaurantes, cafeterías y bares: Una fotografía cálida de la barra de cócteles o mesas de madera con luces colgantes generará un ambiente acogedor para meseros y anfitriones de sala.
  • 📦 Almacenes de mayoreo y logística: Imágenes industriales con estanterías de carga pesada y montacargas reforzarán la solidez de una herramienta de gestión de inventarios a gran escala.

🤝 12. Ecosistema Digital, Repositorios y Comunidad de Desarrollo

El desarrollo de software no se trata únicamente de escribir líneas de código; se trata de construir herramientas sostenibles, compartir conocimiento con la comunidad y colaborar continuamente.

Este desarrollo forma parte del ecosistema impulsado por Cesar Systems y el desarrollador Julio Reyes. Si deseas estar al tanto de futuras actualizaciones, acceder al código fuente completo, participar en debates técnicos o solicitar soporte para tus plataformas, te invitamos a consultar y guardar los siguientes enlaces oficiales:

🌐 Canales y Plataformas Oficiales:

  • 💻 Repositorio Oficial del Boilerplate: Accede directamente al código fuente del paquete, reporta incidencias y envía mejoras a través de GitHub: julio101290/boilerplate.
  • 🌐 Sitio Web Corporativo: Descubre las soluciones de software administrativo, puntos de venta y servicios empresariales en Cesar Systems Oficial.
  • 🧑‍💻 Perfil de GitHub del Desarrollador: Explora todos los proyectos de código abierto, librerías auxiliares y repositorios de Julio Reyes en GitHub @julio101290.
  • 📢 Canal de Telegram Oficial: Únete a nuestra comunidad activa para recibir notificaciones sobre nuevos parches, consejos de programación y lanzamientos en Telegram @CesarSystems.
  • ✍️ Blog de Tecnología y Novedades: Lee artículos técnicos a fondo, reflexiones sobre desarrollo y guías paso a paso en Shalom Now Blog.
  • 🎬 Canal de YouTube: Aprende con videotutoriales prácticos, demostraciones en vivo de los sistemas y explicaciones de arquitectura en YouTube @rasec555.

🚀 Cómo Implementar estos Cambios en tu Proyecto Paso a Paso

Si ya estás utilizando el paquete julio101290/boilerplate en tu instalación de CodeIgniter 4, aplicar esta transformación visual tomará menos de cinco minutos:

  1. Prepara tu imagen corporativa:
    • Selecciona una fotografía alusiva a tu empresa.
    • Conviértela a formato PNG con el nombre back.png.
    • Cópiala dentro de la carpeta pública de tu proyecto: public/img/back.png.
  2. Localiza los archivos de autenticación:
    • Dirígete a la ruta donde se alojan las vistas (app/Views/ o sobreescribe las vistas del vendor en julio101290\boilerplate\Views\Authentication\).
  3. Reemplaza el código:
    • Copia el código presentado en la Sección 4 para login.php.
    • Copia el código presentado en la Sección 5 para forgot.php.
    • Copia el código presentado en la Sección 6 para register.php.
  4. Limpia la caché de tu navegador:
    • Presiona Ctrl + F5 (o Cmd + Shift + R en macOS) para asegurarte de que los nuevos estilos CSS y el efecto backdrop-filter se rendericen de forma inmediata.

La interfaz de usuario no es un adorno: es el rostro visible de la ingeniería de software. Al otorgarle a tu sistema de ventas una apariencia atractiva, equilibrada y moderna, no solo elevas el valor percibido de tu producto ante clientes y directivos, sino que también brindas a los usuarios finales una herramienta en la que trabajar día a día se convierte en una experiencia visualmente agradable y placentera.

Cómo usar Composer con symlinks para desarrollo local en CodeIgniter 4

Entrada fija

Cuando trabajas con múltiples paquetes en PHP (como módulos propios), llega un punto donde necesitas debuggear directamente el código del paquete y no una copia dentro de vendor.

Si alguna vez terminaste debuggeando en vendor/ en lugar de tu proyecto real… esto es para ti.


🔥 El problema

Por defecto, Composer:

  • Descarga paquetes desde GitHub
  • Los copia en vendor/
  • Xdebug trabaja sobre esa copia

Resultado:

  • Código duplicado
  • Cambios no se reflejan
  • Debug incómodo

🧠 La solución: usar type: path

{
  "repositories": [
    {
      "type": "path",
      "url": "../boilerplateproducts",
      "options": {
        "symlink": true
      }
    }
  ]
}

⚙️ ¿Qué hace esto?

  • Usa tu carpeta local
  • No descarga desde GitHub
  • Crea un symlink en vendor

🔍 Verificar que funciona

composer update

Debes ver:

Installing julio101290/boilerplateproducts: Symlinking from ../boilerplateproducts

Y luego:

ls -l vendor/julio101290/boilerplateproducts

Resultado esperado:

boilerplateproducts -> ../../../boilerplateproducts

🚀 Beneficios

  • Debug directo en tu código
  • Cambios en tiempo real
  • Sin duplicación
  • Flujo más rápido

⚠️ Error común

No mezcles path y vcs:

{
  "type": "path",
  "url": "../boilerplateproducts"
},
{
  "type": "vcs",
  "url": "https://github.com/usuario/boilerplateproducts"
}

Composer puede ignorar el local y usar GitHub.


✅ Desarrollo correcto

rm -rf vendor composer.lock
composer update

🟢 Desarrollo vs Producción

Desarrollo

  • path
  • symlink
  • debug directo

Producción

  • vcs
  • descarga desde GitHub
  • entorno limpio

⚡ Scripts útiles

dev.sh

#!/bin/bash
rm -rf vendor composer.lock
COMPOSER=composer.local.json composer update

prod.sh

#!/bin/bash
rm -rf vendor composer.lock
composer update

🧠 Tip PRO

{
  "repositories": [
    {
      "type": "path",
      "url": "../boilerplateproducts",
      "options": { "symlink": true }
    }
  ],
  "config": {
    "preferred-install": "source"
  }
}

Ejecutar:

COMPOSER=composer.local.json composer update

💡 IDE

Puedes integrar esto con NetBeans usando scripts o herramientas externas.


✅ Conclusión

  • No debuggees código en vendor
  • Usa symlink
  • Automatiza tu flujo

Resultado: desarrollo más rápido y limpio 🚀

Boilerplate de Órdenes de Mantenimiento para CodeIgniter 4

Entrada fija
Versión Estable
Descargas Totales
Versión Inestable
Licencia

Boilerplate Mantenimiento

Boilerplate de Órdenes de Mantenimiento para CodeIgniter 4

Módulo de Gestión de Órdenes de Mantenimiento

Un módulo profesional y escalable para la gestión de órdenes de mantenimiento, desarrollado para CodeIgniter 4.

Este boilerplate está diseñado para:

  • Departamentos de TI
  • Talleres automotrices
  • Mantenimiento de equipos industriales
  • Centros de reparación en general

Características

  • Arquitectura modular (fácil integración)
  • Gestión completa de órdenes de mantenimiento
  • Catálogo de departamentos
  • Gestión de empleados
  • Asignación de activos por empleado
  • Dashboard con órdenes pendientes
  • Estructura escalable lista para integrarse en ERP

Requisitos

  • PHP 8.1 o superior
  • CodeIgniter 4
  • phpcfdi/sat-catalogos
  • julio101290/boilerplatelog
  • julio101290/boilerplateinventory

Instalación

Instalar vía Composer

composer require julio101290/boilerplatemaintenance

Ejecutar migraciones y seeders

php spark boilerplatemaintenance:installmaintenance

Capturas del Módulo

Dashboard – Órdenes Pendientes

Catálogo de Departamentos

Órdenes de Mantenimiento


Ejemplo de Integración en el Menú

Menú Principal de Mantenimiento

Dashboard

Departamentos

Empleados

Productos por Empleado

Órdenes de Mantenimiento


Sistema Listo


Uso

Revisa las rutas, controladores, modelos, vistas, migraciones y seeders para comprender el funcionamiento interno y adaptarlo a tu sistema.


Historial de Cambios

Consulta el archivo CHANGELOG para conocer las actualizaciones recientes.


Contribuciones

Las contribuciones son bienvenidas:

  1. Haz un fork del repositorio
  2. Crea una rama de mejora
  3. Envía un pull request

Licencia

Este paquete es software libre distribuido bajo la Licencia MIT.


Autor

Desarrollado y mantenido por Julio Leyva
¡Feliz programación! 🚀

Cómo Sobrescribir o Extender Clases en CodeIgniter 4.5: Caso Práctico con DataTables

Entrada fija

En muchos proyectos de desarrollo web con CodeIgniter 4, nos encontramos con la necesidad de modificar o extender clases de terceros sin alterar el código fuente original. Esto es especialmente común al trabajar con bibliotecas como Hermawan\DataTables, ampliamente utilizada para integrar DataTables con Eloquent y Query Builder.

Uno de los escenarios más comunes es sobrescribir la clase DataTableColumnDefs, ya sea para agregar soporte adicional (como compatibilidad con PostgreSQL) o personalizar cómo se gestionan las columnas y filtros de búsqueda.

En este artículo te mostraré cómo sobrescribir o extender esta clase correctamente en CodeIgniter 4.5, sin comprometer la mantenibilidad de tu proyecto.


🔍 ¿Por qué deberías sobrescribir una clase?

Modificar directamente los archivos de una librería externa puede parecer una solución rápida, pero es una mala práctica. Estas son algunas razones para evitarlo:

  • ❌ Pierdes la capacidad de actualizar el paquete con Composer.
  • ❌ Rompes el principio de separación de responsabilidades.
  • ✅ Extender o sobrescribir desde tu propia aplicación es más limpio y seguro.

🧱 Ejemplo: DataTableColumnDefs

La clase Hermawan\DataTables\DataTableColumnDefs es responsable de definir las columnas que serán procesadas por la tabla, sus alias, si son ordenables, buscables, etc.

Supongamos que quieres modificar el método getSearchable() para agregar compatibilidad con PostgreSQL (por ejemplo, usando CAST a texto y comillas dobles).


✅ Opción 1: Extender la clase original

Paso 1: Crea una nueva clase en app/Libraries

<?php

namespace App\Libraries;

use Hermawan\DataTables\DataTableColumnDefs;

class MyDataTableColumnDefs extends DataTableColumnDefs
{
    public function getSearchable()
    {
        // Aquí tu versión modificada del método original
        return parent::getSearchable(); // Puedes personalizarla como desees
    }
}

Paso 2: Usa tu clase en lugar de la original

use App\Libraries\MyDataTableColumnDefs;

$dt = new MyDataTableColumnDefs($builder);

🔁 Puedes sobrescribir cualquier otro método, como add, remove, o initFromBuilder.


✅ Opción 2: Reemplazar completamente la clase original

⚠️ Solo se recomienda si estás seguro de que no actualizarás el paquete regularmente.

Paso 1: Copia la clase original a app/Libraries/DataTableColumnDefs.php

Paso 2: Cambia el namespace

use App\Libraries\MyDataTableColumnDefs;

$dt = new MyDataTableColumnDefs($builder);

Paso 3: Modifica lo que necesites

Paso 4: Usa tu versión

use App\Libraries\MyDataTableColumnDefs;

$dt = new MyDataTableColumnDefs($builder);

✅ Opción 3: Sobrescribir vía Composer Autoload

Esta es una opción elegante y avanzada si necesitas que tu clase se cargue en lugar de la original sin cambiar el nombre.

Paso 1: Edita composer.json

"autoload": {
    "psr-4": {
        "Hermawan\\DataTables\\": "app/Overrides/DataTables/"
    }
}

Paso 2: Crea el archivo sobrescrito

app/Overrides/DataTables/DataTableColumnDefs.php

Paso 3: Copia el contenido original, modifica lo necesario

Paso 4: Ejecuta:

composer dump-autoload

✨ ¡Listo! CodeIgniter usará tu versión personalizada sin modificar el paquete original.


🎯 Conclusión

Sobrescribir o extender clases en CodeIgniter 4.5 te da la flexibilidad de adaptar librerías a tus necesidades sin sacrificar actualizaciones futuras o buenas prácticas de desarrollo. Ya sea para añadir soporte a PostgreSQL, cambiar la lógica de filtrado o mejorar la compatibilidad con tus modelos, hacerlo correctamente asegura que tu aplicación sea más escalable y mantenible.

¿Qué Base de Datos Elegir? Comparativa de MariaDB, PostgreSQL y SQL Server

Entrada fija
  • Si buscas una solución gratuita, potente, extensible y con una gran comunidad, ideal para una amplia variedad de aplicaciones (web, móviles, empresariales) y si no dependes fuertemente del ecosistema Microsoft: PostgreSQL es una excelente opción. Su robustez y características avanzadas lo hacen muy versátil.
  • Si necesitas una solución gratuita, con buen rendimiento y alta compatibilidad con MySQL, especialmente si ya tienes experiencia con MySQL o planeas una migración sencilla: MariaDB es una alternativa sólida.
  • Si tu infraestructura ya está fuertemente basada en productos Microsoft, necesitas una integración perfecta con ellos, un amplio conjunto de herramientas empresariales y soporte comercial robusto, y el presupuesto no es la principal limitante: SQL Server sería la opción más adecuada.

En resumen:

  • PostgreSQL: Versátil, potente, de código abierto, ideal para diversas aplicaciones.
  • MariaDB: Gratuita, buen rendimiento, compatible con MySQL.
  • SQL Server: Óptimo para entornos Microsoft, con amplias funcionalidades comerciales.

Para tomar la mejor decisión, te recomiendo considerar los siguientes factores específicos para tu situación en Los Mochis:

  • Requisitos de tu aplicación: ¿Qué tipo de datos manejarás? ¿Qué tipo de consultas realizarás? ¿Necesitas características específicas como geodatos?
  • Tamaño y escalabilidad esperada: ¿Cuánto crecerá tu base de datos y tu aplicación?
  • Experiencia de tu equipo: ¿Con qué base de datos están más familiarizados tus desarrolladores y administradores?
  • Presupuesto: ¿Puedes asumir los costos de licencia de SQL Server?
  • Infraestructura existente: ¿Qué sistemas operativos utilizas? ¿Necesitas una integración estrecha con otras herramientas?
  • Soporte local: ¿Hay experiencia y soporte técnico disponible en Los Mochis para alguna de estas bases de datos en particular?

Considerando que trabajarás con CodeIgniter 4, tanto MariaDB como PostgreSQL son excelentes opciones y muy populares en la comunidad de PHP y CodeIgniter. SQL Server también puede funcionar bien, pero podría tener algunas consideraciones adicionales.

MariaDB con CodeIgniter 4:

  • Ventajas:
    • Compatibilidad Directa: CodeIgniter 4 tiene un excelente soporte para MySQL, y dado que MariaDB es altamente compatible, la configuración y el uso serán muy sencillos.
    • Rendimiento: Puede ofrecer un buen rendimiento para aplicaciones web desarrolladas con CodeIgniter 4.
    • Facilidad de Uso: Muchos desarrolladores PHP están familiarizados con MySQL/MariaDB, lo que podría facilitar el desarrollo y la administración.
    • Código Abierto y Gratuito: Sin costos de licencia, lo cual es atractivo para muchos proyectos.
    • Comunidad: Amplia comunidad de usuarios de PHP y MySQL/MariaDB.
  • Desventajas:
    • Menos Características Avanzadas: Comparado con PostgreSQL, podría carecer de algunas características más avanzadas si tu aplicación en el futuro las necesitara (tipos de datos más complejos, extensiones como PostGIS, etc.).

PostgreSQL con CodeIgniter 4:

  • Ventajas:
    • Características Potentes: Ofrece características avanzadas que podrían ser útiles para aplicaciones más complejas (tipos de datos JSON, arrays, funciones avanzadas, etc.).
    • Integridad de Datos: Conocido por su robustez y cumplimiento de los estándares SQL, lo que puede contribuir a una mayor integridad de los datos.
    • Extensiones: La capacidad de extender su funcionalidad con extensiones como PostGIS para datos geoespaciales es una gran ventaja si tu aplicación lo requiere.
    • Rendimiento Sólido: Funciona muy bien con aplicaciones web y puede manejar grandes volúmenes de datos y consultas complejas de manera eficiente.
    • Comunidad: Una comunidad fuerte y activa dentro del mundo de PHP y PostgreSQL.
  • Desventajas:
    • Curva de Aprendizaje Ligeramente Mayor: Si no estás familiarizado con PostgreSQL, podría haber una pequeña curva de aprendizaje en comparación con MySQL/MariaDB.
    • Configuración Inicial: La configuración inicial podría tener algunos pasos ligeramente diferentes en comparación con MySQL/MariaDB.

SQL Server con CodeIgniter 4:

  • Ventajas:
    • Potencia y Funcionalidades: Ofrece un conjunto robusto de características empresariales.
    • Integración (si usas Windows Server): Si tu servidor corre en Windows Server, la integración podría ser más sencilla en algunos aspectos.
  • Desventajas:
    • Costo de Licencia: El costo de las licencias puede ser un factor limitante.
    • Configuración Adicional: La configuración para que CodeIgniter 4 se conecte a SQL Server podría requerir algunos pasos adicionales y la instalación de drivers específicos.
    • Menor Popularidad en el Mundo PHP: Aunque funciona, no es tan comúnmente utilizado con PHP como MariaDB o PostgreSQL, por lo que la comunidad y los ejemplos específicos para CodeIgniter 4 podrían ser menores.

¿Cuál es la mejor opción para CodeIgniter 4 ?

Considerando que se usara CodeIgniter 4, tanto MariaDB como PostgreSQL son excelentes opciones.

  • Si buscas simplicidad, familiaridad (si vienes de MySQL), buen rendimiento para aplicaciones web típicas y una configuración sencilla con CodeIgniter 4, MariaDB es una opción muy sólida y popular.
  • Si anticipas que tu aplicación podría necesitar características más avanzadas en el futuro, valoras la integridad de los datos, o quieres tener la flexibilidad de usar extensiones potentes como PostGIS, PostgreSQL es una opción fantástica y cada vez más popular en la comunidad PHP.

Mi recomendación general para CodeIgniter 4 sería:

  • Si no tienes necesidades muy específicas y buscas una solución probada y sencilla, elige MariaDB. Es muy probable que cumpla con todos tus requisitos para la mayoría de las aplicaciones web.
  • Si prevés que tu aplicación crecerá en complejidad o necesitará características más avanzadas, o si simplemente prefieres la potencia y las características de PostgreSQL, entonces esta sería una excelente elección. CodeIgniter 4 tiene un buen soporte para PostgreSQL.

SQL Server podría ser una buena opción si ya tienes una fuerte inversión en el ecosistema Microsoft y esa es la base de datos estándar en tu entorno. Sin embargo, para un proyecto nuevo con CodeIgniter 4, MariaDB o PostgreSQL suelen ser opciones más comunes y con una integración más directa en el mundo del desarrollo PHP.

En resumen, para CodeIgniter 4, te recomendaría inclinarte por MariaDB por su simplicidad y compatibilidad directa, o por PostgreSQL si anticipas necesidades más avanzadas en el futuro. Ambas son excelentes bases de datos y funcionarán muy bien con el framework. ¡La elección final dependerá de tus requisitos específicos!

CodeIgniter 4 Boilerplate Carta Porte

Entrada fija
Latest Stable Version
Total Downloads
Latest Unstable Version
License

   

image

CodeIgniter 4 Boilerplate Carta Porte

library to generate carta porte complement CFDI 4.0

CodeIgniter 4 Que es Carta Porte

La Carta Porte es un documento fiscal digital que se utiliza en México para amparar el traslado de bienes y mercancías dentro del territorio nacional. Su principal función es acreditar la legal posesión de la mercancía durante su transporte, así como proporcionar información detallada sobre el origen y destino de la misma.

Aquí hay algunos puntos clave sobre la Carta Porte:

  • Documento fiscal digital: Es un comprobante fiscal electrónico (CFDI) al que se le incorpora el complemento Carta Porte.
  • Ampara el traslado de mercancías: Acredita la legal estancia y/o tenencia de los bienes o mercancías durante su traslado en territorio nacional.
  • Identifica el origen y destino: Proporciona información detallada sobre el lugar de donde provienen las mercancías y a dónde se dirigen.
  • Combate el contrabando: Ayuda a prevenir el contrabando y la competencia desleal entre empresas transportistas.
  • Facilita la trazabilidad: Permite rastrear la mercancía durante todo su recorrido.
  • Contrato de transporte: Funciona como un contrato legal entre el remitente, el transportista y el destinatario, estableciendo los términos y condiciones del transporte.

En resumen, la Carta Porte es un documento esencial para el transporte de mercancías en México, ya que garantiza la legalidad, seguridad y trazabilidad de los bienes durante su traslado.

Requerimientos

  • PhpCfdi\SatCatalogos
  • julio101290/boilerplatelog
  • hermawan/codeigniter4-datatables

Instalación

Ejecutar Comandos para la instalación de la librería

composer require phpcfdi/sat-catalogos

composer require hermawan/codeigniter4-datatables

composer require julio101290/boilerplatelog

composer require julio101290/boilerplatecompanies

composer require julio101290/boilerplatestorages
composer require julio101290/boilerplatecartaporte

Ejecutar los comando de migración de las tablas y sembrado de los datos

php spark boilerplatecompanies:installcompaniescrud

php spark boilerplatelog:installlog

php spark boilerplatestorages:installstorages

php spark boilerplatecartaporte:installcartaporte

Creamos el Menú Ejemplo

image

Listo

image
image

Usage

You can find how it works with the read code routes, controller and views etc. Finnally… Happy Coding!

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Contributions are very welcome.

License

This package is free software distributed under the terms of the MIT license.

CodeIgniter 4 Boilerplate Ubicaciones ( Carta Porte)

Entrada fija
Latest Stable Version
Total Downloads
Latest Unstable Version
License

   

image

CodeIgniter 4 Boilerplate Ubicaciones ( Carta Porte)

Biblioteca a ubicaciones, requerida para carta portuaria (Carta Porte) CFDI 4.0

Requerimientos

  • PhpCfdi\SatCatalogos
  • julio101290/boilerplatelog
  • hermawan/codeigniter4-datatables

Instalación

Ejecutar Comandos

composer require phpcfdi/sat-catalogos

composer require hermawan/codeigniter4-datatables
	
composer require julio101290/boilerplatelog

composer require julio101290/boilerplatecompanies

composer require julio101290/boilerplatestorages

composer require julio101290/boilerplatetypesmovement

composer require julio101290/boilerplatequotes

composer require julio101290/boilerplatecomprobanterd

composer require julio101290/boilerplatesells

composer require julio101290/boilerplatelocations

Ejecutar Comandos de migración de las tablas y sembrado de los datos

php spark boilerplatecompanies:installcompaniescrud

php spark boilerplatelog:installlog

php spark boilerplatestorages:installstorages

php spark boilerplatetypesmovement:installtypesmovement

php spark boilerplatequotes:installquotes

php spark boilerplatecomprobanterd:installcomprobanterd

php spark boilerplatequotes:installsells

php spark boilerplatelocations:installlocations

Ejemplo para crear el Menú

image

Listo

image

Usage

You can find how it works with the read code routes, controller and views etc. Finnally… Happy Coding!

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Contributions are very welcome.

License

This package is free software distributed under the terms of the MIT license.

CodeIgniter 4 Boilerplate Ventas

Entrada fija
Latest Stable Version
Total Downloads
Latest Unstable Version
License

   

CodeIgniter 4 Boilerplate Ventas

Biblioteca CodeIgniter4 Boilerplatesells para generar ventas con formato de impresión PDF, CFD4.0 Factura para enviar a los clientes por correo electrónico.

Requerimientos

  • PhpCfdi\SatCatalogos
  • julio101290/boilerplatelog
  • hermawan/codeigniter4-datatables

Instalación

Ejecutar Comandos

composer require phpcfdi/sat-catalogos

composer require hermawan/codeigniter4-datatables

composer require julio101290/boilerplatelog

composer require julio101290/boilerplatecompanies

composer require julio101290/boilerplatestorages

composer require julio101290/boilerplatetypesmovement

composer require julio101290/boilerplatequotes

composer require julio101290/boilerplatecomprobanterd

composer require julio101290/boilerplatesells

Ejecutar comandos de migracion y sembrado

php spark boilerplatecompanies:installcompaniescrud

php spark boilerplatelog:installlog

php spark boilerplatestorages:installstorages

php spark boilerplatetypesmovement:installtypesmovement

php spark boilerplatequotes:installquotes

php spark boilerplatecomprobanterd:installcomprobanterd

php spark boilerplatequotes:installsells

Creamos el menu, Ejemplo

image

Listo, vemos algunos ejemplo de funcionamiento

image
image
image
image
image
image
image

Usage

You can find how it works with the read code routes, controller and views etc. Finnally… Happy Coding!

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Contributions are very welcome.

License

This package is free software distributed under the terms of the MIT license.

CodeIgniter 4 Boilerplate CFDI Series Electrónicas

Entrada fija
Latest Stable Version
Total Downloads
Latest Unstable Version
License

   

image

CodeIgniter 4 Boilerplate CFDI Series Electrónicas

Biblioteca para la administración de series electrónicas CRUD CFDI para facturas, notas de crédito, pagos etc.

Requerimientos

  • julio101290/boilerplatelog
  • hermawan/codeigniter4-datatables

Instalación

Ejecutar Comandos

composer require phpcfdi/sat-catalogos

composer require hermawan/codeigniter4-datatables

composer require julio101290/boilerplatelog

composer require julio101290/boilerplatecompanies

composer require julio101290/boilerplatecfdielectronicseries

Ejecutar comandos para el sembrado y migración de las tablas

php spark boilerplatecompanies:installcompaniescrud

php spark boilerplatelog:installlog

php spark boilerplatecfdielectronicseries:installcfdielectronicseries

Creando el Menú, Ejemplo

image

Listo

image

Usage

You can find how it works with the read code routes, controller and views etc. Finnally… Happy Coding!

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Contributions are very welcome.

License

This package is free software distributed under the terms of the MIT license.

CodeIgniter 4 Boilerplate CFDI

Entrada fija
Latest Stable Version
Total Downloads
Latest Unstable Version
License

   

image

CodeIgniter 4 Boilerplate CFDI

Biblioteca para la administración de facturas electrónicas mexicanas CFDI, impresión, carga, descarga, etc.

Requerimientos

  • PhpCfdi\SatCatalogos
  • julio101290/boilerplatelog
  • hermawan/codeigniter4-datatables
  • phpcfdi/cfditopdf
  • phpcfdi/cfdi-to-json”
  • phpcfdi/xml-cancelacion

Instalación

Ejecutar comandos

composer require phpcfdi/sat-catalogos

composer require hermawan/codeigniter4-datatables

composer require julio101290/boilerplatelog

composer require julio101290/boilerplatecompanies

composer require julio101290/boilerplatestorages

composer require julio101290/boilerplatetypesmovement

composer require julio101290/boilerplatecfdi


Ejecutar comandos de migración y sembrado

php spark boilerplatecompanies:installcompaniescrud

php spark boilerplatelog:installlog

php spark boilerplatestorages:installstorages

php spark boilerplatetypesmovement:installtypesmovement

php spark boilerplatequotes:installquotes

php spark boilerplatecfdi:installcfdi

Creando el ménu, Ejemplo grafico

image

Listo

image
image
image
image

Usage

You can find how it works with the read code routes, controller and views etc. Finnally… Happy Coding!

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Contributions are very welcome.

License

This package is free software distributed under the terms of the MIT license.

Página 1 de 3

Creado con WordPress & Tema de Anders Norén