Add admin accounts and streamlined header UI

This commit is contained in:
2026-01-29 01:14:53 +01:00
parent 81f688cf88
commit 60191a1fe3
16 changed files with 311 additions and 110 deletions

View File

@@ -30,7 +30,7 @@ function setAuthUI(isAuthed) {
[main, statusBar].forEach(el => el?.classList.toggle("hidden", !isAuthed));
if (authCard) authCard.classList.toggle("hidden", isAuthed);
const adminToggle = $("admin-toggle");
if (adminToggle) adminToggle.classList.toggle("hidden", !isAuthed);
if (adminToggle) adminToggle.classList.toggle("hidden", !isAuthed || !state.me?.isAdmin);
}
function setAuthMode(mode) {
@@ -71,13 +71,9 @@ async function loadState() {
state.phase = stateData.currentPhase;
state.counts = stateData;
setAuthUI(true);
renderWelcome();
renderPhasePill();
renderCounts();
const nameInput = $("name-input");
if (nameInput && !nameInput.dataset.userEditing) {
nameInput.value = me.displayName || "";
}
applyNameRequirementUI();
}
async function loadSuggestData() {
@@ -120,7 +116,6 @@ function renderPhasePill() {
if (phaseSelect && !phaseSelect.dataset.userEditing) {
phaseSelect.value = state.phase || "Suggest";
}
applyNameRequirementUI();
}
function renderCounts() {
@@ -128,6 +123,13 @@ function renderCounts() {
$("counts").textContent = `Players: ${state.counts.players} • Suggestions: ${state.counts.suggestions} • Votes: ${state.counts.votes}`;
}
function renderWelcome() {
const el = $("welcome-text");
if (!el) return;
const name = state.me?.displayName?.trim() || state.me?.username || "Player";
el.textContent = `Welcome, ${name}!`;
}
function renderMySuggestions() {
const wrap = $("my-suggestions");
if (!wrap) return;
@@ -258,9 +260,10 @@ function setupHandlers() {
const username = $("register-username").value.trim();
const password = $("register-password").value;
const displayName = $("register-displayName").value.trim();
const adminKey = $("register-adminkey").value.trim();
if (!username || !password) return toast("Username and password required", true);
try {
await api.register({ username, password, displayName });
await api.register({ username, password, displayName, adminKey });
state.isAuthenticated = true;
setAuthUI(true);
await refreshPhaseData();
@@ -272,28 +275,6 @@ function setupHandlers() {
});
}
const nameInput = $("name-input");
if (nameInput) {
["focus", "input"].forEach(evt => {
nameInput.addEventListener(evt, () => { nameInput.dataset.userEditing = "1"; });
});
nameInput.addEventListener("blur", () => { nameInput.dataset.userEditing = ""; });
}
$("save-name").addEventListener("click", async () => {
const name = nameInput.value.trim();
if (!name) return toast("Name required", true);
try {
const me = await api.setName(name);
state.me = me;
nameInput.dataset.userEditing = "";
toast("Saved name");
applyNameRequirementUI();
} catch (err) {
toast(err.message, true);
}
});
$("suggest-form").addEventListener("submit", async (e) => {
e.preventDefault();
const form = e.target;
@@ -311,9 +292,8 @@ function setupHandlers() {
$("set-phase").addEventListener("click", async () => {
const phase = $("phase-select").value;
const adminKey = $("admin-key").value;
try {
await adminApi.setPhase(phase, adminKey);
await adminApi.setPhase(phase);
toast("Phase updated");
state.phase = phase;
$("phase-select").dataset.userEditing = "";
@@ -334,7 +314,8 @@ function setupHandlers() {
const logoutBtn = $("logout");
if (logoutBtn) {
logoutBtn.addEventListener("click", async () => {
logoutBtn.addEventListener("click", async (e) => {
e.preventDefault();
try {
await api.logout();
} catch (err) {
@@ -357,9 +338,8 @@ function setupHandlers() {
}
async function adminAction(fn, successMessage) {
const adminKey = $("admin-key").value;
try {
await fn(adminKey);
await fn();
toast(successMessage);
await refreshPhaseData();
} catch (err) {
@@ -437,32 +417,6 @@ function openLightbox(url, title) {
document.body.appendChild(overlay);
}
function applyNameRequirementUI() {
if (!state.isAuthenticated) return;
const requiresName = !state.me?.displayName?.trim();
const warning = $("name-warning");
if (warning) warning.classList.toggle("hidden", !requiresName);
const suggestForm = $("suggest-form");
if (suggestForm) {
suggestForm.querySelectorAll("input,textarea,button").forEach(el => {
if (el.id === "save-name") return;
el.disabled = requiresName;
});
suggestForm.classList.toggle("disabled-form", requiresName);
}
const voteList = $("vote-list");
if (voteList) {
voteList.querySelectorAll("input[type=range]").forEach(el => el.disabled = requiresName);
voteList.classList.toggle("disabled-form", requiresName);
}
if (requiresName && state.phase !== "Suggest") {
toast("Enter a name to continue.", true);
}
}
async function main() {
setupHandlers();
try {