$components Componentes disponibles */ public function __construct( private readonly ?GetComponentSettingsUseCase $getComponentSettingsUseCase = null, private readonly ?ComponentGroupRegistry $groupRegistry = null, private readonly array $components = [] ) { } public function render(): string { ob_start(); require __DIR__ . '/Views/dashboard.php'; return ob_get_clean(); } public function supports(string $viewType): bool { return in_array($viewType, self::SUPPORTED_VIEWS, true); } /** * Obtiene los componentes disponibles * * @return array> */ public function getComponents(): array { return [ 'top-notification-bar' => [ 'id' => 'top-notification-bar', 'label' => 'TopBar', 'icon' => 'bi-megaphone-fill', ], 'navbar' => [ 'id' => 'navbar', 'label' => 'Navbar', 'icon' => 'bi-list', ], 'cta-lets-talk' => [ 'id' => 'cta-lets-talk', 'label' => "Let's Talk", 'icon' => 'bi-lightning-charge-fill', ], 'hero' => [ 'id' => 'hero', 'label' => 'Hero Section', 'icon' => 'bi-image', ], 'featured-image' => [ 'id' => 'featured-image', 'label' => 'Featured Image', 'icon' => 'bi-card-image', ], 'table-of-contents' => [ 'id' => 'table-of-contents', 'label' => 'Table of Contents', 'icon' => 'bi-list-nested', ], 'cta-box-sidebar' => [ 'id' => 'cta-box-sidebar', 'label' => 'CTA Sidebar', 'icon' => 'bi-megaphone', ], 'social-share' => [ 'id' => 'social-share', 'label' => 'Social Share', 'icon' => 'bi-share', ], 'cta-post' => [ 'id' => 'cta-post', 'label' => 'CTA Post', 'icon' => 'bi-megaphone-fill', ], 'related-post' => [ 'id' => 'related-post', 'label' => 'Related Posts', 'icon' => 'bi-grid-3x3-gap', ], 'contact-form' => [ 'id' => 'contact-form', 'label' => 'Contact Form', 'icon' => 'bi-envelope-paper', ], 'footer' => [ 'id' => 'footer', 'label' => 'Footer', 'icon' => 'bi-layout-text-window-reverse', ], 'theme-settings' => [ 'id' => 'theme-settings', 'label' => 'Theme Settings', 'icon' => 'bi-gear', ], 'adsense-placement' => [ 'id' => 'adsense-placement', 'label' => 'AdSense', 'icon' => 'bi-megaphone', ], 'custom-css-manager' => [ 'id' => 'custom-css-manager', 'label' => 'CSS Personalizado', 'icon' => 'bi-file-earmark-code', ], ]; } /** * Obtiene las configuraciones de un componente * * @param string $componentName Nombre del componente * @return array> Configuraciones agrupadas por grupo */ public function getComponentSettings(string $componentName): array { if ($this->getComponentSettingsUseCase === null) { return []; } return $this->getComponentSettingsUseCase->execute($componentName); } /** * Obtiene el valor de un campo de configuración * * @param string $componentName Nombre del componente * @param string $groupName Nombre del grupo * @param string $attributeName Nombre del atributo * @param mixed $default Valor por defecto si no existe * @return mixed */ public function getFieldValue(string $componentName, string $groupName, string $attributeName, mixed $default = null): mixed { $settings = $this->getComponentSettings($componentName); return $settings[$groupName][$attributeName] ?? $default; } /** * Obtiene la clase del FormBuilder para un componente * * @param string $componentId ID del componente en kebab-case (ej: 'top-notification-bar') * @return string Namespace completo del FormBuilder */ public function getFormBuilderClass(string $componentId): string { // Mapeo especial para componentes con acrónimos (CSS, API, etc.) $specialMappings = [ 'custom-css-manager' => 'CustomCSSManager', ]; // Usar mapeo especial si existe, sino convertir kebab-case a PascalCase if (isset($specialMappings[$componentId])) { $className = $specialMappings[$componentId]; } else { // 'top-notification-bar' → 'TopNotificationBar' $className = str_replace('-', '', ucwords($componentId, '-')); } // Construir namespace completo // ROITheme\Admin\TopNotificationBar\Infrastructure\Ui\TopNotificationBarFormBuilder return "ROITheme\\Admin\\{$className}\\Infrastructure\\Ui\\{$className}FormBuilder"; } /** * Obtiene los grupos de componentes * * @return array> */ public function getComponentGroups(): array { if ($this->groupRegistry === null) { return []; } return $this->groupRegistry->getGroups(); } /** * Obtiene el grupo al que pertenece un componente * * @param string $componentId ID del componente * @return string|null ID del grupo o null */ public function getGroupForComponent(string $componentId): ?string { if ($this->groupRegistry === null) { return null; } return $this->groupRegistry->getGroupForComponent($componentId); } }