81 lines
3.3 KiB
JavaScript
81 lines
3.3 KiB
JavaScript
/* ============================================================================
|
|
Super Sunday — Frontend API client (ESM)
|
|
============================================================================ */
|
|
const BASE = '/api';
|
|
const TOKEN_KEY = 'ss_token';
|
|
|
|
function getToken() { return localStorage.getItem(TOKEN_KEY) || ''; }
|
|
function setToken(t) { if (t) localStorage.setItem(TOKEN_KEY, t); else localStorage.removeItem(TOKEN_KEY); }
|
|
|
|
async function fetchJSON(url, opts = {}) {
|
|
const res = await fetch(url, opts);
|
|
const ct = res.headers.get('content-type') || '';
|
|
const isJSON = ct.includes('application/json');
|
|
const data = isJSON ? await res.json().catch(() => ({})) : await res.text();
|
|
if (!res.ok) {
|
|
const err = new Error((data && data.error) || res.statusText || 'HTTP Error');
|
|
err.status = res.status; err.payload = data;
|
|
throw err;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
async function authFetch(path, options = {}) {
|
|
const token = getToken();
|
|
const headers = new Headers(options.headers || {});
|
|
headers.set('Content-Type','application/json');
|
|
if(token) headers.set('Authorization',`Bearer ${token}`);
|
|
return fetchJSON(`${BASE}${path}`,{...options,headers});
|
|
}
|
|
|
|
/* Public endpoints */
|
|
export async function listTournaments(){ return fetchJSON(`${BASE}/tournaments`); }
|
|
export async function getTournament(id){ return fetchJSON(`${BASE}/tournaments/${id}`); }
|
|
export async function listParticipants(id){ return fetchJSON(`${BASE}/tournaments/${id}/participants`); }
|
|
export async function listMatches(id){ return fetchJSON(`${BASE}/tournaments/${id}/matches`); }
|
|
|
|
/* Admin endpoints */
|
|
export async function login(email,password){
|
|
const data = await fetchJSON(`${BASE}/auth/login`,{
|
|
method:'POST',headers:{'Content-Type':'application/json'},
|
|
body: JSON.stringify({email,password})
|
|
});
|
|
if(data && data.token) setToken(data.token);
|
|
return data;
|
|
}
|
|
export function logout(){ setToken(''); }
|
|
export function isAuthenticated(){ return !!getToken(); }
|
|
|
|
export async function createTournament(payload){
|
|
return authFetch(`/tournaments`,{method:'POST',body:JSON.stringify(payload)});
|
|
}
|
|
export async function addParticipant(tid,payload){
|
|
return authFetch(`/tournaments/${tid}/participants`,{method:'POST',body:JSON.stringify(payload)});
|
|
}
|
|
export async function generateAmericano(tid,payload){
|
|
return authFetch(`/tournaments/${tid}/generate-americano`,{method:'POST',body:JSON.stringify(payload)});
|
|
}
|
|
export async function scoreMatch(mid,payload){
|
|
return authFetch(`/matches/${mid}/score`,{method:'POST',body:JSON.stringify(payload)});
|
|
}
|
|
|
|
/* Helpers */
|
|
export function bindLoginForm({formSel='#loginSection',statusSel='#loginStatus'}={}){
|
|
const form=document.querySelector(formSel);
|
|
const status=document.querySelector(statusSel);
|
|
if(!form) return;
|
|
const email=form.querySelector('#email');
|
|
const password=form.querySelector('#password');
|
|
const btn=form.querySelector('#loginBtn');
|
|
btn?.addEventListener('click',async ()=>{
|
|
status.textContent='Connexion…';
|
|
try{
|
|
await login(email.value.trim(),password.value);
|
|
status.textContent='Connecté ✔';
|
|
const admin=document.querySelector('#adminSection');
|
|
if(admin) admin.style.display='grid';
|
|
form.style.display='none';
|
|
}catch(e){ status.textContent=`Erreur: ${e.payload?.error||e.message}`; }
|
|
});
|
|
}
|