$components Componentes disponibles */ public function __construct( private readonly ?GetComponentSettingsUseCase $getComponentSettingsUseCase = 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', ], ]; } /** * 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 { // Convertir kebab-case a PascalCase // '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"; } }