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

@@ -114,8 +114,8 @@ function roi_preload_custom_fonts() {
// Example preload links - uncomment and modify when you have custom font files
/*
?>
<link rel="preload" href="<?php echo esc_url(get_template_directory_uri() . '/assets/fonts/CustomSans-Regular.woff2'); ?>" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="<?php echo esc_url(get_template_directory_uri() . '/assets/fonts/CustomSans-Bold.woff2'); ?>" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="<?php echo esc_url(get_template_directory_uri() . '/Assets/fonts/CustomSans-Regular.woff2'); ?>" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="<?php echo esc_url(get_template_directory_uri() . '/Assets/fonts/CustomSans-Bold.woff2'); ?>" as="font" type="font/woff2" crossorigin>
<?php
*/
}

View File

@@ -27,7 +27,7 @@ function roi_enqueue_fonts() {
// Fonts CSS local
wp_enqueue_style(
'roi-fonts',
get_template_directory_uri() . '/assets/css/css-global-fonts.css',
get_template_directory_uri() . '/Assets/css/css-global-fonts.css',
array('google-fonts-poppins'),
'1.0.0',
'all'
@@ -43,7 +43,7 @@ function roi_enqueue_bootstrap() {
// Bootstrap CSS - with high priority
wp_enqueue_style(
'roi-bootstrap',
get_template_directory_uri() . '/assets/vendor/bootstrap/css/bootstrap.min.css',
get_template_directory_uri() . '/Assets/vendor/bootstrap/css/bootstrap.min.css',
array('roi-fonts'),
'5.3.2',
'all'
@@ -52,7 +52,7 @@ function roi_enqueue_bootstrap() {
// Bootstrap Icons CSS - LOCAL (Issue #135: CORS bloqueaba CDN)
wp_enqueue_style(
'bootstrap-icons',
get_template_directory_uri() . '/assets/vendor/bootstrap-icons.min.css',
get_template_directory_uri() . '/Assets/vendor/bootstrap-icons.min.css',
array('roi-bootstrap'),
'1.11.3',
'all'
@@ -61,7 +61,7 @@ function roi_enqueue_bootstrap() {
// Variables CSS del Template RDash (NIVEL 1 - BLOQUEANTE - Issue #48)
wp_enqueue_style(
'roi-variables',
get_template_directory_uri() . '/assets/css/css-global-variables.css',
get_template_directory_uri() . '/Assets/css/css-global-variables.css',
array('roi-bootstrap'),
ROI_VERSION,
'all'
@@ -70,7 +70,7 @@ function roi_enqueue_bootstrap() {
// Bootstrap JS Bundle - in footer with defer
wp_enqueue_script(
'roi-bootstrap-js',
get_template_directory_uri() . '/assets/vendor/bootstrap/js/bootstrap.bundle.min.js',
get_template_directory_uri() . '/Assets/vendor/bootstrap/js/bootstrap.bundle.min.js',
array(),
'5.3.2',
array(
@@ -93,7 +93,7 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_bootstrap', 5);
function roi_enqueue_main_stylesheet() {
wp_enqueue_style(
'roi-main-style',
get_template_directory_uri() . '/assets/css/style.css',
get_template_directory_uri() . '/Assets/css/style.css',
array('roi-variables'),
'1.0.5', // Arquitectura: Separación de responsabilidades CSS
'all'
@@ -106,54 +106,34 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_main_stylesheet', 5);
* Enqueue FASE 2 CSS - Template RDash Component Styles (Issues #58-64)
*
* Estilos que replican componentes del template RDash
*
* NOTA: Hero Section, Post Content y Related Posts ahora usan
* estilos generados dinámicamente desde sus Renderers.
*/
function roi_enqueue_fase2_styles() {
// Hero Section CSS - Gradiente azul (Issue #59)
wp_enqueue_style(
'roi-hero',
get_template_directory_uri() . '/assets/css/componente-hero-section.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-hero-section.css'),
'all'
);
// Hero Section CSS - DESHABILITADO: estilos generados por HeroRenderer
// @see Public/Hero/Infrastructure/Ui/HeroRenderer.php
// Category Badges CSS - Clase genérica (Issue #62)
wp_enqueue_style(
'roi-badges',
get_template_directory_uri() . '/assets/css/css-global-badges.css',
get_template_directory_uri() . '/Assets/css/css-global-badges.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/css-global-badges.css'),
filemtime(get_template_directory() . '/Assets/css/css-global-badges.css'),
'all'
);
// Pagination CSS - Estilos personalizados (Issue #64)
wp_enqueue_style(
'roi-pagination',
get_template_directory_uri() . '/assets/css/css-global-pagination.css',
get_template_directory_uri() . '/Assets/css/css-global-pagination.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/css-global-pagination.css'),
filemtime(get_template_directory() . '/Assets/css/css-global-pagination.css'),
'all'
);
// Post Content Typography - Solo en posts individuales (Issue #63)
if (is_single()) {
wp_enqueue_style(
'roi-post-content',
get_template_directory_uri() . '/assets/css/componente-post-content.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-post-content.css'),
'all'
);
// Related Posts CSS - Background gris (Issue #60)
wp_enqueue_style(
'roi-related-posts',
get_template_directory_uri() . '/assets/css/componente-related-posts.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-related-posts.css'),
'all'
);
}
// Post Content Typography y Related Posts - DESHABILITADOS
// Los estilos ahora están integrados en style.css o generados dinámicamente
}
add_action('wp_enqueue_scripts', 'roi_enqueue_fase2_styles', 6);
@@ -167,32 +147,48 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_fase2_styles', 6);
* @since 1.0.7
*/
function roi_enqueue_global_components() {
// Notification Bar CSS - Barra superior (Issue #39)
// Notification Bar CSS - DESHABILITADO: Los estilos de la barra de notificación ahora se generan
// dinámicamente desde el TopNotificationBarRenderer basado en los valores de la BD.
// @see Public/TopNotificationBar/Infrastructure/Ui/TopNotificationBarRenderer.php
/*
wp_enqueue_style(
'roi-notification-bar',
get_template_directory_uri() . '/assets/css/componente-top-bar.css',
get_template_directory_uri() . '/Assets/css/componente-top-bar.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-top-bar.css'),
filemtime(get_template_directory() . '/Assets/css/componente-top-bar.css'),
'all'
);
*/
// Navbar CSS - Navegación principal
// Navbar CSS - DESHABILITADO: Los estilos del navbar ahora se generan
// dinámicamente desde el NavbarRenderer basado en los valores de la BD.
// El archivo componente-navbar.css tenía !important que sobrescribía
// los estilos configurados por el usuario en el Admin Panel.
// @see Public/Navbar/Infrastructure/Ui/NavbarRenderer.php
/*
wp_enqueue_style(
'roi-navbar',
get_template_directory_uri() . '/assets/css/componente-navbar.css',
get_template_directory_uri() . '/Assets/css/componente-navbar.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-navbar.css'),
filemtime(get_template_directory() . '/Assets/css/componente-navbar.css'),
'all'
);
*/
// Buttons CSS - Botones personalizados (Let's Talk, etc.)
// Buttons CSS - DESHABILITADO: Los estilos del botón Let's Talk ahora se generan
// dinámicamente desde el CtaLetsTalkRenderer basado en los valores de la BD.
// El archivo componente-boton-lets-talk.css tenía !important que sobrescribía
// los estilos configurados por el usuario en el Admin Panel.
// @see Public/CtaLetsTalk/Infrastructure/Ui/CtaLetsTalkRenderer.php
/*
wp_enqueue_style(
'roi-buttons',
get_template_directory_uri() . '/assets/css/componente-boton-lets-talk.css',
get_template_directory_uri() . '/Assets/css/componente-boton-lets-talk.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-boton-lets-talk.css'),
filemtime(get_template_directory() . '/Assets/css/componente-boton-lets-talk.css'),
'all'
);
*/
}
add_action('wp_enqueue_scripts', 'roi_enqueue_global_components', 7);
@@ -204,7 +200,7 @@ function roi_enqueue_header() {
// Header CSS
wp_enqueue_style(
'roi-header',
get_template_directory_uri() . '/assets/css/componente-footer-principal.css',
get_template_directory_uri() . '/Assets/css/componente-footer-principal.css',
array('roi-fonts'),
'1.0.0',
'all'
@@ -213,7 +209,7 @@ function roi_enqueue_header() {
// Header JS - with defer strategy
wp_enqueue_script(
'roi-header-js',
get_template_directory_uri() . '/assets/js/header.js',
get_template_directory_uri() . '/Assets/js/header.js',
array(),
'1.0.0',
array(
@@ -240,7 +236,7 @@ function roi_enqueue_generic_tables() {
// Generic Tables CSS
wp_enqueue_style(
'roi-generic-tables',
get_template_directory_uri() . '/assets/css/css-global-generic-tables.css',
get_template_directory_uri() . '/Assets/css/css-global-generic-tables.css',
array('roi-bootstrap'),
ROI_VERSION,
'all'
@@ -264,7 +260,7 @@ function roi_enqueue_video_styles() {
// Video CSS
wp_enqueue_style(
'roi-video',
get_template_directory_uri() . '/assets/css/css-global-video.css',
get_template_directory_uri() . '/Assets/css/css-global-video.css',
array('roi-bootstrap'),
ROI_VERSION,
'all'
@@ -284,7 +280,7 @@ function roi_enqueue_main_javascript() {
// Main JavaScript - navbar scroll effects and interactions
wp_enqueue_script(
'roi-main-js',
get_template_directory_uri() . '/assets/js/main.js',
get_template_directory_uri() . '/Assets/js/main.js',
array('roi-bootstrap-js'),
'1.0.3', // Cache bust: force remove defer with filter
true // Load in footer
@@ -331,7 +327,7 @@ function roi_enqueue_accessibility() {
// Accessibility CSS
wp_enqueue_style(
'roi-accessibility',
get_template_directory_uri() . '/assets/css/css-global-accessibility.css',
get_template_directory_uri() . '/Assets/css/css-global-accessibility.css',
array('roi-theme-style'),
ROI_VERSION,
'all'
@@ -340,7 +336,7 @@ function roi_enqueue_accessibility() {
// Accessibility JavaScript
wp_enqueue_script(
'roi-accessibility-js',
get_template_directory_uri() . '/assets/js/accessibility.js',
get_template_directory_uri() . '/Assets/js/accessibility.js',
array('roi-bootstrap-js'),
ROI_VERSION,
array(
@@ -375,7 +371,7 @@ function roi_enqueue_adsense_loader() {
// Enqueue del script de carga de AdSense
wp_enqueue_script(
'roi-adsense-loader',
get_template_directory_uri() . '/assets/js/adsense-loader.js',
get_template_directory_uri() . '/Assets/js/adsense-loader.js',
array(),
ROI_VERSION,
array(
@@ -399,7 +395,7 @@ function roi_enqueue_theme_styles() {
// Theme Core Styles - ELIMINADO theme.css
// wp_enqueue_style(
// 'roi-theme',
// get_template_directory_uri() . '/assets/css/theme.css',
// get_template_directory_uri() . '/Assets/css/theme.css',
// array('roi-bootstrap'),
// '1.0.0',
// 'all'
@@ -408,7 +404,7 @@ function roi_enqueue_theme_styles() {
// Theme Animations
wp_enqueue_style(
'roi-animations',
get_template_directory_uri() . '/assets/css/css-global-animations.css',
get_template_directory_uri() . '/Assets/css/css-global-animations.css',
array('roi-bootstrap'), // Cambiado de 'roi-theme' a 'roi-bootstrap'
'1.0.0',
'all'
@@ -417,7 +413,7 @@ function roi_enqueue_theme_styles() {
// Theme Responsive Styles
wp_enqueue_style(
'roi-responsive',
get_template_directory_uri() . '/assets/css/css-global-responsive.css',
get_template_directory_uri() . '/Assets/css/css-global-responsive.css',
array('roi-bootstrap'), // Cambiado de 'roi-theme' a 'roi-bootstrap'
'1.0.0',
'all'
@@ -426,7 +422,7 @@ function roi_enqueue_theme_styles() {
// Theme Utilities
wp_enqueue_style(
'roi-utilities',
get_template_directory_uri() . '/assets/css/css-global-utilities.css',
get_template_directory_uri() . '/Assets/css/css-global-utilities.css',
array('roi-bootstrap'), // Cambiado de 'roi-theme' a 'roi-bootstrap'
'1.0.0',
'all'
@@ -435,7 +431,7 @@ function roi_enqueue_theme_styles() {
// Print Styles
wp_enqueue_style(
'roi-print',
get_template_directory_uri() . '/assets/css/css-global-print.css',
get_template_directory_uri() . '/Assets/css/css-global-print.css',
array(),
'1.0.0',
'print'
@@ -449,7 +445,7 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_theme_styles', 13);
*
* HABILITADO: CSS de share buttons debe estar en su propio archivo
* Arquitectura correcta: cada componente tiene su archivo CSS individual
* Ver: wp-content/themes/roi-theme/assets/css/componente-share-buttons.css
* Ver: wp-content/themes/roi-theme/Assets/css/componente-share-buttons.css
*/
function roi_enqueue_social_share_styles() {
// Only enqueue on single posts
@@ -460,7 +456,7 @@ function roi_enqueue_social_share_styles() {
// Social Share CSS
wp_enqueue_style(
'roi-social-share',
get_template_directory_uri() . '/assets/css/componente-share-buttons.css',
get_template_directory_uri() . '/Assets/css/componente-share-buttons.css',
array('roi-bootstrap'),
ROI_VERSION,
'all'
@@ -476,7 +472,7 @@ function roi_enqueue_apu_tables_styles() {
// APU Tables CSS
wp_enqueue_style(
'roi-tables-apu',
get_template_directory_uri() . '/assets/css/css-tablas-apu.css',
get_template_directory_uri() . '/Assets/css/css-tablas-apu.css',
array('roi-bootstrap'),
ROI_VERSION,
'all'
@@ -497,7 +493,7 @@ function roi_enqueue_apu_tables_autoclass_script() {
// APU Tables Auto-Class JS
wp_enqueue_script(
'roi-apu-tables-autoclass',
get_template_directory_uri() . '/assets/js/apu-tables-auto-class.js',
get_template_directory_uri() . '/Assets/js/apu-tables-auto-class.js',
array(),
ROI_VERSION,
array(
@@ -527,7 +523,7 @@ function roi_enqueue_cta_assets() {
// CTA CSS
wp_enqueue_style(
'roi-cta-style',
get_template_directory_uri() . '/assets/css/componente-cta-ab-testing.css',
get_template_directory_uri() . '/Assets/css/componente-cta-ab-testing.css',
array('roi-bootstrap'),
ROI_VERSION,
'all'
@@ -536,7 +532,7 @@ function roi_enqueue_cta_assets() {
// CTA Tracking JS
wp_enqueue_script(
'roi-cta-tracking',
get_template_directory_uri() . '/assets/js/cta-tracking.js',
get_template_directory_uri() . '/Assets/js/cta-tracking.js',
array(),
ROI_VERSION,
array(
@@ -550,63 +546,36 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_cta_assets', 16);
/**
* Enqueue CTA Box Sidebar styles (Issue #36)
*
* DESHABILITADO: Los estilos del CTA Box Sidebar ahora se generan
* dinámicamente desde CtaBoxSidebarRenderer basado en valores de BD.
* @see Public/CtaBoxSidebar/Infrastructure/Ui/CtaBoxSidebarRenderer.php
*/
function roi_enqueue_cta_box_sidebar_assets() {
// Solo enqueue en posts individuales
if (!is_single()) {
return;
}
// CTA Box Sidebar CSS
wp_enqueue_style(
'roi-cta-box-sidebar',
get_template_directory_uri() . '/assets/css/componente-cta-box-sidebar.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-cta-box-sidebar.css'),
'all'
);
}
add_action('wp_enqueue_scripts', 'roi_enqueue_cta_box_sidebar_assets', 17);
// function roi_enqueue_cta_box_sidebar_assets() - REMOVED
/**
* Enqueue TOC Sidebar styles (only on single posts)
*
* ARQUITECTURA: Cada componente debe tener su propio archivo CSS
* Issue #121 - Separación de responsabilidades CSS
* DESHABILITADO: Los estilos del TOC ahora se generan
* dinámicamente desde TableOfContentsRenderer basado en valores de BD.
* @see Public/TableOfContents/Infrastructure/Ui/TableOfContentsRenderer.php
*
* @since 1.0.5
*/
function roi_enqueue_toc_sidebar_assets() {
// Only load on single posts
if (!is_single()) {
return;
}
// TOC Sidebar CSS
wp_enqueue_style(
'roi-toc-sidebar',
get_template_directory_uri() . '/assets/css/componente-sidebar-toc.css',
array('roi-bootstrap'),
filemtime(get_template_directory() . '/assets/css/componente-sidebar-toc.css'),
'all'
);
}
add_action('wp_enqueue_scripts', 'roi_enqueue_toc_sidebar_assets', 18);
// function roi_enqueue_toc_sidebar_assets() - REMOVED
/**
* Enqueue Footer Contact Form styles
*
* ARQUITECTURA CORRECTA: Cada componente debe tener su propio archivo CSS
* Footer Contact Form CSS ahora está en su archivo individual
* Ver: wp-content/themes/roi-theme/assets/css/componente-footer-contact-form.css
* Ver: wp-content/themes/roi-theme/Assets/css/componente-footer-contact-form.css
*/
function roi_enqueue_footer_contact_assets() {
// Footer Contact CSS
wp_enqueue_style(
'roi-footer-contact',
get_template_directory_uri() . '/assets/css/componente-footer-contact-form.css',
get_template_directory_uri() . '/Assets/css/componente-footer-contact-form.css',
array('roi-bootstrap'),
ROI_VERSION,
'all'

View File

@@ -336,7 +336,7 @@ function roi_preload_critical_resources() {
);
foreach ( $fonts as $font ) {
$font_url = get_template_directory_uri() . '/assets/fonts/' . $font;
$font_url = get_template_directory_uri() . '/Assets/fonts/' . $font;
printf(
'<link rel="preload" href="%s" as="font" type="font/woff2" crossorigin="anonymous">' . "\n",
esc_url( $font_url )
@@ -344,14 +344,14 @@ function roi_preload_critical_resources() {
}
// Preload del CSS de Bootstrap (crítico para el layout)
$bootstrap_css = get_template_directory_uri() . '/assets/vendor/bootstrap/css/bootstrap.min.css';
$bootstrap_css = get_template_directory_uri() . '/Assets/vendor/bootstrap/css/bootstrap.min.css';
printf(
'<link rel="preload" href="%s" as="style">' . "\n",
esc_url( $bootstrap_css )
);
// Preload del CSS de fuentes (crítico para evitar FOIT/FOUT)
$fonts_css = get_template_directory_uri() . '/assets/css/fonts.css';
$fonts_css = get_template_directory_uri() . '/Assets/css/fonts.css';
printf(
'<link rel="preload" href="%s" as="style">' . "\n",
esc_url( $fonts_css )

View File

@@ -250,7 +250,7 @@ function roi_enqueue_related_posts_styles() {
if ($enabled) {
wp_enqueue_style(
'roirelated-posts',
get_template_directory_uri() . '/assets/css/related-posts.css',
get_template_directory_uri() . '/Assets/css/related-posts.css',
array('roibootstrap'),
ROI_VERSION,
'all'