Backup pre-corrección namespaces: mejoras schemas y componentes

Cambios incluidos:
- Actualización de copy/textos en 7 schemas JSON
- Mejoras en AdminAjaxHandler con mapeos adicionales
- Refactorización de FormBuilders y Renderers
- Correcciones en dashboard admin JS
- Nuevo ContactFormRenderer funcional

NOTA: Este commit sirve como respaldo antes de corregir
inconsistencias de case en namespaces (API→Api, WordPress→Wordpress)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-26 17:59:01 -06:00
parent 0846a3bf03
commit 4c807e1cf2
26 changed files with 717 additions and 79 deletions

View File

@@ -17,19 +17,62 @@
});
/**
* Inicializa el sistema de tabs
* Inicializa el sistema de tabs con persistencia en URL
*/
function initializeTabs() {
const tabs = document.querySelectorAll('.nav-tab');
const tabButtons = document.querySelectorAll('[data-bs-toggle="tab"]');
tabs.forEach(function(tab) {
tab.addEventListener('click', function(e) {
// Prevenir comportamiento por defecto si es necesario
// (En este caso dejamos que funcione la navegación normal)
// Leer parametro admin-tab de la URL al cargar
const urlParams = new URLSearchParams(window.location.search);
const activeTabParam = urlParams.get('admin-tab');
if (activeTabParam) {
// Buscar el boton del tab correspondiente
const targetButton = document.querySelector('[data-bs-target="#' + activeTabParam + 'Tab"]');
if (targetButton) {
// Activar el tab usando Bootstrap API
const tab = new bootstrap.Tab(targetButton);
tab.show();
}
}
// Escuchar cambios de tab para actualizar URL
tabButtons.forEach(function(tabButton) {
tabButton.addEventListener('shown.bs.tab', function(e) {
// Obtener el ID del componente desde data-bs-target
const target = e.target.getAttribute('data-bs-target');
const componentId = target.replace('#', '').replace('Tab', '');
// Actualizar URL sin recargar pagina
updateUrlWithTab(componentId);
});
});
}
/**
* Actualiza la URL con el parametro admin-tab sin recargar la pagina
*
* @param {string} tabId ID del tab activo
*/
function updateUrlWithTab(tabId) {
const url = new URL(window.location.href);
url.searchParams.set('admin-tab', tabId);
window.history.replaceState({}, '', url.toString());
}
/**
* Obtiene el ID del tab activo actualmente
*
* @returns {string|null} ID del componente activo o null
*/
function getActiveTabId() {
const activeTab = document.querySelector('.tab-pane.active');
if (activeTab) {
return activeTab.id.replace('Tab', '');
}
return null;
}
/**
* Inicializa validación de formularios
*/
@@ -227,7 +270,17 @@
.then(data => {
if (data.success) {
showNotice('success', data.data.message || 'Valores restaurados correctamente.');
setTimeout(() => location.reload(), 1500);
// Recargar preservando el tab activo
setTimeout(() => {
const activeTabId = getActiveTabId();
if (activeTabId) {
const url = new URL(window.location.href);
url.searchParams.set('admin-tab', activeTabId);
window.location.href = url.toString();
} else {
location.reload();
}
}, 1500);
} else {
showNotice('error', data.data.message || 'Error al restaurar los valores.');
}

View File

@@ -13,7 +13,19 @@ if (!defined('ABSPATH')) {
}
$components = $this->getComponents();
$firstComponentId = array_key_first($components);
// Determinar tab activo: desde URL o primer componente
$activeComponentId = array_key_first($components);
// Leer parametro admin-tab de la URL con sanitizacion
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Solo lectura de parametro para UI
if (isset($_GET['admin-tab'])) {
$requestedTab = sanitize_text_field(wp_unslash($_GET['admin-tab']));
// Validar que el componente exista
if (array_key_exists($requestedTab, $components)) {
$activeComponentId = $requestedTab;
}
}
?>
<div class="wrap roi-admin-panel">
@@ -21,13 +33,13 @@ $firstComponentId = array_key_first($components);
<ul class="nav nav-tabs nav-tabs-admin mb-0" role="tablist">
<?php foreach ($components as $componentId => $component): ?>
<li class="nav-item" role="presentation">
<button class="nav-link <?php echo $componentId === $firstComponentId ? 'active' : ''; ?>"
<button class="nav-link <?php echo $componentId === $activeComponentId ? 'active' : ''; ?>"
data-bs-toggle="tab"
data-bs-target="#<?php echo esc_attr($componentId); ?>Tab"
type="button"
role="tab"
aria-controls="<?php echo esc_attr($componentId); ?>Tab"
aria-selected="<?php echo $componentId === $firstComponentId ? 'true' : 'false'; ?>">
aria-selected="<?php echo $componentId === $activeComponentId ? 'true' : 'false'; ?>">
<i class="bi <?php echo esc_attr($component['icon']); ?> me-1"></i>
<?php echo esc_html($component['label']); ?>
</button>
@@ -38,11 +50,11 @@ $firstComponentId = array_key_first($components);
<!-- Tab Content -->
<div class="tab-content mt-3">
<?php foreach ($components as $componentId => $component):
$isFirst = ($componentId === $firstComponentId);
$isActive = ($componentId === $activeComponentId);
$componentSettings = $this->getComponentSettings($componentId);
?>
<!-- Tab: <?php echo esc_html($component['label']); ?> -->
<div class="tab-pane fade <?php echo $isFirst ? 'show active' : ''; ?>"
<div class="tab-pane fade <?php echo $isActive ? 'show active' : ''; ?>"
id="<?php echo esc_attr($componentId); ?>Tab"
role="tabpanel">