From f21a0599fc3b8f0f7be02cea5d4d7050d5265aa2 Mon Sep 17 00:00:00 2001 From: Clemens Creutzburg Date: Mon, 30 Mar 2026 18:22:48 +0200 Subject: [PATCH] =?UTF-8?q?Anpassung=20men=C3=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas-app/public/app-support.php | 78 +++++++++++++++++++ saas-app/public/index.php | 27 ++++++- saas-app/public/support/index.php | 3 +- saas-app/public/surveys/index.php | 31 +++++--- saas-app/public/tenants/roles/index.php | 3 +- .../resources/views/layouts/app.blade.php | 29 +++---- .../resources/views/support/index.blade.php | 17 ++-- .../resources/views/tenants/roles.blade.php | 33 ++++---- 8 files changed, 163 insertions(+), 58 deletions(-) diff --git a/saas-app/public/app-support.php b/saas-app/public/app-support.php index f374443..66dfaf6 100644 --- a/saas-app/public/app-support.php +++ b/saas-app/public/app-support.php @@ -2297,9 +2297,76 @@ function app_tenant_settings_defaults(): array 'location_label' => '', 'allow_self_service_booking' => '1', 'payment_hint' => 'Bitte Einzahlungen zeitnah verbuchen.', + 'brand_color' => '#005e3f', + 'brand_strong_color' => '#00452f', + 'accent_color' => '#c18a00', + 'background_color' => '#f4efe4', + 'card_color' => '#fffdf8', ]; } +function app_is_valid_hex_color(string $value): bool +{ + return preg_match('/^#[0-9A-Fa-f]{6}$/', $value) === 1; +} + +/** + * @return array{brand_color:string,brand_strong_color:string,accent_color:string,background_color:string,card_color:string,text_color:string,muted_color:string,brand_rgb:string,accent_rgb:string} + */ +function app_tenant_theme(array $settings): array +{ + $defaults = [ + 'brand_color' => '#005e3f', + 'brand_strong_color' => '#00452f', + 'accent_color' => '#c18a00', + 'background_color' => '#f4efe4', + 'card_color' => '#fffdf8', + 'text_color' => '#25180f', + 'muted_color' => '#63584a', + ]; + + foreach ($defaults as $key => $default) { + $candidate = strtoupper(trim((string) ($settings[$key] ?? $default))); + $defaults[$key] = app_is_valid_hex_color($candidate) ? $candidate : $default; + } + + $brandRgb = sscanf($defaults['brand_color'], '#%02x%02x%02x') ?: [0, 94, 63]; + $accentRgb = sscanf($defaults['accent_color'], '#%02x%02x%02x') ?: [193, 138, 0]; + + return [ + 'brand_color' => $defaults['brand_color'], + 'brand_strong_color' => $defaults['brand_strong_color'], + 'accent_color' => $defaults['accent_color'], + 'background_color' => $defaults['background_color'], + 'card_color' => $defaults['card_color'], + 'text_color' => $defaults['text_color'], + 'muted_color' => $defaults['muted_color'], + 'brand_rgb' => implode(', ', array_map('intval', $brandRgb)), + 'accent_rgb' => implode(', ', array_map('intval', $accentRgb)), + ]; +} + +function app_tenant_theme_root_css(array $settings): string +{ + $theme = app_tenant_theme($settings); + + return implode('', [ + '--bg:', $theme['background_color'], ';', + '--card:', $theme['card_color'], ';', + '--bg-elevated:', $theme['card_color'], ';', + '--bg-soft:', $theme['card_color'], ';', + '--text:', $theme['text_color'], ';', + '--ink:', $theme['text_color'], ';', + '--muted:', $theme['muted_color'], ';', + '--brand:', $theme['brand_color'], ';', + '--brand-2:', $theme['brand_strong_color'], ';', + '--brand-strong:', $theme['brand_strong_color'], ';', + '--accent:', $theme['accent_color'], ';', + '--brand-rgb:', $theme['brand_rgb'], ';', + '--accent-rgb:', $theme['accent_rgb'], ';', + ]); +} + function app_tenant_settings(PDO $pdo, string $tenantId): array { $settings = app_tenant_settings_defaults(); @@ -2331,6 +2398,11 @@ function app_save_tenant_settings(PDO $pdo, string $tenantId, array $data): void 'location_label' => trim((string) ($data['location_label'] ?? '')), 'allow_self_service_booking' => !empty($data['allow_self_service_booking']) ? '1' : '0', 'payment_hint' => trim((string) ($data['payment_hint'] ?? '')), + 'brand_color' => strtoupper(trim((string) ($data['brand_color'] ?? '#005e3f'))), + 'brand_strong_color' => strtoupper(trim((string) ($data['brand_strong_color'] ?? '#00452f'))), + 'accent_color' => strtoupper(trim((string) ($data['accent_color'] ?? '#c18a00'))), + 'background_color' => strtoupper(trim((string) ($data['background_color'] ?? '#f4efe4'))), + 'card_color' => strtoupper(trim((string) ($data['card_color'] ?? '#fffdf8'))), ]; if (!is_numeric($values['default_unit_price']) || (float) $values['default_unit_price'] <= 0) { @@ -2345,6 +2417,12 @@ function app_save_tenant_settings(PDO $pdo, string $tenantId, array $data): void throw new RuntimeException('Bitte gib eine gültige Support-E-Mail-Adresse an.'); } + foreach (['brand_color', 'brand_strong_color', 'accent_color', 'background_color', 'card_color'] as $colorKey) { + if (!app_is_valid_hex_color($values[$colorKey])) { + throw new RuntimeException('Bitte gib für die Farbfelder gültige HEX-Werte an.'); + } + } + $now = date('Y-m-d H:i:s'); foreach ($values as $key => $value) { diff --git a/saas-app/public/index.php b/saas-app/public/index.php index ddcb7f8..d1f2e9e 100644 --- a/saas-app/public/index.php +++ b/saas-app/public/index.php @@ -223,6 +223,7 @@ if ($auth !== null && isset($restrictedPages[$page]) && !$restrictedPages[$page] $canManageTenant = app_can_manage_tenant($auth); $tenantNavItems = app_tenant_navigation_items($auth, $tenantLicense); +$themeCss = app_tenant_theme_root_css($tenantSettings); ?> @@ -231,8 +232,8 @@ $tenantNavItems = app_tenant_navigation_items($auth, $tenantLicense); Kaffeeliste SaaS @@ -640,6 +641,11 @@ $tenantNavItems = app_tenant_navigation_items($auth, $tenantLicense); + + + + +