Feat: Implementar Top Bar configurable - Issue #143

Implementación completa del componente Top Bar con 15 campos configurables desde el admin panel, siguiendo el algoritmo universal v2.0.

## Cambios Realizados

### Backend (PHP)
- Agregados defaults del Top Bar a class-settings-manager.php
- Implementada validación completa en class-validator.php (15 campos)
- Implementada sanitización con sanitize_text_field, esc_url_raw y sanitize_hex_color
- Modificado header.php con código 100% configurable usando wp_parse_args()

### Frontend (Admin Panel)
- Creado tab HTML completo con 3 secciones: Activación, Contenido y Estilos
- Implementado JavaScript para renderizado y recolección de datos
- 15 campos configurables: enabled, visibility, icon, content, link, custom styles

### Infraestructura
- Creado admin-panel/init.php para carga del módulo
- Creada class-admin-menu.php con enqueue de Bootstrap 5 y assets
- Creada estructura base CSS y JavaScript del admin
- Ya cargado en functions.php línea 276

## Características
- Responsive: Control independiente mobile/desktop
- Estilos personalizables: 4 colores + tamaño de fuente
- Validación robusta: Límites de caracteres, URLs, colores hex
- Defaults inteligentes: Valores seguros si no hay configuración

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-09 15:13:55 -06:00
parent bbc6ed2c98
commit 465b879135
8 changed files with 1136 additions and 5 deletions

View File

@@ -20,16 +20,98 @@
<body <?php body_class(); ?> data-bs-spy="scroll" data-bs-target=".toc-container" data-bs-offset="100">
<?php wp_body_open(); ?>
<!-- Top Notification Bar (Template líneas 55-63) -->
<div class="top-notification-bar">
<!-- Top Notification Bar (Configurable desde Admin Panel) -->
<?php
// Obtener configuración del Top Bar
$settings = get_option('apus_theme_settings', array());
$top_bar_defaults = 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(
'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) . '"' : '';
?>
<div class="<?php echo esc_attr($class_attr); ?>"<?php echo $style_attr; ?>>
<div class="container">
<div class="d-flex align-items-center justify-content-center">
<i class="bi bi-megaphone-fill me-2"></i>
<span><strong>Nuevo:</strong> Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.</span>
<a href="<?php echo esc_url(home_url('/catalogo')); ?>" class="ms-2 text-white text-decoration-underline">Ver Catálogo</a>
<?php if ($top_bar['show_icon'] && !empty($top_bar['icon_class'])): ?>
<i class="<?php echo esc_attr($top_bar['icon_class']); ?> me-2"></i>
<?php endif; ?>
<span>
<?php if (!empty($top_bar['highlight_text'])): ?>
<strong<?php if (!empty($top_bar['custom_styles']['highlight_color'])): ?> style="color: <?php echo esc_attr($top_bar['custom_styles']['highlight_color']); ?>"<?php endif; ?>>
<?php echo esc_html($top_bar['highlight_text']); ?>
</strong>
<?php endif; ?>
<?php echo esc_html($top_bar['message_text']); ?>
</span>
<?php if ($top_bar['show_link'] && !empty($top_bar['link_text']) && !empty($top_bar['link_url'])): ?>
<a href="<?php echo esc_url(home_url($top_bar['link_url'])); ?>"
class="ms-2 text-white text-decoration-underline top-bar-link"
target="<?php echo esc_attr($top_bar['link_target']); ?>"
<?php if (!empty($top_bar['custom_styles']['link_hover_color'])): ?>
data-hover-color="<?php echo esc_attr($top_bar['custom_styles']['link_hover_color']); ?>"
<?php endif; ?>>
<?php echo esc_html($top_bar['link_text']); ?>
</a>
<?php endif; ?>
</div>
</div>
</div>
<?php endif; ?>
<!-- Navbar (Template líneas 264-320) -->
<nav class="navbar navbar-expand-lg navbar-dark py-3" role="navigation" aria-label="<?php esc_attr_e('Primary Navigation', 'apus-theme'); ?>">