/** * Admin > System > Settings */ const { html } = window; const { useState, useEffect, useCallback } = hooks; export default function SettingsSection() { const [cfg, setCfg] = useState({}); const [surfaces, setSurfaces] = useState([]); const [vault, setVault] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const load = useCallback(async () => { try { const [s, v, surfList] = await Promise.all([ sw.api.admin.settings.get(), sw.api.admin.vault.status().catch(() => null), sw.api.admin.surfaces.list().catch(() => []), ]); const raw = s || {}; const pol = raw.policies || {}; const cfg_ = raw.settings || {}; setSurfaces((surfList || []).filter(s => s.enabled)); setCfg({ default_surface: cfg_.default_surface?.id || '', allow_registration: pol.allow_registration === 'true', registration_default_state: cfg_.registration_default_state || 'pending', banner_enabled: !!cfg_.banner?.enabled, banner_text: cfg_.banner?.text || '', banner_bg: cfg_.banner?.bg || '#007a33', banner_fg: cfg_.banner?.fg || '#ffffff', banner_position: cfg_.banner?.position || 'both', message_enabled: !!cfg_.message?.enabled, message_text: cfg_.message?.text || '', message_variant: cfg_.message?.variant || 'info', footer_enabled: !!cfg_.footer?.enabled, footer_text: cfg_.footer?.text || '', }); setVault(v); } catch (e) { sw.toast(e.message, 'error'); } finally { setLoading(false); } }, []); useEffect(() => { load(); }, []); function set(key, val) { setCfg(prev => ({ ...prev, [key]: val })); } async function save() { setSaving(true); try { // Default surface await sw.api.admin.settings.update('default_surface', { value: cfg.default_surface ? { id: cfg.default_surface } : null }); // Registration await sw.api.admin.settings.update('allow_registration', { value: String(cfg.allow_registration) }); await sw.api.admin.settings.update('registration_default_state', { value: cfg.registration_default_state }); // Banner await sw.api.admin.settings.update('banner', { value: { enabled: cfg.banner_enabled, text: cfg.banner_text, bg: cfg.banner_bg, fg: cfg.banner_fg, position: cfg.banner_position, }}); // Message bar await sw.api.admin.settings.update('message', { value: { enabled: cfg.message_enabled, text: cfg.message_text, variant: cfg.message_variant, }}); // Footer await sw.api.admin.settings.update('footer', { value: { enabled: cfg.footer_enabled, text: cfg.footer_text, }}); sw.toast('Settings saved', 'success'); } catch (e) { sw.toast(e.message, 'error'); } finally { setSaving(false); } } async function testEmail() { try { await sw.api.admin.notifications.testEmail(); sw.toast('Test email sent', 'success'); } catch (e) { sw.toast(e.message, 'error'); } } if (loading) return html`
Loading\u2026
`; return html`

Default Surface

Where users land when visiting /. Only extension surfaces are listed.

Registration

Environment Banner

${cfg.banner_enabled && html`
set('banner_text', e.target.value)} placeholder="DEVELOPMENT" />
set('banner_bg', e.target.value)} />
set('banner_fg', e.target.value)} />
`}

Message Bar

${cfg.message_enabled && html`
set('message_text', e.target.value)} placeholder="System maintenance scheduled..." />
`}

Footer

${cfg.footer_enabled && html`
set('footer_text', e.target.value)} placeholder="Powered by Switchboard Core" />
`}

Encryption Vault

${vault ? html`
Key set: ${vault.encryption_key_set ? 'Yes' : 'No'} \u2022 User vaults: ${vault.user_vaults_count ?? '?'}
` : html`Could not load vault status` }

Email

`; }