const errorBox = document.querySelector('#auth-error'); const loginPanel = document.querySelector('#login-panel'); const setupPanel = document.querySelector('#setup-panel'); function showError(message) { errorBox.textContent = message; errorBox.hidden = !message; } async function request(url, options = {}) { const res = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', ...(options.headers || {}) } }); const body = res.status === 204 ? null : await res.json().catch(() => ({})); if (!res.ok) throw new Error(body?.error?.message || `HTTP ${res.status}`); return body; } (async () => { try { const x = await request('/api/bootstrap'); loginPanel.hidden = x.needs_setup; setupPanel.hidden = !x.needs_setup; } catch (e) { showError(e.message); } })(); document.querySelector('#login-form').addEventListener('submit', async (ev) => { ev.preventDefault(); showError(''); const fd = new FormData(ev.currentTarget); try { await request('/api/login', { method: 'POST', body: JSON.stringify({ username: fd.get('username'), password: fd.get('password') }) }); location.assign('/'); } catch (e) { showError(e.message); } }); document.querySelector('#setup-form').addEventListener('submit', async (ev) => { ev.preventDefault(); showError(''); const fd = new FormData(ev.currentTarget); try { await request('/api/setup', { method: 'POST', body: JSON.stringify({ username: fd.get('username'), displayName: fd.get('displayName'), password: fd.get('password') }) }); location.assign('/'); } catch (e) { showError(e.message); } });