diff --git a/web/templates/settings/home.html b/web/templates/settings/home.html index 4e9c309..eba120e 100644 --- a/web/templates/settings/home.html +++ b/web/templates/settings/home.html @@ -162,6 +162,26 @@ + + + + Comms + Publication Codes (JSON) + + + + Edit web/static/data/wol-pub-codes.v1.json + + + + Reload + Save + + + + + {% endif %} @@ -335,6 +355,71 @@ textarea.tool-input{min-height:140px;resize:vertical;width:100%;} }); window.addEventListener('keydown', (e)=>{ if (e.key === 'Escape' && modal.style.display === 'flex') closeModal(); }); })(); + + // === Publication Codes Editor (superuser) === + (function(){ + const ta = document.getElementById('pubCodesEditor'); + const btnR = document.getElementById('pubCodesReloadBtn'); + const btnS = document.getElementById('pubCodesSaveBtn'); + const stat = document.getElementById('pubCodesStatus'); + if (!ta || !btnR || !btnS) return; // not superuser or card missing + + function setStatus(msg, ok=true){ + if (!stat) return; + stat.textContent = msg; + stat.style.color = ok ? '#64748b' : '#b91c1c'; + } + + async function reloadJSON(){ + try{ + setStatus('Loading…'); + const r = await fetch('/static/data/wol-pub-codes.v1.json', { cache:'no-store' }); + if (!r.ok) throw new Error('HTTP '+r.status); + const data = await r.json(); + ta.value = JSON.stringify(data, null, 2); + setStatus('Loaded.'); + }catch(err){ + setStatus('Failed to load JSON: ' + (err?.message||err), false); + } + } + + async function saveJSON(){ + let parsed; + try{ + parsed = JSON.parse(ta.value); + if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.pub_codes)) + throw new Error('JSON must be an object with a "pub_codes" array.'); + }catch(err){ + setStatus('Invalid JSON: ' + (err?.message||err), false); + return; + } + + try{ + setStatus('Saving…'); + const fd = new FormData(); + fd.append('json', JSON.stringify(parsed)); + const r = await fetch("{% url 'api_update_pub_codes' %}", { + method: 'POST', + body: fd, + credentials: 'same-origin', + headers: { 'X-CSRFToken': (document.cookie.match(/(^|;)\s*csrftoken\s*=\s*([^;]+)/)||[]).pop() || '' } + }); + if (!r.ok) { + const txt = await r.text().catch(()=>String(r.status)); + throw new Error(txt.slice(0,200)); + } + const out = await r.json().catch(()=>({ok:false})); + if (!out.ok) throw new Error('Server rejected the update.'); + setStatus('Saved. ' + out.count + ' codes.'); + }catch(err){ + setStatus('Save failed: ' + (err?.message||err), false); + } + } + + btnR.addEventListener('click', reloadJSON); + btnS.addEventListener('click', saveJSON); + reloadJSON(); // initial load + })(); })();
web/static/data/wol-pub-codes.v1.json