From 7f92cc32b7f05087520e9d300309a2a44ae14535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=BChn?= Date: Fri, 8 May 2026 11:38:43 +0200 Subject: [PATCH] Add api.js module --- public/js/api.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 public/js/api.js diff --git a/public/js/api.js b/public/js/api.js new file mode 100644 index 0000000..a4e22b8 --- /dev/null +++ b/public/js/api.js @@ -0,0 +1,30 @@ +let _apiPending = 0; + +function _apiBar() { + document.getElementById('api-bar').classList.toggle('loading', _apiPending > 0); +} + +export function api(method, path, body) { + const opts = { method, credentials: 'include', headers: { 'Content-Type': 'application/json' } }; + if (body) opts.body = JSON.stringify(body); + _apiPending++; _apiBar(); + return fetch('api/' + path, opts) + .then(res => res.json().then(data => { + if (!res.ok) { const e = new Error(data.error || 'Fehler'); e.status = res.status; throw e; } + return data; + }).catch(e => { + if (e.status) throw e; + const ne = new Error('Fehler'); ne.status = res.status; throw ne; + })) + .catch(e => { + if (e.status === 401 && path !== 'login') { + document.dispatchEvent(new CustomEvent('session-expired')); + } + throw e; + }) + .finally(() => { _apiPending--; _apiBar(); }); +} + +export function loadGoals() { + return api('GET', 'goals'); +}