// src/api/axios.ts import axios, { AxiosInstance, AxiosRequestConfig } from "axios"; class ApiClient { private client: AxiosInstance; constructor() { this.client = axios.create({ timeout: 60000, withCredentials: true, }); // Request interceptor for auth headers, content-type, etc. this.client.interceptors.request.use((config) => { // Content-type negotiation config.headers["Accept"] = "application/json"; config.headers["X-Requested-With"] = "nidus-web 0.1"; // Add auth token if logged in const token = localStorage.getItem("authToken"); if (token) { config.headers["Authorization"] = `Bearer ${token}`; } return config; }); // Response interceptor for handling auth errors this.client.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { // Could emit event or redirect here } return Promise.reject(error); }, ); } async JSONGet(url: string, config?: AxiosRequestConfig): Promise { const response = await this.client.get(url, { ...config, headers: { Accept: "application/json", ...config?.headers, }, }); return response.data; } async JSONPost( url: string, data?: any, config?: AxiosRequestConfig, ): Promise { const response = await this.client.post(url, data, { ...config, headers: { "Content-Type": "application/json", Accept: "application/json", ...config?.headers, }, }); return response.data; } async JSONPut( url: string, data?: any, config?: AxiosRequestConfig, ): Promise { const response = await this.client.put(url, data, { ...config, headers: { "Content-Type": "application/json", Accept: "application/json", ...config?.headers, }, }); return response.data; } async JSONDelete( url: string, config?: AxiosRequestConfig, ): Promise { const response = await this.client.delete(url, config); return response.data; } } // Single instance export - this IS the singleton export const apiClient = new ApiClient();