- HeroSectionRenderer: namespace herosection → HeroSection (PascalCase) - TopNotificationBarFormBuilder: namespace UI → Ui - TopNotificationBarRenderer: @package docblock corregido - LegacyDBManagerAdapter: ROITheme\Component → ROITheme\Shared - LegacyDBManagerAdapter: ROITheme\Domain\Component → ROITheme\Shared\Domain\Entities - functions-addon: actualizada referencia a HeroSectionRenderer 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
698 lines
24 KiB
PHP
698 lines
24 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace ROITheme\Shared\Infrastructure\Ui;
|
|
|
|
use ROITheme\Shared\Domain\Entities\Component;
|
|
use ROITheme\Shared\Domain\Contracts\FormBuilderInterface;
|
|
|
|
/**
|
|
* TopNotificationBarFormBuilder - Construye formulario de configuración
|
|
*
|
|
* RESPONSABILIDAD: Generar formulario HTML del admin para Top Notification Bar
|
|
*
|
|
* CARACTERÍSTICAS:
|
|
* - 3 secciones: Visibilidad, Contenido, Estilos
|
|
* - 19 campos configurables
|
|
* - Lógica condicional (data-conditional-field)
|
|
* - WordPress Media Library integration
|
|
* - Vista previa en tiempo real
|
|
*
|
|
* @package ROITheme\Shared\Infrastructure\Ui
|
|
*/
|
|
final class TopNotificationBarFormBuilder implements FormBuilderInterface
|
|
{
|
|
public function build(Component $component): string
|
|
{
|
|
$data = $component->getData();
|
|
$componentId = $component->getName();
|
|
|
|
$html = '<div class="roi-form-builder roi-top-notification-bar-form">';
|
|
|
|
// Sección de Visibilidad
|
|
$html .= $this->buildVisibilitySection($data, $componentId);
|
|
|
|
// Sección de Contenido
|
|
$html .= $this->buildContentSection($data, $componentId);
|
|
|
|
// Sección de Estilos
|
|
$html .= $this->buildStylesSection($data, $componentId);
|
|
|
|
// Vista previa
|
|
$html .= $this->buildPreviewSection($data);
|
|
|
|
$html .= '</div>';
|
|
|
|
// Agregar scripts de formulario
|
|
$html .= $this->buildFormScripts($componentId);
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildVisibilitySection(array $data, string $componentId): string
|
|
{
|
|
$html = '<div class="roi-form-section" data-section="visibility">';
|
|
$html .= '<h3 class="roi-form-section-title">Visibilidad</h3>';
|
|
$html .= '<div class="roi-form-section-content">';
|
|
|
|
// Is Enabled
|
|
$isEnabled = $data['visibility']['is_enabled'] ?? true;
|
|
$html .= $this->buildToggle(
|
|
'is_enabled',
|
|
'Mostrar barra de notificación',
|
|
$isEnabled,
|
|
$componentId,
|
|
'Activa o desactiva la barra de notificación superior'
|
|
);
|
|
|
|
// Show On Pages
|
|
$showOn = $data['visibility']['show_on_pages'] ?? 'all';
|
|
$html .= $this->buildSelect(
|
|
'show_on_pages',
|
|
'Mostrar en',
|
|
$showOn,
|
|
[
|
|
'all' => 'Todas las páginas',
|
|
'home' => 'Solo página de inicio',
|
|
'posts' => 'Solo posts individuales',
|
|
'pages' => 'Solo páginas',
|
|
'custom' => 'Páginas específicas'
|
|
],
|
|
$componentId,
|
|
'Define en qué páginas se mostrará la barra'
|
|
);
|
|
|
|
// Custom Page IDs
|
|
$customPageIds = $data['visibility']['custom_page_ids'] ?? '';
|
|
$html .= $this->buildTextField(
|
|
'custom_page_ids',
|
|
'IDs de páginas específicas',
|
|
$customPageIds,
|
|
$componentId,
|
|
'IDs de páginas separados por comas',
|
|
'Ej: 1,5,10',
|
|
['data-conditional-field' => 'show_on_pages', 'data-conditional-value' => 'custom']
|
|
);
|
|
|
|
// Hide On Mobile
|
|
$hideOnMobile = $data['visibility']['hide_on_mobile'] ?? false;
|
|
$html .= $this->buildToggle(
|
|
'hide_on_mobile',
|
|
'Ocultar en dispositivos móviles',
|
|
$hideOnMobile,
|
|
$componentId,
|
|
'Oculta la barra en pantallas menores a 768px'
|
|
);
|
|
|
|
// Is Dismissible
|
|
$isDismissible = $data['visibility']['is_dismissible'] ?? false;
|
|
$html .= $this->buildToggle(
|
|
'is_dismissible',
|
|
'Permitir cerrar',
|
|
$isDismissible,
|
|
$componentId,
|
|
'Agrega botón X para que el usuario pueda cerrar la barra'
|
|
);
|
|
|
|
// Dismissible Cookie Days
|
|
$cookieDays = $data['visibility']['dismissible_cookie_days'] ?? 7;
|
|
$html .= $this->buildNumberField(
|
|
'dismissible_cookie_days',
|
|
'Días antes de volver a mostrar',
|
|
$cookieDays,
|
|
$componentId,
|
|
'Días que permanece oculta después de cerrarla',
|
|
1,
|
|
365,
|
|
['data-conditional-field' => 'is_dismissible', 'data-conditional-value' => 'true']
|
|
);
|
|
|
|
$html .= '</div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildContentSection(array $data, string $componentId): string
|
|
{
|
|
$html = '<div class="roi-form-section" data-section="content">';
|
|
$html .= '<h3 class="roi-form-section-title">Contenido</h3>';
|
|
$html .= '<div class="roi-form-section-content">';
|
|
|
|
// Icon Type
|
|
$iconType = $data['content']['icon_type'] ?? 'bootstrap';
|
|
$html .= $this->buildSelect(
|
|
'icon_type',
|
|
'Tipo de ícono',
|
|
$iconType,
|
|
[
|
|
'bootstrap' => 'Bootstrap Icons',
|
|
'custom' => 'Imagen personalizada',
|
|
'none' => 'Sin ícono'
|
|
],
|
|
$componentId,
|
|
'Selecciona el tipo de ícono a mostrar'
|
|
);
|
|
|
|
// Bootstrap Icon
|
|
$bootstrapIcon = $data['content']['bootstrap_icon'] ?? 'bi-megaphone-fill';
|
|
$html .= $this->buildTextField(
|
|
'bootstrap_icon',
|
|
'Clase de ícono Bootstrap',
|
|
$bootstrapIcon,
|
|
$componentId,
|
|
'Nombre de la clase del ícono sin el prefijo \'bi\' (ej: megaphone-fill)',
|
|
'Ej: bi-megaphone-fill',
|
|
['data-conditional-field' => 'icon_type', 'data-conditional-value' => 'bootstrap']
|
|
);
|
|
|
|
// Custom Icon URL
|
|
$customIconUrl = $data['content']['custom_icon_url'] ?? '';
|
|
$html .= $this->buildMediaField(
|
|
'custom_icon_url',
|
|
'Imagen personalizada',
|
|
$customIconUrl,
|
|
$componentId,
|
|
'Sube una imagen personalizada (recomendado: PNG 24x24px)',
|
|
['data-conditional-field' => 'icon_type', 'data-conditional-value' => 'custom']
|
|
);
|
|
|
|
// Announcement Label
|
|
$announcementLabel = $data['content']['announcement_label'] ?? 'Nuevo:';
|
|
$html .= $this->buildTextField(
|
|
'announcement_label',
|
|
'Etiqueta del anuncio',
|
|
$announcementLabel,
|
|
$componentId,
|
|
'Texto destacado en negrita antes del mensaje',
|
|
'Ej: Nuevo:, Importante:, Aviso:'
|
|
);
|
|
|
|
// Announcement Text
|
|
$announcementText = $data['content']['announcement_text'] ?? 'Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.';
|
|
$html .= $this->buildTextArea(
|
|
'announcement_text',
|
|
'Texto del anuncio',
|
|
$announcementText,
|
|
$componentId,
|
|
'Mensaje principal del anuncio (máximo 200 caracteres)',
|
|
3
|
|
);
|
|
|
|
// Link Enabled
|
|
$linkEnabled = $data['content']['link_enabled'] ?? true;
|
|
$html .= $this->buildToggle(
|
|
'link_enabled',
|
|
'Mostrar enlace',
|
|
$linkEnabled,
|
|
$componentId,
|
|
'Activa o desactiva el enlace de acción'
|
|
);
|
|
|
|
// Link Text
|
|
$linkText = $data['content']['link_text'] ?? 'Ver Catálogo';
|
|
$html .= $this->buildTextField(
|
|
'link_text',
|
|
'Texto del enlace',
|
|
$linkText,
|
|
$componentId,
|
|
'Texto del enlace de acción',
|
|
'',
|
|
['data-conditional-field' => 'link_enabled', 'data-conditional-value' => 'true']
|
|
);
|
|
|
|
// Link URL
|
|
$linkUrl = $data['content']['link_url'] ?? '#';
|
|
$html .= $this->buildUrlField(
|
|
'link_url',
|
|
'URL del enlace',
|
|
$linkUrl,
|
|
$componentId,
|
|
'URL de destino del enlace',
|
|
'https://',
|
|
['data-conditional-field' => 'link_enabled', 'data-conditional-value' => 'true']
|
|
);
|
|
|
|
// Link Target
|
|
$linkTarget = $data['content']['link_target'] ?? '_self';
|
|
$html .= $this->buildSelect(
|
|
'link_target',
|
|
'Abrir enlace en',
|
|
$linkTarget,
|
|
[
|
|
'_self' => 'Misma ventana',
|
|
'_blank' => 'Nueva ventana'
|
|
],
|
|
$componentId,
|
|
'Define cómo se abrirá el enlace',
|
|
['data-conditional-field' => 'link_enabled', 'data-conditional-value' => 'true']
|
|
);
|
|
|
|
$html .= '</div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildStylesSection(array $data, string $componentId): string
|
|
{
|
|
$html = '<div class="roi-form-section" data-section="styles">';
|
|
$html .= '<h3 class="roi-form-section-title">Estilos</h3>';
|
|
$html .= '<div class="roi-form-section-content">';
|
|
|
|
// Background Color
|
|
$bgColor = $data['styles']['background_color'] ?? '#FF8600';
|
|
$html .= $this->buildColorField(
|
|
'background_color',
|
|
'Color de fondo',
|
|
$bgColor,
|
|
$componentId,
|
|
'Color de fondo de la barra (por defecto: orange primary)'
|
|
);
|
|
|
|
// Text Color
|
|
$textColor = $data['styles']['text_color'] ?? '#FFFFFF';
|
|
$html .= $this->buildColorField(
|
|
'text_color',
|
|
'Color del texto',
|
|
$textColor,
|
|
$componentId,
|
|
'Color del texto del anuncio'
|
|
);
|
|
|
|
// Link Color
|
|
$linkColor = $data['styles']['link_color'] ?? '#FFFFFF';
|
|
$html .= $this->buildColorField(
|
|
'link_color',
|
|
'Color del enlace',
|
|
$linkColor,
|
|
$componentId,
|
|
'Color del enlace de acción'
|
|
);
|
|
|
|
// Font Size
|
|
$fontSize = $data['styles']['font_size'] ?? 'small';
|
|
$html .= $this->buildSelect(
|
|
'font_size',
|
|
'Tamaño de fuente',
|
|
$fontSize,
|
|
[
|
|
'extra-small' => 'Muy pequeño (0.75rem)',
|
|
'small' => 'Pequeño (0.875rem)',
|
|
'normal' => 'Normal (1rem)',
|
|
'large' => 'Grande (1.125rem)'
|
|
],
|
|
$componentId,
|
|
'Tamaño del texto del anuncio'
|
|
);
|
|
|
|
// Padding Vertical
|
|
$padding = $data['styles']['padding_vertical'] ?? 'normal';
|
|
$html .= $this->buildSelect(
|
|
'padding_vertical',
|
|
'Padding vertical',
|
|
$padding,
|
|
[
|
|
'compact' => 'Compacto (0.5rem)',
|
|
'normal' => 'Normal (0.75rem)',
|
|
'spacious' => 'Espacioso (1rem)'
|
|
],
|
|
$componentId,
|
|
'Espaciado vertical interno de la barra'
|
|
);
|
|
|
|
// Text Alignment
|
|
$alignment = $data['styles']['text_alignment'] ?? 'center';
|
|
$html .= $this->buildSelect(
|
|
'text_alignment',
|
|
'Alineación del texto',
|
|
$alignment,
|
|
[
|
|
'left' => 'Izquierda',
|
|
'center' => 'Centro',
|
|
'right' => 'Derecha'
|
|
],
|
|
$componentId,
|
|
'Alineación del contenido de la barra'
|
|
);
|
|
|
|
// Animation Enabled
|
|
$animationEnabled = $data['styles']['animation_enabled'] ?? false;
|
|
$html .= $this->buildToggle(
|
|
'animation_enabled',
|
|
'Activar animación',
|
|
$animationEnabled,
|
|
$componentId,
|
|
'Activa animación de entrada al cargar la página'
|
|
);
|
|
|
|
// Animation Type
|
|
$animationType = $data['styles']['animation_type'] ?? 'slide-down';
|
|
$html .= $this->buildSelect(
|
|
'animation_type',
|
|
'Tipo de animación',
|
|
$animationType,
|
|
[
|
|
'slide-down' => 'Deslizar desde arriba',
|
|
'fade-in' => 'Aparecer gradualmente'
|
|
],
|
|
$componentId,
|
|
'Tipo de animación de entrada',
|
|
['data-conditional-field' => 'animation_enabled', 'data-conditional-value' => 'true']
|
|
);
|
|
|
|
$html .= '</div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildPreviewSection(array $data): string
|
|
{
|
|
$html = '<div class="roi-form-section roi-preview-section">';
|
|
$html .= '<h3 class="roi-form-section-title">Vista Previa</h3>';
|
|
$html .= '<div class="roi-form-section-content">';
|
|
$html .= '<div id="roi-component-preview" class="border rounded p-3 bg-light">';
|
|
$html .= '<p class="text-muted">La vista previa se actualizará automáticamente al modificar los campos.</p>';
|
|
$html .= '</div>';
|
|
$html .= '</div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildToggle(string $name, string $label, bool $value, string $componentId, string $description = ''): string
|
|
{
|
|
$fieldId = "roi_{$componentId}_{$name}";
|
|
$checked = $value ? 'checked' : '';
|
|
|
|
$html = '<div class="roi-form-field roi-form-field-toggle mb-3">';
|
|
$html .= '<div class="form-check form-switch">';
|
|
$html .= sprintf(
|
|
'<input type="checkbox" class="form-check-input" id="%s" name="roi_component[%s][%s]" value="1" %s>',
|
|
esc_attr($fieldId),
|
|
esc_attr($componentId),
|
|
esc_attr($name),
|
|
$checked
|
|
);
|
|
$html .= sprintf('<label class="form-check-label" for="%s">%s</label>', esc_attr($fieldId), esc_html($label));
|
|
$html .= '</div>';
|
|
if (!empty($description)) {
|
|
$html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildTextField(string $name, string $label, string $value, string $componentId, string $description = '', string $placeholder = '', array $attrs = []): string
|
|
{
|
|
$fieldId = "roi_{$componentId}_{$name}";
|
|
|
|
$html = '<div class="roi-form-field roi-form-field-text mb-3">';
|
|
$html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
|
|
|
|
$attrString = $this->buildAttributesString($attrs);
|
|
|
|
$html .= sprintf(
|
|
'<input type="text" class="form-control" id="%s" name="roi_component[%s][%s]" value="%s" placeholder="%s"%s>',
|
|
esc_attr($fieldId),
|
|
esc_attr($componentId),
|
|
esc_attr($name),
|
|
esc_attr($value),
|
|
esc_attr($placeholder),
|
|
$attrString
|
|
);
|
|
|
|
if (!empty($description)) {
|
|
$html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildTextArea(string $name, string $label, string $value, string $componentId, string $description = '', int $rows = 3, array $attrs = []): string
|
|
{
|
|
$fieldId = "roi_{$componentId}_{$name}";
|
|
|
|
$html = '<div class="roi-form-field roi-form-field-textarea mb-3">';
|
|
$html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
|
|
|
|
$attrString = $this->buildAttributesString($attrs);
|
|
|
|
$html .= sprintf(
|
|
'<textarea class="form-control" id="%s" name="roi_component[%s][%s]" rows="%d"%s>%s</textarea>',
|
|
esc_attr($fieldId),
|
|
esc_attr($componentId),
|
|
esc_attr($name),
|
|
$rows,
|
|
$attrString,
|
|
esc_textarea($value)
|
|
);
|
|
|
|
if (!empty($description)) {
|
|
$html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildSelect(string $name, string $label, string $value, array $options, string $componentId, string $description = '', array $attrs = []): string
|
|
{
|
|
$fieldId = "roi_{$componentId}_{$name}";
|
|
|
|
$html = '<div class="roi-form-field roi-form-field-select mb-3">';
|
|
$html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
|
|
|
|
$attrString = $this->buildAttributesString($attrs);
|
|
|
|
$html .= sprintf(
|
|
'<select class="form-select" id="%s" name="roi_component[%s][%s]"%s>',
|
|
esc_attr($fieldId),
|
|
esc_attr($componentId),
|
|
esc_attr($name),
|
|
$attrString
|
|
);
|
|
|
|
foreach ($options as $optValue => $optLabel) {
|
|
$selected = ($value === $optValue) ? 'selected' : '';
|
|
$html .= sprintf(
|
|
'<option value="%s" %s>%s</option>',
|
|
esc_attr($optValue),
|
|
$selected,
|
|
esc_html($optLabel)
|
|
);
|
|
}
|
|
|
|
$html .= '</select>';
|
|
|
|
if (!empty($description)) {
|
|
$html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildNumberField(string $name, string $label, $value, string $componentId, string $description = '', int $min = null, int $max = null, array $attrs = []): string
|
|
{
|
|
$fieldId = "roi_{$componentId}_{$name}";
|
|
|
|
$html = '<div class="roi-form-field roi-form-field-number mb-3">';
|
|
$html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
|
|
|
|
$attrs['type'] = 'number';
|
|
if ($min !== null) {
|
|
$attrs['min'] = $min;
|
|
}
|
|
if ($max !== null) {
|
|
$attrs['max'] = $max;
|
|
}
|
|
|
|
$attrString = $this->buildAttributesString($attrs);
|
|
|
|
$html .= sprintf(
|
|
'<input class="form-control" id="%s" name="roi_component[%s][%s]" value="%s"%s>',
|
|
esc_attr($fieldId),
|
|
esc_attr($componentId),
|
|
esc_attr($name),
|
|
esc_attr($value),
|
|
$attrString
|
|
);
|
|
|
|
if (!empty($description)) {
|
|
$html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildUrlField(string $name, string $label, string $value, string $componentId, string $description = '', string $placeholder = '', array $attrs = []): string
|
|
{
|
|
$attrs['type'] = 'url';
|
|
return $this->buildTextField($name, $label, $value, $componentId, $description, $placeholder, $attrs);
|
|
}
|
|
|
|
private function buildColorField(string $name, string $label, string $value, string $componentId, string $description = ''): string
|
|
{
|
|
$fieldId = "roi_{$componentId}_{$name}";
|
|
|
|
$html = '<div class="roi-form-field roi-form-field-color mb-3">';
|
|
$html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
|
|
$html .= '<div class="input-group">';
|
|
$html .= sprintf(
|
|
'<input type="color" class="form-control form-control-color" id="%s" name="roi_component[%s][%s]" value="%s">',
|
|
esc_attr($fieldId),
|
|
esc_attr($componentId),
|
|
esc_attr($name),
|
|
esc_attr($value)
|
|
);
|
|
$html .= sprintf(
|
|
'<input type="text" class="form-control" value="%s" readonly>',
|
|
esc_attr($value)
|
|
);
|
|
$html .= '</div>';
|
|
if (!empty($description)) {
|
|
$html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildMediaField(string $name, string $label, string $value, string $componentId, string $description = '', array $attrs = []): string
|
|
{
|
|
$fieldId = "roi_{$componentId}_{$name}";
|
|
|
|
$html = '<div class="roi-form-field roi-form-field-media mb-3">';
|
|
$html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
|
|
$html .= '<div class="input-group">';
|
|
|
|
$attrString = $this->buildAttributesString($attrs);
|
|
|
|
$html .= sprintf(
|
|
'<input type="text" class="form-control" id="%s" name="roi_component[%s][%s]" value="%s" readonly%s>',
|
|
esc_attr($fieldId),
|
|
esc_attr($componentId),
|
|
esc_attr($name),
|
|
esc_attr($value),
|
|
$attrString
|
|
);
|
|
$html .= sprintf(
|
|
'<button type="button" class="btn btn-primary roi-media-upload-btn" data-target="%s">Seleccionar</button>',
|
|
esc_attr($fieldId)
|
|
);
|
|
$html .= '</div>';
|
|
|
|
if (!empty($value)) {
|
|
$html .= sprintf('<div class="mt-2"><img src="%s" alt="Preview" style="max-width: 100px; height: auto;"></div>', esc_url($value));
|
|
}
|
|
|
|
if (!empty($description)) {
|
|
$html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
|
|
}
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildAttributesString(array $attrs): string
|
|
{
|
|
$attrString = '';
|
|
foreach ($attrs as $key => $value) {
|
|
$attrString .= sprintf(' %s="%s"', esc_attr($key), esc_attr($value));
|
|
}
|
|
return $attrString;
|
|
}
|
|
|
|
private function buildFormScripts(string $componentId): string
|
|
{
|
|
return <<<SCRIPT
|
|
<script>
|
|
(function($) {
|
|
'use strict';
|
|
|
|
$(document).ready(function() {
|
|
// Conditional logic
|
|
$('[data-conditional-field]').each(function() {
|
|
const field = $(this);
|
|
const targetFieldName = field.data('conditional-field');
|
|
const targetValue = field.data('conditional-value');
|
|
const targetField = $('[name*="[' + targetFieldName + ']"]');
|
|
|
|
function updateVisibility() {
|
|
let currentValue;
|
|
if (targetField.is(':checkbox')) {
|
|
currentValue = targetField.is(':checked') ? 'true' : 'false';
|
|
} else {
|
|
currentValue = targetField.val();
|
|
}
|
|
|
|
if (currentValue === targetValue) {
|
|
field.closest('.roi-form-field').show();
|
|
} else {
|
|
field.closest('.roi-form-field').hide();
|
|
}
|
|
}
|
|
|
|
targetField.on('change', updateVisibility);
|
|
updateVisibility();
|
|
});
|
|
|
|
// Media upload
|
|
$('.roi-media-upload-btn').on('click', function(e) {
|
|
e.preventDefault();
|
|
const button = $(this);
|
|
const targetId = button.data('target');
|
|
const targetField = $('#' + targetId);
|
|
|
|
const mediaUploader = wp.media({
|
|
title: 'Seleccionar imagen',
|
|
button: { text: 'Usar esta imagen' },
|
|
multiple: false
|
|
});
|
|
|
|
mediaUploader.on('select', function() {
|
|
const attachment = mediaUploader.state().get('selection').first().toJSON();
|
|
targetField.val(attachment.url);
|
|
|
|
const preview = targetField.closest('.roi-form-field-media').find('img');
|
|
if (preview.length) {
|
|
preview.attr('src', attachment.url);
|
|
} else {
|
|
targetField.closest('.input-group').after('<div class="mt-2"><img src="' + attachment.url + '" alt="Preview" style="max-width: 100px; height: auto;"></div>');
|
|
}
|
|
});
|
|
|
|
mediaUploader.open();
|
|
});
|
|
|
|
// Color picker sync
|
|
$('.form-control-color').on('change', function() {
|
|
$(this).next('input[type="text"]').val($(this).val());
|
|
});
|
|
|
|
// Auto-update preview
|
|
$('.roi-form-field input, .roi-form-field select, .roi-form-field textarea').on('change keyup', function() {
|
|
updatePreview();
|
|
});
|
|
|
|
function updatePreview() {
|
|
// Aquí iría la lógica para actualizar la vista previa en tiempo real
|
|
console.log('Preview updated');
|
|
}
|
|
});
|
|
})(jQuery);
|
|
</script>
|
|
SCRIPT;
|
|
}
|
|
|
|
public function supports(string $componentType): bool
|
|
{
|
|
return $componentType === 'top-notification-bar';
|
|
}
|
|
}
|