Archivos de configuración global, dependencias y assets base

This commit is contained in:
Lucho
2026-06-24 16:30:14 -03:00
parent 9474236226
commit 4d29f6bb49
11 changed files with 2046 additions and 51 deletions
+542 -1
View File
@@ -1,2 +1,543 @@
// Confirmación de envío de formulario en welcome
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector('form[action="/formulario"]');
const btnConfirmar = document.getElementById('btnConfirmarEnvioForm');
if (form && btnConfirmar) {
btnConfirmar.addEventListener('click', function () {
form.submit();
});
}
// Confirmación de envío de formulario en dashboard cliente
const formCliente = document.querySelector('form[action="/cliente/formulario"]');
const btnConfirmarCliente = document.getElementById('btnConfirmarEnvioFormCliente');
if (formCliente && btnConfirmarCliente) {
btnConfirmarCliente.addEventListener('click', function () {
formCliente.submit();
});
}
});
import './bootstrap';
import 'bootstrap';
import * as bootstrap from 'bootstrap';
import html2canvas from 'html2canvas';
import { Calendar } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import esLocale from '@fullcalendar/core/locales/es';
window.html2canvas = html2canvas;
import timeGridPlugin from '@fullcalendar/timegrid';
window.FullCalendar = { Calendar };
window.FullCalendarPlugins = {
dayGridPlugin,
interactionPlugin,
timeGridPlugin,
};
window.FullCalendarLocales = {
es: esLocale,
};
window.bootstrap = bootstrap;
document.addEventListener('DOMContentLoaded', function () {
const carouseles = document.querySelectorAll('.carousel');
if (!carouseles.length) {
return;
}
carouseles.forEach((carouselEl) => {
const totalItems = carouselEl.querySelectorAll('.carousel-item').length;
if (totalItems <= 1) {
return;
}
const instancia = bootstrap.Carousel.getOrCreateInstance(carouselEl, {
interval: 10000,
ride: 'carousel',
pause: 'hover',
wrap: true,
touch: true,
});
instancia.cycle();
});
});
const requiereSidebarLateral =
window.location.pathname.startsWith('/administrador') ||
window.location.pathname.startsWith('/profesional');
const mainSidebarTarget = requiereSidebarLateral ? document.querySelector('main') : null;
const limpiarEstadoPendingSidebar = () => {
document.documentElement.classList.remove('sidebar-nav-pending');
mainSidebarTarget?.classList.remove('sidebar-main-pending');
};
if (requiereSidebarLateral) {
if (mainSidebarTarget) {
mainSidebarTarget.classList.add('admin-main-content', 'sidebar-main-pending');
}
document.documentElement.classList.add('sidebar-nav-pending');
window.setTimeout(() => {
limpiarEstadoPendingSidebar();
}, 900);
}
const asegurarFavicon = () => {
const faviconHref = '/favicon.ico?v=20260403';
const rels = ['icon', 'shortcut icon', 'apple-touch-icon'];
rels.forEach((rel) => {
let link = document.head?.querySelector(`link[rel="${rel}"]`);
if (!link) {
link = document.createElement('link');
link.setAttribute('rel', rel);
document.head?.appendChild(link);
}
link.setAttribute('type', 'image/x-icon');
link.setAttribute('href', faviconHref);
});
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', asegurarFavicon, { once: true });
} else {
asegurarFavicon();
}
document.addEventListener('DOMContentLoaded', function () {
const mapWidgets = document.querySelectorAll('[data-map-widget]');
if (!mapWidgets.length) {
return;
}
const updateMapWidget = (widget) => {
const iframe = widget.querySelector('[data-map-embed]');
const fallback = widget.querySelector('[data-map-fallback]');
if (!iframe) {
return;
}
const mapSrc = iframe.getAttribute('data-map-src') || '';
const offline = !navigator.onLine;
if (offline) {
iframe.classList.add('d-none');
fallback?.classList.remove('d-none');
return;
}
if (mapSrc && iframe.getAttribute('src') !== mapSrc) {
iframe.setAttribute('src', mapSrc);
}
iframe.classList.remove('d-none');
fallback?.classList.add('d-none');
};
mapWidgets.forEach((widget) => {
const iframe = widget.querySelector('[data-map-embed]');
if (iframe) {
iframe.addEventListener('error', () => {
iframe.classList.add('d-none');
widget.querySelector('[data-map-fallback]')?.classList.remove('d-none');
});
}
updateMapWidget(widget);
});
window.addEventListener('online', () => {
mapWidgets.forEach(updateMapWidget);
});
window.addEventListener('offline', () => {
mapWidgets.forEach(updateMapWidget);
});
});
const STORAGE_KEY_NOTIF_CERRADAS = 'notif_cerradas_profesional';
const STORAGE_KEY_NOTIF_VISTAS = 'notif_vistas_profesional';
function getNotificacionesCerradas() {
try {
return JSON.parse(localStorage.getItem(STORAGE_KEY_NOTIF_CERRADAS) || '[]');
} catch {
return [];
}
}
function guardarNotificacionesCerradas(claves) {
localStorage.setItem(STORAGE_KEY_NOTIF_CERRADAS, JSON.stringify(claves));
}
function getNotificacionesVistas() {
try {
const vistas = JSON.parse(localStorage.getItem(STORAGE_KEY_NOTIF_VISTAS) || '[]');
return Array.from(new Set([...(Array.isArray(vistas) ? vistas : []), ...getNotificacionesCerradas()]));
} catch {
return getNotificacionesCerradas();
}
}
function guardarNotificacionesVistas(claves) {
localStorage.setItem(STORAGE_KEY_NOTIF_VISTAS, JSON.stringify(Array.from(new Set(claves))));
}
function marcarNotificacionesComoVistas(clavesActivas) {
if (!Array.isArray(clavesActivas) || !clavesActivas.length) {
return;
}
const vistasActuales = getNotificacionesVistas();
guardarNotificacionesVistas([...vistasActuales, ...clavesActivas]);
}
function podarNotificacionesVistas(clavesActivas) {
const vistas = getNotificacionesVistas();
if (!vistas.length) {
return [];
}
const vistasVigentes = vistas.filter((clave) => clavesActivas.includes(clave));
if (vistasVigentes.length !== vistas.length) {
guardarNotificacionesVistas(vistasVigentes);
}
return vistasVigentes;
}
function actualizarBadgeNotificaciones() {
const enlace = document.querySelector('a[href="/profesional/notificaciones"][data-notificaciones-claves]');
if (!enlace) {
return;
}
const badge = enlace.querySelector('.js-notificaciones-badge');
if (!badge) {
return;
}
let clavesActivas = [];
try {
clavesActivas = JSON.parse(enlace.dataset.notificacionesClaves || '[]');
} catch {
clavesActivas = [];
}
if (window.location.pathname === '/profesional/notificaciones') {
marcarNotificacionesComoVistas(clavesActivas);
}
const vistas = podarNotificacionesVistas(clavesActivas);
const tienePendientes = clavesActivas.some((clave) => !vistas.includes(clave));
badge.classList.toggle('d-none', !tienePendientes);
}
window.actualizarBadgeNotificaciones = actualizarBadgeNotificaciones;
actualizarBadgeNotificaciones();
document.addEventListener('DOMContentLoaded', function () {
actualizarBadgeNotificaciones();
});
document.addEventListener('DOMContentLoaded', function () {
const soloNumeros = ['cuil', 'celular', 'telefono'];
const soloLetras = ['nombre', 'apellido'];
const normalizarIdentificador = (valor) => String(valor || '').trim().toLowerCase();
const esCampo = (input, listaCampos) => {
const nombre = normalizarIdentificador(input.name);
const id = normalizarIdentificador(input.id);
return listaCampos.includes(nombre) || listaCampos.includes(id);
};
const esNumerico = (char) => /\d/.test(char);
const esLetra = (char) => /[A-Za-zÁÉÍÓÚáéíóúÑñ\s]/.test(char);
const inputs = Array.from(document.querySelectorAll('input'));
inputs.forEach((input) => {
if (esCampo(input, soloNumeros)) {
input.setAttribute('inputmode', 'numeric');
input.setAttribute('pattern', '[0-9]+');
input.addEventListener('beforeinput', function (e) {
if (!esNumerico(e.data) && e.data !== null) {
e.preventDefault();
}
});
input.addEventListener('input', function () {
input.value = input.value.replace(/\D/g, '');
});
}
if (esCampo(input, soloLetras)) {
input.setAttribute('pattern', '[A-Za-zÁÉÍÓÚáéíóúÑñ\\s]+');
input.addEventListener('beforeinput', function (e) {
if (!esLetra(e.data) && e.data !== null) {
e.preventDefault();
}
});
input.addEventListener('input', function () {
input.value = input.value.replace(/[^A-Za-zÁÉÍÓÚáéíóúÑñ\s]/g, '');
});
}
if (input.type === 'password') {
const formAction = String(input.form?.getAttribute('action') || '');
const nombre = normalizarIdentificador(input.name);
const esLogin = formAction.includes('/login/');
const esContraActual = nombre === 'contra_actual' || nombre === 'contra_actual_secreta';
if (!esLogin && !esContraActual) {
input.setAttribute('minlength', '6');
}
}
});
});
document.addEventListener('DOMContentLoaded', function () {
if (!window.location.pathname.startsWith('/administrador')) {
return;
}
const header = document.querySelector('.app-navbar');
if (!header) {
limpiarEstadoPendingSidebar();
return;
}
const navbarContainer = header.querySelector('.navbar .container');
const collapse = header.querySelector('#menuPrincipal');
const logout = (collapse || header).querySelector('a[href="/logout"]');
const adminMenuList = (collapse || header).querySelector('ul.navbar-nav');
if (adminMenuList && !adminMenuList.querySelector('a[href="/administrador/ayuda"]')) {
const ayudaItem = document.createElement('li');
ayudaItem.className = 'nav-item';
const ayudaLink = document.createElement('a');
ayudaLink.className = 'btn app-navbar-link';
ayudaLink.setAttribute('href', '/administrador/ayuda');
ayudaLink.setAttribute('title', 'Ayuda para administrador');
ayudaLink.setAttribute('aria-label', 'Ayuda para administrador');
ayudaLink.textContent = '¿Necesitas Ayuda?';
ayudaItem.appendChild(ayudaLink);
adminMenuList.appendChild(ayudaItem);
}
const menuLinks = Array.from((collapse || header).querySelectorAll('ul .app-navbar-link'));
if (menuLinks.length && !document.querySelector('.admin-sidebar')) {
const aside = document.createElement('aside');
aside.className = 'admin-sidebar';
aside.setAttribute('aria-label', 'Menu administrador');
const nav = document.createElement('nav');
nav.className = 'admin-sidebar-nav';
const subitemsContenido = [
{ label: 'Quienes Somos', href: '/administrador/contenido/quienes-somos' },
{ label: 'Profesiones', href: '/administrador/contenido/profesiones' },
{ label: 'Servicios', href: '/administrador/contenido/servicios' },
{ label: 'Asistente Virtual', href: '/administrador/contenido/asistente-virtual/ver-faqs' },
];
menuLinks.forEach((link) => {
const href = link.getAttribute('href') || '';
if (href === '/administrador/contenido-web') {
const enContenido =
window.location.pathname.startsWith('/administrador/contenido/') ||
window.location.pathname === '/administrador/contenido-web' ||
window.location.pathname === '/administrador/asistente-consultas';
const details = document.createElement('details');
details.className = 'admin-sidebar-details';
if (enContenido) {
details.setAttribute('open', '');
}
const summary = document.createElement('summary');
summary.className = 'btn app-navbar-link admin-sidebar-link admin-sidebar-summary';
if (enContenido) {
summary.classList.add('active');
}
summary.textContent = 'Contenido';
details.appendChild(summary);
const subitemsContenidoConConsultas = [
...subitemsContenido,
{ label: 'Consultas sin respuesta', href: '/administrador/asistente-consultas' },
];
subitemsContenidoConConsultas.forEach(({ label, href: subhref }) => {
const a = document.createElement('a');
a.className = 'btn app-navbar-link admin-sidebar-link admin-sidebar-sublink';
a.setAttribute('href', subhref);
if (window.location.pathname === subhref) {
a.classList.add('active');
}
a.textContent = label;
details.appendChild(a);
});
nav.appendChild(details);
return;
}
const item = link.cloneNode(true);
item.classList.add('admin-sidebar-link');
const esRutaActiva =
href &&
href !== '#top' &&
(window.location.pathname === href || window.location.pathname.startsWith(`${href}/`));
const esMisDatosEnDashboard = href === '#top' && window.location.pathname === '/administrador/dashboard';
if (esRutaActiva || esMisDatosEnDashboard) {
item.classList.add('active');
}
nav.appendChild(item);
});
aside.appendChild(nav);
header.insertAdjacentElement('afterend', aside);
}
if (collapse) {
const ul = collapse.querySelector('ul');
if (ul) {
ul.remove();
}
collapse.classList.remove('collapse', 'navbar-collapse');
collapse.removeAttribute('id');
collapse.classList.add('d-flex', 'ms-auto', 'align-items-center');
}
const toggler = header.querySelector('.navbar-toggler');
if (toggler) {
toggler.remove();
}
if (logout && navbarContainer) {
logout.classList.add('btn', 'app-navbar-link');
navbarContainer.appendChild(logout);
}
const actualizarOffsetSidebar = () => {
const alturaNavbar = Math.ceil(header.offsetHeight || 74);
document.documentElement.style.setProperty('--admin-navbar-height', `${alturaNavbar}px`);
};
actualizarOffsetSidebar();
window.addEventListener('resize', actualizarOffsetSidebar);
limpiarEstadoPendingSidebar();
});
document.addEventListener('DOMContentLoaded', function () {
if (!window.location.pathname.startsWith('/profesional')) {
return;
}
const header = document.querySelector('.app-navbar');
if (!header) {
limpiarEstadoPendingSidebar();
return;
}
const navbarContainer = header.querySelector('.navbar .container');
const collapse = header.querySelector('#menuPrincipal');
const logout = (collapse || header).querySelector('a[href="/logout"]');
const menuList = (collapse || header).querySelector('ul.navbar-nav');
if (menuList && !menuList.querySelector('a[href="/profesional/ayuda"]')) {
const ayudaItem = document.createElement('li');
ayudaItem.className = 'nav-item';
const ayudaLink = document.createElement('a');
ayudaLink.className = 'btn app-navbar-link';
ayudaLink.setAttribute('href', '/profesional/ayuda');
ayudaLink.setAttribute('title', 'Ayuda para profesionales');
ayudaLink.setAttribute('aria-label', 'Ayuda para profesionales');
ayudaLink.textContent = '¿Necesitas Ayuda?';
ayudaItem.appendChild(ayudaLink);
menuList.appendChild(ayudaItem);
}
const menuLinks = Array.from((collapse || header).querySelectorAll('ul .app-navbar-link'));
if (menuLinks.length && !document.querySelector('.admin-sidebar')) {
const aside = document.createElement('aside');
aside.className = 'admin-sidebar';
aside.setAttribute('aria-label', 'Menu profesional');
const nav = document.createElement('nav');
nav.className = 'admin-sidebar-nav';
menuLinks.forEach((link) => {
const href = link.getAttribute('href') || '';
const item = link.cloneNode(true);
item.classList.add('admin-sidebar-link');
const esRutaActiva =
href &&
href !== '#top' &&
(window.location.pathname === href || window.location.pathname.startsWith(`${href}/`));
const esMiAgendaEnDashboard = href === '#top' && window.location.pathname === '/profesional/dashboard';
if (esRutaActiva || esMiAgendaEnDashboard) {
item.classList.add('active');
}
nav.appendChild(item);
});
aside.appendChild(nav);
header.insertAdjacentElement('afterend', aside);
}
if (collapse) {
const ul = collapse.querySelector('ul');
if (ul) {
ul.remove();
}
collapse.classList.remove('collapse', 'navbar-collapse');
collapse.removeAttribute('id');
collapse.classList.add('d-flex', 'ms-auto', 'align-items-center');
}
const toggler = header.querySelector('.navbar-toggler');
if (toggler) {
toggler.remove();
}
if (logout && navbarContainer) {
logout.classList.add('btn', 'app-navbar-link');
navbarContainer.appendChild(logout);
}
const actualizarOffsetSidebar = () => {
const alturaNavbar = Math.ceil(header.offsetHeight || 74);
document.documentElement.style.setProperty('--admin-navbar-height', `${alturaNavbar}px`);
};
actualizarOffsetSidebar();
window.addEventListener('resize', actualizarOffsetSidebar);
limpiarEstadoPendingSidebar();
});