🚀 Patch auto
This commit is contained in:
@@ -1,12 +1,80 @@
|
||||
const api = {
|
||||
base: '',
|
||||
token: null,
|
||||
setToken(t){ this.token = t; localStorage.setItem('ss_token', t); },
|
||||
getToken(){ return this.token || localStorage.getItem('ss_token'); },
|
||||
headers(){ const h = { 'Content-Type':'application/json' }; const t=this.getToken(); if(t) h['Authorization']='Bearer '+t; return h; },
|
||||
async get(path){ const r = await fetch('/api'+path, { headers: this.headers() }); if(!r.ok) throw new Error(await r.text()); return r.json(); },
|
||||
async post(path, body){ const r = await fetch('/api'+path, { method:'POST', headers:this.headers(), body: JSON.stringify(body) }); if(!r.ok) throw new Error(await r.text()); return r.json(); },
|
||||
async put(path, body){ const r = await fetch('/api'+path, { method:'PUT', headers:this.headers(), body: JSON.stringify(body) }); if(!r.ok) throw new Error(await r.text()); return r.json(); },
|
||||
async del(path, body){ const r = await fetch('/api'+path, { method:'DELETE', headers:this.headers(), body: JSON.stringify(body) }); if(!r.ok) throw new Error(await r.text()); return r.json(); }
|
||||
};
|
||||
window.SSAPI = api;
|
||||
/* ============================================================================
|
||||
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}`; }
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user