import axios, { AxiosInstance, AxiosRequestConfig } from "axios"; const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:4000"; class ApiClient { private client: AxiosInstance; constructor() { this.client = axios.create({ baseURL: API_URL, headers: { "Content-Type": "application/json", }, }); this.client.interceptors.request.use((config) => { const token = typeof window !== "undefined" ? localStorage.getItem("auth_token") : null; if (token && token !== "null" && token !== "undefined") { config.headers.Authorization = `Bearer ${token}`; } return config; }); // /fayda/verification/* is used by guests filling out the passenger form, and a 401 // there just means the user canceled/closed the Fayda popup without completing it (no // valid verification session) — that should surface as an inline error on the page, // not force-clear the session and redirect to /login out from under them. const PUBLIC_PREFIXES = [ "/config/", "/auth/login", "/auth/register", "/passengers/me", "/fayda/verification", ]; this.client.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { const url: string = error.config?.url || ""; const isPublic = PUBLIC_PREFIXES.some((p) => url.includes(p)); if (!isPublic && typeof window !== "undefined") { localStorage.removeItem("auth_token"); localStorage.removeItem("auth_user"); // window.location.href = '/login'; } } return Promise.reject(error); }, ); } async get(url: string, config?: AxiosRequestConfig): Promise { const response = await this.client.get(url, config); // Handle both direct data and wrapped responses return response.data?.data || response.data; } async post( url: string, data?: any, config?: AxiosRequestConfig, ): Promise { const response = await this.client.post(url, data, config); return response.data?.data || response.data; } async put( url: string, data?: any, config?: AxiosRequestConfig, ): Promise { const response = await this.client.put(url, data, config); return response.data; } async patch( url: string, data?: any, config?: AxiosRequestConfig, ): Promise { const response = await this.client.patch(url, data, config); return response.data; } async delete(url: string, config?: AxiosRequestConfig): Promise { const response = await this.client.delete(url, config); return response.data; } } export const apiClient = new ApiClient();