buildHeader($componentId); $html .= '
'; // Columna izquierda $html .= '
'; $html .= $this->buildVisibilityGroup($componentId); $html .= $this->buildWidget1Group($componentId); $html .= $this->buildWidget2Group($componentId); $html .= $this->buildWidget3Group($componentId); $html .= $this->buildNewsletterGroup($componentId); $html .= '
'; // Columna derecha $html .= '
'; $html .= $this->buildFooterBottomGroup($componentId); $html .= $this->buildColorsGroup($componentId); $html .= $this->buildSpacingGroup($componentId); $html .= $this->buildEffectsGroup($componentId); $html .= '
'; $html .= '
'; return $html; } private function buildHeader(string $componentId): string { $html = '
renderer->getFieldValue($componentId, 'visibility', 'is_enabled', true); $html .= $this->buildSwitch('footerEnabled', 'Activar componente', 'bi-power', $enabled); $showOnDesktop = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_desktop', true); $html .= $this->buildSwitch('footerShowOnDesktop', 'Mostrar en escritorio', 'bi-display', $showOnDesktop); $showOnMobile = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_mobile', true); $html .= $this->buildSwitch('footerShowOnMobile', 'Mostrar en movil', 'bi-phone', $showOnMobile); $html .= '
'; $html .= ''; return $html; } private function buildWidget1Group(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Widget 1 (Menu)'; $html .= '
'; $visible = $this->renderer->getFieldValue($componentId, 'widget_1', 'widget_1_visible', true); $html .= $this->buildSwitch('footerWidget1Visible', 'Mostrar Widget 1', 'bi-eye', $visible); $title = $this->renderer->getFieldValue($componentId, 'widget_1', 'widget_1_title', 'Recursos'); $html .= $this->buildTextInput('footerWidget1Title', 'Titulo', 'bi-type', $title); $html .= '
'; $html .= ' '; $html .= ' El contenido se gestiona desde Apariencia > Menus > Footer Menu 1'; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildWidget2Group(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Widget 2 (Menu)'; $html .= '
'; $visible = $this->renderer->getFieldValue($componentId, 'widget_2', 'widget_2_visible', true); $html .= $this->buildSwitch('footerWidget2Visible', 'Mostrar Widget 2', 'bi-eye', $visible); $title = $this->renderer->getFieldValue($componentId, 'widget_2', 'widget_2_title', 'Soporte'); $html .= $this->buildTextInput('footerWidget2Title', 'Titulo', 'bi-type', $title); $html .= '
'; $html .= ' '; $html .= ' El contenido se gestiona desde Apariencia > Menus > Footer Menu 2'; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildWidget3Group(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Widget 3 (Menu)'; $html .= '
'; $visible = $this->renderer->getFieldValue($componentId, 'widget_3', 'widget_3_visible', true); $html .= $this->buildSwitch('footerWidget3Visible', 'Mostrar Widget 3', 'bi-eye', $visible); $title = $this->renderer->getFieldValue($componentId, 'widget_3', 'widget_3_title', 'Empresa'); $html .= $this->buildTextInput('footerWidget3Title', 'Titulo', 'bi-type', $title); $html .= '
'; $html .= ' '; $html .= ' El contenido se gestiona desde Apariencia > Menus > Footer Menu 3'; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildNewsletterGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Newsletter'; $html .= '
'; $visible = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_visible', true); $html .= $this->buildSwitch('footerNewsletterVisible', 'Mostrar Newsletter', 'bi-eye', $visible); $title = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_title', 'Suscribete al Newsletter'); $html .= $this->buildTextInput('footerNewsletterTitle', 'Titulo', 'bi-type', $title); $description = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_description', 'Recibe las ultimas actualizaciones.'); $html .= $this->buildTextarea('footerNewsletterDescription', 'Descripcion', 'bi-text-paragraph', $description); $placeholder = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_placeholder', 'Email'); $html .= $this->buildTextInput('footerNewsletterPlaceholder', 'Placeholder email', 'bi-input-cursor', $placeholder); $buttonText = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_button_text', 'Suscribirse'); $html .= $this->buildTextInput('footerNewsletterButtonText', 'Texto boton', 'bi-cursor', $buttonText); $webhookUrl = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_webhook_url', ''); $html .= $this->buildPasswordInput('footerNewsletterWebhookUrl', 'URL del Webhook', 'bi-link-45deg', $webhookUrl); $successMsg = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_success_message', 'Gracias por suscribirte!'); $html .= $this->buildTextInput('footerNewsletterSuccessMessage', 'Mensaje exito', 'bi-check-circle', $successMsg); $errorMsg = $this->renderer->getFieldValue($componentId, 'newsletter', 'newsletter_error_message', 'Error al suscribirse.'); $html .= $this->buildTextInput('footerNewsletterErrorMessage', 'Mensaje error', 'bi-x-circle', $errorMsg); $html .= '
'; $html .= '
'; return $html; } private function buildFooterBottomGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Pie de Footer'; $html .= '
'; $copyright = $this->renderer->getFieldValue($componentId, 'footer_bottom', 'copyright_text', date('Y') . ' Todos los derechos reservados.'); $html .= $this->buildTextInput('footerCopyrightText', 'Texto copyright', 'bi-c-circle', $copyright); $html .= '
'; $html .= ' '; $html .= ' El simbolo © se agrega automaticamente'; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildColorsGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Colores'; $html .= '
'; $bgColor = $this->renderer->getFieldValue($componentId, 'colors', 'bg_color', '#212529'); $html .= $this->buildColorInput('footerBgColor', 'Fondo footer', $bgColor); $textColor = $this->renderer->getFieldValue($componentId, 'colors', 'text_color', '#ffffff'); $html .= $this->buildColorInput('footerTextColor', 'Color texto', $textColor); $titleColor = $this->renderer->getFieldValue($componentId, 'colors', 'title_color', '#ffffff'); $html .= $this->buildColorInput('footerTitleColor', 'Color titulos', $titleColor); $linkColor = $this->renderer->getFieldValue($componentId, 'colors', 'link_color', '#ffffff'); $html .= $this->buildColorInput('footerLinkColor', 'Color links', $linkColor); $linkHoverColor = $this->renderer->getFieldValue($componentId, 'colors', 'link_hover_color', '#FF8600'); $html .= $this->buildColorInput('footerLinkHoverColor', 'Color links hover', $linkHoverColor); $buttonBgColor = $this->renderer->getFieldValue($componentId, 'colors', 'button_bg_color', '#0d6efd'); $html .= $this->buildColorInput('footerButtonBgColor', 'Fondo boton', $buttonBgColor); $buttonTextColor = $this->renderer->getFieldValue($componentId, 'colors', 'button_text_color', '#ffffff'); $html .= $this->buildColorInput('footerButtonTextColor', 'Texto boton', $buttonTextColor); $buttonHoverBg = $this->renderer->getFieldValue($componentId, 'colors', 'button_hover_bg', '#0b5ed7'); $html .= $this->buildColorInput('footerButtonHoverBg', 'Fondo boton hover', $buttonHoverBg); $html .= '
'; $html .= '
'; return $html; } private function buildSpacingGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Espaciado'; $html .= '
'; $paddingY = $this->renderer->getFieldValue($componentId, 'spacing', 'padding_y', '3rem'); $html .= $this->buildTextInput('footerPaddingY', 'Padding vertical', 'bi-arrows-vertical', $paddingY); $marginTop = $this->renderer->getFieldValue($componentId, 'spacing', 'margin_top', '0'); $html .= $this->buildTextInput('footerMarginTop', 'Margen superior', 'bi-arrow-up', $marginTop); $html .= '
'; $html .= '
'; return $html; } private function buildEffectsGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Efectos Visuales'; $html .= '
'; $inputRadius = $this->renderer->getFieldValue($componentId, 'visual_effects', 'input_border_radius', '6px'); $html .= $this->buildTextInput('footerInputBorderRadius', 'Radio input', 'bi-square', $inputRadius); $buttonRadius = $this->renderer->getFieldValue($componentId, 'visual_effects', 'button_border_radius', '6px'); $html .= $this->buildTextInput('footerButtonBorderRadius', 'Radio boton', 'bi-square', $buttonRadius); $transition = $this->renderer->getFieldValue($componentId, 'visual_effects', 'transition_duration', '0.3s'); $html .= $this->buildTextInput('footerTransitionDuration', 'Duracion transicion', 'bi-hourglass', $transition); $html .= '
'; $html .= '
'; return $html; } // Helper methods private function buildSwitch(string $id, string $label, string $icon, $value): string { $checked = $value === true || $value === '1' || $value === 1 ? 'checked' : ''; $html = '
'; $html .= ' '; $html .= ' '; $html .= '
'; return $html; } private function buildTextInput(string $id, string $label, string $icon, mixed $value): string { $value = $this->normalizeStringValue($value); $html = '
'; $html .= ' '; $html .= ' '; $html .= '
'; return $html; } private function buildPasswordInput(string $id, string $label, string $icon, mixed $value): string { $value = $this->normalizeStringValue($value); $html = '
'; $html .= ' '; $html .= ' '; $html .= '
URL oculta por seguridad
'; $html .= '
'; return $html; } private function buildTextarea(string $id, string $label, string $icon, mixed $value): string { $value = $this->normalizeStringValue($value); $html = '
'; $html .= ' '; $html .= ' '; $html .= '
'; return $html; } private function buildColorInput(string $id, string $label, mixed $value): string { $value = $this->normalizeStringValue($value); $html = '
'; $html .= ' '; $html .= ' '; $html .= '
'; return $html; } /** * Normaliza un valor a string para inputs de formulario * * El repositorio convierte '0' a false y '1' a true automáticamente, * pero para campos de texto necesitamos el valor original como string. */ private function normalizeStringValue(mixed $value): string { if ($value === false) { return '0'; } if ($value === true) { return '1'; } return (string) $value; } }