first commit
This commit is contained in:
586
resources/views/livewire/contacts/contacts-index.blade copy.php
Normal file
586
resources/views/livewire/contacts/contacts-index.blade copy.php
Normal file
@ -0,0 +1,586 @@
|
||||
<section id="crm-contacts-index">
|
||||
<div class="crm-contacts-index alert-errors"></div>
|
||||
|
||||
<div wire:ignore>
|
||||
<div class="query-filters" id="toolbar">
|
||||
<div class="d-flex flex-wrap">
|
||||
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
|
||||
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar contacto</button>
|
||||
</div>
|
||||
<div class="accordion mr-3 mb-3" id="accordionParentFiltrado">
|
||||
<div class="card accordion-item">
|
||||
<h2 class="accordion-header" id="headingFiltrado">
|
||||
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
|
||||
Filtrado
|
||||
</button>
|
||||
</h2>
|
||||
<div id="accordionFiltrado" class="accordion-collapse collapse" aria-labelledby="headingFiltrado" data-bs-parent="#accordionParentFiltrado">
|
||||
<div class="accordion-body">
|
||||
<div class="d-flex flex-wrap">
|
||||
|
||||
<div class="pr-2 pl-4">
|
||||
<div class="form-check form-check-secondary mb-0">
|
||||
<input class="form-check-input" type="checkbox" id="filter_is_prospect" checked="checked">
|
||||
<label class="form-check-label" for="filter_is_prospect">Es prospecto</label>
|
||||
</div>
|
||||
<div class="form-check form-check-secondary mb-0">
|
||||
<input class="form-check-input" type="checkbox" id="filter_is_prospect" checked="checked">
|
||||
<label class="form-check-label" for="filter_is_customer">Es cliente</label>
|
||||
</div>
|
||||
<div class="form-check form-check-secondary m-0">
|
||||
<input class="form-check-input" type="checkbox" id="filter_is_provider" checked="checked">
|
||||
<label class="form-check-label" for="filter_is_provider">Es proveedor</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pr-2 pl-4">
|
||||
<div class="form-check form-check-secondary m-0">
|
||||
<input class="form-check-input" type="checkbox" id="filter_is_user">
|
||||
<label class="form-check-label" for="filter_is_user">Es usuario</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-2 pt-1">
|
||||
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
|
||||
</div>
|
||||
<div class="pr-2" style="width: 60px;">
|
||||
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="bt-contacts"></table>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
@push('page-script')
|
||||
<script>
|
||||
|
||||
const store_route = '{{ route('admin.system.users.store') }}',
|
||||
route_show = '{{ route('admin.contacts.show', ['contact' => '~contact~']) }}',
|
||||
route_destroy = '{{ route('admin.contacts.destroy', ['contact' => '~contact~']) }}',
|
||||
statusList = {!! json_encode($status_list) !!},
|
||||
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
|
||||
|
||||
var btt_height;
|
||||
|
||||
|
||||
// BootstrapTable Petición AJAX
|
||||
function ajaxRequest(params) {
|
||||
let url = '{{ url()->current() }}' +
|
||||
'?' +
|
||||
$.param(params.data) +
|
||||
'&' +
|
||||
$('.query-filters :input').serialize();
|
||||
|
||||
$.get(url).then(function (res) {
|
||||
params.success(res)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// BootstrapTable Formatter
|
||||
function userAvatarFormatter(value, row, index) {
|
||||
if(row.id){
|
||||
let show_href = route_show.replace('~contacto~', row.id);
|
||||
|
||||
return [
|
||||
'<div class="d-flex justify-content-start align-items-center user-name">',
|
||||
'<div class="avatar-wrapper">',
|
||||
'<div class="avatar avatar-sm me-4">' +
|
||||
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="d-flex flex-column">',
|
||||
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
|
||||
'<small>' + row.email + '</small>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
].join('')
|
||||
}
|
||||
}
|
||||
|
||||
function uidFormatter(value, row, index) {
|
||||
if(row.id){
|
||||
let show_href = route_show.replace('~contacto~', row.id);
|
||||
|
||||
return [
|
||||
'<div class="d-flex align-items-center justify-content-center">',
|
||||
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver Contacto"> ' + row.id + '</a>',
|
||||
@can('crm.contacts.update')
|
||||
'<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:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
|
||||
'</div>',
|
||||
@endcan
|
||||
'</div>'
|
||||
].join('')
|
||||
}
|
||||
}
|
||||
|
||||
// BootstrapTable Init
|
||||
function initTable(table) {
|
||||
$(table)
|
||||
.bootstrapTable('destroy')
|
||||
.bootstrapTable({
|
||||
height: btt_height,
|
||||
locale: 'es-MX',
|
||||
ajax: "ajaxRequest",
|
||||
toolbar: "#toolbar",
|
||||
search: true,
|
||||
showColumns: true,
|
||||
showColumnsToggleAll: true,
|
||||
showExport: true,
|
||||
showFullscreen: true,
|
||||
showPaginationSwitch: true,
|
||||
showRefresh: true,
|
||||
showToggle: true,
|
||||
clickToSelect: true,
|
||||
minimumCountColumns: 4,
|
||||
fixedColumns: true,
|
||||
fixedNumber: 1,
|
||||
idField: "id",
|
||||
pagination: true,
|
||||
pageList: [10, 25, 50, 100, 500],
|
||||
sidePagination: "server",
|
||||
exportTypes: ['csv', 'txt', 'excel'],
|
||||
exportOptions: {
|
||||
fileName: 'Contactos',
|
||||
},
|
||||
sortName: 'users.id',
|
||||
sortOrder: 'desc',
|
||||
mobileResponsive: true,
|
||||
cookie: true,
|
||||
resizable: true,
|
||||
cookieIdTable:"crm-contacts-index",
|
||||
columns: [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'UID',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
sortName: 'users.id',
|
||||
switchable: false,
|
||||
formatter: uidFormatter
|
||||
},
|
||||
|
||||
{
|
||||
field: 'name',
|
||||
title: 'Nombre',
|
||||
formatter: userAvatarFormatter,
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
title: 'Correo electrónico',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
field: 'tipo_persona',
|
||||
title: 'Tipo persona',
|
||||
visible: false,
|
||||
sortable: true,
|
||||
formatter: window.btFormatter.tipoPersona,
|
||||
},
|
||||
{
|
||||
field: 'rfc',
|
||||
title: 'RFC',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'nombre_fiscal',
|
||||
title: 'Nombre fiscal',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'c_regimen_fiscal',
|
||||
title: 'Regimen fiscal',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
formatter: window.btFormatter.regimenFiscal,
|
||||
},
|
||||
{
|
||||
field: 'domicilio_fiscal',
|
||||
title: 'Domicilio fiscal',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
field: 'estado',
|
||||
title: 'Estado',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'municipio',
|
||||
title: 'Municipio',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'localidad',
|
||||
title: 'Localidad',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
},
|
||||
|
||||
{
|
||||
field: 'c_uso_cfdi',
|
||||
title: 'Uso de CFDI',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
formatter: window.btFormatter.usoCfdi,
|
||||
},
|
||||
{
|
||||
field: 'cargo',
|
||||
title: 'Cargo',
|
||||
visible: false,
|
||||
sortable: true,
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'is_prospect',
|
||||
title: 'Es prospecto',
|
||||
align: 'center',
|
||||
visible: false,
|
||||
sortable: true,
|
||||
formatter: window.btFormatter.check,
|
||||
},
|
||||
{
|
||||
field: 'is_customer',
|
||||
title: 'Es cliente',
|
||||
align: 'center',
|
||||
visible: false,
|
||||
sortable: true,
|
||||
formatter: window.btFormatter.check,
|
||||
},
|
||||
{
|
||||
field: 'is_provider',
|
||||
title: 'Es proveedor',
|
||||
align: 'center',
|
||||
visible: false,
|
||||
sortable: true,
|
||||
formatter: window.btFormatter.check,
|
||||
},
|
||||
{
|
||||
field: 'is_user',
|
||||
title: 'Es usuario',
|
||||
align: 'center',
|
||||
visible: false,
|
||||
sortable: true,
|
||||
formatter: window.btFormatter.check,
|
||||
},
|
||||
|
||||
{
|
||||
field: 'status',
|
||||
title: 'Estado',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
formatter: window.btFormatter.status,
|
||||
},
|
||||
{
|
||||
field: 'created_at',
|
||||
title: 'Creado ',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
field: 'created_by_name',
|
||||
title: 'Creado por',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
sortName: 'created_by_name',
|
||||
},
|
||||
{
|
||||
field: 'updated_at',
|
||||
title: 'Modificado ',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
visible: false,
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function toggleSections() {
|
||||
const isProspect = $('#is_prospect').is(':checked');
|
||||
const isCustomer = $('#is_customer').is(':checked');
|
||||
const isProvider = $('#is_provider').is(':checked');
|
||||
const isUser = $('#is_user').is(':checked');
|
||||
|
||||
$('.div-sat').toggle(isCustomer || isProvider);
|
||||
$('.div-sat-customer').toggle(isCustomer);
|
||||
$('.div-user-auth').toggle(isCustomer || isUser);
|
||||
$('.div-roles').toggle(isUser);
|
||||
}
|
||||
|
||||
function toggleCheckboxes(status) {
|
||||
const isDisabled = status == 1;
|
||||
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
});
|
||||
});
|
||||
|
||||
$("#pdf-dropzone")
|
||||
.dropzone({
|
||||
url: '{{ route('admin.contacts.extraer-datos-pdf-constancia') }}',
|
||||
paramName: "file",
|
||||
maxFiles: 1,
|
||||
acceptedFiles: '.pdf',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(file, response) {
|
||||
if($('#name').val().trim() == '')
|
||||
@this.set('name', response.nombre_fiscal, false);
|
||||
|
||||
@this.set('rfc', response.rfc, false);
|
||||
@this.set('nombre_fiscal', response.nombre_fiscal, false);
|
||||
|
||||
if($('#email').val().trim() == '' && response.email)
|
||||
@this.set('email', response.email, false);
|
||||
|
||||
if(response.c_regimen_fiscal)
|
||||
@this.set('c_regimen_fiscal', response.c_regimen_fiscal, false);
|
||||
|
||||
@this.set('domicilio_fiscal', response.domicilio_fiscal, false);
|
||||
|
||||
$('.pdf-dropzone-div').slideUp(200);
|
||||
},
|
||||
error: function(file, response) {
|
||||
$('.pdf-dropzone-div .error-message').html('<label class="error">' + response + '</label>');
|
||||
|
||||
this.removeAllFiles(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Evento para los checkboxes
|
||||
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
|
||||
|
||||
// Evento para el select de estado
|
||||
$('.div-status').on('change', 'select[name="status"]', function() {
|
||||
toggleCheckboxes($(this).val());
|
||||
});
|
||||
|
||||
|
||||
// Previo de imagenes
|
||||
document.getElementById("photo").addEventListener('change', updatePreviewImage);
|
||||
|
||||
|
||||
// Reset form
|
||||
$("#userForm")
|
||||
.on('reset', function(){
|
||||
var form = $("#userForm");
|
||||
|
||||
form.validate().resetForm();
|
||||
|
||||
setTimeout(function(){
|
||||
$('#roles').trigger('change');
|
||||
|
||||
toggleSections();
|
||||
}, 250)
|
||||
|
||||
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
|
||||
$('#userForm .alert-errors').html('');
|
||||
|
||||
$('.pdf-dropzone-div').show();
|
||||
|
||||
$("#pdf-dropzone").removeAllFiles(true);
|
||||
});
|
||||
|
||||
|
||||
$("#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: 5
|
||||
},
|
||||
email: {
|
||||
required: true,
|
||||
email: true
|
||||
},
|
||||
password: {
|
||||
required: function(element) {
|
||||
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
|
||||
},
|
||||
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, event) {
|
||||
// Evita que el formulario se envíe automáticamente
|
||||
event.preventDefault();
|
||||
|
||||
var form = $("#userForm")[0],
|
||||
data = new FormData(form);
|
||||
|
||||
$('#userForm :input').prop('disabled', true);
|
||||
$('#userForm .alert-errors').html('');
|
||||
|
||||
$.ajax({
|
||||
url: store_route,
|
||||
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 {
|
||||
let $usersIndexAlert = $('.crm-contacts-index.alert-errors');
|
||||
|
||||
$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');
|
||||
$('#toolbar .clear-filters').trigger('click');
|
||||
}
|
||||
},
|
||||
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>');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Inicializar el estado al cargar la página
|
||||
toggleSections();
|
||||
toggleCheckboxes($('select[name="status"]').val());
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
$(document).ready(function() {
|
||||
var $table = $('#bt-contacts'),
|
||||
$btnRefresh = $('#toolbar .btn-refresh'),
|
||||
$clearFilters = $('a.clear-filters');
|
||||
|
||||
var btt_rest_height = 220,
|
||||
btt_min_height = 600;
|
||||
|
||||
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
|
||||
btt_height:
|
||||
window.innerHeight - btt_rest_height;
|
||||
|
||||
var offcanvasElement = document.getElementById('offcanvasUser'),
|
||||
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
|
||||
|
||||
const refreshButton = document.querySelector('.btn-refresh');
|
||||
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
|
||||
|
||||
inputs.forEach(input => {
|
||||
input.addEventListener('change', () => {
|
||||
refreshButton.disabled = false;
|
||||
refreshButton.classList.remove('btn-label-secondary');
|
||||
refreshButton.classList.add('btn-label-success');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Button Refresh
|
||||
$btnRefresh
|
||||
.on('click', () => {
|
||||
$table.bootstrapTable('refresh');
|
||||
refreshButton.disabled = true;
|
||||
refreshButton.classList.remove('btn-label-success');
|
||||
refreshButton.classList.add('btn-label-secondary');
|
||||
});
|
||||
|
||||
// Button clear filters
|
||||
$clearFilters
|
||||
.on('click', () => {
|
||||
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
|
||||
refreshButton.disabled = true;
|
||||
refreshButton.classList.remove('btn-label-success');
|
||||
refreshButton.classList.add('btn-label-secondary');
|
||||
});
|
||||
|
||||
|
||||
initTable('#bt-contacts'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
|
||||
|
||||
|
||||
load_js_form();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
165
resources/views/livewire/contacts/form.blade.php
Normal file
165
resources/views/livewire/contacts/form.blade.php
Normal file
@ -0,0 +1,165 @@
|
||||
<div>
|
||||
<x-vuexy-admin::form id="{{ $formId }}" :mode="$mode" wireSubmit="onSubmit" actionPosition="both">
|
||||
<x-slot name="actions">
|
||||
<x-vuexy-admin::button.offcanvas-buttons :mode="$mode" :tagName="$tagName" />
|
||||
</x-slot>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
{{-- Identificación --}}
|
||||
<x-vuexy-admin::card.basic title="Identificación">
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="code" label="Identificador único" icon="ti ti-tag" placeholder="UID code" autofocus autocomplete="off" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="name" label="Nombre de la sucursal" autocomplete="organization" />
|
||||
<x-vuexy-admin::form.textarea :uid="$uniqueId" model="description" label="Descripción" placeholder="Descripción de la sucursal" :autosize=true />
|
||||
</x-vuexy-admin::card.basic>
|
||||
|
||||
{{-- Series de facturación --}}
|
||||
<x-vuexy-admin::card.basic title="Series de facturación">
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="serie_ingresos" label="Serie para Ingresos" inline=true :labelCol=6 :inputCol=6 maxlength="5" autocomplete="off" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="serie_egresos" label="Serie para Egresos" inline=true :labelCol=6 :inputCol=6 maxlength="5" autocomplete="off" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="serie_pagos" label="Serie para Pagos" inline=true :labelCol=6 :inputCol=6 maxlength="5" autocomplete="off" />
|
||||
</x-vuexy-admin::card.basic>
|
||||
|
||||
{{-- Configuraciones --}}
|
||||
<x-vuexy-admin::card.basic title="Configuraciones">
|
||||
<x-vuexy-admin::form.checkbox uid="random" model="status" label="Habilitar sucursal" switch="true" />
|
||||
<x-vuexy-admin::form.checkbox uid="random" model="show_on_website" label="Mostrar en sitio web" switch="true" />
|
||||
<x-vuexy-admin::form.checkbox uid="random" model="enable_ecommerce" label="eCommerce habilitado en sitio Web" switch="true" />
|
||||
</x-vuexy-admin::card.basic>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
{{-- Información de contacto --}}
|
||||
<x-vuexy-admin::card.basic title="Información de contacto">
|
||||
<x-vuexy-admin::form.input type="tel" :uid="$uniqueId" model="tel" label="Teléfono" icon="ti ti-phone" phoneMode="national" />
|
||||
<x-vuexy-admin::form.input type="tel" :uid="$uniqueId" model="tel2" label="Teléfono alternativo" icon="ti ti-phone" phoneMode="both" />
|
||||
<x-vuexy-admin::form.input type="email" :uid="$uniqueId" model="email" label="Correo electrónico" icon="ti ti-mail" autocomplete="email" inputmode="email" />
|
||||
<x-vuexy-admin::form.select :uid="$uniqueId" model="manager_id" label="Gerente" :options="$manager_id_options" placeholder="Selecciona el gerente" />
|
||||
</x-vuexy-admin::card.basic>
|
||||
|
||||
{{-- Información fiscal --}}
|
||||
<x-vuexy-admin::card.basic title="Información fiscal">
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="rfc" label="RFC" autocomplete="off" pattern="^[A-Z&Ñ]{3,4}[0-9]{6}[A-Z0-9]{3}$" maxlength="13" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="nombre_fiscal" label="Nombre fiscal" autocomplete="organization" />
|
||||
<x-vuexy-admin::form.select :uid="$uniqueId" model="c_regimen_fiscal" label="Régimen fiscal" :options="$c_regimen_fiscal_options" placeholder="Selecciona el régimen fiscal" />
|
||||
<x-vuexy-admin::form.input :uid="$uniqueId" model="domicilio_fiscal" label="Domicilio fiscal" autocomplete="address-line1" maxlength="100" />
|
||||
</x-vuexy-admin::card.basic>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
{{-- Dirección --}}
|
||||
<x-vuexy-contacts::card.address :uid="$uniqueId" :paisOptions="$c_pais_options" :estadoOptions="$c_estado_options" :localidadOptions="$c_localidad_options" :municipioOptions="$c_municipio_options" :coloniaOptions="$c_colonia_options"/>
|
||||
|
||||
{{-- Ubicación --}}
|
||||
<x-vuexy-contacts::card.location :uid="$uniqueId" />
|
||||
</div>
|
||||
</div>
|
||||
</x-vuexy-admin::form>
|
||||
</div>
|
||||
|
||||
@push('page-script')
|
||||
<script>
|
||||
const initializeStoreForm = (mode) => {
|
||||
const initializeContactInformation = () => {
|
||||
let $manager_id = $("#manager_id_{{ $uniqueId }}");
|
||||
|
||||
$manager_id
|
||||
.select2({
|
||||
language: "es",
|
||||
placeholder: "Selecciona el gerente",
|
||||
allowClear: true,
|
||||
width: "100%"
|
||||
})
|
||||
.on('select2:select select2:clear', function (e) {
|
||||
@this.manager_id = e.params?.data?.id || null;
|
||||
});
|
||||
}
|
||||
|
||||
const initializeFiscalInformation = () => {
|
||||
let $c_regimen_fiscal = $("#c_regimen_fiscal_{{ $uniqueId }}");
|
||||
|
||||
$c_regimen_fiscal
|
||||
.select2({
|
||||
language: "es",
|
||||
placeholder: "Selecciona el regimen fiscal",
|
||||
allowClear: true,
|
||||
width: "100%"
|
||||
})
|
||||
.on('select2:select select2:clear', function (e) {
|
||||
@this.c_regimen_fiscal = e.params?.data?.id || null;
|
||||
});
|
||||
}
|
||||
|
||||
const initializeLocationIQ = () => {
|
||||
//
|
||||
}
|
||||
|
||||
const initializeAddressFormHandler = () => {
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
||||
|
||||
// Definición de selectores AddressFormHandler
|
||||
formSelectors = {
|
||||
c_pais: '#c_pais_{{ $uniqueId }}',
|
||||
c_estado: '#c_estado_{{ $uniqueId }}',
|
||||
c_localidad: '#c_localidad_{{ $uniqueId }}',
|
||||
c_municipio: '#c_municipio_{{ $uniqueId }}',
|
||||
c_colonia: '#c_colonia_{{ $uniqueId }}',
|
||||
c_codigo_postal: '#c_codigo_postal_{{ $uniqueId }}',
|
||||
direccion: '#direccion_{{ $uniqueId }}',
|
||||
notification: '#{{ $formId }} .address-notification'
|
||||
};
|
||||
|
||||
// Definición de rutas AJAX Componente AddressFormHandler
|
||||
const ajaxRoutes = {
|
||||
codigo_postal: "{{ route('admin.core.sat.get.ajax', 'codigo_postal') }}",
|
||||
localidad: "{{ route('admin.core.sat.get.ajax', 'localidad') }}",
|
||||
estado: "{{ route('admin.core.sat.get.ajax', 'estado') }}",
|
||||
municipio: "{{ route('admin.core.sat.get.ajax', 'municipio') }}",
|
||||
colonia: "{{ route('admin.core.sat.get.ajax', 'colonia') }}"
|
||||
};
|
||||
|
||||
// Inicializamos el handler de la información de la dirección
|
||||
new AddressFormHandler(formSelectors, ajaxRoutes, @this, csrfToken);
|
||||
}
|
||||
|
||||
const initializeLocationCard = (mode) => {
|
||||
const locationInputs = {
|
||||
search: '#location_search_{{ $uniqueId }}',
|
||||
btnSearch: '#btn_search_{{ $uniqueId }}',
|
||||
lat: '#lat_{{ $uniqueId }}',
|
||||
lng: '#lng_{{ $uniqueId }}',
|
||||
btnClear: '#{{ $formId }} .btn-clear-coords',
|
||||
mapId: 'locationMap_{{ $uniqueId }}',
|
||||
}
|
||||
|
||||
leafletMap = LeafletMapHelper.initializeMap(locationInputs, mode, @this);
|
||||
}
|
||||
|
||||
|
||||
// Inicializamos Tarjeta de Información de contacto
|
||||
initializeContactInformation();
|
||||
|
||||
// Inicializamos Tarjeta de Información fiscal
|
||||
initializeFiscalInformation();
|
||||
|
||||
// Inicializamos Tarjeta de Dirección
|
||||
initializeAddressFormHandler();
|
||||
|
||||
// Inicializamos Tarjeta de Ubicación
|
||||
initializeLocationCard(mode);
|
||||
|
||||
// Deshabilitamos el formulario si estamos eliminando
|
||||
if (mode === 'delete') {
|
||||
window.disableStoreForm('#{{ $formId }}');
|
||||
}
|
||||
}
|
||||
|
||||
// Evento para inicializar el formulario
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.addEventListener('on-failed-validation-store', (event) => {
|
||||
setTimeout(() => {
|
||||
initializeStoreForm('{{ $mode }}');
|
||||
}, 10);
|
||||
});
|
||||
|
||||
initializeStoreForm('{{ $mode }}');
|
||||
});
|
||||
</script>
|
||||
@endpush
|
57
resources/views/livewire/contacts/index.blade.php
Normal file
57
resources/views/livewire/contacts/index.blade.php
Normal file
@ -0,0 +1,57 @@
|
||||
<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" />
|
||||
</div>
|
||||
</x-slot>
|
||||
<x-slot name="postTools">
|
||||
<div class="mb-4 pr-2">
|
||||
<x-vuexy-admin::file.dropzone id="user_doc_file" model="user_doc_file" message="Crear nuevo usuario" note="XML CFDI o PDF CSF" size="xs" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-vuexy-admin::table.bootstrap.manager>
|
||||
|
||||
@push('page-script')
|
||||
<script>
|
||||
// Evento para inicializar el formulario cuando se carga la página
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
let dropzone = new Dropzone("#dropzone_user_doc_file", {
|
||||
url: "#",
|
||||
autoProcessQueue: false,
|
||||
acceptedFiles: ".pdf,.xml",
|
||||
maxFiles: 1,
|
||||
addRemoveLinks: true,
|
||||
dictDefaultMessage: "Arrastra aquí tu PDF de Constancia de Situación Fiscal",
|
||||
init: function () {
|
||||
this.on("addedfile", function (file) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
let input = document.querySelector("#user_doc_file");
|
||||
let dataTransfer = new DataTransfer();
|
||||
|
||||
dataTransfer.items.add(new File([file], file.name, { type: file.type }));
|
||||
|
||||
// Asignamos solo un archivo, no un FileList
|
||||
//input.files = dataTransfer.files;
|
||||
|
||||
// Livewire solo recibe archivos en forma de input, no como FileList
|
||||
@this.upload('doc_file', dataTransfer.files[0],
|
||||
(uploadedFile) => {
|
||||
@this.call('processDocument');
|
||||
},
|
||||
(error) => {
|
||||
console.error("Error al subir PDF:", error);
|
||||
},
|
||||
(progressEvent) => {
|
||||
console.log("Progreso de subida:", progressEvent);
|
||||
}
|
||||
);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endpush
|
94
resources/views/livewire/contacts/offcanvas-form.blade.php
Normal file
94
resources/views/livewire/contacts/offcanvas-form.blade.php
Normal file
@ -0,0 +1,94 @@
|
||||
<div>
|
||||
<x-vuexy-admin::offcanvas.basic :id="$offcanvasId" :tag-name="$tagName">
|
||||
{{-- Dropzone Constancia de Situación Fiscal --}}
|
||||
<x-vuexy-admin::file.dropzone :uid="$uniqueId" model="doc_file" message="CSF PDF o CFDI XML" note="Arrastra aquí un PDF de Constancia de Situación Fiscal o XML de CFDI para cargar los datos al fomulario" />
|
||||
|
||||
<x-vuexy-admin::form :uid="$uniqueId" :id="$formId" :mode="$mode" wireSubmit="onSubmit" actionPosition="both">
|
||||
<x-slot name="actions">
|
||||
<x-vuexy-admin::button.offcanvas-buttons :mode="$mode" :tagName="$tagName" />
|
||||
</x-slot>
|
||||
|
||||
{{-- Selección de Sucursal --}}
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
{{-- Teléfonos y Correos --}}
|
||||
<x-vuexy-admin::form.input type="email" :uid="$uniqueId" model="email" label="Correo electrónico" icon="ti ti-mail" autocomplete="email" inputmode="email" />
|
||||
<x-vuexy-admin::form.input type="tel" :uid="$uniqueId" model="tel" label="Teléfono" icon="ti ti-phone" phoneMode="both" />
|
||||
|
||||
<hr>
|
||||
|
||||
<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>
|
||||
</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 = () => {
|
||||
let dropzone = new Dropzone("#dropzone_doc_file_{{ $uniqueId }}", {
|
||||
url: "#",
|
||||
autoProcessQueue: false,
|
||||
acceptedFiles: ".pdf,.xml",
|
||||
maxFiles: 1,
|
||||
addRemoveLinks: true,
|
||||
dictDefaultMessage: "Arrastra aquí tu PDF de Constancia de Situación Fiscal",
|
||||
init: function () {
|
||||
this.on("addedfile", function (file) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
let input = document.querySelector("#doc_file_{{ $uniqueId }}");
|
||||
let dataTransfer = new DataTransfer();
|
||||
|
||||
dataTransfer.items.add(new File([file], file.name, { type: file.type }));
|
||||
|
||||
// Asignamos solo un archivo, no un FileList
|
||||
//input.files = dataTransfer.files;
|
||||
|
||||
// Livewire solo recibe archivos en forma de input, no como FileList
|
||||
@this.upload('doc_file', dataTransfer.files[0],
|
||||
(uploadedFile) => {
|
||||
@this.call('processDocument');
|
||||
},
|
||||
(error) => {
|
||||
console.error("Error al subir PDF:", error);
|
||||
},
|
||||
(progressEvent) => {
|
||||
console.log("Progreso de subida:", progressEvent);
|
||||
}
|
||||
);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var myOffcanvas = document.getElementById('{{ $offcanvasId }}');
|
||||
myOffcanvas.addEventListener('show.bs.offcanvas', function () {
|
||||
initializeUserForm();
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endpush
|
1685
resources/views/livewire/contacts/show.blade.php
Normal file
1685
resources/views/livewire/contacts/show.blade.php
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user