import { createContext, useContext, useEffect, useState, useCallback, useMemo } from 'react' import { api } from '../api/client.js' const SiteContext = createContext(null) // Public site settings + mode (always reachable, even during maintenance). export function SiteProvider({ children }) { const [settings, setSettings] = useState({}) const [loading, setLoading] = useState(true) const refresh = useCallback(async () => { try { const data = await api.publicSettings() setSettings(data || {}) } catch { setSettings({}) } finally { setLoading(false) } }, []) useEffect(() => { refresh() }, [refresh]) const brand = useMemo(() => settings.brand || {}, [settings]) // Apply the instance accent color to the CSS variable the theme is built on, // so branding flows to every `var(--accent)` at runtime (no rebuild). useEffect(() => { if (brand.accent) document.documentElement.style.setProperty('--accent', brand.accent) }, [brand.accent]) // Memoized so consumers don't re-render on every provider render (brand is a // fresh object each render, which would otherwise churn the context value). const value = useMemo( () => ({ settings, loading, refresh, brand, mode: settings.site_mode || 'live', siteTitle: brand.name || settings.site_title || 'Runic Gateway', siteShortName: brand.shortName || brand.name || settings.site_title || 'Runic Gateway', contactEmail: brand.contactEmail || settings.contact_email || '', heroImage: brand.hero || '/assets/img/runic-emblem.png', }), [settings, loading, refresh, brand], ) return {children} } export function useSite() { const ctx = useContext(SiteContext) if (!ctx) throw new Error('useSite must be used within SiteProvider') return ctx }