/* ===================================================================== supporter.js — gemeinsame Helfer für abonnieren.html + supporter.html (Dogfather Supporter-Abo). Eigenes, von main.js/forms.js komplett getrenntes Token-System (localStorage-Key "supporterToken"), siehe cloudflare-worker/src/lib/supporter-auth.js. ===================================================================== */ (function () { const API_BASE = "https://postfach.dogfather-universe.com"; function getToken() { return localStorage.getItem("supporterToken") || ""; } function setToken(token) { localStorage.setItem("supporterToken", token); } function clearToken() { localStorage.removeItem("supporterToken"); localStorage.removeItem("supporterSubStatus"); localStorage.removeItem("supporterDisplayName"); } /* Wird vom Nav-Abo-Button in main.js gelesen (renderAboButton), damit die Beschriftung/das Ziel sofort beim nächsten Seitenwechsel stimmt, ohne dass main.js selbst einen API-Aufruf machen muss. */ function cacheSubStatus(status) { if (status) localStorage.setItem("supporterSubStatus", status); else localStorage.removeItem("supporterSubStatus"); } /* Name der eingeloggten Person (aus /supporter/me → profile.displayName) — damit der Nav-Knopf bei aktivem Abo statt des generischen "Supporter- Bereich" gleich den Benutzernamen zeigen kann (Nutzer-Feedback 03.08.2026). Wird von abonnieren.html/supporter.html nach jedem erfolgreichen /supporter/me-Aufruf gesetzt. */ function cacheDisplayName(name) { if (name) localStorage.setItem("supporterDisplayName", name); else localStorage.removeItem("supporterDisplayName"); } async function apiFetch(path, body, authed) { const headers = { "Content-Type": "application/json" }; if (authed) headers.Authorization = `Bearer ${getToken()}`; let res; try { res = await fetch(`${API_BASE}${path}`, { method: "POST", headers, body: JSON.stringify(body || {}) }); } catch { throw new Error("Verbindung zum Server fehlgeschlagen. Bitte prüfe deine Internetverbindung."); } let data = null; try { data = await res.json(); } catch { /* leere Antwort ist ok, z.B. bei manchen Fehlern */ } if (!res.ok || !data || data.ok === false) { const err = new Error((data && data.error) || `Anfrage fehlgeschlagen (${res.status}).`); err.code = data && data.code; err.status = res.status; throw err; } return data; } window.DogiSupporter = { API_BASE, getToken, setToken, clearToken, cacheSubStatus, cacheDisplayName, apiFetch }; })();