| const API_BASE = import.meta.env.VITE_API_BASE_URL || (import.meta.env.DEV ? "http://localhost:8000" : ""); |
|
|
| const inFlightRequests = new Map(); |
|
|
| export const apiRequest = async (endpoint, method = "GET", body = null) => { |
| |
| if (method === "GET" && !body) { |
| if (inFlightRequests.has(endpoint)) { |
| return inFlightRequests.get(endpoint); |
| } |
| const promise = (async () => { |
| try { |
| return await _performRequest(endpoint, method, body); |
| } finally { |
| inFlightRequests.delete(endpoint); |
| } |
| })(); |
| inFlightRequests.set(endpoint, promise); |
| return promise; |
| } |
|
|
| return _performRequest(endpoint, method, body); |
| }; |
|
|
| const _performRequest = async (endpoint, method = "GET", body = null) => { |
| const token = localStorage.getItem("token"); |
| const headers = {}; |
|
|
| if (!(body instanceof FormData)) { |
| headers["Content-Type"] = "application/json"; |
| } |
|
|
| if (token) { |
| headers["Authorization"] = `Bearer ${token}`; |
| } |
|
|
| const response = await fetch(API_BASE + endpoint, { |
| method, |
| headers, |
| body: body instanceof FormData ? body : body ? JSON.stringify(body) : null, |
| }); |
|
|
| |
| if (response.status === 401 && endpoint !== "/auth/login" && endpoint !== "/auth/me") { |
| localStorage.removeItem("token"); |
| window.location.href = "/login"; |
| return { detail: "Session expired" }; |
| } |
|
|
| |
| if (response.status === 204) { |
| return { ok: true }; |
| } |
|
|
| return response.json(); |
| }; |
|
|
| export const loginRequest = async (email, password) => { |
| const formData = new URLSearchParams(); |
| formData.append("username", email); |
| formData.append("password", password); |
|
|
| const response = await fetch(API_BASE + "/auth/login", { |
| method: "POST", |
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, |
| body: formData, |
| }); |
|
|
| return response.json(); |
| }; |
|
|
| export const demoLoginRequest = async () => { |
| const response = await fetch(API_BASE + "/auth/demo-login", { |
| method: "POST", |
| headers: { "Content-Type": "application/json" }, |
| }); |
|
|
| return response.json(); |
| }; |
|
|