Prepare modules
This commit is contained in:
@ -1,70 +0,0 @@
|
||||
<div>
|
||||
<div class="form-custom-listener" id="application-settings-card">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Información de aplicación</h5>
|
||||
<div class="fv-row mb-3">
|
||||
<label for="admin_app_name" class="form-label">
|
||||
Titulo de aplicación <span class="text-xs">(Nombre corto)</span>
|
||||
</label>
|
||||
<input type="text" id="admin_app_name" wire:model="admin_app_name" class="form-control" placeholder="Titulo de aplicación">
|
||||
@error('admin_app_name')
|
||||
<span class="text-danger">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="fv-row mb-6">
|
||||
<h5>Logotipo tema claro</h5>
|
||||
<div class="fv-row mb-4">
|
||||
<input type="file" wire:model="upload_image_logo" id="upload_image_logo" class="form-control" accept="image/*" />
|
||||
@error('upload_image_logo')
|
||||
<span class="text-danger">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mb-8 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>
|
||||
<h5>Logotipo tema obscuro</h5>
|
||||
<div class="fv-row mb-4">
|
||||
<input type="file" wire:model="upload_image_logo_dark" id="upload_image_logo_dark" class="form-control" accept="image/*" />
|
||||
@error('upload_image_logo_dark')
|
||||
<span class="text-danger">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{{-- Botones --}}
|
||||
<div class="row my-4">
|
||||
<div class="col-lg-12 text-end">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="save"
|
||||
class="btn btn-primary btn-save btn-sm mt-2 mr-2 waves-effect waves-light"
|
||||
:disabled="{{ $upload_image_logo === null && $upload_image_logo_dark === null ? 'true' : 'false' }}"
|
||||
data-loading-text="Guardando...">
|
||||
<i class="ti ti-device-floppy mr-2"></i>
|
||||
Guardar cambios
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="loadSettings"
|
||||
class="btn btn-secondary btn-cancel btn-sm mt-2 mr-2 waves-effect waves-light"
|
||||
:disabled="{{ $upload_image_logo === null && $upload_image_logo_dark === null ? 'true' : 'false' }}">
|
||||
<i class="ti ti-rotate-2 mr-2"></i>
|
||||
Cancelar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,105 +0,0 @@
|
||||
<div>
|
||||
<div class="form-custom-listener" id="general-settings-card">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Información de página web</h5>
|
||||
<div class="fv-row mb-3">
|
||||
<label for="admin_title" class="form-label">
|
||||
Titulo del sitio <span class="text-xs">(Nombre completo)</span>
|
||||
</label>
|
||||
<input type="text" id="admin_title" wire:model="admin_title" class="form-control"
|
||||
placeholder="Titulo del sitio">
|
||||
@error('admin_title')
|
||||
<span class="text-danger">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="fv-row mb-6">
|
||||
<label for="upload_image_favicon" class="form-label">
|
||||
Icono de página <span class="text-xs">(Favicon)</span>
|
||||
</label>
|
||||
<input type="file" wire:model="upload_image_favicon" id="upload_image_favicon" class="form-control"
|
||||
accept="image/*" />
|
||||
@error('upload_image_favicon')
|
||||
<span class="text-danger">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{{-- Botones --}}
|
||||
<div class="row my-4">
|
||||
<div class="col-lg-12 text-end">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="save"
|
||||
class="btn btn-primary btn-save btn-sm mt-2 mr-2 waves-effect waves-light"
|
||||
{{ !$upload_image_favicon ? 'disabled' : '' }}
|
||||
data-loading-text="Guardando...">
|
||||
<i class="ti ti-device-floppy mr-2"></i>
|
||||
Guardar cambios
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="loadSettings"
|
||||
class="btn btn-secondary btn-cancel btn-sm mt-2 mr-2 waves-effect waves-light"
|
||||
{{ !$upload_image_favicon ? 'disabled' : '' }}>
|
||||
<i class="ti ti-rotate-2 mr-2"></i>
|
||||
Cancelar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,196 +0,0 @@
|
||||
<div>
|
||||
<div class="form-custom-listener" id="interface-settings-card">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Ajustes menú y barra superior</h5>
|
||||
|
||||
{{-- Diseño (Layout) --}}
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_myLayout" class="form-label">Diseño</label>
|
||||
<select id="vuexy_myLayout" class="form-select" wire:model="vuexy_myLayout">
|
||||
<option value="vertical">Vertical</option>
|
||||
<option value="horizontal">Horizontal</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{-- Campos exclusivos para diseño Horizontal --}}
|
||||
<div x-show="$wire.vuexy_myLayout === 'horizontal'" x-transition>
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_headerType" class="form-label">Tipo de barra superior</label>
|
||||
<select id="vuexy_headerType" class="form-select" wire:model="vuexy_headerType">
|
||||
<option value="static">Estático</option>
|
||||
<option value="fixed">Fijo</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Campos exclusivos para diseño Vertical --}}
|
||||
<div x-show="$wire.vuexy_myLayout === 'vertical'" x-transition>
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_navbarType" class="form-label">Tipo de barra de navegación</label>
|
||||
<select id="vuexy_navbarType" class="form-select" wire:model="vuexy_navbarType">
|
||||
<option value="sticky">Fija</option>
|
||||
<option value="static">Estática</option>
|
||||
<option value="hidden">Oculta</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="$wire.vuexy_hasCustomizer" x-transition>
|
||||
<div x-show="$wire.vuexy_myLayout === 'horizontal'" x-transition>
|
||||
<div class="mb-3">
|
||||
<x-vuexy-admin::form.checkbox
|
||||
wire:model='vuexy_showDropdownOnHover'
|
||||
parent_class='form-switch'>
|
||||
Mostrar desplegable al pasar el mouse
|
||||
</x-vuexy-admin::form.checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Campos exclusivos para diseño Vertical --}}
|
||||
<div x-show="$wire.vuexy_myLayout === 'vertical'" x-transition>
|
||||
<div class="mb-3">
|
||||
<x-vuexy-admin::form.checkbox
|
||||
wire:model='vuexy_menuFixed'
|
||||
parent_class='form-switch'>
|
||||
Menú fijo
|
||||
</x-vuexy-admin::form.checkbox>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<x-vuexy-admin::form.checkbox
|
||||
wire:model='vuexy_menuCollapsed'
|
||||
parent_class='form-switch'>
|
||||
Menú colapsado
|
||||
</x-vuexy-admin::form.checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{{-- Habilitar UI Customizer --}}
|
||||
<div class="mb-3">
|
||||
<x-vuexy-admin::form.checkbox
|
||||
wire:model='vuexy_hasCustomizer'
|
||||
parent_class='form-switch'>
|
||||
Habilitar personalizador de plantilla
|
||||
</x-vuexy-admin::form.checkbox>
|
||||
</div>
|
||||
|
||||
<div x-show="$wire.vuexy_hasCustomizer" x-transition>
|
||||
<div class="mb-3">
|
||||
<x-vuexy-admin::form.checkbox
|
||||
wire:model='vuexy_displayCustomizer'
|
||||
parent_class='form-switch'>
|
||||
Mostrar personalizador de plantilla
|
||||
</x-vuexy-admin::form.checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Máximo de Enlaces Rápidos --}}
|
||||
<div x-show="$wire.vuexy_myLayout === 'horizontal' || $wire.vuexy_navbarType !== 'hidden'" x-transition>
|
||||
<hr>
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_maxQuickLinks" class="form-label">Máximo de enlaces rápidos</label>
|
||||
<input type="number" id="vuexy_maxQuickLinks" class="form-control" wire:model="vuexy_maxQuickLinks" min="2" max="20">
|
||||
<p class="text-muted">Selecciona un valor entre 2 y 20.</p>
|
||||
@error('vuexy_maxQuickLinks') <span class="text-danger">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h5 class="card-title mt-6">Ajustes de tema</h5>
|
||||
|
||||
{{-- Tema --}}
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_myTheme" class="form-label">Tema</label>
|
||||
<select id="vuexy_myTheme" class="form-select" wire:model="vuexy_myTheme">
|
||||
<option value="theme-default">Tema predeterminado</option>
|
||||
<option value="theme-bordered">Tema bordeado</option>
|
||||
<option value="theme-semi-dark">Tema semi-oscuro</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{-- Estilo --}}
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_myStyle" class="form-label">Estilo</label>
|
||||
<select id="vuexy_myStyle" class="form-select" wire:model="vuexy_myStyle">
|
||||
<option value="light">Claro</option>
|
||||
<option value="dark">Oscuro</option>
|
||||
<option value="system">Modo del sistema</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h5 class="card-title mt-6">Ajustes de diseño</h5>
|
||||
|
||||
{{-- Vista de Autenticación --}}
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_authViewMode" class="form-label">Modo de vista de autenticación</label>
|
||||
<select id="vuexy_authViewMode" class="form-select" wire:model="vuexy_authViewMode">
|
||||
<option value="cover">Pantalla completa</option>
|
||||
<option value="basic">Básico</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{-- Diseño del Contenido --}}
|
||||
<div class="mb-4">
|
||||
<label for="vuexy_contentLayout" class="form-label">Diseño del contenido</label>
|
||||
<select id="vuexy_contentLayout" class="form-select" wire:model="vuexy_contentLayout">
|
||||
<option value="compact">Compacto</option>
|
||||
<option value="wide">Ancho</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{-- Pie de Página Fijo --}}
|
||||
<div class="mb-3">
|
||||
<x-vuexy-admin::form.checkbox
|
||||
wire:model='vuexy_footerFixed'
|
||||
parent_class='form-switch'>
|
||||
Pie de página fijo
|
||||
</x-vuexy-admin::form.checkbox>
|
||||
</div>
|
||||
|
||||
{{-- Botones --}}
|
||||
<div class="row mt-6">
|
||||
<div class="col-lg-12 text-end">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{{-- Botones --}}
|
||||
<div class="row my-4">
|
||||
<div class="col-lg-12 text-end">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="save"
|
||||
disabled
|
||||
class="btn btn-primary btn-save btn-sm mt-2 mr-2 waves-effect waves-light">
|
||||
<i class="ti ti-device-floppy me-1"></i>
|
||||
Guardar cambios
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="loadSettings"
|
||||
disabled
|
||||
class="btn btn-secondary btn-cancel btn-sm mt-2 mr-2 waves-effect waves-light">
|
||||
<i class="ti ti-rotate-2 me-1"></i>
|
||||
Cancelar
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="clearCustomConfig"
|
||||
class="btn btn-success btn-reset btn-sm mt-2 mr-2 waves-effect waves-light">
|
||||
<i class="ti ti-adjustments-cog me-1"></i>
|
||||
Restaurar valores predeterminados
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,67 +0,0 @@
|
||||
<div>
|
||||
<form id="mail-sender-response-settings-card">
|
||||
<div class="card">
|
||||
<h5 class="card-header">Correo electrónicos de salida</h5>
|
||||
<div class="card-body">
|
||||
<div class="mb-3 fv-row">
|
||||
<label for="from_address" class="form-label">Correo electrónico</label>
|
||||
<input type="text" name="from_address" id="from_address" wire:model='from_address' class="form-control" placeholder="Correo electrónico">
|
||||
@error('from_address') <span class="text-danger">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
<div class="mb-3 fv-row">
|
||||
<label for="from_name" class="form-label">Nombre</label>
|
||||
<input type="text" name="from_name" id="from_name" wire:model='from_name' class="form-control" placeholder="Nombre">
|
||||
@error('from_name') <span class="text-danger">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
<h5 class="mt-6">Correo electrónico de respuesta</h5>
|
||||
<div class="mb-3 fv-row">
|
||||
<label for="reply_to_method" class="form-label">Correo electrónico de respuesta</label>
|
||||
<x-vuexy-admin::form.select
|
||||
wire:model='reply_to_method'
|
||||
:options="$reply_email_options"
|
||||
placeholder="Selecciona el correo electrónico de respuesta" />
|
||||
@error('reply_to_method') <span class="text-danger">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
<div class="email-custom-div">
|
||||
<div class="mb-3 fv-row">
|
||||
<label for="reply_to_email" class="form-label">Correo electrónico</label>
|
||||
<input type="text" name="reply_to_email" id="reply_to_email" wire:model='reply_to_email' class="form-control" placeholder="Correo electrónico">
|
||||
@error('reply_to_email') <span class="text-danger">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
<div class="fv-row">
|
||||
<label for="reply_to_name" class="form-label">Nombre</label>
|
||||
<input type="text" name="reply_to_name" id="reply_to_name" wire:model='reply_to_name' class="form-control" placeholder="Nombre">
|
||||
@error('reply_to_name') <span class="text-danger">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{{-- Botones --}}
|
||||
<div class="row my-4">
|
||||
<div class="col-lg-12 text-end">
|
||||
<button
|
||||
type="submit"
|
||||
id="save_sender_response_button"
|
||||
class="btn btn-primary btn-sm mt-2 mr-2 waves-effect waves-light"
|
||||
disabled
|
||||
data-loading-text="Guardando...">
|
||||
<i class="ti ti-device-floppy mr-2"></i>
|
||||
Guardar cambios
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="cancel_sender_response_button"
|
||||
class="btn btn-secondary btn-sm mt-2 mr-2 waves-effect waves-light"
|
||||
wire:click="loadSettings"
|
||||
disabled>
|
||||
<i class="ti ti-rotate-2 mr-2"></i>
|
||||
Cancelar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -198,7 +198,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
<div class="notification-container pt-4" wire:ignore></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<div class="form-custom-listener" id="cache-stats-card">
|
||||
<div id="cache-stats-card" class="form-custom-listener mb-4">
|
||||
{{-- Form Card --}}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -99,7 +99,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
<div class="notification-container pt-4" wire:ignore></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<div class="form-custom-listener" id="memcached-stats-card">
|
||||
<div id="memcached-stats-card" class="form-custom-listener mb-4">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Estadísticas de Memcached</h5>
|
||||
@ -115,7 +115,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
<div class="notification-container pt-4" wire:ignore></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<div class="form-custom-listener" id="redis-stats-card">
|
||||
<div id="redis-stats-card" class="form-custom-listener mb-4">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Estadísticas de Redis</h5>
|
||||
@ -138,7 +138,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
<div class="notification-container pt-4" wire:ignore></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<div class="form-custom-listener" id="session-stats-card">
|
||||
<div id="session-stats-card" class="form-custom-listener mb-4">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Configuraciones de Sesiones</h5>
|
||||
@ -114,7 +114,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
<div class="notification-container pt-4" wire:ignore></div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
7
resources/views/livewire/global-settings/index.blade.php
Normal file
7
resources/views/livewire/global-settings/index.blade.php
Normal file
@ -0,0 +1,7 @@
|
||||
<x-vuexy-admin::table.bootstrap.manager :tagName="$tagName" :datatableConfig="$bt_datatable">
|
||||
<x-slot name="tools">
|
||||
<div class="mb-4 pr-2">
|
||||
<x-vuexy-admin::button.index-offcanvas :label="$singularName" :tagName="$tagName" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-vuexy-admin::table.bootstrap.manager>
|
@ -0,0 +1,64 @@
|
||||
<div>
|
||||
<x-vuexy-admin::offcanvas.basic :id="$offcanvasId" :tag-name="$tagName">
|
||||
<x-vuexy-admin::form :id="$formId" :mode="$mode" wireSubmit="onSubmit">
|
||||
<x-slot name="actions">
|
||||
<x-vuexy-admin::button.offcanvas-buttons :mode="$mode" :tagName="$tagName" />
|
||||
</x-slot>
|
||||
|
||||
{{-- Sección: Identificación --}}
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="key" label="Clave del parámetro" required icon="ti ti-key" placeholder="Ej: ui.theme" />
|
||||
|
||||
<div class="row">
|
||||
<x-vuexy-admin::form.select :uid="$uniqueId" model="category" label="Categoría"
|
||||
:options="[
|
||||
'general' => 'General',
|
||||
'ui' => 'Interfaz',
|
||||
'mail' => 'Correo',
|
||||
'cfdi' => 'CFDI',
|
||||
]"
|
||||
placeholder="Selecciona una categoría"
|
||||
parentClass="col-md-6"
|
||||
/>
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="user_id" label="ID Usuario (Opcional)"
|
||||
type="number"
|
||||
parentClass="col-md-6"
|
||||
icon="ti ti-user"
|
||||
placeholder="ID del usuario asociado"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{{-- Sección: Valores (solo llena uno) --}}
|
||||
<div class="alert" type="info" icon="ti ti-info-circle" class="mb-1">
|
||||
Puedes llenar **solo uno** de los valores siguientes según el tipo de configuración.
|
||||
</div>
|
||||
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="value_string" label="Valor (Texto Corto)" icon="ti ti-typography" placeholder="Ej: dark" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="value_integer" label="Valor (Entero)" type="number" icon="ti ti-hash" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="value_float" label="Valor (Decimal)" type="number" step="0.01" icon="ti ti-percentage" />
|
||||
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="value_boolean" label="Valor (Booleano)" />
|
||||
<x-vuexy-admin::form.textarea :uid="$uniqueId" model="value_text" label="Valor (Texto Largo)" placeholder="Valor largo o configuración avanzada en texto" rows="3" />
|
||||
|
||||
<hr>
|
||||
</x-vuexy-admin::form>
|
||||
</x-vuexy-admin::offcanvas.basic>
|
||||
</div>
|
||||
|
||||
@push('page-script')
|
||||
<script>
|
||||
// Evento para inicializar el formulario cuando se carga la página
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const initializeGlobalSettingsForm = () => {
|
||||
|
||||
};
|
||||
|
||||
var myOffcanvas = document.getElementById('{{ $offcanvasId }}');
|
||||
|
||||
myOffcanvas.addEventListener('show.bs.offcanvas', function () {
|
||||
initializeGlobalSettingsForm();
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endpush
|
@ -1,152 +1,7 @@
|
||||
<!-- Permission Table -->
|
||||
<div class="card">
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="datatables-permissions table border-top">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>Nombre</th>
|
||||
<th>Asignado a</th>
|
||||
<th>Creado</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Permission Table -->
|
||||
|
||||
|
||||
<?php
|
||||
/*
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
$(document).ready(function() {
|
||||
// Datatable
|
||||
var dt_permission = $('.datatables-permissions')
|
||||
.DataTable({
|
||||
ajax: '{{ url()->current() }}',
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{data: ''},
|
||||
{data: 'id'},
|
||||
{data: 'name'},
|
||||
{data: 'assigned_to'},
|
||||
{data: 'created_at'},
|
||||
//{data: ''}
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function(data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: 1,
|
||||
searchable: false,
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
// Name
|
||||
targets: 2,
|
||||
render: function(data, type, full, meta) {
|
||||
return "<span data-id=" + full.id + ">" + data + "</span><br>" +
|
||||
'<small>' + (typeof(full['sub_group']) == 'string'? full['sub_group']: '') + "</small>";
|
||||
}
|
||||
},
|
||||
{
|
||||
// assigned_to
|
||||
targets: 3,
|
||||
orderable: false,
|
||||
render: function(data, type, full, meta) {
|
||||
var $assignedTo = full['assigned_to'],
|
||||
$output = '',
|
||||
roleBadgeObj = <?= json_encode($rows_roles) ?>;
|
||||
|
||||
for (var i = 0; i < $assignedTo.length; i++) {
|
||||
var val = $assignedTo[i];
|
||||
|
||||
$output += roleBadgeObj[val];
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Created at
|
||||
targets: 4,
|
||||
orderable: false
|
||||
},
|
||||
],
|
||||
order: [
|
||||
[1, 'asc']
|
||||
],
|
||||
dom:
|
||||
'<"row mx-1"' +
|
||||
'<"col-sm-12 col-md-3" l>' +
|
||||
'<"col-sm-12 col-lg-9"<"dt-action-buttons d-flex align-items-center justify-content-lg-end justify-content-center flex-md-nowrap flex-wrap"<"me-1"f><"user_role mt-50 width-200 me-1">B>>' +
|
||||
'>t' +
|
||||
'<"row mx-2"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
language: $.fn.dataTable.ext.datatable_spanish_default,
|
||||
// Buttons with Dropdown
|
||||
buttons: [],
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function(row) {
|
||||
var data = row.data();
|
||||
|
||||
return 'Detalles del permiso';
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function(api, rowIdx, columns) {
|
||||
var data = $.map(columns, function(col, i) {
|
||||
return col.title !== ''? // ? Do not show row in modal popup if title is blank (for check box)
|
||||
'<tr data-dt-row="' + col.rowIndex + '" data-dt-column="' + col.columnIndex + '">' +
|
||||
'<td>' + col.name + ':' + '</td> ' +
|
||||
'<td>' + col.data + '</td>' +
|
||||
'</tr>' :
|
||||
'';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table table-striped"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
initComplete: function() {
|
||||
// Adding role filter once table initialized
|
||||
this.api()
|
||||
.columns(3)
|
||||
.every(function() {
|
||||
var column = this;
|
||||
|
||||
var select = $('{!! $roles_html_select !!}')
|
||||
.appendTo('.user_role')
|
||||
.on('change', function() {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
|
||||
column.search(val? val: '', true, false).draw();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
*/
|
||||
|
||||
?>
|
||||
<x-vuexy-admin::table.bootstrap.manager :tagName="$tagName" :datatableConfig="$bt_datatable">
|
||||
<x-slot name="tools">
|
||||
<div class="mb-4 pr-2">
|
||||
<x-vuexy-admin::button.index-offcanvas :label="$singularName" :tagName="$tagName" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-vuexy-admin::table.bootstrap.manager>
|
||||
|
@ -0,0 +1,39 @@
|
||||
<div>
|
||||
<x-vuexy-admin::offcanvas.basic :id="$offcanvasId" :tag-name="$tagName">
|
||||
<x-vuexy-admin::form :uid="$uniqueId" :id="$formId" :mode="$mode" wireSubmit="onSubmit">
|
||||
<x-slot name="actions">
|
||||
<x-vuexy-admin::button.offcanvas-buttons :mode="$mode" :tagName="$tagName" />
|
||||
</x-slot>
|
||||
{{-- Usuario --}}
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="name" label="Nombre(s)" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="last_name" label="Apellidos" />
|
||||
{{-- Correos electrónicos --}}
|
||||
<x-vuexy-admin::form.input type="email" :uid="$uniqueId" model="email" label="Correo electrónico" icon="ti ti-mail" autocomplete="email" inputmode="email" />
|
||||
|
||||
{{-- Contraseña --}}
|
||||
<x-vuexy-admin::form.input type="password" :uid="$uniqueId" model="password" label="Contraseña" icon="ti ti-lock" autocomplete="new-password" />
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
</x-vuexy-admin::form>
|
||||
</x-vuexy-admin::offcanvas.basic>
|
||||
</div>
|
||||
|
||||
@push('page-script')
|
||||
<script>
|
||||
// Evento para inicializar el formulario cuando se carga la página
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const initializeUserForm = () => {
|
||||
|
||||
};
|
||||
|
||||
var myOffcanvas = document.getElementById('{{ $offcanvasId }}');
|
||||
|
||||
myOffcanvas.addEventListener('show.bs.offcanvas', function () {
|
||||
initializeUserForm();
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endpush
|
@ -0,0 +1,95 @@
|
||||
<x-form-section submit="updateProfileInformation">
|
||||
<x-slot name="title">
|
||||
{{ __('Profile Information') }}
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="description">
|
||||
{{ __('Update your account\'s profile information and email address.') }}
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="form">
|
||||
<!-- Profile Photo -->
|
||||
@if (Laravel\Jetstream\Jetstream::managesProfilePhotos())
|
||||
<div x-data="{photoName: null, photoPreview: null}" class="col-span-6 sm:col-span-4">
|
||||
<!-- Profile Photo File Input -->
|
||||
<input type="file" id="photo" class="hidden"
|
||||
wire:model.live="photo"
|
||||
x-ref="photo"
|
||||
x-on:change="
|
||||
photoName = $refs.photo.files[0].name;
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
photoPreview = e.target.result;
|
||||
};
|
||||
reader.readAsDataURL($refs.photo.files[0]);
|
||||
" />
|
||||
|
||||
<x-label for="photo" value="{{ __('Photo') }}" />
|
||||
|
||||
<!-- Current Profile Photo -->
|
||||
<div class="mt-2" x-show="! photoPreview">
|
||||
<img src="{{ $this->user->profile_photo_url }}" alt="{{ $this->user->name }}" class="rounded-full size-20 object-cover">
|
||||
</div>
|
||||
|
||||
<!-- New Profile Photo Preview -->
|
||||
<div class="mt-2" x-show="photoPreview" style="display: none;">
|
||||
<span class="block rounded-full size-20 bg-cover bg-no-repeat bg-center"
|
||||
x-bind:style="'background-image: url(\'' + photoPreview + '\');'">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<x-secondary-button class="mt-2 me-2" type="button" x-on:click.prevent="$refs.photo.click()">
|
||||
{{ __('Select A New Photo') }}
|
||||
</x-secondary-button>
|
||||
|
||||
@if ($this->user->profile_photo_path)
|
||||
<x-secondary-button type="button" class="mt-2" wire:click="deleteProfilePhoto">
|
||||
{{ __('Remove Photo') }}
|
||||
</x-secondary-button>
|
||||
@endif
|
||||
|
||||
<x-input-error for="photo" class="mt-2" />
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Name -->
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<x-label for="name" value="{{ __('Name') }}" />
|
||||
<x-input id="name" type="text" class="mt-1 block w-full" wire:model="state.name" required autocomplete="name" />
|
||||
<x-input-error for="name" class="mt-2" />
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<x-label for="email" value="{{ __('Email') }}" />
|
||||
<x-input id="email" type="email" class="mt-1 block w-full" wire:model="state.email" required autocomplete="username" />
|
||||
<x-input-error for="email" class="mt-2" />
|
||||
|
||||
@if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::emailVerification()) && ! $this->user->hasVerifiedEmail())
|
||||
<p class="text-sm mt-2 dark:text-white">
|
||||
{{ __('Your email address is unverified.') }}
|
||||
|
||||
<button type="button" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" wire:click.prevent="sendEmailVerification">
|
||||
{{ __('Click here to re-send the verification email.') }}
|
||||
</button>
|
||||
</p>
|
||||
|
||||
@if ($this->verificationLinkSent)
|
||||
<p class="mt-2 font-medium text-sm text-green-600 dark:text-green-400">
|
||||
{{ __('A new verification link has been sent to your email address.') }}
|
||||
</p>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="actions">
|
||||
<x-action-message class="me-3" on="saved">
|
||||
{{ __('Saved.') }}
|
||||
</x-action-message>
|
||||
|
||||
<x-button wire:loading.attr="disabled" wire:target="photo">
|
||||
{{ __('Save') }}
|
||||
</x-button>
|
||||
</x-slot>
|
||||
</x-form-section>
|
@ -1,704 +0,0 @@
|
||||
<div>
|
||||
<div class="users-index alert-errors">{!! $indexAlert !!}</div>
|
||||
|
||||
<!-- Users List Table -->
|
||||
<div class="card" wire:ignore>
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="datatables-users table">
|
||||
<thead class="border-top">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Id</th>
|
||||
<th>Usuario</th>
|
||||
<th>Roles</th>
|
||||
<th>Estatus</th>
|
||||
<th>Creado</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Offcanvas to add new user -->
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasUser" aria-labelledby="offcanvasLabel">
|
||||
<div class="offcanvas-header border-bottom">
|
||||
<h5 id="offcanvasLabel" class="offcanvas-title">{{ $modalTitle }}</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
|
||||
<form class="pt-0" id="userForm" autocomplete='off'>
|
||||
<input type="hidden" name="id" wire:model='userId' />
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Nombre completo</label>
|
||||
<div class="input-group input-group-merge">
|
||||
<span class="input-group-text"><i class="ti ti-user"></i></span>
|
||||
<input type="text" name="name" wire:model='name' id="name" class="form-control" placeholder="Pepe Pecas" />
|
||||
</div>
|
||||
<div class="error-message"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Correo electrónico</label>
|
||||
<div class="input-group input-group-merge">
|
||||
<span class="input-group-text"><i class="ti ti-mail"></i></span>
|
||||
<input type="text" name="email" wire:model='email' id="email" class="form-control" placeholder="picapapas@mail.com" />
|
||||
</div>
|
||||
<div class="error-message"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Contraseña</label>
|
||||
<div class="input-group input-group-merge form-password-toggle">
|
||||
<span class="input-group-text"><i class="ti ti-key"></i></span>
|
||||
<input type="password" name="password" wire:model='password' class="form-control form-control-merge" id="password" placeholder="············" />
|
||||
<span class="input-group-text cursor-pointer"><i class="ti ti-eye"></i></span>
|
||||
</div>
|
||||
<div class="error-message"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="roles" class="form-label">Roles del usuario</label>
|
||||
<x-vuexy-admin::form.select
|
||||
id="roles"
|
||||
name="roles[]"
|
||||
wire:model='roles'
|
||||
:options="$roles_options"
|
||||
multiple
|
||||
class="select2 form-select" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">Estatus</label>
|
||||
<div class="input-group input-group-merge">
|
||||
<span class="input-group-text"><i class="ti ti-alert-triangle"></i></span>
|
||||
<x-vuexy-admin::form.select
|
||||
id="status"
|
||||
name="status"
|
||||
wire:model='status'
|
||||
:options="$status_options"
|
||||
class="form-select" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="photo" class="form-label">Imagen de perfil</label>
|
||||
<div class="image-wrapper mb-1">
|
||||
<img id="user-image" class="max-w-full" src="{{ $src_photo }}" alt="">
|
||||
</div>
|
||||
<input type="file" name="photo" id="photo" class='form-control' accept='image/*' />
|
||||
</div>
|
||||
|
||||
<div class="alert-errors"></div>
|
||||
|
||||
<button type="submit" class="btn btn-primary me-3 data-submit">{{ $btnSubmitTxt }}</button>
|
||||
<button type="reset" class="btn btn-label-danger" data-bs-dismiss="offcanvas">Cancelar</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete User Modal -->
|
||||
<div class="modal fade" id="deleteUserModal" tabindex="-1" aria-hidden="true" wire:ignore>
|
||||
<div class="modal-dialog modal-dialog-centered modal-simple">
|
||||
<div class="modal-content p-3 p-md-5">
|
||||
<div class="modal-body">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<div class="text-center mb-4">
|
||||
<h3 class="mb-2">Eliminar usuario</h3>
|
||||
<p class="text-muted">El proceso de eliminación es definitivo e irreversible</p>
|
||||
</div>
|
||||
<form class="row g-3">
|
||||
<div class="col-12">
|
||||
<p class="name text-center font-bold"></p>
|
||||
</div>
|
||||
<div class="col-12 text-center">
|
||||
<button type="submit" class="btn btn-primary me-sm-3 me-1 btn-submit">Eliminar usuario</button>
|
||||
<button type="reset" class="btn btn-secondary btn-reset" data-bs-dismiss="modal" aria-label="Close">Cancelar</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Delete User Modal -->
|
||||
</div>
|
||||
|
||||
@push('page-script')
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const store_route = '{{ route('admin.core.users.store') }}',
|
||||
update_route = '{{ route('admin.core.users.update-ajax', '0~0') }}',
|
||||
show_route = '{{ route('admin.core.users.show', '0~0') }}',
|
||||
destroy_route = '{{ route('admin.core.users.destroy', '0~0') }}';
|
||||
|
||||
var statusObj = <?= json_encode($statuses) ?>,
|
||||
$usersIndexAlert = $('.users-index.alert-errors'),
|
||||
$dt_user_table = $('.datatables-users'),
|
||||
dt_user;
|
||||
|
||||
var offcanvasElement = document.getElementById('offcanvasUser'),
|
||||
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
|
||||
|
||||
|
||||
load_js_form = () => {
|
||||
$('#userForm .select2')
|
||||
.each(function() {
|
||||
var $this = $(this)
|
||||
|
||||
$this.wrap('<div class="position-relative"></div>')
|
||||
|
||||
$this.select2({
|
||||
dropdownAutoWidth: true,
|
||||
width: '100%',
|
||||
dropdownParent: $this.parent()
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Previo de imagenes
|
||||
document.getElementById("photo").addEventListener('change', updatePreviewImage);
|
||||
|
||||
|
||||
// Reset form
|
||||
$("#userForm")
|
||||
.on('reset', function(){
|
||||
setTimeout(function(){
|
||||
$('#roles').trigger('change');
|
||||
}, 250)
|
||||
|
||||
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
|
||||
$('#userForm .alert-errors').html('');
|
||||
});
|
||||
|
||||
|
||||
$("#userForm")
|
||||
.validate({
|
||||
errorClass: 'error',
|
||||
highlight: function(element, errorClass, validClass) {
|
||||
// Agrega la clase de error a la fila (contenedor del campo)
|
||||
$(element).closest('.mb-3').addClass('has-error');
|
||||
},
|
||||
unhighlight: function(element, errorClass, validClass) {
|
||||
// Elimina la clase de error de la fila (contenedor del campo)
|
||||
$(element).closest('.mb-3').removeClass('has-error');
|
||||
},
|
||||
errorPlacement: function(error, element) {
|
||||
// Controla dónde se colocan los mensajes de error
|
||||
error.appendTo(element.closest('.mb-3').find('.error-message'));
|
||||
},
|
||||
rules: {
|
||||
name: {
|
||||
required: true,
|
||||
minlength: 8
|
||||
},
|
||||
email: {
|
||||
required: true,
|
||||
email: true
|
||||
},
|
||||
password: {
|
||||
required: function(element) {
|
||||
return !$("#userForm input[name=id]").val();
|
||||
},
|
||||
minlength: 6
|
||||
}
|
||||
},
|
||||
messages: {
|
||||
name: {
|
||||
required: "Por favor ingrese su nombre completo",
|
||||
minlength: "El nombre completo debe tener al menos 8 caracteres"
|
||||
},
|
||||
email: {
|
||||
required: "Por favor ingrese su correo electrónico",
|
||||
email: "El valor no es una dirección de correo válida"
|
||||
},
|
||||
password: {
|
||||
required: "La contraseña es obligatoria para nuevos usuarios",
|
||||
minlength: "La contraseña debe tener al menos 6 caracteres"
|
||||
}
|
||||
},
|
||||
submitHandler: function(form) {
|
||||
var form = $("#userForm")[0],
|
||||
data = new FormData(form);
|
||||
|
||||
$('#userForm :input').prop('disabled', true);
|
||||
|
||||
var url = $(form.id).val() ?
|
||||
update_route.replace('0~0', $(form.id).val()) :
|
||||
store_route;
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
data: data,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
cache: false,
|
||||
timeout: 3000,
|
||||
success: function(data) {
|
||||
$('#userForm :input').prop('disabled', false);
|
||||
|
||||
if (data.errors) {
|
||||
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
|
||||
'<div class="alert-body">' + data.errors + '</div>' +
|
||||
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
|
||||
'</div>');
|
||||
|
||||
} else {
|
||||
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
|
||||
'<div class="alert-body">' +
|
||||
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
|
||||
'</div>' +
|
||||
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
|
||||
'</div>');
|
||||
|
||||
$('#userForm button[type=reset]').trigger('click');
|
||||
|
||||
//@this.call('refreshUserCount');
|
||||
|
||||
dt_user.ajax.reload();
|
||||
}
|
||||
},
|
||||
error: function(e) {
|
||||
$('#userForm :input').prop('disabled', false);
|
||||
|
||||
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
|
||||
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
|
||||
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
|
||||
'</div>');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Previo de imagen de perfil
|
||||
updatePreviewImage = (event) => {
|
||||
var file = event.target.files[0],
|
||||
reader = new FileReader();
|
||||
|
||||
reader.onload = event => {
|
||||
document.getElementById('user-image').setAttribute('src', event.target.result);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
// Add User
|
||||
add_user = () => {
|
||||
let $offcanvasUser = $('#offcanvasUser');
|
||||
|
||||
$('.offcanvas-title', $offcanvasUser).html('Crear usuario nuevo');
|
||||
$('.btn-submit', $offcanvasUser).html('Crear usuario');
|
||||
|
||||
if ($('input[name=id]', $offcanvasUser).val()){
|
||||
document.getElementById('userForm').reset();
|
||||
|
||||
$('input[name=id]', $offcanvasUser).val('');
|
||||
|
||||
$('#roles').trigger('change');
|
||||
|
||||
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
|
||||
$('.alert-errors', $offcanvasUser).html('');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Livewire.on('openModal', () => {
|
||||
setTimeout(() =>{
|
||||
offcanvasUser.show();
|
||||
|
||||
load_js_form();
|
||||
|
||||
dt_user.ajax.reload();
|
||||
}, 1)
|
||||
});
|
||||
|
||||
Livewire.on('afterDelete', () => {
|
||||
setTimeout(() =>{
|
||||
var modalElement = document.getElementById('deleteUserModal'),
|
||||
modalDelete = bootstrap.Modal.getInstance(modalElement);
|
||||
|
||||
modalDelete.hide();
|
||||
|
||||
load_js_form();
|
||||
|
||||
dt_user.ajax.reload();
|
||||
}, 1)
|
||||
});
|
||||
|
||||
|
||||
// (jquery)
|
||||
$(function () {
|
||||
let borderColor, bodyBg, headingColor;
|
||||
|
||||
if (isDarkStyle) {
|
||||
borderColor = config.colors_dark.borderColor;
|
||||
bodyBg = config.colors_dark.bodyBg;
|
||||
headingColor = config.colors_dark.headingColor;
|
||||
} else {
|
||||
borderColor = config.colors.borderColor;
|
||||
bodyBg = config.colors.bodyBg;
|
||||
headingColor = config.colors.headingColor;
|
||||
}
|
||||
|
||||
// Users datatable
|
||||
dt_user = $dt_user_table.DataTable({
|
||||
ajax: '{{ url()->current() }}',
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: 'id' },
|
||||
{ data: 'id' },
|
||||
{ data: 'name' },
|
||||
{ data: 'roles' },
|
||||
{ data: 'status' },
|
||||
{ data: 'created_at' },
|
||||
{ data: 'action' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// User name and email
|
||||
targets: 2,
|
||||
responsivePriority: 3,
|
||||
render: function (data, type, full, meta) {
|
||||
var $name = full['name'],
|
||||
$email = full['email'],
|
||||
$image = full['avatar'];
|
||||
|
||||
if ($image) {
|
||||
// For Avatar image
|
||||
var $output =
|
||||
'<img src="' + $image + '" alt="Avatar" class="rounded-circle">';
|
||||
} else {
|
||||
// For Avatar badge
|
||||
var $name = full['full_name'],
|
||||
$initials = $name.match(/\b\w/g) || [];
|
||||
$initials = (($initials.shift() || '') + ($initials.pop() || '')).toUpperCase();
|
||||
$output = '<span class="avatar-initial rounded-circle>' + $initials + '</span>';
|
||||
}
|
||||
|
||||
// Creates full output for row
|
||||
var $row_output =
|
||||
'<div class="d-flex justify-content-start align-items-center user-name">' +
|
||||
'<div class="avatar-wrapper">' +
|
||||
'<div class="avatar avatar-sm me-4">' + $output + '</div>' +
|
||||
'</div>' +
|
||||
'<div class="d-flex flex-column">' +
|
||||
'<a href="' + show_route.replace('0~0', full['id']) + '" class="text-heading text-truncate"><span class="fw-medium">' + $name + '</span></a>' +
|
||||
'<small>' + $email + '</small>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// User Role
|
||||
targets: 3,
|
||||
render: function(data, type, full, meta) {
|
||||
var $assignedTo = full['roles'],
|
||||
$output = '',
|
||||
roleBadgeObj = <?= json_encode($rows_roles) ?>;
|
||||
|
||||
for (var i = 0; i < $assignedTo.length; i++) {
|
||||
var val = $assignedTo[i];
|
||||
|
||||
$output += roleBadgeObj[val];
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// User Status
|
||||
targets: 4,
|
||||
render: function (data, type, full, meta) {
|
||||
var $status = full['status'];
|
||||
|
||||
return ('<span class="badge rounded-pill ' + statusObj[$status].class + '" text-capitalized>' + statusObj[$status].title + '</span>');
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
// Created
|
||||
targets: 5,
|
||||
render: function (data, type, full, meta) {
|
||||
return full['created_at'];
|
||||
}
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
title: 'Acciones',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return ('<div class="d-flex align-items-center">' +
|
||||
'<a href="' + show_route.replace('0~0', full['id']) + '" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill"><i class="ti ti-eye ti-md"></i></a>' +
|
||||
'<a href="javascript:;"" wire:click.prevent="edit(' + full['id'] + ')" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill"><i class="ti ti-edit ti-md"></i></a>' +
|
||||
@can('system.users.destroy')
|
||||
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>' +
|
||||
'<div class="dropdown-menu dropdown-menu-end m-0">' +
|
||||
'<a href="javascript:;" class="dropdown-item delete-record">Eliminar</a>' +
|
||||
'</div>' +
|
||||
@endcan
|
||||
'</div>');
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [[2, 'desc']],
|
||||
dom:
|
||||
'<"row"' +
|
||||
'<"col-md-2"<"ms-n2"l>>' +
|
||||
'<"col-md-10"<"dt-action-buttons text-xl-end text-lg-start text-md-end text-start d-flex align-items-center justify-content-end flex-md-row flex-column mb-6 mb-md-0 mt-n6 mt-md-0"<"user_role dataTables_filter">fB>>' +
|
||||
'>t' +
|
||||
'<"row"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
language: $.fn.dataTable.ext.datatable_spanish_default,
|
||||
// Buttons with Dropdown
|
||||
buttons: [
|
||||
{
|
||||
extend: 'collection',
|
||||
className: 'btn btn-label-secondary dropdown-toggle mx-4 waves-effect waves-light',
|
||||
text: '<i class="ti ti-upload me-2 ti-xs"></i>Exportar',
|
||||
buttons: [
|
||||
{
|
||||
extend: 'print',
|
||||
text: '<i class="ti ti-printer me-2" ></i>Imprimir',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be print
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
},
|
||||
customize: function (win) {
|
||||
//customize print view for dark
|
||||
$(win.document.body)
|
||||
.css('color', headingColor)
|
||||
.css('border-color', borderColor)
|
||||
.css('background-color', bodyBg);
|
||||
$(win.document.body)
|
||||
.find('table')
|
||||
.addClass('compact')
|
||||
.css('color', 'inherit')
|
||||
.css('border-color', 'inherit')
|
||||
.css('background-color', 'inherit');
|
||||
}
|
||||
},
|
||||
{
|
||||
extend: 'csv',
|
||||
text: '<i class="ti ti-file-text me-2" ></i>Csv',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
extend: 'excel',
|
||||
text: '<i class="ti ti-file-spreadsheet me-2"></i>Excel',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/*
|
||||
{
|
||||
extend: 'pdf',
|
||||
text: '<i class="ti ti-file-code-2 me-2"></i>Pdf',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
*/
|
||||
{
|
||||
extend: 'copy',
|
||||
text: '<i class="ti ti-copy me-2" ></i>Copiar',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@can('system.users.create') {
|
||||
text: '<i class="ti ti-plus me-0 me-sm-1 ti-xs"></i><span class="d-none d-sm-inline-block">Nuevo usuario</span>',
|
||||
className: 'add-new btn btn-primary waves-effect waves-light',
|
||||
attr: {
|
||||
'onclick': 'add_user()',
|
||||
'data-bs-toggle': 'offcanvas',
|
||||
'data-bs-target': '#offcanvasUser'
|
||||
}
|
||||
}
|
||||
@endcan
|
||||
],
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['full_name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' + col.rowIndex + '" data-dt-column="' + col.columnIndex + '">' +
|
||||
'<td>' + col.title + ':' + '</td> ' +
|
||||
'<td>' + col.data + '</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
},
|
||||
initComplete: function () {
|
||||
this.api()
|
||||
.columns(3)
|
||||
.every(function () {
|
||||
var column = this,
|
||||
select = $('{!! $roles_html_select !!}')
|
||||
.appendTo('.user_role')
|
||||
.on('change', function() {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
|
||||
column.search(val? val: '', true, false).draw();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Delete Record
|
||||
$('.datatables-users tbody')
|
||||
.on('click', '.delete-record', function () {
|
||||
var tr = $(this).closest('tr'),
|
||||
data = dt_user.row(tr).data();
|
||||
|
||||
$('#deleteUserModal').modal('show');
|
||||
$('#deleteUserModal .name').html(data.id + ': ' + data.name);
|
||||
|
||||
$('#deleteUserModal').data('userId', data.id);
|
||||
});
|
||||
|
||||
|
||||
// Attach the event listener to the submit button
|
||||
$('#deleteUserModal .btn-submit')
|
||||
.on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
@this.call('delete', $('#deleteUserModal').data('userId'));
|
||||
});
|
||||
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
|
||||
|
||||
load_js_form();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
@endpush
|
@ -1,7 +1,7 @@
|
||||
<x-vuexy-admin::table.bootstrap.manager :tagName="$tagName" :datatableConfig="$bt_datatable" :routes="$routes" >
|
||||
<x-slot name="tools">
|
||||
<div class="mb-4 pr-2">
|
||||
<x-vuexy-admin::button.index-off-canvas :label="$singularName" :tagName="$tagName" />
|
||||
<x-vuexy-admin::button.index-offcanvas :label="$singularName" :tagName="$tagName" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-vuexy-admin::table.bootstrap.manager>
|
||||
|
@ -5,28 +5,15 @@
|
||||
<x-vuexy-admin::button.offcanvas-buttons :mode="$mode" :tagName="$tagName" />
|
||||
</x-slot>
|
||||
{{-- Usuario --}}
|
||||
<div class="row">
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="code" label="Código de usuario" icon="ti ti-tag" parent-class="col-md-8" autocomplete="off" />
|
||||
</div>
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="name" label="Nombre(s)" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="last_name" label="Apellidos" />
|
||||
<hr>
|
||||
|
||||
{{-- Teléfonos y Correos --}}
|
||||
<x-vuexy-admin::form.input type="tel" :uid="$uniqueId" model="tel" label="Teléfono" icon="ti ti-phone" phoneMode="both" />
|
||||
{{-- Correos electrónicos --}}
|
||||
<x-vuexy-admin::form.input type="email" :uid="$uniqueId" model="email" label="Correo electrónico" icon="ti ti-mail" autocomplete="email" inputmode="email" />
|
||||
<hr>
|
||||
|
||||
{{-- Contraseña --}}
|
||||
<x-vuexy-admin::form.input type="password" :uid="$uniqueId" model="password" label="Contraseña" icon="ti ti-lock" autocomplete="new-password" />
|
||||
|
||||
|
||||
<x-vuexy-admin::form.textarea :uid="$uniqueId" model="notes" label="Notas / Observaciones" />
|
||||
<hr>
|
||||
|
||||
{{-- Estado del Centro de Trabajo --}}
|
||||
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="is_partner" label="Es socio" switch />
|
||||
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="is_employee" label="Es empleado" switch />
|
||||
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="is_prospect" label="Es prospecto" switch />
|
||||
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="is_customer" label="Es cliente" switch />
|
||||
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="is_provider" label="Es proveedor" switch />
|
||||
<hr>
|
||||
|
||||
</x-vuexy-admin::form>
|
||||
|
@ -42,7 +42,7 @@
|
||||
<i class="ti ti-user pr-2"></i> Cuenta de usuario
|
||||
</button>
|
||||
</li>
|
||||
@if (($is_customer || $is_user) && $this->tipo_persona != App\Models\User::TIPO_RFC_PUBLICO)
|
||||
@if (($is_customer) && $this->tipo_persona != App\Models\User::TIPO_RFC_PUBLICO)
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" @click="setActiveTabPan('accesos')" :class="{ 'active': activeTabPan === 'accesos' }" class="nav-link waves-effect" role="tab" data-bs-toggle="tab" data-bs-target="#navs-left-accesos" aria-controls="navs-left-accesos">
|
||||
<i class="ti ti-key pr-2"></i> Accesos
|
||||
@ -56,14 +56,14 @@
|
||||
</button>
|
||||
</li>
|
||||
@endif
|
||||
@if (($is_prospect || $is_customer || $is_provider || $is_user) && $this->tipo_persona != App\Models\User::TIPO_RFC_PUBLICO)
|
||||
@if (($is_prospect || $is_customer || $is_provider) && $this->tipo_persona != App\Models\User::TIPO_RFC_PUBLICO)
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" @click="setActiveTabPan('direcciones')" :class="{ 'active': activeTabPan === 'direcciones' }" class="nav-link waves-effect" role="tab" data-bs-toggle="tab" data-bs-target="#navs-left-direcciones" aria-controls="navs-left-direcciones">
|
||||
<i class="ti ti-map-pin pr-2"></i> Direcciones
|
||||
</button>
|
||||
</li>
|
||||
@endif
|
||||
@if (($is_prospect || $is_customer || $is_provider || $is_user) && $this->tipo_persona != App\Models\User::TIPO_RFC_PUBLICO)
|
||||
@if (($is_prospect || $is_customer || $is_provider) && $this->tipo_persona != App\Models\User::TIPO_RFC_PUBLICO)
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" @click="setActiveTabPan('contacto')" :class="{ 'active': activeTabPan === 'contacto' }" class="nav-link waves-effect" role="tab" data-bs-toggle="tab" data-bs-target="#navs-left-contacto" aria-controls="navs-left-contacto">
|
||||
<i class="ti ti-address-book pr-2"></i> Contacto
|
||||
@ -158,14 +158,6 @@
|
||||
Es proveedor
|
||||
</x-checkbox-v>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<x-checkbox-v value="{{ old('is_user', $is_user) }}"
|
||||
name='is_user'
|
||||
wire:model='is_user'
|
||||
parent_class='form-switch'>
|
||||
Es usuario
|
||||
</x-checkbox-v>
|
||||
</div>
|
||||
<div class="row pricelist-div mb-3">
|
||||
<div class="col-lg-12">
|
||||
<label for="pricelist_id" class="form-label">Lista de precios</label>
|
||||
@ -616,16 +608,13 @@
|
||||
@this.set('is_prospect', false, false);
|
||||
@this.set('is_customer', true, false);
|
||||
@this.set('is_provider', false, false);
|
||||
@this.set('is_user', false, false);
|
||||
@this.set('enable_credit', false, false);
|
||||
|
||||
$("#is_prospect").prop("disabled", true);
|
||||
$("#is_provider").prop("disabled", true);
|
||||
$("#is_user").prop("disabled", true);
|
||||
}else{
|
||||
$("#is_prospect").prop("disabled", false);
|
||||
$("#is_provider").prop("disabled", false);
|
||||
$("#is_user").prop("disabled", false);
|
||||
}
|
||||
|
||||
if (is_prospect || is_customer) {
|
||||
@ -1643,7 +1632,7 @@
|
||||
$(document).ready(function() {
|
||||
$("#pdf-dropzone")
|
||||
.dropzone({
|
||||
url: '{{ route('admin.crm.contacts.extraer-datos-pdf-constancia') }}',
|
||||
url: '{{ route('admin.crm.contacts.extract-data-pdf-certificate') }}',
|
||||
paramName: "file",
|
||||
maxFiles: 1,
|
||||
acceptedFiles: '.pdf',
|
||||
|
@ -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>
|
@ -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>
|
69
resources/views/livewire/vuexy/interface-settings.blade.php
Normal file
69
resources/views/livewire/vuexy/interface-settings.blade.php
Normal 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>
|
@ -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>
|
@ -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>
|
53
resources/views/livewire/vuexy/quick-access-widget.blade.php
Normal file
53
resources/views/livewire/vuexy/quick-access-widget.blade.php
Normal 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>
|
@ -2,7 +2,7 @@
|
||||
changeSmtpSettings: @entangle('change_smtp_settings'),
|
||||
saveButtonDisabled: @entangle('save_button_disabled'),
|
||||
}">
|
||||
<form id="mail-smtp-settings-card">
|
||||
<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">
|
||||
@ -80,7 +80,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{-- Notifications --}}
|
||||
<div class="notification-container" wire:ignore></div>
|
||||
<div class="notification-container pt-4" wire:ignore></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
Reference in New Issue
Block a user