Migración completa a Clean Architecture con componentes funcionales

- Reorganización de estructura: Admin/, Public/, Shared/, Schemas/
- 12 componentes migrados: TopNotificationBar, Navbar, CtaLetsTalk, Hero,
  FeaturedImage, TableOfContents, CtaBoxSidebar, SocialShare, CtaPost,
  RelatedPost, ContactForm, Footer
- Panel de administración con tabs Bootstrap 5 funcionales
- Schemas JSON para configuración de componentes
- Renderers dinámicos con CSSGeneratorService (cero CSS hardcodeado)
- FormBuilders para UI admin con Design System consistente
- Fix: Bootstrap JS cargado en header para tabs funcionales
- Fix: buildTextInput maneja valores mixed (bool/string)
- Eliminación de estructura legacy (src/, admin/, assets/css/componente-*)

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-25 21:20:06 -06:00
parent 90de6df77c
commit 0846a3bf03
224 changed files with 21670 additions and 17816 deletions

View File

@@ -0,0 +1,544 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Navbar - Preview de Diseño</title>
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #f0f0f1;
padding: 20px;
}
</style>
</head>
<body>
<!-- ============================================================
TAB: NAVBAR CONFIGURATION
============================================================ -->
<div class="tab-pane fade show active" id="navbarTab" role="tabpanel">
<!-- ========================================
PATRÓN 1: HEADER CON GRADIENTE
======================================== -->
<div class="rounded p-4 mb-4 shadow text-white" style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%); border-left: 4px solid #FF8600;">
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
<div>
<h3 class="h4 mb-1 fw-bold">
<i class="bi bi-list-ul me-2" style="color: #FF8600;"></i>
Configuración de Navbar
</h3>
<p class="mb-0 small" style="opacity: 0.85;">
Personaliza el menú de navegación principal del sitio
</p>
</div>
<button type="button" class="btn btn-sm btn-outline-light" id="resetNavbarDefaults">
<i class="bi bi-arrow-counterclockwise me-1"></i>
Restaurar valores por defecto
</button>
</div>
</div>
<!-- ========================================
PATRÓN 2: LAYOUT 2 COLUMNAS
======================================== -->
<div class="row g-3">
<div class="col-lg-6">
<!-- ========================================
GRUPO 1: ACTIVACIÓN Y VISIBILIDAD (OBLIGATORIO)
PATRÓN 3: CARD CON BORDER-LEFT NAVY
======================================== -->
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-toggle-on me-2" style="color: #FF8600;"></i>
Activación y Visibilidad
</h5>
<!-- ⚠️ PATRÓN 4: SWITCHES VERTICALES CON ICONOS (3 OBLIGATORIOS) -->
<!-- Switch 1: Enabled (OBLIGATORIO) -->
<div class="mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarEnabled" checked>
<label class="form-check-label small" for="navbarEnabled" style="color: #495057;">
<i class="bi bi-power me-1" style="color: #FF8600;"></i>
<strong>Activar Navbar</strong>
</label>
</div>
</div>
<!-- Switch 2: Show on Mobile (OBLIGATORIO) -->
<div class="mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarShowOnMobile" checked>
<label class="form-check-label small" for="navbarShowOnMobile" style="color: #495057;">
<i class="bi bi-phone me-1" style="color: #FF8600;"></i>
<strong>Mostrar en Mobile</strong> <span class="text-muted">(&lt;768px)</span>
</label>
</div>
</div>
<!-- Switch 3: Show on Desktop (OBLIGATORIO) -->
<div class="mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarShowOnDesktop" checked>
<label class="form-check-label small" for="navbarShowOnDesktop" style="color: #495057;">
<i class="bi bi-display me-1" style="color: #FF8600;"></i>
<strong>Mostrar en Desktop</strong> <span class="text-muted">(≥768px)</span>
</label>
</div>
</div>
<!-- Campo adicional del schema: show_on_pages (select) -->
<div class="mb-2 mt-3">
<label for="navbarShowOnPages" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-file-earmark-text me-1" style="color: #FF8600;"></i>
Mostrar en
</label>
<select id="navbarShowOnPages" class="form-select form-select-sm">
<option value="all" selected>Todas las páginas</option>
<option value="home">Solo página de inicio</option>
<option value="posts">Solo posts individuales</option>
<option value="pages">Solo páginas</option>
</select>
</div>
<!-- Switch 5: Sticky Enabled -->
<div class="mb-0 mt-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarStickyEnabled" checked>
<label class="form-check-label small" for="navbarStickyEnabled" style="color: #495057;">
<i class="bi bi-pin-angle me-1" style="color: #FF8600;"></i>
<strong>Navbar fijo (sticky)</strong>
</label>
</div>
</div>
</div>
</div>
<!-- ========================================
GRUPO 2: LAYOUT Y ESTRUCTURA
======================================== -->
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-columns-gap me-2" style="color: #FF8600;"></i>
Layout y Estructura
</h5>
<!-- container_type (select) -->
<div class="mb-2">
<label for="navbarContainerType" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-box me-1" style="color: #FF8600;"></i>
Tipo de contenedor
</label>
<select id="navbarContainerType" class="form-select form-select-sm">
<option value="container" selected>Container (ancho fijo)</option>
<option value="container-fluid">Container Fluid (ancho completo)</option>
</select>
</div>
<!-- padding_vertical + z_index (compactados) -->
<div class="row g-2 mb-0">
<div class="col-6">
<label for="navbarPaddingVertical" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-arrows-vertical me-1" style="color: #FF8600;"></i>
Padding vertical
</label>
<input type="text" id="navbarPaddingVertical" class="form-control form-control-sm" value="0.75rem 0">
</div>
<div class="col-6">
<label for="navbarZIndex" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-layers me-1" style="color: #FF8600;"></i>
Z-index
</label>
<input type="number" id="navbarZIndex" class="form-control form-control-sm" value="1030" min="1" max="9999">
</div>
</div>
</div>
</div>
<!-- ========================================
GRUPO 3: CONFIGURACIÓN DEL MENÚ
======================================== -->
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-gear me-2" style="color: #FF8600;"></i>
Configuración del Menú
</h5>
<!-- menu_location + custom_menu_id (compactados) -->
<div class="row g-2 mb-2">
<div class="col-6">
<label for="navbarMenuLocation" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-pin-map me-1" style="color: #FF8600;"></i>
Ubicación del menú
</label>
<select id="navbarMenuLocation" class="form-select form-select-sm">
<option value="primary" selected>Menú Principal</option>
<option value="secondary">Menú Secundario</option>
<option value="custom">Menú personalizado</option>
</select>
</div>
<div class="col-6">
<label for="navbarCustomMenuId" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-hash me-1" style="color: #FF8600;"></i>
ID del menú
</label>
<input type="number" id="navbarCustomMenuId" class="form-control form-control-sm" value="0" min="0">
</div>
</div>
<!-- enable_dropdowns (switch) -->
<div class="mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarEnableDropdowns" checked>
<label class="form-check-label small" for="navbarEnableDropdowns" style="color: #495057;">
<i class="bi bi-chevron-down me-1" style="color: #FF8600;"></i>
<strong>Habilitar submenús desplegables</strong>
</label>
</div>
</div>
<!-- mobile_breakpoint (select) -->
<div class="mb-0">
<label for="navbarMobileBreakpoint" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-phone-landscape me-1" style="color: #FF8600;"></i>
Breakpoint para menú móvil
</label>
<select id="navbarMobileBreakpoint" class="form-select form-select-sm">
<option value="sm">Small (576px)</option>
<option value="md">Medium (768px)</option>
<option value="lg" selected>Large (992px)</option>
<option value="xl">Extra Large (1200px)</option>
</select>
</div>
</div>
</div>
<!-- ========================================
GRUPO 4: LOGO/MARCA
======================================== -->
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-award me-2" style="color: #FF8600;"></i>
Logo/Marca
</h5>
<!-- show_brand (switch) -->
<div class="mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarShowBrand">
<label class="form-check-label small" for="navbarShowBrand" style="color: #495057;">
<i class="bi bi-eye me-1" style="color: #FF8600;"></i>
<strong>Mostrar logo/marca</strong>
</label>
</div>
</div>
<!-- use_logo (switch) -->
<div class="mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarUseLogo">
<label class="form-check-label small" for="navbarUseLogo" style="color: #495057;">
<i class="bi bi-image me-1" style="color: #FF8600;"></i>
<strong>Usar logo (imagen)</strong>
</label>
</div>
<small class="text-muted d-block ms-4 mt-1">Usa una imagen en lugar de texto</small>
</div>
<!-- logo_url + logo_height (compactados) -->
<div class="row g-2 mb-2">
<div class="col-8">
<label for="navbarLogoUrl" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-link-45deg me-1" style="color: #FF8600;"></i>
URL del logo
</label>
<input type="url" id="navbarLogoUrl" class="form-control form-control-sm" placeholder="https://...">
</div>
<div class="col-4">
<label for="navbarLogoHeight" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-arrows-vertical me-1" style="color: #FF8600;"></i>
Altura
</label>
<input type="text" id="navbarLogoHeight" class="form-control form-control-sm" value="40px">
</div>
</div>
<!-- brand_text -->
<div class="mb-2">
<label for="navbarBrandText" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-fonts me-1" style="color: #FF8600;"></i>
Texto de la marca
</label>
<input type="text" id="navbarBrandText" class="form-control form-control-sm" value="Mi Sitio" maxlength="50">
<small class="text-muted">Se muestra si no hay logo</small>
</div>
<!-- brand_font_size + brand_color (compactados) -->
<div class="row g-2 mb-2">
<div class="col-6">
<label for="navbarBrandFontSize" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-type me-1" style="color: #FF8600;"></i>
Tamaño fuente
</label>
<input type="text" id="navbarBrandFontSize" class="form-control form-control-sm" value="1.5rem">
</div>
<div class="col-6">
<label for="navbarBrandColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-palette me-1" style="color: #FF8600;"></i>
Color
</label>
<input type="color" id="navbarBrandColor" class="form-control form-control-color w-100" value="#FFFFFF">
</div>
</div>
<!-- brand_hover_color -->
<div class="mb-0">
<label for="navbarBrandHoverColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-hand-index me-1" style="color: #FF8600;"></i>
Color hover
</label>
<input type="color" id="navbarBrandHoverColor" class="form-control form-control-color w-100" value="#FF8600">
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<!-- ========================================
GRUPO 5: ESTILOS DEL NAVBAR
======================================== -->
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-paint-bucket me-2" style="color: #FF8600;"></i>
Estilos del Navbar
</h5>
<!-- background_color -->
<div class="mb-2">
<label for="navbarBackgroundColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-palette me-1" style="color: #FF8600;"></i>
Color de fondo
</label>
<input type="color" id="navbarBackgroundColor" class="form-control form-control-color w-100" value="#1e3a5f">
<small class="text-muted d-block mt-1" id="navbarBackgroundColorValue">#1E3A5F</small>
</div>
<!-- box_shadow -->
<div class="mb-0">
<label for="navbarBoxShadow" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-droplet me-1" style="color: #FF8600;"></i>
Sombra del navbar
</label>
<input type="text" id="navbarBoxShadow" class="form-control form-control-sm" value="0 4px 12px rgba(30, 58, 95, 0.15)">
<small class="text-muted">Sombra CSS (ej: 0 4px 12px rgba(0,0,0,0.15))</small>
</div>
</div>
</div>
<!-- ========================================
GRUPO 6: ESTILOS DE ENLACES
======================================== -->
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-link-45deg me-2" style="color: #FF8600;"></i>
Estilos de Enlaces
</h5>
<!-- COLOR PICKERS EN GRID 3 COLORES -->
<div class="row g-2 mb-2">
<div class="col-4">
<label for="navbarTextColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-fonts me-1" style="color: #FF8600;"></i>
Color texto
</label>
<input type="color" id="navbarTextColor" class="form-control form-control-color w-100" value="#FFFFFF">
<small class="text-muted d-block mt-1" id="navbarTextColorValue">#FFFFFF</small>
</div>
<div class="col-4">
<label for="navbarHoverColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-hand-index me-1" style="color: #FF8600;"></i>
Color hover
</label>
<input type="color" id="navbarHoverColor" class="form-control form-control-color w-100" value="#FF8600">
<small class="text-muted d-block mt-1" id="navbarHoverColorValue">#FF8600</small>
</div>
<div class="col-4">
<label for="navbarActiveColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-check-circle me-1" style="color: #FF8600;"></i>
Color activo
</label>
<input type="color" id="navbarActiveColor" class="form-control form-control-color w-100" value="#FF8600">
<small class="text-muted d-block mt-1" id="navbarActiveColorValue">#FF8600</small>
</div>
</div>
<!-- font_size + font_weight (compactados) -->
<div class="row g-2 mb-2">
<div class="col-6">
<label for="navbarFontSize" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-type me-1" style="color: #FF8600;"></i>
Tamaño fuente
</label>
<input type="text" id="navbarFontSize" class="form-control form-control-sm" value="0.9rem">
</div>
<div class="col-6">
<label for="navbarFontWeight" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-fonts me-1" style="color: #FF8600;"></i>
Grosor fuente
</label>
<input type="number" id="navbarFontWeight" class="form-control form-control-sm" value="500" min="100" max="900" step="100">
</div>
</div>
<!-- padding + border_radius (compactados) -->
<div class="row g-2 mb-2">
<div class="col-6">
<label for="navbarLinkPadding" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-bounding-box me-1" style="color: #FF8600;"></i>
Padding
</label>
<input type="text" id="navbarLinkPadding" class="form-control form-control-sm" value="0.5rem 0.65rem">
</div>
<div class="col-6">
<label for="navbarBorderRadius" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-square me-1" style="color: #FF8600;"></i>
Border radius
</label>
<input type="text" id="navbarBorderRadius" class="form-control form-control-sm" value="4px">
</div>
</div>
<!-- show_underline_effect (switch) -->
<div class="mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="navbarShowUnderlineEffect" checked>
<label class="form-check-label small" for="navbarShowUnderlineEffect" style="color: #495057;">
<i class="bi bi-dash-lg me-1" style="color: #FF8600;"></i>
<strong>Mostrar efecto de subrayado</strong>
</label>
</div>
</div>
<!-- underline_color -->
<div class="mb-0">
<label for="navbarUnderlineColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-palette me-1" style="color: #FF8600;"></i>
Color del subrayado
</label>
<input type="color" id="navbarUnderlineColor" class="form-control form-control-color w-100" value="#FF8600">
<small class="text-muted d-block mt-1" id="navbarUnderlineColorValue">#FF8600</small>
</div>
</div>
</div>
<!-- ========================================
GRUPO 7: ESTILOS DE DROPDOWN
======================================== -->
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-chevron-down me-2" style="color: #FF8600;"></i>
Estilos de Dropdown
</h5>
<!-- background_color -->
<div class="mb-2">
<label for="navbarDropdownBackground" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-paint-bucket me-1" style="color: #FF8600;"></i>
Fondo dropdown
</label>
<input type="color" id="navbarDropdownBackground" class="form-control form-control-color w-100" value="#FFFFFF">
<small class="text-muted d-block mt-1" id="navbarDropdownBackgroundValue">#FFFFFF</small>
</div>
<!-- border_radius + shadow (compactados) -->
<div class="row g-2 mb-2">
<div class="col-6">
<label for="navbarDropdownBorderRadius" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-square me-1" style="color: #FF8600;"></i>
Border radius
</label>
<input type="text" id="navbarDropdownBorderRadius" class="form-control form-control-sm" value="8px">
</div>
<div class="col-6">
<label for="navbarDropdownShadow" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-droplet me-1" style="color: #FF8600;"></i>
Sombra
</label>
<input type="text" id="navbarDropdownShadow" class="form-control form-control-sm" value="0 8px 24px rgba(0,0,0,0.12)">
</div>
</div>
<!-- item_color + item_hover_background -->
<div class="row g-2 mb-2">
<div class="col-6">
<label for="navbarDropdownItemColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-fonts me-1" style="color: #FF8600;"></i>
Color items
</label>
<input type="color" id="navbarDropdownItemColor" class="form-control form-control-color w-100" value="#495057">
</div>
<div class="col-6">
<label for="navbarDropdownItemHoverBg" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-paint-bucket me-1" style="color: #FF8600;"></i>
Fondo hover
</label>
<input type="color" id="navbarDropdownItemHoverBg" class="form-control form-control-color w-100" value="#FFF5EB">
</div>
</div>
<!-- item_padding -->
<div class="mb-0">
<label for="navbarDropdownItemPadding" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-bounding-box me-1" style="color: #FF8600;"></i>
Padding de items
</label>
<input type="text" id="navbarDropdownItemPadding" class="form-control form-control-sm" value="0.625rem 1.25rem">
<small class="text-muted">Espaciado interno de items (ej: 0.625rem 1.25rem)</small>
</div>
</div>
</div>
</div>
</div>
</div><!-- /tab-pane -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Actualizar valores HEX de color pickers
document.querySelectorAll('input[type="color"]').forEach(picker => {
const valueDisplay = document.getElementById(picker.id + 'Value');
if (valueDisplay) {
picker.addEventListener('input', function() {
valueDisplay.textContent = this.value.toUpperCase();
});
}
});
// Simular reset button
document.getElementById('resetNavbarDefaults').addEventListener('click', function() {
if (confirm('¿Restaurar todos los valores a los valores por defecto?')) {
alert('En producción, esto restauraría los valores del schema JSON');
}
});
</script>
</body>
</html>