import { useCallback, useEffect, useState } from 'react'; import { aktiverMandant } from './mandant'; export class ApiFehler extends Error { constructor( message: string, public status: number, ) { super(message); } } async function anfrage(pfad: string, init?: RequestInit): Promise { // Jeder Aufruf trägt den aktiven Mandanten; ohne Angabe wählt der Server. const slug = aktiverMandant(); const antwort = await fetch(pfad, { ...init, headers: { 'Content-Type': 'application/json', ...(slug ? { 'X-Mandant': slug } : {}), ...(init?.headers ?? {}), }, }); const text = await antwort.text(); const daten = text ? JSON.parse(text) : null; if (!antwort.ok) { throw new ApiFehler(daten?.fehler ?? `Fehler ${antwort.status}`, antwort.status); } return daten as T; } export const api = { get: (pfad: string) => anfrage(pfad), post: (pfad: string, body?: unknown) => anfrage(pfad, { method: 'POST', body: JSON.stringify(body ?? {}) }), put: (pfad: string, body: unknown) => anfrage(pfad, { method: 'PUT', body: JSON.stringify(body) }), del: (pfad: string) => anfrage(pfad, { method: 'DELETE' }), }; export function useDaten(pfad: string | null): { daten: T | null; fehler: string | null; laedt: boolean; neuLaden: () => void; } { const [daten, setDaten] = useState(null); const [fehler, setFehler] = useState(null); const [laedt, setLaedt] = useState(true); const [zaehler, setZaehler] = useState(0); useEffect(() => { if (!pfad) return; let abgebrochen = false; setLaedt(true); api .get(pfad) .then((d) => { if (!abgebrochen) { setDaten(d); setFehler(null); } }) .catch((e: Error) => !abgebrochen && setFehler(e.message)) .finally(() => !abgebrochen && setLaedt(false)); return () => { abgebrochen = true; }; }, [pfad, zaehler]); const neuLaden = useCallback(() => setZaehler((z) => z + 1), []); return { daten, fehler, laedt, neuLaden }; }