'use client' import { useEffect, useState, createContext, useContext } from 'react' import { ThemeProvider as NextThemesProvider } from 'next-themes' import { getBrandingSettings } from '@/lib/actions/branding' import { PRESET_COLOR_SCHEMES, BrandingSettings } from '@/lib/constants/branding' function hexToHsl(hex: string): string { try { let c = hex.replace('#', '') if (c.length === 3) c = c.split('').map(x => x + x).join('') const r = parseInt(c.substring(0, 2), 16) / 255 const g = parseInt(c.substring(2, 4), 16) / 255 const b = parseInt(c.substring(4, 6), 16) / 255 const max = Math.max(r, g, b) const min = Math.min(r, g, b) let h = 0, s = 0, l = (max + min) / 2 if (max !== min) { const d = max - min s = l > 0.5 ? d / (2 - max - min) : d / (max + min) switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break case g: h = (b - r) / d + 2; break case b: h = (r - g) / d + 4; break } h /= 6 } return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%` } catch (e) { return '217 91% 60%' } } const ThemeContext = createContext<{ branding: BrandingSettings | null refreshBranding: () => Promise }>({ branding: null, refreshBranding: async () => {}, }) export function ThemeProvider({ children, ...props }: { children: React.ReactNode [key: string]: any }) { const [branding, setBranding] = useState(null) const loadTheme = async () => { try { const settings = await getBrandingSettings() setBranding(settings) // Preset Ermittlung const preset = PRESET_COLOR_SCHEMES.find(p => p.id === settings.colorScheme) || PRESET_COLOR_SCHEMES[3] const isCustom = settings.colorScheme === 'custom' const primary = isCustom ? (settings.primaryColor || '#2563eb') : preset.primary const accent = isCustom ? (settings.accentColor || '#38bdf8') : preset.accent const primaryHsl = hexToHsl(primary) const accentHsl = hexToHsl(accent) const root = document.documentElement // 10 Color CSS Tokens applied globally onto :root root.style.setProperty('--primary', primaryHsl) root.style.setProperty('--ring', primaryHsl) root.style.setProperty('--accent', accentHsl) root.style.setProperty('--primary-custom', primary) root.style.setProperty('--accent-custom', accent) root.style.setProperty('--success-custom', settings.successColor || preset.success) root.style.setProperty('--warning-custom', settings.warningColor || preset.warning) root.style.setProperty('--destructive-custom', settings.destructiveColor || preset.destructive) root.style.setProperty('--bg-glow-1', isCustom ? primary : preset.bgGlow1) root.style.setProperty('--bg-glow-2', isCustom ? accent : preset.bgGlow2) root.style.setProperty('--gradient-from', isCustom ? primary : preset.gradientFrom) root.style.setProperty('--gradient-to', isCustom ? accent : preset.gradientTo) root.style.setProperty('--card-border-glow', isCustom ? `${accent}40` : preset.cardBorder) root.style.setProperty('--text-highlight', isCustom ? accent : preset.textHighlight) root.style.setProperty('--button-bg', isCustom ? primary : preset.buttonBg) root.style.setProperty('--ring-color', isCustom ? primary : preset.ringColor) } catch (e) { console.error('Failed to load branding theme:', e) } } useEffect(() => { loadTheme() }, []) return ( {children} ) } export function useTheme() { return useContext(ThemeContext) }