diff --git a/.gitignore b/.gitignore index 8f966f3b..78066f63 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,4 @@ _planeacion/ .playwright-mcp/ .serena/ .claude/ +nul diff --git a/admin/assets/css/component-navbar.css b/admin/assets/css/component-navbar.css deleted file mode 100644 index a788fae1..00000000 --- a/admin/assets/css/component-navbar.css +++ /dev/null @@ -1,292 +0,0 @@ -/* ======================================== - ADMIN PANEL - NAVBAR COMPONENT STYLES - Estilos compactos para el panel de administración -======================================== */ - -/* Sobrescribir estilos del contenedor tab-content */ -.tab-content { - padding: 24px 12px !important; - background-color: transparent !important; -} - -/* Títulos de sección compactos */ -.section-title-compact { - font-size: 1rem; - font-weight: 700; - color: var(--color-navy-primary); - margin-bottom: 0.75rem; - padding-bottom: 0.5rem; - border-bottom: 2px solid var(--color-neutral-100); -} - -.section-title-compact i { - margin-right: 0.5rem; -} - -/* Fix conflicto con WordPress: Sobreescribir max-width de .card */ -body .card, -.apus-admin .card { - max-width: none !important; -} - -/* Fix conflicto con WordPress: Sobreescribir estilos de checkbox para que funcionen los switches de Bootstrap */ -.form-switch .form-check-input[type="checkbox"] { - width: 2em !important; - height: 1em !important; - border-radius: 2em !important; - background-color: var(--bs-form-check-bg) !important; - background-image: var(--bs-form-switch-bg) !important; - background-position: left center !important; - background-size: contain !important; - background-repeat: no-repeat !important; - margin-left: -2.5em !important; - box-shadow: none !important; -} - -.form-switch .form-check-input[type="checkbox"]:checked { - background-color: #0d6efd !important; - border-color: #0d6efd !important; - background-position: right center !important; - background-size: contain !important; - background-repeat: no-repeat !important; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e") !important; -} - -body .form-switch .form-check-input[type="checkbox"]::before, -.apus-admin .form-switch .form-check-input[type="checkbox"]::before { - content: none !important; - display: none !important; - background-image: none !important; - width: 0 !important; - height: 0 !important; -} - -body .form-switch .form-check-input[type="checkbox"]::after, -.apus-admin .form-switch .form-check-input[type="checkbox"]::after { - content: none !important; - display: none !important; -} - -/* Cards compactos */ -#navbarTab .card { - border: 1px solid #dee2e6 !important; - border-left: 4px solid #1e3a5f !important; - border-radius: 6px !important; - box-shadow: rgba(0, 0, 0, 0.075) 0px 2px 4px 0px !important; - transition: all 0.3s ease !important; - background-color: #ffffff !important; - padding: 0 !important; - margin: 0 0 16px !important; -} - -.form-section.card { - border: 2px solid #d1d5db !important; - border-radius: 12px !important; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08) !important; - transition: all 0.3s ease; -} - -.form-section.card:hover { - border-color: #FF8600 !important; - box-shadow: 0 4px 16px rgba(255, 134, 0, 0.15) !important; -} - -.form-section.card .card-body.p-3 { - padding: 1.25rem !important; -} - -/* Color pickers compactos */ -.form-control-color-compact { - width: 100%; - height: 40px; - border-radius: 0.375rem; - border: 1px solid var(--color-neutral-100); - cursor: pointer; - transition: border-color 0.3s ease; -} - -.form-control-color-compact:hover { - border-color: var(--color-orange-primary); -} - -/* Form controls pequeños con mejor UX */ -#navbarTab .form-control-sm, -#navbarTab .form-select-sm { - font-size: 14px !important; - padding: 6px 12px !important; - border: 1px solid rgb(222, 226, 230) !important; - border-radius: 4px !important; - color: rgb(33, 37, 41) !important; -} - -.form-control-sm, -.form-select-sm { - font-size: 0.875rem; - padding: 0.375rem 0.75rem; -} - -/* Labels compactos */ -.form-label.small { - font-size: 0.875rem; - font-weight: 600; - color: var(--color-neutral-700); - margin-bottom: 0.25rem; -} - -/* Fix alineación vertical de labels en switches */ -#navbarTab .form-check.form-switch { - display: flex !important; - align-items: center !important; -} - -#navbarTab .form-switch .form-check-input { - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -#navbarTab .form-switch .form-check-label, -.form-switch .form-check-label.small { - line-height: 16px !important; - padding-top: 0 !important; - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -/* Switches más compactos */ -.form-check-switch .form-check-input { - width: 2.5rem; - height: 1.25rem; -} - -/* Reducir gaps globales */ -.row.g-3 { - --bs-gutter-x: 1rem; - --bs-gutter-y: 1rem; -} - -.row.g-2 { - --bs-gutter-x: 0.5rem; - --bs-gutter-y: 0.5rem; -} - -/* Badges pequeños */ -.badge { - font-size: 0.7rem; - padding: 0.2em 0.5em; - vertical-align: middle; -} - -/* Tab header compacto */ -.tab-header { - background: linear-gradient(135deg, #0E2337 0%, #1a3a5c 100%); - border-radius: 12px; - padding: 1.5rem; - border: 2px solid #FF8600; - box-shadow: 0 4px 12px rgba(14, 35, 55, 0.15); -} - -.tab-header h3 { - font-size: 1.4rem; - margin-bottom: 0.25rem; - color: #ffffff; - font-weight: 700; -} - -.tab-header p { - color: rgba(255, 255, 255, 0.85); -} - -/* Header específico del Navbar Tab */ -#navbarTab > .rounded { - background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%) !important; - border-left: 4px solid #FF8600 !important; - border-radius: 6px !important; - padding: 24px !important; - margin-bottom: 24px !important; - box-shadow: rgba(0, 0, 0, 0.15) 0px 8px 16px 0px !important; -} - -#navbarTab > .rounded h3 { - font-size: 1.5rem !important; - margin-bottom: 0.25rem !important; - color: #ffffff !important; - font-weight: 700 !important; -} - -#navbarTab > .rounded p { - color: rgba(255, 255, 255, 0.85) !important; - margin-bottom: 0 !important; -} - -/* Card body padding */ -#navbarTab .card-body { - padding: 1rem !important; -} - -/* Progress bar pequeña */ -.progress[style*="height: 3px"] { - border-radius: 2px; - background-color: var(--color-neutral-100); -} - -/* Botones pequeños */ -.btn-sm { - font-size: 0.875rem; - padding: 0.375rem 0.75rem; -} - -/* Botón primario con estilo de marca */ -.btn-primary { - background-color: var(--color-orange-primary); - border-color: var(--color-orange-primary); - font-weight: 600; -} - -.btn-primary:hover { - background-color: var(--color-orange-hover); - border-color: var(--color-orange-hover); -} - -/* Clases de utilidad de colores */ -.text-navy-primary { - color: var(--color-navy-primary); -} - -.text-orange-primary { - color: var(--color-orange-primary); -} - -.text-neutral-600 { - color: var(--color-neutral-600); -} - -.border-neutral-200 { - border-color: #dee2e6 !important; -} - -/* Responsive: Mobile First */ -@media (max-width: 991px) { - .tab-header { - padding: 0.75rem; - } - - .tab-header h3 { - font-size: 1.1rem; - } - - .form-section.card .card-body.p-3 { - padding: 0.75rem !important; - } -} - -@media (max-width: 576px) { - .tab-header .d-flex { - flex-direction: column; - align-items: flex-start !important; - } - - .tab-header button { - width: 100%; - margin-top: 0.5rem; - } -} diff --git a/admin/assets/js/admin-app.js b/admin/assets/js/admin-app.js index 6152ff68..4732c4ea 100644 --- a/admin/assets/js/admin-app.js +++ b/admin/assets/js/admin-app.js @@ -30,14 +30,18 @@ const AdminPanel = { */ bindEvents() { // Botón guardar - document.getElementById('saveSettings').addEventListener('click', () => { - this.saveSettings(); - }); + const saveBtn = document.getElementById('saveSettings'); + if (saveBtn) { + saveBtn.addEventListener('click', () => { + this.saveSettings(); + }); + } // Detectar cambios en formularios const enableSaveButton = () => { this.STATE.hasChanges = true; - document.getElementById('saveSettings').disabled = false; + const btn = document.getElementById('saveSettings'); + if (btn) btn.disabled = false; }; document.querySelectorAll('input, select, textarea').forEach(input => { @@ -55,145 +59,6 @@ const AdminPanel = { this.switchTab(tab); }); }); - - // Contador de caracteres - this.setupCharacterCounter(); - - // Vista previa en tiempo real - this.setupLivePreview(); - }, - - /** - * Configurar contador de caracteres para textarea - */ - setupCharacterCounter() { - const messageTextarea = document.getElementById('topBarMessageText'); - if (!messageTextarea) return; - - messageTextarea.addEventListener('input', () => { - const count = messageTextarea.value.length; - const maxLength = 250; - const percentage = (count / maxLength) * 100; - - const counter = document.getElementById('topBarMessageTextCount'); - const progress = document.getElementById('topBarMessageTextProgress'); - - if (counter) { - counter.textContent = count; - - // Cambiar color según proximidad al límite - counter.classList.remove('text-danger', 'text-warning', 'text-muted'); - - if (count > 230) { - counter.classList.add('text-danger'); - } else if (count > 200) { - counter.classList.add('text-warning'); - } else { - counter.classList.add('text-muted'); - } - } - - // Actualizar progress bar - if (progress) { - progress.style.width = percentage + '%'; - progress.setAttribute('aria-valuenow', count); - - // Cambiar color del progress bar - progress.classList.remove('bg-orange-primary', 'bg-warning', 'bg-danger'); - if (count > 230) { - progress.classList.add('bg-danger'); - } else if (count > 200) { - progress.classList.add('bg-warning'); - } else { - progress.classList.add('bg-orange-primary'); - } - } - }); - - // Trigger inicial para mostrar count actual - messageTextarea.dispatchEvent(new Event('input')); - }, - - /** - * Configurar vista previa en tiempo real - */ - setupLivePreview() { - const preview = document.getElementById('topBarPreview'); - if (!preview) return; - - // Campos que afectan la vista previa - const fields = { - iconClass: document.getElementById('topBarIconClass'), - showIcon: document.getElementById('topBarShowIcon'), - highlightText: document.getElementById('topBarHighlightText'), - messageText: document.getElementById('topBarMessageText'), - linkText: document.getElementById('topBarLinkText'), - showLink: document.getElementById('topBarShowLink'), - bgColor: document.getElementById('topBarBgColor'), - textColor: document.getElementById('topBarTextColor'), - highlightColor: document.getElementById('topBarHighlightColor'), - fontSize: document.getElementById('topBarFontSize') - }; - - // Función para actualizar la vista previa - const updatePreview = () => { - // Obtener valores - const iconClass = fields.iconClass.value || 'bi bi-megaphone-fill'; - const showIcon = fields.showIcon.checked; - const highlightText = fields.highlightText.value; - const messageText = fields.messageText.value || 'Tu mensaje aquí...'; - const linkText = fields.linkText.value || 'Ver más'; - const showLink = fields.showLink.checked; - const bgColor = fields.bgColor.value || '#0E2337'; - const textColor = fields.textColor.value || '#ffffff'; - const highlightColor = fields.highlightColor.value || '#FF8600'; - - // Mapeo de tamaños de fuente - const fontSizeMap = { - 'small': '0.8rem', - 'normal': '0.9rem', - 'large': '1rem' - }; - const fontSize = fontSizeMap[fields.fontSize.value] || '0.9rem'; - - // Construir HTML de la vista previa - let html = ''; - - // Icono - if (showIcon && iconClass) { - html += ``; - } - - // Texto destacado - if (highlightText) { - html += `${highlightText}`; - } - - // Mensaje principal - html += `${messageText}`; - - // Enlace - if (showLink && linkText) { - html += `${linkText}`; - } - - // Actualizar la vista previa - preview.innerHTML = html; - preview.style.backgroundColor = bgColor; - preview.style.color = textColor; - preview.style.fontSize = fontSize; - }; - - // Agregar listeners a todos los campos - Object.values(fields).forEach(field => { - if (field) { - field.addEventListener('input', updatePreview); - field.addEventListener('change', updatePreview); - } - }); - - // Actualización inicial - updatePreview(); }, /** @@ -282,7 +147,8 @@ const AdminPanel = { if (response.data.success) { this.STATE.hasChanges = false; - document.getElementById('saveSettings').disabled = true; + const btn = document.getElementById('saveSettings'); + if (btn) btn.disabled = true; this.showNotice('Configuración guardada correctamente', 'success'); } else { this.showNotice(response.data.data.message || 'Error al guardar', 'error'); @@ -297,34 +163,12 @@ const AdminPanel = { /** * Recolectar datos del formulario - * Cada componente agregará su sección aquí + * Cada componente agregará su sección aquí cuando se implemente */ collectFormData() { return { components: { - top_bar: { - enabled: document.getElementById('topBarEnabled').checked, - show_on_mobile: document.getElementById('topBarShowOnMobile').checked, - show_on_desktop: document.getElementById('topBarShowOnDesktop').checked, - icon_class: document.getElementById('topBarIconClass').value.trim(), - show_icon: document.getElementById('topBarShowIcon').checked, - highlight_text: document.getElementById('topBarHighlightText').value.trim(), - message_text: document.getElementById('topBarMessageText').value.trim(), - link_text: document.getElementById('topBarLinkText').value.trim(), - link_url: document.getElementById('topBarLinkUrl').value.trim(), - link_target: document.getElementById('topBarLinkTarget').value, - show_link: document.getElementById('topBarShowLink').checked, - custom_styles: { - background_color: this.getColorValue('topBarBgColor', ''), - text_color: this.getColorValue('topBarTextColor', ''), - highlight_color: this.getColorValue('topBarHighlightColor', ''), - link_hover_color: this.getColorValue('topBarLinkHoverColor', ''), - font_size: document.getElementById('topBarFontSize').value - } - } - // Navbar - Pendiente - // Hero - Pendiente - // Footer - Pendiente + // Los componentes se agregarán aquí cuando se ejecute el algoritmo } }; }, @@ -335,62 +179,7 @@ const AdminPanel = { renderAllComponents() { const components = this.STATE.settings.components || {}; - // Top Bar - if (components.top_bar) { - this.renderTopBar(components.top_bar); - } - // Navbar - Pendiente - // Hero - Pendiente - // Footer - Pendiente - }, - - /** - * Renderizar Top Bar - */ - renderTopBar(topBar) { - document.getElementById('topBarEnabled').checked = topBar.enabled !== undefined ? topBar.enabled : true; - document.getElementById('topBarShowOnMobile').checked = topBar.show_on_mobile !== undefined ? topBar.show_on_mobile : true; - document.getElementById('topBarShowOnDesktop').checked = topBar.show_on_desktop !== undefined ? topBar.show_on_desktop : true; - document.getElementById('topBarIconClass').value = topBar.icon_class || 'bi bi-megaphone-fill'; - document.getElementById('topBarShowIcon').checked = topBar.show_icon !== undefined ? topBar.show_icon : true; - document.getElementById('topBarHighlightText').value = topBar.highlight_text || 'Nuevo:'; - document.getElementById('topBarMessageText').value = topBar.message_text || 'Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.'; - document.getElementById('topBarLinkText').value = topBar.link_text || 'Ver Catálogo'; - document.getElementById('topBarLinkUrl').value = topBar.link_url || '/catalogo'; - document.getElementById('topBarLinkTarget').value = topBar.link_target || '_self'; - document.getElementById('topBarShowLink').checked = topBar.show_link !== undefined ? topBar.show_link : true; - - // Estilos personalizados - if (topBar.custom_styles) { - if (topBar.custom_styles.background_color) { - document.getElementById('topBarBgColor').value = topBar.custom_styles.background_color; - } - if (topBar.custom_styles.text_color) { - document.getElementById('topBarTextColor').value = topBar.custom_styles.text_color; - } - if (topBar.custom_styles.highlight_color) { - document.getElementById('topBarHighlightColor').value = topBar.custom_styles.highlight_color; - } - if (topBar.custom_styles.link_hover_color) { - document.getElementById('topBarLinkHoverColor').value = topBar.custom_styles.link_hover_color; - } - document.getElementById('topBarFontSize').value = topBar.custom_styles.font_size || 'normal'; - } - - // Trigger contador de caracteres - const messageTextarea = document.getElementById('topBarMessageText'); - if (messageTextarea) { - messageTextarea.dispatchEvent(new Event('input')); - } - }, - - /** - * Utilidad: Obtener valor de color con fallback - */ - getColorValue(inputId, defaultValue) { - const input = document.getElementById(inputId); - const value = input ? input.value.trim() : ''; - return value || defaultValue; + // Los métodos render de componentes se llamarán aquí cuando se implementen }, /** diff --git a/admin/assets/js/component-navbar.js b/admin/assets/js/component-navbar.js deleted file mode 100644 index 919d6c51..00000000 --- a/admin/assets/js/component-navbar.js +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Navbar Component - JavaScript Controller - * - * @package Apus_Theme - * @since 2.0.0 - */ - -window.NavbarComponent = { - /** - * Inicialización del componente - */ - init: function() { - console.log('Navbar component initialized'); - - // Actualizar valores hexadecimales de color pickers en tiempo real - this.initColorPickers(); - }, - - /** - * Inicializar event listeners para color pickers - */ - initColorPickers: function() { - const colorPickers = [ - { input: 'navbarBgColor', display: 'navbarBgColorValue' }, - { input: 'navbarTextColor', display: 'navbarTextColorValue' }, - { input: 'navbarLinkHoverColor', display: 'navbarLinkHoverColorValue' }, - { input: 'navbarLinkHoverBgColor', display: 'navbarLinkHoverBgColorValue' }, - { input: 'navbarDropdownBgColor', display: 'navbarDropdownBgColorValue' }, - { input: 'navbarDropdownItemColor', display: 'navbarDropdownItemColorValue' }, - { input: 'navbarDropdownItemHoverColor', display: 'navbarDropdownItemHoverColorValue' } - ]; - - colorPickers.forEach(function(picker) { - const inputEl = document.getElementById(picker.input); - const displayEl = document.getElementById(picker.display); - - if (inputEl && displayEl) { - // Actualizar cuando cambia el color - inputEl.addEventListener('input', function() { - displayEl.textContent = inputEl.value.toUpperCase(); - }); - - // Inicializar valor al cargar - displayEl.textContent = inputEl.value.toUpperCase(); - } - }); - }, - - /** - * Recolectar datos del formulario - * @returns {Object} Configuración del navbar - */ - collect: function() { - return { - // Grupo 1: Activación y Visibilidad - enabled: document.getElementById('navbarEnabled').checked, - show_on_mobile: document.getElementById('navbarShowOnMobile').checked, - show_on_desktop: document.getElementById('navbarShowOnDesktop').checked, - position: document.getElementById('navbarPosition').value, - responsive_breakpoint: document.getElementById('navbarBreakpoint').value, - - // Grupo 4: Efectos (booleans) - enable_box_shadow: document.getElementById('navbarEnableBoxShadow').checked, - enable_underline_effect: document.getElementById('navbarEnableUnderlineEffect').checked, - enable_hover_background: document.getElementById('navbarEnableHoverBackground').checked, - - // Grupo 6: Let's Talk Button - lets_talk_button: { - enabled: document.getElementById('navbarLetsTalkEnabled').checked, - text: document.getElementById('navbarLetsTalkText').value.trim(), - icon_class: document.getElementById('navbarLetsTalkIconClass').value.trim(), - show_icon: document.getElementById('navbarLetsTalkShowIcon').checked, - position: document.getElementById('navbarLetsTalkPosition').value - }, - - // Grupo 7: Dropdown - dropdown: { - enable_hover_desktop: document.getElementById('navbarDropdownEnableHoverDesktop').checked, - max_height: parseInt(document.getElementById('navbarDropdownMaxHeight').value) || 70, - border_radius: parseInt(document.getElementById('navbarDropdownBorderRadius').value) || 8, - item_padding_vertical: parseFloat(document.getElementById('navbarDropdownItemPaddingVertical').value) || 0.5, - item_padding_horizontal: parseFloat(document.getElementById('navbarDropdownItemPaddingHorizontal').value) || 1.25 - }, - - // Grupos 2, 3, 5: Custom Styles - custom_styles: { - // Grupo 2: Colores - background_color: document.getElementById('navbarBgColor').value || '#1e3a5f', - text_color: document.getElementById('navbarTextColor').value || '#ffffff', - link_hover_color: document.getElementById('navbarLinkHoverColor').value || '#FF8600', - link_hover_bg_color: document.getElementById('navbarLinkHoverBgColor').value || '#FF8600', - dropdown_bg_color: document.getElementById('navbarDropdownBgColor').value || '#ffffff', - dropdown_item_color: document.getElementById('navbarDropdownItemColor').value || '#4A5568', - dropdown_item_hover_color: document.getElementById('navbarDropdownItemHoverColor').value || '#FF8600', - - // Grupo 3: Tipografía - font_size: document.getElementById('navbarFontSize').value, - font_weight: document.getElementById('navbarFontWeight').value, - - // Grupo 4: Efectos - box_shadow_intensity: document.getElementById('navbarBoxShadowIntensity').value, - border_radius: parseInt(document.getElementById('navbarBorderRadius').value) || 4, - - // Grupo 5: Spacing - padding_vertical: parseFloat(document.getElementById('navbarPaddingVertical').value) || 0.75, - link_padding_vertical: parseFloat(document.getElementById('navbarLinkPaddingVertical').value) || 0.5, - link_padding_horizontal: parseFloat(document.getElementById('navbarLinkPaddingHorizontal').value) || 0.65, - - // Grupo 8: Avanzado - z_index: parseInt(document.getElementById('navbarZIndex').value) || 1030, - transition_speed: document.getElementById('navbarTransitionSpeed').value || 'normal' - } - }; - }, - - /** - * Renderizar configuración en el formulario - * @param {Object} config - Configuración del navbar - */ - render: function(config) { - if (!config) { - console.warn('No navbar config provided'); - return; - } - - // Grupo 1: Activación y Visibilidad - document.getElementById('navbarEnabled').checked = config.enabled !== undefined ? config.enabled : true; - document.getElementById('navbarShowOnMobile').checked = config.show_on_mobile !== undefined ? config.show_on_mobile : true; - document.getElementById('navbarShowOnDesktop').checked = config.show_on_desktop !== undefined ? config.show_on_desktop : true; - document.getElementById('navbarPosition').value = config.position || 'sticky'; - document.getElementById('navbarBreakpoint').value = config.responsive_breakpoint || 'lg'; - - // Grupo 2: Colores Personalizados - if (config.custom_styles) { - document.getElementById('navbarBgColor').value = config.custom_styles.background_color || '#1e3a5f'; - document.getElementById('navbarTextColor').value = config.custom_styles.text_color || '#ffffff'; - document.getElementById('navbarLinkHoverColor').value = config.custom_styles.link_hover_color || '#FF8600'; - document.getElementById('navbarLinkHoverBgColor').value = config.custom_styles.link_hover_bg_color || '#FF8600'; - document.getElementById('navbarDropdownBgColor').value = config.custom_styles.dropdown_bg_color || '#ffffff'; - document.getElementById('navbarDropdownItemColor').value = config.custom_styles.dropdown_item_color || '#4A5568'; - document.getElementById('navbarDropdownItemHoverColor').value = config.custom_styles.dropdown_item_hover_color || '#FF8600'; - } - - // Grupo 3: Tipografía - if (config.custom_styles) { - document.getElementById('navbarFontSize').value = config.custom_styles.font_size || 'normal'; - document.getElementById('navbarFontWeight').value = config.custom_styles.font_weight || '500'; - } - - // Grupo 4: Efectos Visuales - document.getElementById('navbarEnableBoxShadow').checked = config.enable_box_shadow !== undefined ? config.enable_box_shadow : true; - document.getElementById('navbarEnableUnderlineEffect').checked = config.enable_underline_effect !== undefined ? config.enable_underline_effect : true; - document.getElementById('navbarEnableHoverBackground').checked = config.enable_hover_background !== undefined ? config.enable_hover_background : true; - - if (config.custom_styles) { - document.getElementById('navbarBoxShadowIntensity').value = config.custom_styles.box_shadow_intensity || 'normal'; - document.getElementById('navbarBorderRadius').value = config.custom_styles.border_radius !== undefined ? config.custom_styles.border_radius : 4; - } - - // Grupo 5: Spacing - if (config.custom_styles) { - document.getElementById('navbarPaddingVertical').value = config.custom_styles.padding_vertical !== undefined ? config.custom_styles.padding_vertical : 0.75; - document.getElementById('navbarLinkPaddingVertical').value = config.custom_styles.link_padding_vertical !== undefined ? config.custom_styles.link_padding_vertical : 0.5; - document.getElementById('navbarLinkPaddingHorizontal').value = config.custom_styles.link_padding_horizontal !== undefined ? config.custom_styles.link_padding_horizontal : 0.65; - } - - // Grupo 8: Avanzado - if (config.custom_styles) { - document.getElementById('navbarZIndex').value = config.custom_styles.z_index !== undefined ? config.custom_styles.z_index : 1030; - document.getElementById('navbarTransitionSpeed').value = config.custom_styles.transition_speed || 'normal'; - } - - // Grupo 6: Let's Talk Button - if (config.lets_talk_button) { - document.getElementById('navbarLetsTalkEnabled').checked = config.lets_talk_button.enabled !== undefined ? config.lets_talk_button.enabled : true; - document.getElementById('navbarLetsTalkText').value = config.lets_talk_button.text || "Let's Talk"; - document.getElementById('navbarLetsTalkIconClass').value = config.lets_talk_button.icon_class || 'bi bi-lightning-charge-fill'; - document.getElementById('navbarLetsTalkShowIcon').checked = config.lets_talk_button.show_icon !== undefined ? config.lets_talk_button.show_icon : true; - document.getElementById('navbarLetsTalkPosition').value = config.lets_talk_button.position || 'right'; - } - - // Grupo 7: Dropdown - if (config.dropdown) { - document.getElementById('navbarDropdownEnableHoverDesktop').checked = config.dropdown.enable_hover_desktop !== undefined ? config.dropdown.enable_hover_desktop : true; - document.getElementById('navbarDropdownMaxHeight').value = config.dropdown.max_height !== undefined ? config.dropdown.max_height : 70; - document.getElementById('navbarDropdownBorderRadius').value = config.dropdown.border_radius !== undefined ? config.dropdown.border_radius : 8; - document.getElementById('navbarDropdownItemPaddingVertical').value = config.dropdown.item_padding_vertical !== undefined ? config.dropdown.item_padding_vertical : 0.5; - document.getElementById('navbarDropdownItemPaddingHorizontal').value = config.dropdown.item_padding_horizontal !== undefined ? config.dropdown.item_padding_horizontal : 1.25; - } - } -}; diff --git a/admin/components/component-hero-section.php b/admin/components/component-hero-section.php deleted file mode 100644 index 91f483a2..00000000 --- a/admin/components/component-hero-section.php +++ /dev/null @@ -1,604 +0,0 @@ - - - -
- - -
-
-
-

- - Configuración del Hero Section -

-

- Personaliza el banner principal con título y categorías -

-
- -
-
- - -
- -
- - -
-
-
- - Activación y Visibilidad -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
-
- - Contenido y Estructura -
- - -
-
- - -
-
- - -
- - - Clase de Bootstrap Icons -
- - -
- - - Una categoría por línea -
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
-
- - Colores del Hero -
- - -
-
- - -
-
- - -
-
- - - #1E3A5F -
-
- - - #2C5282 -
-
- - -
-
- - - #ffffff -
-
- - - #1E3A5F -
-
- - -
- - -
- -
-
- - -
-
-
- - Colores de Category Badges -
- - -
-
- - - Soporta RGBA -
-
- - - Soporta RGBA -
-
- - -
-
- - - Soporta RGBA -
-
- - - Soporta RGBA -
-
- - -
- - - #FFB800 -
- -
-
- -
- - -
- - -
-
-
- - Espaciado y Dimensiones -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- - -
- -
-
- - -
-
-
- - Tipografía -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
-
- - Efectos Visuales -
- - -
-
- - -
-
- - -
- - - Sintaxis CSS: x y blur color -
- - -
-
- - -
-
- - -
- - - Sintaxis CSS: x y blur spread color -
- - -
-
- - -
-
- - -
- - - Ej: blur(10px), brightness(1.2) -
- -
-
- - -
-
-
- - Transiciones y Animaciones -
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
-
- - Avanzado -
- - -
- - - Clases CSS adicionales separadas por espacio -
- - -
- - - Clases CSS adicionales para badges -
- -
-
- -
-
- -
diff --git a/admin/components/component-lets-talk-button.php b/admin/components/component-lets-talk-button.php deleted file mode 100644 index 5eb6f72e..00000000 --- a/admin/components/component-lets-talk-button.php +++ /dev/null @@ -1,393 +0,0 @@ - - - -
- - -
-
-
-

- - Configuración del Botón Let's Talk -

-

- Personaliza el botón de contacto "Let's Talk" del navbar -

-
- -
-
- - -
-
- -
-
-
- - Activación y Visibilidad -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
-
- - Contenido -
- - -
-
- - -
-
- - -
-
- - - Máximo 30 caracteres -
-
- - - Bootstrap Icons -
-
-
-
- - -
-
-
- - Tipografía -
- - -
- - -
-
-
- - -
-
-
- - Comportamiento -
- - -
- - - Debe comenzar con # -
-
-
- - -
-
-
- - Espaciado y Posición -
- - -
-
- - - En rem (0-3) -
-
- - - En rem (0-5) -
-
- - -
- - -
-
-
- -
- -
- -
-
-
- - Colores Personalizados -
- - -
-
- - - #FF8600 -
-
- - - #FF6B35 -
-
-
-
- - - #ffffff -
-
- - - #ffffff -
-
-
-
- - -
-
-
- - Estilos Avanzados -
- - -
-
- - - En px (0-30) -
-
- - - En px (0-10) -
-
- - -
-
- - - #000000 -
-
- - -
-
- - -
-
- - -
-
- - -
- - - Ejemplo: 0 4px 12px rgba(255, 134, 0, 0.3) -
- - -
-
- - -
-
- - -
-
-
-
- -
-
- -
diff --git a/admin/components/component-navbar.php b/admin/components/component-navbar.php deleted file mode 100644 index ce9b9b36..00000000 --- a/admin/components/component-navbar.php +++ /dev/null @@ -1,585 +0,0 @@ - - - - diff --git a/admin/components/component-top-bar.php b/admin/components/component-top-bar.php deleted file mode 100644 index ecbb4f63..00000000 --- a/admin/components/component-top-bar.php +++ /dev/null @@ -1,237 +0,0 @@ - - -
- -
-
-
-

- - Configuración Top Bar -

-

- Personaliza la barra de anuncios superior de tu sitio -

-
- -
-
- - -
- -
- -
-
-
- - Activación y Visibilidad -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
-
- - Estilos Personalizados -
- - -
-
- - - #0E2337 -
-
- - - #FFFFFF -
-
- - - #FF8600 -
-
- - - #FF6B35 -
-
- - -
- - -
-
-
-
- - -
- -
-
-
- - Contenido y Mensajes -
- - -
-
- - - - - Ver: Bootstrap Icons - -
-
- -
- - -
-
-
- - -
- - -
- - -
- - -
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
-
-
-
- -
-
diff --git a/admin/includes/class-admin-menu.php b/admin/includes/class-admin-menu.php index ded6f982..845fe8b9 100644 --- a/admin/includes/class-admin-menu.php +++ b/admin/includes/class-admin-menu.php @@ -80,13 +80,6 @@ class APUS_Admin_Menu { APUS_ADMIN_PANEL_VERSION ); - // Component: Navbar CSS (estilos admin específicos) - wp_enqueue_style( - 'apus-component-navbar-css', - APUS_ADMIN_PANEL_URL . 'assets/css/component-navbar.css', - array('apus-admin-panel-css'), - APUS_ADMIN_PANEL_VERSION - ); // Bootstrap 5.3.2 JS wp_enqueue_script( @@ -106,20 +99,12 @@ class APUS_Admin_Menu { true ); - // Component: Navbar JS (cargar antes de admin-app.js) - wp_enqueue_script( - 'apus-component-navbar-js', - APUS_ADMIN_PANEL_URL . 'assets/js/component-navbar.js', - array('jquery'), - APUS_ADMIN_PANEL_VERSION, - true - ); - // Admin Panel JS (Core - depende de componentes) + // Admin Panel JS (Core) wp_enqueue_script( 'apus-admin-panel-js', APUS_ADMIN_PANEL_URL . 'assets/js/admin-app.js', - array('jquery', 'axios', 'apus-component-navbar-js'), + array('jquery', 'axios'), APUS_ADMIN_PANEL_VERSION, true ); diff --git a/admin/includes/class-settings-manager.php b/admin/includes/class-settings-manager.php index 5ab3ffc7..b75e2581 100644 --- a/admin/includes/class-settings-manager.php +++ b/admin/includes/class-settings-manager.php @@ -68,74 +68,27 @@ class APUS_Settings_Manager { /** * Valores por defecto - * NOTA: Aquí se agregan los defaults de cada componente + * NOTA: Los defaults se cargarán desde la tabla wp_apus_theme_components_defaults */ public function get_defaults() { return array( 'version' => APUS_ADMIN_PANEL_VERSION, 'components' => array( - 'top_bar' => array( - 'enabled' => true, - 'show_on_mobile' => true, - 'show_on_desktop' => true, - 'icon_class' => 'bi bi-megaphone-fill', - 'show_icon' => true, - 'highlight_text' => 'Nuevo:', - 'message_text' => 'Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.', - 'link_text' => 'Ver Catálogo', - 'link_url' => '/catalogo', - 'link_target' => '_self', - 'show_link' => true, - 'custom_styles' => array( - // Valores extraídos de componente-top-bar.css - 'background_color' => '#0E2337', // var(--color-navy-dark) - 'text_color' => '#ffffff', - 'highlight_color' => '#FF8600', // var(--color-orange-primary) - 'link_hover_color' => '#FF8600', // var(--color-orange-primary) - 'font_size' => 'normal' // 0.9rem del CSS - ) - ) - // Navbar - Pendiente - // Hero - Pendiente - // Footer - Pendiente + // Los componentes se agregarán aquí cuando se ejecute el algoritmo ) ); } /** * Sanitizar configuraciones - * NOTA: Aquí se agrega sanitización de cada componente + * NOTA: Los sanitizers de componentes se ejecutarán aquí cuando se implementen */ public function sanitize_settings($data) { $sanitized = array( 'components' => array() ); - // Sanitizar Top Bar - if (isset($data['components']['top_bar'])) { - $top_bar = $data['components']['top_bar']; - - $sanitized['components']['top_bar'] = array( - 'enabled' => !empty($top_bar['enabled']), - 'show_on_mobile' => !empty($top_bar['show_on_mobile']), - 'show_on_desktop' => !empty($top_bar['show_on_desktop']), - 'icon_class' => sanitize_text_field($top_bar['icon_class'] ?? ''), - 'show_icon' => !empty($top_bar['show_icon']), - 'highlight_text' => sanitize_text_field($top_bar['highlight_text'] ?? ''), - 'message_text' => sanitize_text_field($top_bar['message_text'] ?? ''), - 'link_text' => sanitize_text_field($top_bar['link_text'] ?? ''), - 'link_url' => esc_url_raw($top_bar['link_url'] ?? ''), - 'link_target' => in_array($top_bar['link_target'] ?? '', array('_self', '_blank')) ? $top_bar['link_target'] : '_self', - 'show_link' => !empty($top_bar['show_link']), - 'custom_styles' => array( - 'background_color' => sanitize_hex_color($top_bar['custom_styles']['background_color'] ?? ''), - 'text_color' => sanitize_hex_color($top_bar['custom_styles']['text_color'] ?? ''), - 'highlight_color' => sanitize_hex_color($top_bar['custom_styles']['highlight_color'] ?? ''), - 'link_hover_color' => sanitize_hex_color($top_bar['custom_styles']['link_hover_color'] ?? ''), - 'font_size' => in_array($top_bar['custom_styles']['font_size'] ?? '', array('small', 'normal', 'large')) ? $top_bar['custom_styles']['font_size'] : 'normal' - ) - ); - } + // Los componentes se sanitizarán aquí cuando se ejecute el algoritmo return $sanitized; } diff --git a/admin/includes/class-validator.php b/admin/includes/class-validator.php index 0b5c3198..f2c05901 100644 --- a/admin/includes/class-validator.php +++ b/admin/includes/class-validator.php @@ -16,6 +16,7 @@ class APUS_Validator { /** * Validar todas las configuraciones + * Los validators de componentes se ejecutarán aquí cuando se implementen */ public function validate($data) { $errors = array(); @@ -26,81 +27,11 @@ class APUS_Validator { return array('valid' => false, 'errors' => $errors); } - // Validar Top Bar - if (isset($data['components']['top_bar'])) { - $top_bar_errors = $this->validate_top_bar($data['components']['top_bar']); - $errors = array_merge($errors, $top_bar_errors); - } + // Los componentes se validarán aquí cuando se ejecute el algoritmo return array( 'valid' => empty($errors), 'errors' => $errors ); } - - /** - * Validar Top Bar - */ - public function validate_top_bar($top_bar) { - $errors = array(); - - // Validar icon_class - if (!empty($top_bar['icon_class']) && strlen($top_bar['icon_class']) > 50) { - $errors[] = 'La clase del icono no puede exceder 50 caracteres'; - } - - // Validar highlight_text - if (!empty($top_bar['highlight_text']) && strlen($top_bar['highlight_text']) > 30) { - $errors[] = 'El texto destacado no puede exceder 30 caracteres'; - } - - // Validar message_text - if (empty($top_bar['message_text'])) { - $errors[] = 'El mensaje principal es obligatorio'; - } elseif (strlen($top_bar['message_text']) > 250) { - $errors[] = 'El mensaje principal no puede exceder 250 caracteres'; - } - - // Validar link_text - if (!empty($top_bar['link_text']) && strlen($top_bar['link_text']) > 50) { - $errors[] = 'El texto del enlace no puede exceder 50 caracteres'; - } - - // Validar link_url (acepta URLs completas y relativas que empiecen con /) - if (!empty($top_bar['link_url'])) { - $url = $top_bar['link_url']; - $is_valid_url = filter_var($url, FILTER_VALIDATE_URL) !== false; - $is_relative_url = preg_match('/^\//', $url); - - if (!$is_valid_url && !$is_relative_url) { - $errors[] = 'La URL del enlace no es válida'; - } - } - - // Validar link_target - if (!in_array($top_bar['link_target'] ?? '', array('_self', '_blank'))) { - $errors[] = 'El target del enlace debe ser _self o _blank'; - } - - // Validar colores - if (!empty($top_bar['custom_styles']['background_color']) && !preg_match('/^#[a-f0-9]{6}$/i', $top_bar['custom_styles']['background_color'])) { - $errors[] = 'El color de fondo debe ser un color hexadecimal válido'; - } - if (!empty($top_bar['custom_styles']['text_color']) && !preg_match('/^#[a-f0-9]{6}$/i', $top_bar['custom_styles']['text_color'])) { - $errors[] = 'El color de texto debe ser un color hexadecimal válido'; - } - if (!empty($top_bar['custom_styles']['highlight_color']) && !preg_match('/^#[a-f0-9]{6}$/i', $top_bar['custom_styles']['highlight_color'])) { - $errors[] = 'El color del highlight debe ser un color hexadecimal válido'; - } - if (!empty($top_bar['custom_styles']['link_hover_color']) && !preg_match('/^#[a-f0-9]{6}$/i', $top_bar['custom_styles']['link_hover_color'])) { - $errors[] = 'El color hover del enlace debe ser un color hexadecimal válido'; - } - - // Validar font_size - if (!in_array($top_bar['custom_styles']['font_size'] ?? '', array('small', 'normal', 'large'))) { - $errors[] = 'El tamaño de fuente debe ser small, normal o large'; - } - - return $errors; - } } diff --git a/admin/includes/sanitizers/class-herosection-sanitizer.php b/admin/includes/sanitizers/class-herosection-sanitizer.php deleted file mode 100644 index 720d7956..00000000 --- a/admin/includes/sanitizers/class-herosection-sanitizer.php +++ /dev/null @@ -1,173 +0,0 @@ - true, - 'show_on_mobile' => true, - 'show_on_desktop' => true, - - // Contenido y Estructura - 'show_category_badges' => true, - 'category_badge_icon' => 'bi bi-folder-fill', - 'excluded_categories' => array('Uncategorized', 'Sin categoría'), - 'title_alignment' => 'center', - 'title_display_class' => 'display-5', - - // Colores del Hero - 'use_gradient_background' => true, - 'gradient_start_color' => '#1e3a5f', - 'gradient_end_color' => '#2c5282', - 'gradient_angle' => 135, - 'hero_text_color' => '#ffffff', - 'solid_background_color' => '#1e3a5f', - - // Colores de Category Badges - 'badge_bg_color' => 'rgba(255, 255, 255, 0.15)', - 'badge_bg_hover_color' => 'rgba(255, 133, 0, 0.2)', - 'badge_border_color' => 'rgba(255, 255, 255, 0.2)', - 'badge_text_color' => 'rgba(255, 255, 255, 0.95)', - 'badge_icon_color' => '#FFB800', - - // Espaciado y Dimensiones - 'hero_padding_vertical' => 3.0, - 'hero_padding_horizontal' => 0.0, - 'hero_margin_bottom' => 1.5, - 'badges_gap' => 0.5, - 'badge_padding_vertical' => 0.375, - 'badge_padding_horizontal' => 0.875, - 'badge_border_radius' => 20, - - // Tipografía - 'h1_font_weight' => 700, - 'badge_font_size' => 0.813, - 'badge_font_weight' => 500, - 'h1_line_height' => 1.4, - - // Efectos Visuales - 'enable_h1_text_shadow' => true, - 'h1_text_shadow' => '1px 1px 2px rgba(0, 0, 0, 0.2)', - 'enable_hero_box_shadow' => true, - 'hero_box_shadow' => '0 4px 16px rgba(30, 58, 95, 0.25)', - 'enable_badge_backdrop_filter' => true, - 'badge_backdrop_filter' => 'blur(10px)', - - // Transiciones y Animaciones - 'badge_transition_speed' => 'normal', - 'badge_hover_effect' => 'background', - - // Avanzado - 'custom_hero_classes' => '', - 'custom_badge_classes' => '' - ); - } - - /** - * Sanitiza los datos del Hero Section - * - * @param array $data Datos sin sanitizar del Hero Section - * @return array Datos sanitizados - */ - public function sanitize($data) { - return array_merge( - // Activación y Visibilidad - Booleanos - APUS_Sanitizer_Helper::sanitize_booleans($data, array( - 'enabled', 'show_on_mobile', 'show_on_desktop', 'show_category_badges', - 'use_gradient_background', 'enable_h1_text_shadow', 'enable_hero_box_shadow', - 'enable_badge_backdrop_filter' - )), - - // Contenido y Estructura - Textos - APUS_Sanitizer_Helper::sanitize_texts($data, array( - 'category_badge_icon' => 'bi bi-folder-fill', - 'title_display_class' => 'display-5', - 'h1_text_shadow' => '1px 1px 2px rgba(0, 0, 0, 0.2)', - 'hero_box_shadow' => '0 4px 16px rgba(30, 58, 95, 0.25)', - 'badge_backdrop_filter' => 'blur(10px)', - 'custom_hero_classes' => '', - 'custom_badge_classes' => '' - )), - - // Colores de Category Badges - RGBA strings (text) - array( - 'badge_bg_color' => APUS_Sanitizer_Helper::sanitize_text($data, 'badge_bg_color', 'rgba(255, 255, 255, 0.15)'), - 'badge_bg_hover_color' => APUS_Sanitizer_Helper::sanitize_text($data, 'badge_bg_hover_color', 'rgba(255, 133, 0, 0.2)'), - 'badge_border_color' => APUS_Sanitizer_Helper::sanitize_text($data, 'badge_border_color', 'rgba(255, 255, 255, 0.2)'), - 'badge_text_color' => APUS_Sanitizer_Helper::sanitize_text($data, 'badge_text_color', 'rgba(255, 255, 255, 0.95)') - ), - - // Colores del Hero - Hex colors - array( - 'gradient_start_color' => APUS_Sanitizer_Helper::sanitize_color($data, 'gradient_start_color', '#1e3a5f'), - 'gradient_end_color' => APUS_Sanitizer_Helper::sanitize_color($data, 'gradient_end_color', '#2c5282'), - 'hero_text_color' => APUS_Sanitizer_Helper::sanitize_color($data, 'hero_text_color', '#ffffff'), - 'solid_background_color' => APUS_Sanitizer_Helper::sanitize_color($data, 'solid_background_color', '#1e3a5f'), - 'badge_icon_color' => APUS_Sanitizer_Helper::sanitize_color($data, 'badge_icon_color', '#FFB800') - ), - - // Enums - APUS_Sanitizer_Helper::sanitize_enums($data, array( - 'title_alignment' => array('allowed' => array('left', 'center', 'right'), 'default' => 'center'), - 'badge_transition_speed' => array('allowed' => array('fast', 'normal', 'slow'), 'default' => 'normal'), - 'badge_hover_effect' => array('allowed' => array('none', 'background', 'scale', 'brightness'), 'default' => 'background') - )), - - // Enteros - APUS_Sanitizer_Helper::sanitize_ints($data, array( - 'gradient_angle' => 135, - 'badge_border_radius' => 20 - )), - - // Enteros en arrays (h1_font_weight, badge_font_weight) - array( - 'h1_font_weight' => APUS_Sanitizer_Helper::sanitize_enum($data, 'h1_font_weight', array(400, 500, 600, 700), 700), - 'badge_font_weight' => APUS_Sanitizer_Helper::sanitize_enum($data, 'badge_font_weight', array(400, 500, 600, 700), 500) - ), - - // Floats - APUS_Sanitizer_Helper::sanitize_floats($data, array( - 'hero_padding_vertical' => 3.0, - 'hero_padding_horizontal' => 0.0, - 'hero_margin_bottom' => 1.5, - 'badges_gap' => 0.5, - 'badge_padding_vertical' => 0.375, - 'badge_padding_horizontal' => 0.875, - 'badge_font_size' => 0.813, - 'h1_line_height' => 1.4 - )), - - // Array de strings - array('excluded_categories' => APUS_Sanitizer_Helper::sanitize_array_of_strings( - $data, - 'excluded_categories', - array('Uncategorized', 'Sin categoría') - )) - ); - } -} diff --git a/admin/includes/sanitizers/class-letstalkbutton-sanitizer.php b/admin/includes/sanitizers/class-letstalkbutton-sanitizer.php deleted file mode 100644 index 0783fcbe..00000000 --- a/admin/includes/sanitizers/class-letstalkbutton-sanitizer.php +++ /dev/null @@ -1,99 +0,0 @@ - true, - 'text' => "Let's Talk", - 'icon_class' => 'bi bi-lightning-charge-fill', - 'show_icon' => true, - 'position' => 'right', - 'enable_box_shadow' => false, - 'hover_effect' => 'none', - 'modal_target' => '#contactModal', - 'custom_styles' => array( - 'background_color' => '#FF8600', - 'background_hover_color' => '#FF6B35', - 'text_color' => '#ffffff', - 'icon_color' => '#ffffff', - 'font_weight' => '600', - 'padding_vertical' => 0.5, - 'padding_horizontal' => 1.5, - 'border_radius' => 6, - 'border_width' => 0, - 'border_color' => '', - 'border_style' => 'solid', - 'transition_speed' => 'normal', - 'box_shadow' => '0 2px 8px rgba(0, 0, 0, 0.15)' - ) - ); - } - - /** - * Sanitiza los datos del Let's Talk Button - * - * @param array $data Datos sin sanitizar del Let's Talk Button - * @return array Datos sanitizados - */ - public function sanitize($data) { - return array_merge( - // Booleanos - APUS_Sanitizer_Helper::sanitize_booleans($data, array( - 'enabled', 'show_icon', 'enable_box_shadow' - )), - - // Textos - APUS_Sanitizer_Helper::sanitize_texts($data, array( - 'text', 'icon_class', 'modal_target' - )), - - // Enums - APUS_Sanitizer_Helper::sanitize_enums($data, array( - 'position' => array('allowed' => array('left', 'center', 'right'), 'default' => 'right'), - 'hover_effect' => array('allowed' => array('none', 'scale', 'brightness'), 'default' => 'none') - )), - - // Custom styles anidado - array('custom_styles' => APUS_Sanitizer_Helper::sanitize_nested_group($data, 'custom_styles', array( - 'background_color' => array('type' => 'color', 'default' => ''), - 'background_hover_color' => array('type' => 'color', 'default' => ''), - 'text_color' => array('type' => 'color', 'default' => ''), - 'icon_color' => array('type' => 'color', 'default' => ''), - 'font_weight' => array('type' => 'text', 'default' => ''), - 'padding_vertical' => array('type' => 'float', 'default' => 0.0), - 'padding_horizontal' => array('type' => 'float', 'default' => 0.0), - 'border_radius' => array('type' => 'int', 'default' => 0), - 'border_width' => array('type' => 'int', 'default' => 0), - 'border_color' => array('type' => 'color', 'default' => ''), - 'border_style' => array('type' => 'enum', 'allowed' => array('solid', 'dashed', 'dotted'), 'default' => 'solid'), - 'transition_speed' => array('type' => 'enum', 'allowed' => array('fast', 'normal', 'slow'), 'default' => 'normal'), - 'box_shadow' => array('type' => 'text', 'default' => '') - ))) - ); - } -} diff --git a/admin/includes/sanitizers/class-navbar-sanitizer.php b/admin/includes/sanitizers/class-navbar-sanitizer.php deleted file mode 100644 index 3b230d6f..00000000 --- a/admin/includes/sanitizers/class-navbar-sanitizer.php +++ /dev/null @@ -1,136 +0,0 @@ - true, - 'show_on_mobile' => true, - 'show_on_desktop' => true, - 'position' => 'sticky', - 'responsive_breakpoint' => 'lg', - 'enable_box_shadow' => true, - 'enable_underline_effect' => true, - 'enable_hover_background' => true, - - 'lets_talk_button' => array( - 'enabled' => true, - 'text' => "Let's Talk", - 'icon_class' => 'bi bi-lightning-charge-fill', - 'show_icon' => true, - 'position' => 'right' - ), - - 'dropdown' => array( - 'enable_hover_desktop' => true, - 'max_height' => 70, - 'border_radius' => 8, - 'item_padding_vertical' => 0.5, - 'item_padding_horizontal' => 1.25 - ), - - 'custom_styles' => array( - 'background_color' => '#1e3a5f', - 'text_color' => '#ffffff', - 'link_hover_color' => '#FF8600', - 'link_hover_bg_color' => '#FF8600', - 'dropdown_bg_color' => '#ffffff', - 'dropdown_item_color' => '#4A5568', - 'dropdown_item_hover_color' => '#FF8600', - 'font_size' => 'normal', - 'font_weight' => '500', - 'box_shadow_intensity' => 'normal', - 'border_radius' => 4, - 'padding_vertical' => 0.75, - 'link_padding_vertical' => 0.5, - 'link_padding_horizontal' => 0.65, - 'z_index' => 1030, - 'transition_speed' => 'normal' - ) - ); - } - - /** - * Sanitiza los datos del Navbar - * - * @param array $data Datos sin sanitizar del Navbar - * @return array Datos sanitizados - */ - public function sanitize($data) { - return array_merge( - // Booleanos principales - APUS_Sanitizer_Helper::sanitize_booleans($data, array( - 'enabled', 'show_on_mobile', 'show_on_desktop', - 'enable_box_shadow', 'enable_underline_effect', 'enable_hover_background' - )), - - // Enums principales - APUS_Sanitizer_Helper::sanitize_enums($data, array( - 'position' => array('allowed' => array('sticky', 'static', 'fixed'), 'default' => 'sticky'), - 'responsive_breakpoint' => array('allowed' => array('sm', 'md', 'lg', 'xl', 'xxl'), 'default' => 'lg') - )), - - // Let's Talk Button anidado - array('lets_talk_button' => APUS_Sanitizer_Helper::sanitize_nested_group($data, 'lets_talk_button', array( - 'enabled' => array('type' => 'bool'), - 'text' => array('type' => 'text', 'default' => ''), - 'icon_class' => array('type' => 'text', 'default' => ''), - 'show_icon' => array('type' => 'bool'), - 'position' => array('type' => 'enum', 'allowed' => array('left', 'center', 'right'), 'default' => 'right') - ))), - - // Dropdown anidado - array('dropdown' => APUS_Sanitizer_Helper::sanitize_nested_group($data, 'dropdown', array( - 'enable_hover_desktop' => array('type' => 'bool'), - 'max_height' => array('type' => 'int', 'default' => 70), - 'border_radius' => array('type' => 'int', 'default' => 8), - 'item_padding_vertical' => array('type' => 'float', 'default' => 0.5), - 'item_padding_horizontal' => array('type' => 'float', 'default' => 1.25) - ))), - - // Custom styles anidado - array('custom_styles' => APUS_Sanitizer_Helper::sanitize_nested_group($data, 'custom_styles', array( - 'background_color' => array('type' => 'color', 'default' => ''), - 'text_color' => array('type' => 'color', 'default' => ''), - 'link_hover_color' => array('type' => 'color', 'default' => ''), - 'link_hover_bg_color' => array('type' => 'color', 'default' => ''), - 'dropdown_bg_color' => array('type' => 'color', 'default' => ''), - 'dropdown_item_color' => array('type' => 'color', 'default' => ''), - 'dropdown_item_hover_color' => array('type' => 'color', 'default' => ''), - 'font_size' => array('type' => 'enum', 'allowed' => array('small', 'normal', 'large'), 'default' => 'normal'), - 'font_weight' => array('type' => 'enum', 'allowed' => array('400', '500', '600', '700'), 'default' => '500'), - 'box_shadow_intensity' => array('type' => 'enum', 'allowed' => array('none', 'light', 'normal', 'strong'), 'default' => 'normal'), - 'border_radius' => array('type' => 'int', 'default' => 4), - 'padding_vertical' => array('type' => 'float', 'default' => 0.75), - 'link_padding_vertical' => array('type' => 'float', 'default' => 0.5), - 'link_padding_horizontal' => array('type' => 'float', 'default' => 0.65), - 'z_index' => array('type' => 'int', 'default' => 1030), - 'transition_speed' => array('type' => 'enum', 'allowed' => array('fast', 'normal', 'slow'), 'default' => 'normal') - ))) - ); - } -} diff --git a/admin/includes/sanitizers/class-topbar-sanitizer.php b/admin/includes/sanitizers/class-topbar-sanitizer.php deleted file mode 100644 index 54892526..00000000 --- a/admin/includes/sanitizers/class-topbar-sanitizer.php +++ /dev/null @@ -1,88 +0,0 @@ - true, - 'show_on_mobile' => true, - 'show_on_desktop' => true, - 'icon_class' => 'bi bi-megaphone-fill', - 'show_icon' => true, - 'highlight_text' => 'Nuevo:', - 'message_text' => 'Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.', - 'link_text' => 'Ver Catálogo', - 'link_url' => '/catalogo', - 'link_target' => '_self', - 'show_link' => true, - 'custom_styles' => array( - 'background_color' => '#0E2337', - 'text_color' => '#ffffff', - 'highlight_color' => '#FF8600', - 'link_hover_color' => '#FF8600', - 'font_size' => 'normal' - ) - ); - } - - /** - * Sanitiza los datos del Top Bar - * - * @param array $data Datos sin sanitizar del Top Bar - * @return array Datos sanitizados - */ - public function sanitize($data) { - return array_merge( - // Booleanos - APUS_Sanitizer_Helper::sanitize_booleans($data, array( - 'enabled', 'show_on_mobile', 'show_on_desktop', 'show_icon', 'show_link' - )), - - // Textos - APUS_Sanitizer_Helper::sanitize_texts($data, array( - 'icon_class', 'highlight_text', 'message_text', 'link_text' - )), - - // URL - array('link_url' => APUS_Sanitizer_Helper::sanitize_url($data, 'link_url')), - - // Enum - array('link_target' => APUS_Sanitizer_Helper::sanitize_enum( - $data, 'link_target', array('_self', '_blank'), '_self' - )), - - // Custom styles anidado - array('custom_styles' => APUS_Sanitizer_Helper::sanitize_nested_group($data, 'custom_styles', array( - 'background_color' => array('type' => 'color', 'default' => ''), - 'text_color' => array('type' => 'color', 'default' => ''), - 'highlight_color' => array('type' => 'color', 'default' => ''), - 'link_hover_color' => array('type' => 'color', 'default' => ''), - 'font_size' => array('type' => 'enum', 'allowed' => array('small', 'normal', 'large'), 'default' => 'normal') - ))) - ); - } -} diff --git a/admin/pages/main.php b/admin/pages/main.php index 8ca4b592..191c2158 100644 --- a/admin/pages/main.php +++ b/admin/pages/main.php @@ -19,505 +19,12 @@ if (!defined('ABSPATH')) {
- - - -
- -
-
-
-

- - Configuración Top Bar -

-

- Personaliza la barra de anuncios superior de tu sitio -

-
- -
-
- - -
- - - -
-
-
-

- - - - Activación y Visibilidad -

- - -
- -
-
- - -
- - Activa o desactiva el Top Bar en todo el sitio - -
-
- - -
- -
-
- - -
- - Pantallas menores a 768px - -
-
- - -
- -
-
- - -
- - Pantallas de 768px en adelante - -
-
-
-
- -
- - - -
-
-
-

- - - - Contenido y Mensajes -

- - -
-
-
- -
- - - - -
- - - Ver iconos disponibles: - - Bootstrap Icons - - -
-
- -
-
- -
-
- - -
-
-
-
-
- - -
-
-
- - - - - Se muestra en negritas y con color destacado. Dejar vacío para omitir. - -
-
-
- - -
-
-
- - -
- - - Mensaje que se mostrará en la barra superior - - - 75/250 caracteres - -
-
-
-
-
-
-
- - -
-
-
- - -
-
- -
-
- - - - URLs relativas (/page) o absolutas (https://...) - -
-
- -
-
- - -
-
- -
-
-
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
-
-
-

- - - - Estilos Personalizados -

- - -
-
-
- -
- -
- #0E2337 - Navy Dark (Default) -
-
-
-
- -
-
- -
- -
- #ffffff - White (Default) -
-
-
-
- -
-
- -
- -
- #FF8600 - Orange Primary (Default) -
-
-
-
- -
-
- -
- -
- #FF6B35 - Orange Hover (Default) -
-
-
-
-
- - -
-
-
- - - - - El tamaño afecta la altura total de la barra - -
-
- -
- -
-
-
-
- - - - -
-
-
-

- - - - Vista Previa en Tiempo Real -

- -
- -
- - Nuevo: - Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025. - Ver Catálogo → -
- -
- - - La vista previa se actualiza automáticamente al modificar los campos - -
-
- -
- - -
-
-
-
-
+
diff --git a/header.php b/header.php index 968da77c..16f5b802 100644 --- a/header.php +++ b/header.php @@ -20,98 +20,7 @@ data-bs-spy="scroll" data-bs-target=".toc-container" data-bs-offset="100"> - - true, - 'show_on_mobile' => true, - 'show_on_desktop' => true, - 'icon_class' => 'bi bi-megaphone-fill', - 'show_icon' => true, - 'highlight_text' => 'Nuevo:', - 'message_text' => 'Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.', - 'link_text' => 'Ver Catálogo', - 'link_url' => '/catalogo', - 'link_target' => '_self', - 'show_link' => true, - 'custom_styles' => array( - 'background_color' => '', - 'text_color' => '', - 'highlight_color' => '', - 'link_hover_color' => '', - 'font_size' => 'normal' - ) -); - -$top_bar_config = isset($settings['components']['top_bar']) ? $settings['components']['top_bar'] : array(); -$top_bar = wp_parse_args($top_bar_config, $top_bar_defaults); - -// Verificar si está habilitado -if ($top_bar['enabled']): - // Construir clases CSS - $classes = array('top-notification-bar'); - if (!$top_bar['show_on_mobile']) { - $classes[] = 'd-none'; - $classes[] = 'd-md-block'; - } - if (!$top_bar['show_on_desktop']) { - $classes[] = 'd-md-none'; - } - $class_attr = implode(' ', $classes); - - // Construir estilos inline - $inline_styles = array(); - if (!empty($top_bar['custom_styles']['background_color'])) { - $inline_styles[] = 'background-color: ' . esc_attr($top_bar['custom_styles']['background_color']); - } - if (!empty($top_bar['custom_styles']['text_color'])) { - $inline_styles[] = 'color: ' . esc_attr($top_bar['custom_styles']['text_color']); - } - - // Font size - $font_size_map = array( - 'small' => '0.8rem', - 'normal' => '0.9rem', - 'large' => '1rem' - ); - if (isset($font_size_map[$top_bar['custom_styles']['font_size']])) { - $inline_styles[] = 'font-size: ' . $font_size_map[$top_bar['custom_styles']['font_size']]; - } - - $style_attr = !empty($inline_styles) ? ' style="' . implode('; ', $inline_styles) . '"' : ''; -?> -
> -
-
- - - - - - - style="color: "> - - - - - - - - - data-hover-color="" - > - - - -
-
-
- +