/* Central API client — all fetch calls go through here */ const API = (() => { const base = '/api'; function token() { return localStorage.getItem('bb_token'); } async function request(method, path, body) { const headers = { 'Content-Type': 'application/json' }; const tok = token(); if (tok) headers['Authorization'] = `Bearer ${tok}`; const res = await fetch(base + path, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined, }); if (res.status === 204) return null; const data = await res.json().catch(() => null); if (!res.ok) { const msg = data?.detail || `HTTP ${res.status}`; throw new Error(Array.isArray(msg) ? msg.map(e => e.msg).join(', ') : msg); } return data; } return { get: (path) => request('GET', path), post: (path, body) => request('POST', path, body), put: (path, body) => request('PUT', path, body), delete: (path) => request('DELETE', path), auth: { login: (email, password) => request('POST', '/auth/login', { email, password }), register: (email, password, display_name) => request('POST', '/auth/register', { email, password, display_name }), }, users: { me: () => request('GET', '/users/me'), update: (body) => request('PUT', '/users/me', body), changePassword: (body) => request('PUT', '/users/me/password', body), }, entries: { list: () => request('GET', '/entries'), stats: () => request('GET', '/entries/stats'), create: (body) => request('POST', '/entries', body), delete: (id) => request('DELETE', `/entries/${id}`), }, public: { stats: () => request('GET', '/public/stats'), }, }; })();