const API_BASE = "http://127.0.0.1:5000/api"; const THEME_STORAGE_KEY = "journey-theme"; const DEFAULT_THEME = "dark"; const VALID_THEMES = ["dark", "light", "system"]; let currentUser = null; function getThemePreference() { const storedTheme = localStorage.getItem(THEME_STORAGE_KEY); return VALID_THEMES.includes(storedTheme) ? storedTheme : DEFAULT_THEME; } function applyThemePreference(theme = getThemePreference()) { const selectedTheme = VALID_THEMES.includes(theme) ? theme : DEFAULT_THEME; document.documentElement.dataset.theme = selectedTheme; } function setThemePreference(theme) { const selectedTheme = VALID_THEMES.includes(theme) ? theme : DEFAULT_THEME; localStorage.setItem(THEME_STORAGE_KEY, selectedTheme); applyThemePreference(selectedTheme); } function getThemeControlHtml() { return `
`; } function attachThemeControl(root = document) { const select = root.querySelector("#theme-select"); if (!select) return; select.value = getThemePreference(); select.addEventListener("change", () => setThemePreference(select.value)); } function ensureStandaloneThemeControl() { if (document.getElementById("user-menu") || document.getElementById("theme-switcher-floating")) return; const container = document.createElement("div"); container.id = "theme-switcher-floating"; container.className = "theme-switcher-floating"; container.innerHTML = getThemeControlHtml(); document.body.appendChild(container); attachThemeControl(container); } applyThemePreference(); async function checkAuth() { try { const res = await fetch(`${API_BASE}/me`, { credentials: "include" }); if (res.ok) { currentUser = await res.json(); return true; } return false; } catch (err) { return false; } } async function checkAuthAndRedirect() { const ok = await checkAuth(); if (!ok) { window.location.href = "login.html"; return false; } return true; } function updateUserMenu() { const container = document.getElementById("user-menu"); if (!container) return; if (currentUser) { container.innerHTML = ` ${getThemeControlHtml()} ${escapeHtml(currentUser.username)} `; attachThemeControl(container); document.getElementById("logout-btn")?.addEventListener("click", logout); } else { container.innerHTML = ` ${getThemeControlHtml()} `; attachThemeControl(container); document.getElementById("login-open-btn")?.addEventListener("click", () => { window.location.href = "login.html"; }); } } async function logout() { await fetch(`${API_BASE}/logout`, { method: "POST", credentials: "include" }); window.location.href = "login.html"; } function escapeHtml(str) { if (!str) return ""; return str.replace(/[&<>]/g, function (m) { if (m === "&") return "&"; if (m === "<") return "<"; if (m === ">") return ">"; return m; }); } function showToast(msg, isError = false) { const toast = document.getElementById("toast"); if (!toast) return; toast.textContent = msg; toast.style.backgroundColor = isError ? "var(--red-7)" : "var(--green-7)"; toast.style.display = "block"; setTimeout(() => { toast.style.display = "none"; }, 3000); } document.addEventListener("DOMContentLoaded", ensureStandaloneThemeControl);