/* Innstillinger for legacy-automater — leser og skriver til v1 Firestore settings-doc. Brukes for å konfigurere Vipps-credentials, admin-mobile-nummer, lyd-/lys- toggler, gass-alarm-flagg, etc. for v1-automater som fortsatt kjører RPi-stacken og leser sine settings fra Firestore. */ const LegacySettings = ({ machine, lang }) => { const [loading, setLoading] = React.useState(true); const [error, setError] = React.useState(null); const [fields, setFields] = React.useState({}); const [edits, setEdits] = React.useState({}); const [saving, setSaving] = React.useState(false); const [savedAt, setSavedAt] = React.useState(null); React.useEffect(() => { let cancelled = false; setLoading(true); window.api.legacyGetSettings(machine.id).then(r => { if (cancelled) return; setFields(r.fields || {}); setLoading(false); }).catch(e => { setError(e.message); setLoading(false); }); return () => { cancelled = true; }; }, [machine.id]); const set = (k, v) => setEdits(prev => ({ ...prev, [k]: v })); const val = (k) => (edits[k] !== undefined ? edits[k] : fields[k]); const save = async (keys) => { setSaving(true); setError(null); const updates = {}; keys.forEach(k => { if (edits[k] !== undefined) updates[k] = edits[k]; }); if (Object.keys(updates).length === 0) { setSaving(false); alert('Ingen endringer å lagre'); return; } try { await window.api.legacySaveSettings(machine.id, updates); setFields(prev => ({ ...prev, ...updates })); setEdits(prev => { const c = { ...prev }; keys.forEach(k => delete c[k]); return c; }); setSavedAt(new Date().toLocaleTimeString('no-NO')); } catch (e) { setError(e.message); } setSaving(false); }; if (loading) return
Laster v1-settings…
; return ( <>
ℹ Disse innstillingene skrives direkte til v1 Firestore locations/{machine.firestoreLocId}/settings/…. v1 RPi leser dem live via snapshot-listener og oppdateres uten omstart.
Sensitive felt (vipps-credentials, admin-mobile) — endre med varsomhet.
{error &&
{error}
} {savedAt &&
✓ Lagret {savedAt}
}
{/* --- VIPPS --- */}

Vipps eCommerce

set('vipps_url', v)} /> set('vipps_client_id', v)} /> set('vipps_client_secret', v)} /> set('vipps_Ocp_Apim_Subscription_Key', v)} /> set('vipps_Ocp_Apim_Subscription_Key2', v)} /> set('vipps_MerchantSerialNumber', v)} />
{/* --- DRIFT --- */}

Admin & varsling

set('admin_mobile', v.split(',').map(s => s.trim()).filter(Boolean))} /> set('predict_accept_limit', v)} /> set('num_groups', v)} /> set('stockpage_timeout_min', v)} /> set('receiptpage_timeout_min', v)} /> set('receipt_templ', v)} />

Drift-flagg

set('maintenance_mode', v)} /> set('gas_alarm_enabled', v)} /> set('check_open_doors', v)} />
{/* --- Rå felt for inspeksjon --- */}
Vis alle felt i settings-doc (rå)
{JSON.stringify(fields, null, 2)}
); }; const SettingField = ({ label, value, onChange, secret, hint }) => { const [show, setShow] = React.useState(false); return (
onChange(e.target.value)} /> {secret && ( )}
); }; const SettingNumber = ({ label, value, onChange }) => (
onChange(e.target.value === '' ? null : +e.target.value)} />
); const BoolToggle = ({ label, value, onChange }) => (
{label}
onChange(!value)} style={{ width: 44, height: 24, borderRadius: 12, flexShrink: 0, background: value ? 'var(--accent)' : 'var(--surface-3)', border: '1px solid var(--border)', position: 'relative', cursor: 'pointer', transition: 'background .15s', }}>
); Object.assign(window, { LegacySettings });