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>
441 lines
22 KiB
PHP
441 lines
22 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace ROITheme\Admin\CtaPost\Infrastructure\Ui;
|
|
|
|
use ROITheme\Admin\Infrastructure\Ui\AdminDashboardRenderer;
|
|
|
|
/**
|
|
* FormBuilder para CTA Post
|
|
*
|
|
* @package ROITheme\Admin\CtaPost\Infrastructure\Ui
|
|
*/
|
|
final class CtaPostFormBuilder
|
|
{
|
|
public function __construct(
|
|
private AdminDashboardRenderer $renderer
|
|
) {}
|
|
|
|
public function buildForm(string $componentId): string
|
|
{
|
|
$html = '';
|
|
|
|
$html .= $this->buildHeader($componentId);
|
|
|
|
$html .= '<div class="row g-3">';
|
|
|
|
// Columna izquierda
|
|
$html .= '<div class="col-lg-6">';
|
|
$html .= $this->buildVisibilityGroup($componentId);
|
|
$html .= $this->buildContentGroup($componentId);
|
|
$html .= $this->buildTypographyGroup($componentId);
|
|
$html .= '</div>';
|
|
|
|
// Columna derecha
|
|
$html .= '<div class="col-lg-6">';
|
|
$html .= $this->buildColorsGroup($componentId);
|
|
$html .= $this->buildSpacingGroup($componentId);
|
|
$html .= $this->buildEffectsGroup($componentId);
|
|
$html .= '</div>';
|
|
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildHeader(string $componentId): string
|
|
{
|
|
$html = '<div class="rounded p-4 mb-4 shadow text-white" ';
|
|
$html .= 'style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%); border-left: 4px solid #FF8600;">';
|
|
$html .= ' <div class="d-flex align-items-center justify-content-between flex-wrap gap-3">';
|
|
$html .= ' <div>';
|
|
$html .= ' <h3 class="h4 mb-1 fw-bold">';
|
|
$html .= ' <i class="bi bi-megaphone-fill me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Configuracion de CTA Post';
|
|
$html .= ' </h3>';
|
|
$html .= ' <p class="mb-0 small" style="opacity: 0.85;">';
|
|
$html .= ' CTA promocional debajo del contenido del post';
|
|
$html .= ' </p>';
|
|
$html .= ' </div>';
|
|
$html .= ' <button type="button" class="btn btn-sm btn-outline-light btn-reset-defaults" data-component="cta-post">';
|
|
$html .= ' <i class="bi bi-arrow-counterclockwise me-1"></i>';
|
|
$html .= ' Restaurar valores por defecto';
|
|
$html .= ' </button>';
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildVisibilityGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-toggle-on me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Visibilidad';
|
|
$html .= ' </h5>';
|
|
|
|
$enabled = $this->renderer->getFieldValue($componentId, 'visibility', 'is_enabled', true);
|
|
$html .= $this->buildSwitch('ctaPostEnabled', 'Activar componente', 'bi-power', $enabled);
|
|
|
|
$showOnDesktop = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_desktop', true);
|
|
$html .= $this->buildSwitch('ctaPostShowOnDesktop', 'Mostrar en escritorio', 'bi-display', $showOnDesktop);
|
|
|
|
$showOnMobile = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_mobile', true);
|
|
$html .= $this->buildSwitch('ctaPostShowOnMobile', 'Mostrar en movil', 'bi-phone', $showOnMobile);
|
|
|
|
$showOnPages = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_pages', 'posts');
|
|
$html .= ' <div class="mb-0 mt-3">';
|
|
$html .= ' <label for="ctaPostShowOnPages" class="form-label small mb-1 fw-semibold">';
|
|
$html .= ' <i class="bi bi-file-earmark-text me-1" style="color: #FF8600;"></i>';
|
|
$html .= ' Mostrar en';
|
|
$html .= ' </label>';
|
|
$html .= ' <select id="ctaPostShowOnPages" class="form-select form-select-sm">';
|
|
$html .= ' <option value="all"' . ($showOnPages === 'all' ? ' selected' : '') . '>Todos</option>';
|
|
$html .= ' <option value="posts"' . ($showOnPages === 'posts' ? ' selected' : '') . '>Solo posts</option>';
|
|
$html .= ' <option value="pages"' . ($showOnPages === 'pages' ? ' selected' : '') . '>Solo paginas</option>';
|
|
$html .= ' </select>';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildContentGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-card-text me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Contenido';
|
|
$html .= ' </h5>';
|
|
|
|
// Title
|
|
$title = $this->renderer->getFieldValue($componentId, 'content', 'title', 'Accede a 200,000+ Analisis de Precios Unitarios');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="ctaPostTitle" class="form-label small mb-1 fw-semibold">Titulo</label>';
|
|
$html .= ' <input type="text" id="ctaPostTitle" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($title) . '">';
|
|
$html .= ' </div>';
|
|
|
|
// Description
|
|
$description = $this->renderer->getFieldValue($componentId, 'content', 'description', '');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="ctaPostDescription" class="form-label small mb-1 fw-semibold">Descripcion</label>';
|
|
$html .= ' <textarea id="ctaPostDescription" class="form-control form-control-sm" rows="3">';
|
|
$html .= esc_textarea($description);
|
|
$html .= '</textarea>';
|
|
$html .= ' </div>';
|
|
|
|
// Button Text
|
|
$buttonText = $this->renderer->getFieldValue($componentId, 'content', 'button_text', 'Ver Catalogo Completo');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="ctaPostButtonText" class="form-label small mb-1 fw-semibold">Texto del boton</label>';
|
|
$html .= ' <input type="text" id="ctaPostButtonText" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($buttonText) . '">';
|
|
$html .= ' </div>';
|
|
|
|
// Button URL
|
|
$buttonUrl = $this->renderer->getFieldValue($componentId, 'content', 'button_url', '/catalogo');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="ctaPostButtonUrl" class="form-label small mb-1 fw-semibold">URL del boton</label>';
|
|
$html .= ' <input type="text" id="ctaPostButtonUrl" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($buttonUrl) . '">';
|
|
$html .= ' </div>';
|
|
|
|
// Button Icon
|
|
$buttonIcon = $this->renderer->getFieldValue($componentId, 'content', 'button_icon', 'bi-arrow-right');
|
|
$html .= ' <div class="mb-0">';
|
|
$html .= ' <label for="ctaPostButtonIcon" class="form-label small mb-1 fw-semibold">Icono del boton</label>';
|
|
$html .= ' <input type="text" id="ctaPostButtonIcon" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($buttonIcon) . '" placeholder="bi-arrow-right">';
|
|
$html .= ' <small class="text-muted">Clase de Bootstrap Icons</small>';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildTypographyGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-fonts me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Tipografia';
|
|
$html .= ' </h5>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$titleFontSize = $this->renderer->getFieldValue($componentId, 'typography', 'title_font_size', '1.5rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostTitleFontSize" class="form-label small mb-1 fw-semibold">Tamano titulo</label>';
|
|
$html .= ' <input type="text" id="ctaPostTitleFontSize" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($titleFontSize) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$titleFontWeight = $this->renderer->getFieldValue($componentId, 'typography', 'title_font_weight', '700');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostTitleFontWeight" class="form-label small mb-1 fw-semibold">Peso titulo</label>';
|
|
$html .= ' <input type="text" id="ctaPostTitleFontWeight" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($titleFontWeight) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-0">';
|
|
|
|
$descFontSize = $this->renderer->getFieldValue($componentId, 'typography', 'description_font_size', '1rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostDescFontSize" class="form-label small mb-1 fw-semibold">Tamano descripcion</label>';
|
|
$html .= ' <input type="text" id="ctaPostDescFontSize" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($descFontSize) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$buttonFontSize = $this->renderer->getFieldValue($componentId, 'typography', 'button_font_size', '1.125rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostButtonFontSize" class="form-label small mb-1 fw-semibold">Tamano boton</label>';
|
|
$html .= ' <input type="text" id="ctaPostButtonFontSize" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($buttonFontSize) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildColorsGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-palette me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Colores';
|
|
$html .= ' </h5>';
|
|
|
|
// Gradiente
|
|
$html .= ' <p class="small fw-semibold mb-2">Gradiente de fondo</p>';
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$gradientStart = $this->renderer->getFieldValue($componentId, 'colors', 'gradient_start', '#FF8600');
|
|
$html .= $this->buildColorPicker('ctaPostGradientStart', 'Inicio', $gradientStart);
|
|
|
|
$gradientEnd = $this->renderer->getFieldValue($componentId, 'colors', 'gradient_end', '#FFB800');
|
|
$html .= $this->buildColorPicker('ctaPostGradientEnd', 'Fin', $gradientEnd);
|
|
|
|
$html .= ' </div>';
|
|
|
|
// Textos
|
|
$html .= ' <p class="small fw-semibold mb-2">Textos</p>';
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$titleColor = $this->renderer->getFieldValue($componentId, 'colors', 'title_color', '#ffffff');
|
|
$html .= $this->buildColorPicker('ctaPostTitleColor', 'Titulo', $titleColor);
|
|
|
|
$descColor = $this->renderer->getFieldValue($componentId, 'colors', 'description_color', '#ffffff');
|
|
$html .= $this->buildColorPicker('ctaPostDescColor', 'Descripcion', $descColor);
|
|
|
|
$html .= ' </div>';
|
|
|
|
// Boton
|
|
$html .= ' <p class="small fw-semibold mb-2">Boton</p>';
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$buttonBg = $this->renderer->getFieldValue($componentId, 'colors', 'button_bg_color', '#ffffff');
|
|
$html .= $this->buildColorPicker('ctaPostButtonBg', 'Fondo', $buttonBg);
|
|
|
|
$buttonTextColor = $this->renderer->getFieldValue($componentId, 'colors', 'button_text_color', '#212529');
|
|
$html .= $this->buildColorPicker('ctaPostButtonTextColor', 'Texto', $buttonTextColor);
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-0">';
|
|
|
|
$buttonHoverBg = $this->renderer->getFieldValue($componentId, 'colors', 'button_hover_bg', '#f8f9fa');
|
|
$html .= $this->buildColorPicker('ctaPostButtonHoverBg', 'Hover', $buttonHoverBg);
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildSpacingGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-arrows-move me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Espaciado';
|
|
$html .= ' </h5>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$marginTop = $this->renderer->getFieldValue($componentId, 'spacing', 'container_margin_top', '3rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostMarginTop" class="form-label small mb-1 fw-semibold">Margen superior</label>';
|
|
$html .= ' <input type="text" id="ctaPostMarginTop" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($marginTop) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$marginBottom = $this->renderer->getFieldValue($componentId, 'spacing', 'container_margin_bottom', '3rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostMarginBottom" class="form-label small mb-1 fw-semibold">Margen inferior</label>';
|
|
$html .= ' <input type="text" id="ctaPostMarginBottom" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($marginBottom) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-0">';
|
|
|
|
$padding = $this->renderer->getFieldValue($componentId, 'spacing', 'container_padding', '1.5rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostPadding" class="form-label small mb-1 fw-semibold">Padding interno</label>';
|
|
$html .= ' <input type="text" id="ctaPostPadding" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($padding) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$titleMargin = $this->renderer->getFieldValue($componentId, 'spacing', 'title_margin_bottom', '0.5rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostTitleMargin" class="form-label small mb-1 fw-semibold">Margen titulo</label>';
|
|
$html .= ' <input type="text" id="ctaPostTitleMargin" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($titleMargin) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildEffectsGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-magic me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Efectos Visuales';
|
|
$html .= ' </h5>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$borderRadius = $this->renderer->getFieldValue($componentId, 'visual_effects', 'border_radius', '0.375rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostBorderRadius" class="form-label small mb-1 fw-semibold">Radio contenedor</label>';
|
|
$html .= ' <input type="text" id="ctaPostBorderRadius" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($borderRadius) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$gradientAngle = $this->renderer->getFieldValue($componentId, 'visual_effects', 'gradient_angle', '135deg');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostGradientAngle" class="form-label small mb-1 fw-semibold">Angulo gradiente</label>';
|
|
$html .= ' <input type="text" id="ctaPostGradientAngle" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($gradientAngle) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$buttonRadius = $this->renderer->getFieldValue($componentId, 'visual_effects', 'button_border_radius', '0.375rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostButtonRadius" class="form-label small mb-1 fw-semibold">Radio boton</label>';
|
|
$html .= ' <input type="text" id="ctaPostButtonRadius" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($buttonRadius) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$buttonPadding = $this->renderer->getFieldValue($componentId, 'visual_effects', 'button_padding', '0.5rem 1rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostButtonPadding" class="form-label small mb-1 fw-semibold">Padding boton</label>';
|
|
$html .= ' <input type="text" id="ctaPostButtonPadding" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($buttonPadding) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-0">';
|
|
|
|
$transition = $this->renderer->getFieldValue($componentId, 'visual_effects', 'transition_duration', '0.3s');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostTransition" class="form-label small mb-1 fw-semibold">Transicion</label>';
|
|
$html .= ' <input type="text" id="ctaPostTransition" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($transition) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$boxShadow = $this->renderer->getFieldValue($componentId, 'visual_effects', 'box_shadow', 'none');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="ctaPostBoxShadow" class="form-label small mb-1 fw-semibold">Sombra</label>';
|
|
$html .= ' <input type="text" id="ctaPostBoxShadow" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($boxShadow) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildSwitch(string $id, string $label, string $icon, mixed $checked): string
|
|
{
|
|
$checked = $checked === true || $checked === '1' || $checked === 1;
|
|
|
|
$html = ' <div class="mb-2">';
|
|
$html .= ' <div class="form-check form-switch">';
|
|
$html .= sprintf(
|
|
' <input class="form-check-input" type="checkbox" id="%s" %s>',
|
|
esc_attr($id),
|
|
$checked ? 'checked' : ''
|
|
);
|
|
$html .= sprintf(
|
|
' <label class="form-check-label small" for="%s">',
|
|
esc_attr($id)
|
|
);
|
|
$html .= sprintf(' <i class="bi %s me-1" style="color: #FF8600;"></i>', esc_attr($icon));
|
|
$html .= sprintf(' <strong>%s</strong>', esc_html($label));
|
|
$html .= ' </label>';
|
|
$html .= ' </div>';
|
|
$html .= ' </div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildColorPicker(string $id, string $label, string $value): string
|
|
{
|
|
$html = ' <div class="col-6">';
|
|
$html .= sprintf(
|
|
' <label class="form-label small fw-semibold">%s</label>',
|
|
esc_html($label)
|
|
);
|
|
$html .= ' <div class="input-group input-group-sm">';
|
|
$html .= sprintf(
|
|
' <input type="color" class="form-control form-control-color" id="%s" value="%s">',
|
|
esc_attr($id),
|
|
esc_attr($value)
|
|
);
|
|
$html .= sprintf(
|
|
' <span class="input-group-text" id="%sValue">%s</span>',
|
|
esc_attr($id),
|
|
esc_html(strtoupper($value))
|
|
);
|
|
$html .= ' </div>';
|
|
$html .= ' </div>';
|
|
|
|
return $html;
|
|
}
|
|
}
|