Files
roi-theme/Admin/Infrastructure/Ui/AdminDashboardRenderer.php
FrankZamora f52a395e0d feat(admin): Add theme-settings component for global configurations
- Add Schemas/theme-settings.json with analytics and custom_code groups
- Add ThemeSettingsFormBuilder for Admin Panel UI
- Add ThemeSettingsFieldMapper for AJAX field mapping
- Add ThemeSettingsRenderer for injecting GA/CSS/JS
- Add ThemeSettingsInjector for wp_head/wp_footer hooks
- Register component in AdminDashboardRenderer::getComponents()
- Register FieldMapper in FieldMapperProvider

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 21:58:14 -06:00

166 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
namespace ROITheme\Admin\Infrastructure\Ui;
use ROITheme\Admin\Domain\Contracts\DashboardRendererInterface;
use ROITheme\Shared\Application\UseCases\GetComponentSettings\GetComponentSettingsUseCase;
/**
* Renderiza el dashboard del panel de administración
*
* Infrastructure - Implementación con WordPress
*/
final class AdminDashboardRenderer implements DashboardRendererInterface
{
private const SUPPORTED_VIEWS = ['dashboard'];
/**
* @param GetComponentSettingsUseCase|null $getComponentSettingsUseCase
* @param array<string, mixed> $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<string, array<string, string>>
*/
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',
],
];
}
/**
* Obtiene las configuraciones de un componente
*
* @param string $componentName Nombre del componente
* @return array<string, array<string, mixed>> 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";
}
}