Prepare modules

This commit is contained in:
2025-03-22 12:44:30 -06:00
parent 099267ee07
commit 7d8566350d
137 changed files with 3723 additions and 4325 deletions

View File

@ -0,0 +1,41 @@
<div>
<div id="app-description-settings-card" class="form-custom-listener mb-4">
<x-vuexy-admin::card.basic title="Datos de la aplicación" class="mb-4">
<x-vuexy-admin::form.input
label="Titulo de la aplicación"
model="app_name"
placeholder="Nombre corto" />
<x-vuexy-admin::form.input
label="Titulo del sitio"
model="title"
placeholder="Titulo del sitio" />
<x-vuexy-admin::form.textarea
label="Descripción del sitio"
model="description"
placeholder="Descripción del sitio" />
</x-vuexy-admin::card.basic>
<div class="row">
<div class="col-lg-12 text-end">
<x-vuexy-admin::button.basic
variant="primary"
size="sm"
icon="ti ti-device-floppy"
label="Guardar cambios"
disabled
wire:click="save"
class="btn-save"
waves />
<x-vuexy-admin::button.basic
variant="secondary"
size="sm"
icon="ti ti-rotate-2"
label="Cancelar"
disabled
wire:click="resetForm"
class="btn-cancel"
waves />
</div>
</div>
<div class="notification-container pt-4" wire:ignore></div>
</div>
</div>

View File

@ -0,0 +1,84 @@
<div>
<div id="app-favicon-settings-card" class="mb-4">
<x-vuexy-admin::card.basic title="Favicon" class="mb-2">
<x-vuexy-admin::form.input
type="file"
label="Icono de navegador"
model="upload_image_favicon"
accept="image/*" />
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
<div class="text-center flex flex-col items-center">
<div class="mb-3 text-center d-flex flex-column align-items-center">
<div class="image-wrapper-16x16 d-flex justify-content-center align-items-center">
<img src="{{ $upload_image_favicon ? $upload_image_favicon->temporaryUrl() : asset('storage/' . $admin_favicon_16x16) }}">
</div>
<span class="text-muted mt-1">Navegadores web (16x16)</span>
</div>
</div>
<div class="text-center flex flex-col items-center">
<div class="mb-3 text-center d-flex flex-column align-items-center">
<div class="image-wrapper-76x76 d-flex justify-content-center align-items-center">
<img src="{{ $upload_image_favicon ? $upload_image_favicon->temporaryUrl() : asset('storage/' . $admin_favicon_76x76) }}">
</div>
<span class="text-muted mt-1">iPad sin Retina (76x76)</span>
</div>
</div>
<div class="text-center flex flex-col items-center">
<div class="mb-3 text-center d-flex flex-column align-items-center">
<div class="image-wrapper-120x120 d-flex justify-content-center align-items-center">
<img src="{{ $upload_image_favicon ? $upload_image_favicon->temporaryUrl() : asset('storage/' . $admin_favicon_120x120) }}">
</div>
<span class="text-muted mt-1">iPhone (120x120)</span>
</div>
</div>
<div class="text-center flex flex-col items-center">
<div class="mb-3 text-center d-flex flex-column align-items-center">
<div class="image-wrapper-152x152 d-flex justify-content-center align-items-center">
<img src="{{ $upload_image_favicon ? $upload_image_favicon->temporaryUrl() : asset('storage/' . $admin_favicon_152x152) }}">
</div>
<span class="text-muted mt-1">iPad (152x152)</span>
</div>
</div>
<div class="text-center flex flex-col items-center">
<div class="mb-3 text-center d-flex flex-column align-items-center">
<div class="image-wrapper-180x180 d-flex justify-content-center align-items-center">
<img src="{{ $upload_image_favicon ? $upload_image_favicon->temporaryUrl() : asset('storage/' . $admin_favicon_180x180) }}">
</div>
<span class="text-muted mt-1">iPhone con Retina HD (180x180)</span>
</div>
</div>
<div class="text-center flex flex-col items-center">
<div class="mb-3 text-center d-flex flex-column align-items-center">
<div class="image-wrapper-192x192 d-flex justify-content-center align-items-center">
<img src="{{ $upload_image_favicon ? $upload_image_favicon->temporaryUrl() : asset('storage/' . $admin_favicon_192x192) }}">
</div>
<span class="text-muted mt-1">Android y otros dispositivos móviles (192x192)</span>
</div>
</div>
</div>
</x-vuexy-admin::card.basic>
<div class="row">
<div class="col-lg-12 text-end">
<x-vuexy-admin::button.basic
variant="primary"
size="sm"
icon="ti ti-device-floppy"
label="Guardar cambios"
wire:click="save"
:disabled="$upload_image_favicon === null"
class="btn-save mt-2 mr-2"
waves />
<x-vuexy-admin::button.basic
variant="secondary"
size="sm"
icon="ti ti-rotate-2"
label="Cancelar"
wire:click="resetForm"
:disabled="$upload_image_favicon === null"
class="btn-cancel mt-2 mr-2"
waves />
</div>
</div>
<div class="notification-container pt-4" wire:ignore></div>
</div>
</div>

View File

@ -0,0 +1,69 @@
<div x-data>
<div id="interface-settings-card" class="form-custom-listener mb-4">
<div class="row">
<div class="col-md-6">
{{-- Tema --}}
<x-vuexy-admin::card.basic title="Ajustes de tema" class="mb-6">
<x-vuexy-admin::form.select :uid="$uniqueId" model="vuexy_myTheme" label="Tema" :options="['theme-default' => 'Tema predeterminado', 'theme-bordered' => 'Tema bordeado', 'theme-semi-dark' => 'Tema semi-oscuro']" />
<x-vuexy-admin::form.select :uid="$uniqueId" model="vuexy_myStyle" label="Estilo" :options="['light' => 'Claro', 'dark' => 'Oscuro', 'system' => 'Modo del sistema']" />
</x-vuexy-admin::card.basic>
{{-- Diseño --}}
<x-vuexy-admin::card.basic title="Ajustes de diseño" class="mb-6">
<x-vuexy-admin::form.select :uid="$uniqueId" model="vuexy_authViewMode" label="Modo de vista de autenticación" :options="['cover' => 'Pantalla completa', 'basic' => 'Básico']" />
<x-vuexy-admin::form.select :uid="$uniqueId" model="vuexy_contentLayout" label="Ancho predeterminado" :options="['compact' => 'Compacto', 'wide' => 'Ancho completo']" />
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="vuexy_footerFixed" label="Fijar pie de página" switch />
</x-vuexy-admin::card.basic>
</div>
<div class="col-md-6">
{{-- Ajustes de menú y barra superior --}}
<x-vuexy-admin::card.basic title="Ajustes menú y barra superior" class="mb-6">
{{-- Diseño (Layout) --}}
<x-vuexy-admin::form.select :uid="$uniqueId" model="vuexy_myLayout" label="Diseño de menú" :options="['vertical' => 'Vertical', 'horizontal' => 'Horizontal']" />
{{-- Horizontal layout --}}
<div x-show="$wire.vuexy_myLayout === 'horizontal'" x-cloak x-transition>
<x-vuexy-admin::form.select :uid="$uniqueId" model="vuexy_headerType" label="Tipo de barra superior" :options="['static' => 'Estático', 'fixed' => 'Fijo']" />
</div>
{{-- Vertical layout --}}
<div x-show="$wire.vuexy_myLayout === 'vertical'" x-cloak x-transition>
<x-vuexy-admin::form.select :uid="$uniqueId" model="vuexy_navbarType" label="Tipo de barra de navegación" :options="['sticky' => 'Fija', 'static' => 'Estática', 'hidden' => 'Oculta']" />
</div>
{{-- Personalizador activo --}}
<div x-show="$wire.vuexy_myLayout === 'horizontal'" x-cloak x-transition>
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="vuexy_showDropdownOnHover" label="Mostrar desplegable al pasar el mouse" switch />
</div>
{{-- Opciones para diseño vertical --}}
<div x-show="$wire.vuexy_myLayout === 'vertical'" x-cloak x-transition>
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="vuexy_menuFixed" label="Menú fijo" switch />
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="vuexy_menuCollapsed" label="Menú colapsado" switch />
</div>
</x-vuexy-admin::card.basic>
{{-- Atajos --}}
<div x-show="$wire.vuexy_myLayout === 'horizontal' || $wire.vuexy_navbarType !== 'hidden'" x-cloak x-transition>
<x-vuexy-admin::card.basic title="Atajos" class="mb-6">
<x-vuexy-admin::form.input type="number" :uid="$uniqueId" model="vuexy_maxQuickLinks" label="Máximo de enlaces rápidos" min="2" max="20" helperText="Selecciona un valor entre 2 y 20." />
</x-vuexy-admin::card.basic>
</div>
{{-- Personalizador de plantilla --}}
<x-vuexy-admin::card.basic title="Personalizador de plantilla" class="mb-6">
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="vuexy_hasCustomizer" label="Habilitar personalizador de plantilla" switch />
<div x-show="$wire.vuexy_hasCustomizer" x-cloak x-transition>
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="vuexy_displayCustomizer" label="Mostrar personalizador de plantilla" switch />
</div>
</x-vuexy-admin::card.basic>
</div>
</div>
{{-- Acciones --}}
<div class="row">
<div class="col-lg-12 text-end">
<x-vuexy-admin::button.basic wire:click="save" disabled variant="primary" icon="ti ti-check" label="Aplicar cambios" class="btn-save mb-2 mx-2" size="sm" waves />
<x-vuexy-admin::button.basic wire:click="resetForm" disabled variant="secondary" icon="ti ti-rotate-2" label="Cancelar" class="btn-cancel mb-2 mx-2" size="sm" waves />
<x-vuexy-admin::button.basic wire:click="clearCustomConfig" variant="success" icon="ti ti-adjustments-cog" label="Restaurar valores predeterminados" class="btn-reset mb-2 mx-2" size="sm" waves />
</div>
</div>
{{-- Notificaciones --}}
<div class="notification-container pt-4" wire:ignore></div>
</div>
</div>

View File

@ -0,0 +1,39 @@
<div>
<div id="logo-on-dark-bg-settings-card" class="mb-4">
<x-vuexy-admin::card.basic title="Logotipo sobre fondo oscuro" class="mb-2">
<x-vuexy-admin::form.input
type="file"
label="Logotipo sobre fondo oscuro"
model="upload_image_logo_dark"
accept="image/*" />
<div class="mb-3 text-center align-items-center">
<div class="justify-content-center align-items-center bg-slate-800 p-4">
<img src="{{ $upload_image_logo_dark ? $upload_image_logo_dark->temporaryUrl() : asset('storage/' . $admin_image_logo_dark) }}">
</div>
</div>
</x-vuexy-admin::card.basic>
<div class="row">
<div class="col-lg-12 text-end">
<x-vuexy-admin::button.basic
variant="primary"
size="sm"
icon="ti ti-device-floppy"
disabled="{{ $upload_image_logo_dark === null }}"
label="Guardar cambios"
wire:click="save"
class="btn-save mt-2 mr-2"
waves />
<x-vuexy-admin::button.basic
variant="secondary"
size="sm"
icon="ti ti-rotate-2"
disabled="{{ $upload_image_logo_dark === null }}"
label="Cancelar"
wire:click="resetForm"
class="btn-cancel mt-2 mr-2"
waves />
</div>
</div>
<div class="notification-container pt-4" wire:ignore></div>
</div>
</div>

View File

@ -0,0 +1,39 @@
<div>
<div id="logo-on-light-bg-settings-card" class="mb-4">
<x-vuexy-admin::card.basic title="Logotipo sobre fondo claro" class="mb-2">
<x-vuexy-admin::form.input
type="file"
label="Logotipo sobre fondo claro"
model="upload_image_logo"
accept="image/*" />
<div class="mb-3 text-center align-items-center">
<div class="justify-content-center align-items-center bg-slate-100 p-4">
<img src="{{ $upload_image_logo ? $upload_image_logo->temporaryUrl() : asset('storage/' . $admin_image_logo) }}">
</div>
</div>
</x-vuexy-admin::card.basic>
<div class="row">
<div class="col-lg-12 text-end">
<x-vuexy-admin::button.basic
variant="primary"
size="sm"
icon="ti ti-device-floppy"
disabled="{{ $upload_image_logo === null }}"
label="Guardar cambios"
wire:click="save"
class="btn-save mt-2 mr-2"
waves />
<x-vuexy-admin::button.basic
variant="secondary"
size="sm"
icon="ti ti-rotate-2"
disabled="{{ $upload_image_logo === null }}"
label="Cancelar"
wire:click="resetForm"
class="btn-cancel mt-2 mr-2"
waves />
</div>
</div>
<div class="notification-container pt-4" wire:ignore></div>
</div>
</div>

View File

@ -0,0 +1,53 @@
@php
/**
* Vista Blade para mostrar los accesos rápidos.
* Compatible con Vuexy Admin y modo oscuro.
*/
@endphp
<div class="p-6 space-y-8">
@foreach ($quickAccessItems as $category)
<div class="mb-8">
<!-- Título de categoría con icono -->
<div class="d-flex align-items-center mb-3">
<i class="{{ $category['icon'] }} text-3xl text-primary"></i>
<h5 class="mb-0 ms-2 text-dark dark:text-white">{{ $category['title'] }}</h5>
</div>
<!-- Descripción de categoría -->
@if (!empty($category['description']))
<p class="text-muted">
{{ $category['description'] }}
</p>
@endif
<!-- Grid de accesos rápidos en formato de Cards -->
@if (!empty($category['submenu']))
<div class="row row-cols-2 row-cols-md-4 row-cols-lg-5 g-4">
@foreach ($category['submenu'] as $item)
<div class="col">
<a href="{{ $item['url'] }}" class="text-decoration-none">
<div class="card border-0 shadow-sm hover:shadow-lg transition-all duration-300">
<div class="card-body d-flex flex-column align-items-center justify-content-center text-center p-4">
<!-- Ícono -->
<i class="{{ $item['icon'] }} text-4xl text-primary mb-2"></i>
<!-- Título -->
<h6 class="mb-0 text-dark dark:text-light fw-semibold">
{{ $item['title'] }}
</h6>
</div>
</div>
</a>
</div>
@endforeach
</div>
@else
<p class="text-muted fst-italic">
No hay accesos rápidos en esta categoría.
</p>
@endif
</div>
@endforeach
</div>

View File

@ -0,0 +1,86 @@
<div x-data="{
changeSmtpSettings: @entangle('change_smtp_settings'),
saveButtonDisabled: @entangle('save_button_disabled'),
}">
<form id="sendmail-settings-card">
<div class="card mb-6">
<h5 class="card-header">Servidor saliente de correo electrónico</h5>
<div class="card-body">
<div class="mb-3">
<x-vuexy-admin::form.checkbox
wire:model='change_smtp_settings'
parent_class='form-switch'>
Cambiar configuración
</x-form.checkbox>
</div>
<div class="mb-3 fv-row">
<label for="host" class="form-label">Servidor de correo saliente (SMTP)</label>
<input type="text" name="host" id="host" wire:model='host' class="form-control" placeholder="Servidor de salida" :disabled="!changeSmtpSettings">
@error('host') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3 fv-row">
<label for="port" class="form-label">Puerto SMTP</label>
<input type="number" name="port" id="port" wire:model='port' class="form-control" placeholder="Puerto SMTP" :disabled="!changeSmtpSettings">
@error('port') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3 fv-row">
<label for="encryption" class="form-label">Encriptación</label>
<x-vuexy-admin::form.select
wire:model='encryption'
:options="$encryption_options"
:disabled="!$change_smtp_settings"
placeholder="Selecciona el método de encriptación" />
@error('encryption') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3 fv-row">
<label for="username" class="form-label">Usuario</label>
<input type="text" name="username" id="username" wire:model='username' class="form-control" placeholder="Usuario" autocomplete="username" :disabled="!changeSmtpSettings">
@error('username') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="fv-row">
<label for="password" class="form-label">Contraseña</label>
<input type="password" name="password" id="password" wire:model='password' class="form-control" placeholder="Contraseña" autocomplete="current-password" :disabled="!changeSmtpSettings">
@error('password') <span class="text-danger">{{ $message }}</span> @enderror
</div>
</div>
</div>
<div>
{{-- Botones --}}
<div class="row my-4">
<div class="col-lg-12 text-end">
<button
type="button"
id="test_smtp_connection_button"
class="btn btn-success btn-sm mt-2 mr-2 waves-effect waves-light"
:disabled="!changeSmtpSettings"
data-loading-text="Realizando prueba...">
<i class="ti ti-flask mr-2"></i>
Realizar una prueba
</button>
<button
type="submit"
id="save_smtp_connection_button"
class="btn btn-primary btn-sm mt-2 mr-2 waves-effect waves-light"
:disabled="saveButtonDisabled"
wire:click="save"
data-loading-text="Guardando...">
<i class="ti ti-device-floppy mr-2"></i>
Guardar cambios
</button>
<button
type="button"
id="cancel_smtp_connection_button"
class="btn btn-secondary btn-sm mt-2 mr-2 waves-effect waves-light"
wire:click="loadSettings"
:disabled="!changeSmtpSettings">
<i class="ti ti-rotate-2 mr-2"></i>
Cancelar
</button>
</div>
</div>
{{-- Notifications --}}
<div class="notification-container pt-4" wire:ignore></div>
</div>
</form>
</div>