{
if (!signedIn) {
const wrap = html`<div style="text-align:center;padding:3rem 1rem;color:var(--bs-secondary-color)">
<p style="font-size:1.1rem;margin-bottom:1rem">Sign in to manage your settings.</p>
<button class="btn btn-primary">Sign in</button>
</div>`
wrap.querySelector("button").addEventListener("click", () => window.auth && window.auth.signIn())
return wrap
}
if (myData === undefined) {
return html`<p style="text-align:center;color:var(--bs-secondary-color);padding:2rem">Loading…</p>`
}
const currentTheme = (myData && myData.user && myData.user.preferences && myData.user.preferences.theme) || "system"
const wrap = html`<div style="max-width:560px;margin:1rem auto">
<section style="margin-bottom:2.5rem">
<h2 style="font-size:1.05rem;color:var(--bs-secondary-color);text-transform:uppercase;letter-spacing:0.05em;margin-bottom:0.75rem">Theme</h2>
<p style="color:var(--bs-secondary-color);margin-bottom:0.75rem;font-size:0.9rem">
Choose how the site appears. <em>System</em> follows your operating system's color scheme.
Your preference syncs across devices when you sign in.
</p>
<div style="display:flex;align-items:center;gap:0.5rem;flex-wrap:wrap">
<select id="theme-select" class="form-select" style="max-width:240px;background:var(--bs-body-bg);color:var(--bs-body-color);border:1px solid var(--bs-border-color)">
<option value="system">System (auto)</option>
<option value="dark">Dark</option>
<option value="light">Light</option>
</select>
<button class="btn btn-primary btn-sm" id="save-theme">Save</button>
<span id="save-status" style="color:var(--bs-secondary-color);font-size:0.9rem"></span>
</div>
</section>
<section>
<h2 style="font-size:1.05rem;color:var(--bs-secondary-color);text-transform:uppercase;letter-spacing:0.05em;margin-bottom:0.75rem">Account</h2>
<p style="color:var(--bs-secondary-color);font-size:0.9rem">
Profile info, security, and account deletion live in the user menu (top right) under
<em>Manage account</em>. To remove all data this site has stored about you, sign out
and email Pete via <a href="https://github.com/peteowen1">GitHub</a>.
</p>
</section>
</div>`
const select = wrap.querySelector("#theme-select")
select.value = currentTheme
const status = wrap.querySelector("#save-status")
wrap.querySelector("#save-theme").addEventListener("click", async () => {
const newTheme = select.value
status.textContent = "Saving…"
try {
const res = await window.auth.fetch(window.WORKER_BASE_URL + "api/me", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ preferences: { theme: newTheme } }),
})
const data = await res.json()
if (data.error) {
status.textContent = "Error: " + data.error
console.error("[settings] save failed:", data.error)
return
}
status.textContent = "Saved."
// Apply locally and reload so Quarto picks up the new scheme
if (newTheme === "system") {
localStorage.removeItem("quarto-color-scheme")
} else {
localStorage.setItem("quarto-color-scheme", newTheme)
}
setTimeout(() => window.location.reload(), 400)
} catch (e) {
status.textContent = "Error: " + e.message
console.error("[settings] save threw:", e)
}
})
return wrap
}