Files
newbury-exhibit-v2/public/admin/admin.js
T

47 lines
2.1 KiB
JavaScript

/* admin.js — shared auth + API helpers for admin pages. */
export async function api(path, method = 'GET', body) {
const res = await fetch(path, {
method,
headers: {
'Content-Type': 'application/json',
'x-exhibit-token': localStorage.getItem('exhibitToken') || '',
},
body: body === undefined ? undefined : JSON.stringify(body),
});
if (res.status === 401) { location.href = '/admin/login.html?next=' + encodeURIComponent(location.pathname); throw new Error('unauthorized'); }
if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || res.statusText);
return res.json();
}
export async function requireAuth() {
const info = await (await fetch('/api/info')).json();
if (!info.authRequired) return info;
// probe a guarded endpoint
const res = await fetch('/api/client-errors', { headers: { 'x-exhibit-token': localStorage.getItem('exhibitToken') || '' } });
if (res.status === 401) location.href = '/admin/login.html?next=' + encodeURIComponent(location.pathname);
return info;
}
export const styles = `
:root { color-scheme: dark; }
body { margin:0; background:#0a0d18; color:#e8ecff; font-family:system-ui,sans-serif; }
header { display:flex; gap:14px; align-items:center; padding:10px 16px; background:#111730; }
header a { color:#8fb8ff; text-decoration:none; font-size:.9rem; }
header a.active { color:#51eaf1; }
h1 { font-size:1.05rem; margin:0 auto 0 0; }
button { background:#2a3a6e; color:#fff; border:0; border-radius:6px; padding:6px 14px; cursor:pointer; }
button.primary { background:linear-gradient(135deg,#51eaf1,#529eff); color:#04121a; font-weight:600; }
button.danger { background:#7a2437; }
input, select { background:#141a33; color:#fff; border:1px solid #2a3a6e; border-radius:5px; padding:4px 8px; }
label { font-size:.8rem; opacity:.85; }
`;
export function nav(active) {
return `<header>
<h1>Newbury Exhibit — Admin</h1>
${['layout', 'playlist', 'print', 'calibrate', 'errors'].map(p =>
`<a href="/admin/${p}.html" class="${p === active ? 'active' : ''}">${p}</a>`).join('')}
<a href="/">viewer ↗</a>
</header>`;
}