158 lines
6.9 KiB
JavaScript
158 lines
6.9 KiB
JavaScript
import { apiLogin, apiRegister, apiGetMe, apiFetchPlayerCounts } from "./api.js";
|
||
import { setCurrentTeam, refreshFromServer } from "./game.js";
|
||
|
||
// ── DOM refs ──────────────────────────────────────────────────────────────────
|
||
|
||
const authOverlay = document.getElementById("authOverlay");
|
||
const tabLogin = document.getElementById("tabLogin");
|
||
const tabRegister = document.getElementById("tabRegister");
|
||
const loginForm = document.getElementById("loginForm");
|
||
const registerForm = document.getElementById("registerForm");
|
||
const loginUsernameEl = document.getElementById("loginUsername");
|
||
const loginPasswordEl = document.getElementById("loginPassword");
|
||
const loginErrorEl = document.getElementById("loginError");
|
||
const regUsernameEl = document.getElementById("regUsername");
|
||
const regEmailEl = document.getElementById("regEmail");
|
||
const regPasswordEl = document.getElementById("regPassword");
|
||
const registerErrorEl = document.getElementById("registerError");
|
||
const regCountBlueEl = document.getElementById("regCountBlue");
|
||
const regCountRedEl = document.getElementById("regCountRed");
|
||
const userDisplayEl = document.getElementById("userDisplay");
|
||
const logoutBtn = document.getElementById("logoutBtn");
|
||
|
||
// ── Auth state ────────────────────────────────────────────────────────────────
|
||
|
||
export let authToken = localStorage.getItem("authToken") ?? null;
|
||
export let currentUser = null;
|
||
|
||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||
|
||
function showError(el, msg) { el.textContent = msg; el.classList.remove("hidden"); }
|
||
function clearError(el) { el.textContent = ""; el.classList.add("hidden"); }
|
||
|
||
export function showAuthOverlay() { authOverlay.classList.remove("hidden"); }
|
||
export function hideAuthOverlay() { authOverlay.classList.add("hidden"); }
|
||
|
||
// ── Apply user (after login / register / session restore) ─────────────────────
|
||
|
||
export function applyUser(user, token) {
|
||
currentUser = user;
|
||
authToken = token;
|
||
localStorage.setItem("authToken", token);
|
||
setCurrentTeam(user.team);
|
||
userDisplayEl.textContent = `${user.username} [${user.team}]`;
|
||
logoutBtn.classList.remove("hidden");
|
||
}
|
||
|
||
function logout() {
|
||
currentUser = null;
|
||
authToken = null;
|
||
localStorage.removeItem("authToken");
|
||
userDisplayEl.textContent = "—";
|
||
logoutBtn.classList.add("hidden");
|
||
showAuthOverlay();
|
||
}
|
||
|
||
// ── Session restore ───────────────────────────────────────────────────────────
|
||
|
||
export async function tryRestoreSession() {
|
||
if (!authToken) return false;
|
||
try {
|
||
const res = await apiGetMe(authToken);
|
||
if (!res.ok) { localStorage.removeItem("authToken"); authToken = null; return false; }
|
||
const data = await res.json();
|
||
applyUser(data.user, data.token);
|
||
return true;
|
||
} catch {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// ── Tab switching ─────────────────────────────────────────────────────────────
|
||
|
||
async function loadRegisterCounts() {
|
||
try {
|
||
const counts = await apiFetchPlayerCounts();
|
||
const fmt = (n) => `${n} joueur${n > 1 ? "s" : ""}`;
|
||
regCountBlueEl.textContent = fmt(counts.blue ?? 0);
|
||
regCountRedEl.textContent = fmt(counts.red ?? 0);
|
||
} catch { /* silently ignore */ }
|
||
}
|
||
|
||
tabLogin.addEventListener("click", () => {
|
||
tabLogin.classList.add("authTab--active");
|
||
tabRegister.classList.remove("authTab--active");
|
||
loginForm.classList.remove("hidden");
|
||
registerForm.classList.add("hidden");
|
||
clearError(loginErrorEl);
|
||
});
|
||
|
||
tabRegister.addEventListener("click", () => {
|
||
tabRegister.classList.add("authTab--active");
|
||
tabLogin.classList.remove("authTab--active");
|
||
registerForm.classList.remove("hidden");
|
||
loginForm.classList.add("hidden");
|
||
clearError(registerErrorEl);
|
||
loadRegisterCounts();
|
||
});
|
||
|
||
// ── Login form ────────────────────────────────────────────────────────────────
|
||
|
||
loginForm.addEventListener("submit", async (e) => {
|
||
e.preventDefault();
|
||
clearError(loginErrorEl);
|
||
const username = loginUsernameEl.value.trim();
|
||
const password = loginPasswordEl.value;
|
||
if (!username || !password) return;
|
||
try {
|
||
const res = await apiLogin(username, password);
|
||
const data = await res.json();
|
||
if (!res.ok) {
|
||
const msgs = { invalid_credentials: "Invalid username or password.", missing_fields: "Please fill in all fields." };
|
||
showError(loginErrorEl, msgs[data.error] ?? "Login failed.");
|
||
return;
|
||
}
|
||
applyUser(data.user, data.token);
|
||
hideAuthOverlay();
|
||
await refreshFromServer();
|
||
} catch {
|
||
showError(loginErrorEl, "Network error. Try again.");
|
||
}
|
||
});
|
||
|
||
// ── Register form ─────────────────────────────────────────────────────────────
|
||
|
||
registerForm.addEventListener("submit", async (e) => {
|
||
e.preventDefault();
|
||
clearError(registerErrorEl);
|
||
const username = regUsernameEl.value.trim();
|
||
const email = regEmailEl.value.trim();
|
||
const password = regPasswordEl.value;
|
||
const teamInput = registerForm.querySelector('input[name="regTeam"]:checked');
|
||
if (!teamInput) { showError(registerErrorEl, "Please choose a team."); return; }
|
||
try {
|
||
const res = await apiRegister(username, email, password, teamInput.value);
|
||
const data = await res.json();
|
||
if (!res.ok) {
|
||
const msgs = {
|
||
username_taken: "This username is already taken.",
|
||
email_taken: "This email is already registered.",
|
||
password_too_short:"Password must be at least 6 characters.",
|
||
invalid_username: "Username must be 2–32 characters.",
|
||
missing_fields: "Please fill in all fields.",
|
||
invalid_team: "Invalid team selected.",
|
||
};
|
||
showError(registerErrorEl, msgs[data.error] ?? "Registration failed.");
|
||
return;
|
||
}
|
||
applyUser(data.user, data.token);
|
||
hideAuthOverlay();
|
||
await refreshFromServer();
|
||
} catch {
|
||
showError(registerErrorEl, "Network error. Try again.");
|
||
}
|
||
});
|
||
|
||
// ── Logout ────────────────────────────────────────────────────────────────────
|
||
|
||
logoutBtn.addEventListener("click", logout); |