diff --git a/admin/index.html b/admin/index.html index b86dfbf..dd1921f 100644 --- a/admin/index.html +++ b/admin/index.html @@ -231,7 +231,7 @@ // ── tiny utils ────────────────────────────────────────────────────────── const $ = (sel) => document.querySelector(sel); const fmtDate = (d) => d ? new Date(d).toLocaleString() : '—'; -const esc = (s) => String(s ?? '').replace(/&/g,'&').replace(//g,'>'); +const esc = (s) => String(s ?? '').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,'''); const api = { async request(method, path, body) { @@ -240,13 +240,24 @@ opts.headers['Content-Type'] = 'application/json'; opts.body = JSON.stringify(body); } - const r = await fetch(path, opts); - if (!r.ok) { - const txt = await r.text().catch(() => ''); - throw new Error(`${method} ${path} → ${r.status}: ${txt}`); + try { + const r = await fetch(path, opts); + if (r.status === 401) { + window.location.href = '/'; + return; + } + if (!r.ok) { + const txt = await r.text().catch(() => ''); + throw new Error(`${method} ${path} → ${r.status}: ${txt}`); + } + if (r.status === 204) return null; + return r.json(); + } catch (err) { + if (err.name === 'TypeError') { + throw new Error('Network error — check your connection or server availability'); + } + throw err; } - if (r.status === 204) return null; - return r.json(); }, get(path) { return this.request('GET', path); }, patch(path, body) { return this.request('PATCH', path, body); }, @@ -588,7 +599,7 @@ function renderProfiles(profiles) { if (!profiles.length) return '
| ${h} | `); + ['ID','Name','Description','Admin Only'].forEach(h => html += `${h} | `); html += '
|---|---|
| ${p.is_admin_only ? 'Yes' : 'No'} |