const BASE = "/api/v1"; function getToken(): string | null { return localStorage.getItem("rh_token"); } export function setToken(token: string): void { localStorage.setItem("rh_token", token); } export function clearToken(): void { localStorage.removeItem("rh_token"); } async function request( path: string, options: RequestInit = {}, isFormData = false ): Promise { const token = getToken(); const headers: Record = { ...(options.headers as Record), }; if (!isFormData) { headers["Content-Type"] = "application/json"; } if (token) { headers["Authorization"] = `Bearer ${token}`; } const resp = await fetch(`${BASE}${path}`, { ...options, headers }); if (!resp.ok) { if (resp.status === 401) { clearToken(); window.location.href = "/login"; throw new Error("Session expired"); } const error = await resp.json().catch(() => ({ detail: resp.statusText })); throw new Error(error.detail ?? resp.statusText); } if (resp.status === 204) return undefined as T; return resp.json(); } export const api = { get: (path: string) => request(path), post: (path: string, body: unknown) => request(path, { method: "POST", body: JSON.stringify(body) }), upload: (path: string, formData: FormData) => request(path, { method: "POST", body: formData }, true), patch: (path: string, body: unknown) => request(path, { method: "PATCH", body: JSON.stringify(body) }), delete: (path: string) => request(path, { method: "DELETE" }), };