Add per-user phase navigation with results toggle
This commit is contained in:
@@ -46,10 +46,12 @@ export const api = {
|
||||
vote: (suggestionId, score) => request("/api/votes", { method: "POST", body: { suggestionId, score } }),
|
||||
|
||||
results: () => request("/api/results"),
|
||||
nextPhase: () => request("/api/me/phase/next", { method: "POST" }),
|
||||
prevPhase: () => request("/api/me/phase/prev", { method: "POST" }),
|
||||
};
|
||||
|
||||
export const adminApi = {
|
||||
setPhase: (phase) => request("/api/admin/phase", { method: "POST", body: { phase } }),
|
||||
setResultsOpen: (resultsOpen) => request("/api/admin/results", { method: "POST", body: { resultsOpen } }),
|
||||
reset: () => request("/api/admin/reset", { method: "POST" }),
|
||||
factoryReset: () => request("/api/admin/factory-reset", { method: "POST" }),
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ export async function loadState() {
|
||||
state.me = me;
|
||||
state.prevPhase = state.phase;
|
||||
state.phase = stateData.currentPhase;
|
||||
state.resultsOpen = stateData.resultsOpen;
|
||||
state.counts = stateData;
|
||||
if (state.prevPhase !== state.phase && state.phase === "Vote") {
|
||||
state.votesRendered = false;
|
||||
@@ -52,7 +53,7 @@ export async function loadVoteData() {
|
||||
}
|
||||
|
||||
export async function loadResults() {
|
||||
if (state.phase !== "Results") return;
|
||||
if (state.phase !== "Results" || !state.resultsOpen) return;
|
||||
state.results = await api.results();
|
||||
renderResults();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ const translations = {
|
||||
|
||||
"counts.format": "Players: {players} • Suggestions: {suggestions} • Votes: {votes}",
|
||||
|
||||
"nav.prev": "Back",
|
||||
"nav.next": "Next",
|
||||
"nav.waitingForResults": "Waiting…",
|
||||
|
||||
"suggest.title": "Suggest games (up to 5)",
|
||||
"suggest.new": "Add new suggestion",
|
||||
"suggest.addButton": "Suggest a game",
|
||||
@@ -79,10 +83,11 @@ const translations = {
|
||||
|
||||
"admin.title": "Admin",
|
||||
"admin.tools": "Admin tools",
|
||||
"admin.setPhase": "Set phase",
|
||||
"admin.resultsOpenToggle": "Allow results phase",
|
||||
"admin.resultsLocked": "Results locked by admin",
|
||||
"admin.resultsUpdated": "Results availability updated",
|
||||
"admin.reset": "Reset (keep players)",
|
||||
"admin.factoryReset": "Factory reset",
|
||||
"admin.phaseUpdated": "Phase updated",
|
||||
"admin.resetDone": "Reset complete",
|
||||
"admin.factoryResetDone": "Factory reset complete",
|
||||
|
||||
@@ -138,6 +143,10 @@ const translations = {
|
||||
|
||||
"counts.format": "Spieler: {players} • Vorschläge: {suggestions} • Stimmen: {votes}",
|
||||
|
||||
"nav.prev": "Zurück",
|
||||
"nav.next": "Weiter",
|
||||
"nav.waitingForResults": "Warten…",
|
||||
|
||||
"suggest.title": "Schlage Spiele vor (bis zu 5)",
|
||||
"suggest.new": "Neuen Vorschlag hinzufügen",
|
||||
"suggest.addButton": "Spiel vorschlagen",
|
||||
@@ -186,10 +195,11 @@ const translations = {
|
||||
|
||||
"admin.title": "Admin",
|
||||
"admin.tools": "Admin-Werkzeuge",
|
||||
"admin.setPhase": "Phase setzen",
|
||||
"admin.resultsOpenToggle": "Ergebnisse freigeben",
|
||||
"admin.resultsLocked": "Ergebnisse vom Admin gesperrt",
|
||||
"admin.resultsUpdated": "Ergebnisfreigabe aktualisiert",
|
||||
"admin.reset": "Zurücksetzen (Spieler behalten)",
|
||||
"admin.factoryReset": "Werkseinstellung",
|
||||
"admin.phaseUpdated": "Phase aktualisiert",
|
||||
"admin.resetDone": "Zurücksetzen abgeschlossen",
|
||||
"admin.factoryResetDone": "Werkseinstellung abgeschlossen",
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ export const state = {
|
||||
me: null,
|
||||
phase: null,
|
||||
prevPhase: null,
|
||||
resultsOpen: false,
|
||||
counts: null,
|
||||
mySuggestions: [],
|
||||
allSuggestions: [],
|
||||
@@ -17,6 +18,7 @@ export function clearUserState() {
|
||||
state.me = null;
|
||||
state.phase = null;
|
||||
state.prevPhase = null;
|
||||
state.resultsOpen = false;
|
||||
state.counts = null;
|
||||
state.mySuggestions = [];
|
||||
state.allSuggestions = [];
|
||||
|
||||
@@ -65,7 +65,8 @@ export function handleAuthError(err, clearUserState) {
|
||||
|
||||
export function renderPhasePill() {
|
||||
const phaseKey = typeof state.phase === "string" ? state.phase.toLowerCase() : null;
|
||||
$("phase-pill").textContent = phaseKey ? "" : t("phase.loading");
|
||||
const pill = $("phase-pill");
|
||||
if (pill) pill.textContent = phaseKey ? t(`phase.${phaseKey}`) : t("phase.loading");
|
||||
document.querySelectorAll(".phase-view").forEach((el) =>
|
||||
el.classList.add("hidden"),
|
||||
);
|
||||
@@ -77,9 +78,27 @@ export function renderPhasePill() {
|
||||
};
|
||||
const id = viewMap[state.phase];
|
||||
if (id) $(id).classList.remove("hidden");
|
||||
const phaseSelect = $("phase-select");
|
||||
if (phaseSelect && !phaseSelect.dataset.userEditing) {
|
||||
phaseSelect.value = state.phase || "Suggest";
|
||||
|
||||
const prevBtn = $("prev-phase");
|
||||
if (prevBtn) prevBtn.disabled = state.phase === "Suggest";
|
||||
|
||||
const nextBtn = $("next-phase");
|
||||
if (nextBtn) {
|
||||
const atResults = state.phase === "Results";
|
||||
const locked = !state.resultsOpen && state.phase === "Vote";
|
||||
nextBtn.disabled = atResults || locked;
|
||||
nextBtn.textContent = locked ? t("nav.waitingForResults") : t("nav.next");
|
||||
}
|
||||
|
||||
const resultsLock = $("results-lock");
|
||||
if (resultsLock) {
|
||||
resultsLock.classList.toggle("hidden", state.resultsOpen);
|
||||
resultsLock.textContent = t("admin.resultsLocked");
|
||||
}
|
||||
|
||||
const adminResultsToggle = $("results-open");
|
||||
if (adminResultsToggle) {
|
||||
adminResultsToggle.checked = !!state.resultsOpen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user