import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' export interface ApiResponse { data: T meta?: { pagination?: { page: number page_size: number total: number total_pages: number } } } export interface ApiError { error: { code: string message: string details?: unknown request_id?: string } } class ApiClient { private client: AxiosInstance constructor(baseURL: string = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080') { this.client = axios.create({ baseURL, timeout: 30000, headers: { 'Content-Type': 'application/json', }, }) // Request interceptor this.client.interceptors.request.use( (config) => { // Add API key if available const apiKey = this.getApiKey() if (apiKey) { config.headers['X-API-Key'] = apiKey } return config }, (error) => Promise.reject(error) ) // Response interceptor this.client.interceptors.response.use( (response) => response, (error) => { // Handle errors if (error.response) { const apiError: ApiError = error.response.data return Promise.reject(apiError) } return Promise.reject(error) } ) } private getApiKey(): string | null { if (typeof window !== 'undefined') { return localStorage.getItem('api_key') } return null } async get(url: string, config?: AxiosRequestConfig): Promise> { const response: AxiosResponse> = await this.client.get(url, config) return response.data } async post(url: string, data?: unknown, config?: AxiosRequestConfig): Promise> { const response: AxiosResponse> = await this.client.post(url, data, config) return response.data } async put(url: string, data?: unknown, config?: AxiosRequestConfig): Promise> { const response: AxiosResponse> = await this.client.put(url, data, config) return response.data } async delete(url: string, config?: AxiosRequestConfig): Promise> { const response: AxiosResponse> = await this.client.delete(url, config) return response.data } } export const apiClient = new ApiClient()