componentId = $componentId;
$this->data = $data;
}
public function build(): string
{
$data = $this->data;
$componentId = $this->componentId;
$html = '
';
$html .= $this->buildFormScripts($componentId);
return $html;
}
private function buildTabsNavigation(): string
{
return <<
HTML;
}
private function buildVisibilityTab(array $data, string $componentId): string
{
$html = '';
$isEnabled = $data['visibility']['is_enabled'] ?? true;
$html .= $this->buildToggle('is_enabled', 'Mostrar hero section', $isEnabled, $componentId, 'visibility');
$showOn = $data['visibility']['show_on_pages'] ?? 'posts';
$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' => 'Tipos de post específicos'], $componentId, 'visibility');
$customPostTypes = $data['visibility']['custom_post_types'] ?? '';
$html .= $this->buildTextField('custom_post_types', 'Tipos de post personalizados', $customPostTypes, $componentId, 'visibility', 'Ej: post,page,producto', ['data-conditional-field' => 'show_on_pages', 'data-conditional-value' => 'custom']);
$html .= '
';
return $html;
}
private function buildCategoriesTab(array $data, string $componentId): string
{
$html = '';
$showCategories = $data['categories']['show_categories'] ?? true;
$html .= $this->buildToggle('show_categories', 'Mostrar badges de categorías', $showCategories, $componentId, 'categories');
$categoriesSource = $data['categories']['categories_source'] ?? 'post_categories';
$html .= $this->buildSelect('categories_source', 'Fuente de categorías', $categoriesSource, ['post_categories' => 'Categorías del post', 'post_tags' => 'Etiquetas del post', 'custom_taxonomy' => 'Taxonomía personalizada', 'custom_list' => 'Lista personalizada'], $componentId, 'categories', ['data-conditional-field' => 'show_categories', 'data-conditional-value' => 'true']);
$customTaxonomy = $data['categories']['custom_taxonomy_name'] ?? '';
$html .= $this->buildTextField('custom_taxonomy_name', 'Nombre de taxonomía personalizada', $customTaxonomy, $componentId, 'categories', 'Ej: project_category', ['data-conditional-field' => 'categories_source', 'data-conditional-value' => 'custom_taxonomy']);
$customList = $data['categories']['custom_categories_list'] ?? '';
$html .= $this->buildTextArea('custom_categories_list', 'Lista personalizada de categorías', $customList, $componentId, 'categories', 'Análisis de Precios|#', 5, ['data-conditional-field' => 'categories_source', 'data-conditional-value' => 'custom_list']);
$maxCategories = $data['categories']['max_categories'] ?? 5;
$html .= $this->buildNumberField('max_categories', 'Máximo de categorías a mostrar', $maxCategories, $componentId, 'categories', 1, 20, ['data-conditional-field' => 'show_categories', 'data-conditional-value' => 'true']);
$categoryIcon = $data['categories']['category_icon'] ?? 'bi-folder-fill';
$html .= $this->buildTextField('category_icon', 'Ícono de categoría', $categoryIcon, $componentId, 'categories', 'Ej: bi-folder-fill', ['data-conditional-field' => 'show_categories', 'data-conditional-value' => 'true']);
$categoriesAlignment = $data['categories']['categories_alignment'] ?? 'center';
$html .= $this->buildSelect('categories_alignment', 'Alineación de categorías', $categoriesAlignment, ['left' => 'Izquierda', 'center' => 'Centro', 'right' => 'Derecha'], $componentId, 'categories', ['data-conditional-field' => 'show_categories', 'data-conditional-value' => 'true']);
$html .= '
';
return $html;
}
private function buildTitleTab(array $data, string $componentId): string
{
$html = '';
$titleSource = $data['title']['title_source'] ?? 'post_title';
$html .= $this->buildSelect('title_source', 'Fuente del título', $titleSource, ['post_title' => 'Título del post', 'custom_field' => 'Campo personalizado', 'custom_text' => 'Texto personalizado'], $componentId, 'title');
$customField = $data['title']['custom_field_name'] ?? '';
$html .= $this->buildTextField('custom_field_name', 'Nombre del campo personalizado', $customField, $componentId, 'title', 'Ej: hero_title', ['data-conditional-field' => 'title_source', 'data-conditional-value' => 'custom_field']);
$customText = $data['title']['custom_text'] ?? '';
$html .= $this->buildTextArea('custom_text', 'Texto personalizado', $customText, $componentId, 'title', '', 3, ['data-conditional-field' => 'title_source', 'data-conditional-value' => 'custom_text']);
$titleTag = $data['title']['title_tag'] ?? 'h1';
$html .= $this->buildSelect('title_tag', 'Etiqueta HTML del título', $titleTag, ['h1' => 'H1', 'h2' => 'H2', 'h3' => 'H3', 'div' => 'DIV'], $componentId, 'title');
$titleClasses = $data['title']['title_classes'] ?? 'display-5 fw-bold';
$html .= $this->buildTextField('title_classes', 'Clases CSS adicionales', $titleClasses, $componentId, 'title', 'Ej: display-5 fw-bold');
$titleAlignment = $data['title']['title_alignment'] ?? 'center';
$html .= $this->buildSelect('title_alignment', 'Alineación del título', $titleAlignment, ['left' => 'Izquierda', 'center' => 'Centro', 'right' => 'Derecha'], $componentId, 'title');
$enableGradient = $data['title']['enable_gradient'] ?? false;
$html .= $this->buildToggle('enable_gradient', 'Activar gradiente en el texto', $enableGradient, $componentId, 'title');
$gradientStart = $data['title']['gradient_color_start'] ?? '#1e3a5f';
$html .= $this->buildColorField('gradient_color_start', 'Color inicial del gradiente', $gradientStart, $componentId, 'title', ['data-conditional-field' => 'enable_gradient', 'data-conditional-value' => 'true']);
$gradientEnd = $data['title']['gradient_color_end'] ?? '#FF8600';
$html .= $this->buildColorField('gradient_color_end', 'Color final del gradiente', $gradientEnd, $componentId, 'title', ['data-conditional-field' => 'enable_gradient', 'data-conditional-value' => 'true']);
$gradientDirection = $data['title']['gradient_direction'] ?? 'to-right';
$html .= $this->buildSelect('gradient_direction', 'Dirección del gradiente', $gradientDirection, ['to-right' => 'Izquierda a derecha', 'to-left' => 'Derecha a izquierda', 'to-bottom' => 'Arriba a abajo', 'to-top' => 'Abajo a arriba', 'diagonal' => 'Diagonal'], $componentId, 'title', ['data-conditional-field' => 'enable_gradient', 'data-conditional-value' => 'true']);
$html .= '
';
return $html;
}
private function buildStylesTab(array $data, string $componentId): string
{
$html = '';
$backgroundType = $data['styles']['background_type'] ?? 'gradient';
$html .= $this->buildSelect('background_type', 'Tipo de fondo', $backgroundType, ['color' => 'Color sólido', 'gradient' => 'Gradiente', 'image' => 'Imagen', 'none' => 'Sin fondo'], $componentId, 'styles');
$bgColor = $data['styles']['background_color'] ?? '#1e3a5f';
$html .= $this->buildColorField('background_color', 'Color de fondo', $bgColor, $componentId, 'styles', ['data-conditional-field' => 'background_type', 'data-conditional-value' => 'color']);
$gradientStart = $data['styles']['gradient_start_color'] ?? '#1e3a5f';
$html .= $this->buildColorField('gradient_start_color', 'Color inicial del gradiente', $gradientStart, $componentId, 'styles', ['data-conditional-field' => 'background_type', 'data-conditional-value' => 'gradient']);
$gradientEnd = $data['styles']['gradient_end_color'] ?? '#2c5282';
$html .= $this->buildColorField('gradient_end_color', 'Color final del gradiente', $gradientEnd, $componentId, 'styles', ['data-conditional-field' => 'background_type', 'data-conditional-value' => 'gradient']);
$gradientAngle = $data['styles']['gradient_angle'] ?? 135;
$html .= $this->buildNumberField('gradient_angle', 'Ángulo del gradiente (grados)', $gradientAngle, $componentId, 'styles', 0, 360, ['data-conditional-field' => 'background_type', 'data-conditional-value' => 'gradient']);
$bgImage = $data['styles']['background_image_url'] ?? '';
$html .= $this->buildMediaField('background_image_url', 'Imagen de fondo', $bgImage, $componentId, 'styles', ['data-conditional-field' => 'background_type', 'data-conditional-value' => 'image']);
$bgOverlay = $data['styles']['background_overlay'] ?? true;
$html .= $this->buildToggle('background_overlay', 'Overlay oscuro sobre imagen', $bgOverlay, $componentId, 'styles', ['data-conditional-field' => 'background_type', 'data-conditional-value' => 'image']);
$overlayOpacity = $data['styles']['overlay_opacity'] ?? 60;
$html .= $this->buildNumberField('overlay_opacity', 'Opacidad del overlay (%)', $overlayOpacity, $componentId, 'styles', 0, 100, ['data-conditional-field' => 'background_overlay', 'data-conditional-value' => 'true']);
$textColor = $data['styles']['text_color'] ?? '#FFFFFF';
$html .= $this->buildColorField('text_color', 'Color del texto', $textColor, $componentId, 'styles');
$padding = $data['styles']['padding_vertical'] ?? 'normal';
$html .= $this->buildSelect('padding_vertical', 'Padding vertical', $padding, ['compact' => 'Compacto (2rem)', 'normal' => 'Normal (3rem)', 'spacious' => 'Espacioso (4rem)', 'extra-spacious' => 'Extra espacioso (5rem)'], $componentId, 'styles');
$margin = $data['styles']['margin_bottom'] ?? 'normal';
$html .= $this->buildSelect('margin_bottom', 'Margen inferior', $margin, ['none' => 'Sin margen', 'small' => 'Pequeño (1rem)', 'normal' => 'Normal (1.5rem)', 'large' => 'Grande (2rem)'], $componentId, 'styles');
$badgeBg = $data['styles']['category_badge_background'] ?? 'rgba(255, 255, 255, 0.2)';
$html .= $this->buildTextField('category_badge_background', 'Fondo de badges', $badgeBg, $componentId, 'styles');
$badgeText = $data['styles']['category_badge_text_color'] ?? '#FFFFFF';
$html .= $this->buildColorField('category_badge_text_color', 'Color del texto de badges', $badgeText, $componentId, 'styles');
$badgeBlur = $data['styles']['category_badge_blur'] ?? true;
$html .= $this->buildToggle('category_badge_blur', 'Efecto blur en badges', $badgeBlur, $componentId, 'styles');
$html .= '
';
return $html;
}
private function buildToggle(string $name, string $label, bool $value, string $componentId, string $group, array $attrs = []): string
{
$fieldId = "roi_{$componentId}_{$group}_{$name}";
$checked = $value ? 'checked' : '';
$attrString = $this->buildAttributesString($attrs);
return sprintf('', esc_attr($fieldId), esc_attr($componentId), esc_attr($group), esc_attr($name), $checked, $attrString, esc_attr($fieldId), esc_html($label));
}
private function buildTextField(string $name, string $label, string $value, string $componentId, string $group, string $placeholder = '', array $attrs = []): string
{
$fieldId = "roi_{$componentId}_{$group}_{$name}";
$attrString = $this->buildAttributesString($attrs);
return sprintf('', esc_attr($fieldId), esc_html($label), esc_attr($fieldId), esc_attr($componentId), esc_attr($group), esc_attr($name), esc_attr($value), esc_attr($placeholder), $attrString);
}
private function buildTextArea(string $name, string $label, string $value, string $componentId, string $group, string $placeholder = '', int $rows = 3, array $attrs = []): string
{
$fieldId = "roi_{$componentId}_{$group}_{$name}";
$attrString = $this->buildAttributesString($attrs);
return sprintf('', esc_attr($fieldId), esc_html($label), esc_attr($fieldId), esc_attr($componentId), esc_attr($group), esc_attr($name), $rows, esc_attr($placeholder), $attrString, esc_textarea($value));
}
private function buildSelect(string $name, string $label, string $value, array $options, string $componentId, string $group, array $attrs = []): string
{
$fieldId = "roi_{$componentId}_{$group}_{$name}";
$attrString = $this->buildAttributesString($attrs);
$html = sprintf('', esc_attr($fieldId), esc_html($label));
$html .= sprintf('
';
return $html;
}
private function buildNumberField(string $name, string $label, $value, string $componentId, string $group, int $min = null, int $max = null, array $attrs = []): string
{
$fieldId = "roi_{$componentId}_{$group}_{$name}";
$attrs['type'] = 'number';
if ($min !== null) $attrs['min'] = $min;
if ($max !== null) $attrs['max'] = $max;
$attrString = $this->buildAttributesString($attrs);
return sprintf('', esc_attr($fieldId), esc_html($label), esc_attr($fieldId), esc_attr($componentId), esc_attr($group), esc_attr($name), esc_attr($value), $attrString);
}
private function buildColorField(string $name, string $label, string $value, string $componentId, string $group, array $attrs = []): string
{
$fieldId = "roi_{$componentId}_{$group}_{$name}";
return sprintf('', esc_attr($fieldId), esc_html($label), esc_attr($fieldId), esc_attr($componentId), esc_attr($group), esc_attr($name), esc_attr($value), esc_attr($value));
}
private function buildMediaField(string $name, string $label, string $value, string $componentId, string $group, array $attrs = []): string
{
$fieldId = "roi_{$componentId}_{$group}_{$name}";
$attrString = $this->buildAttributesString($attrs);
$html = sprintf('';
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;
}
public function getComponentId(): string
{
return $this->componentId;
}
}