import axios, { AxiosInstance, AxiosRequestConfig, AxiosError } from 'axios' const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000/api/v1' // Create axios instance export const apiClient: AxiosInstance = axios.create({ baseURL: API_BASE_URL, headers: { 'Content-Type': 'application/json', }, timeout: 30000, // 30 seconds }) // Request interceptor to add auth token apiClient.interceptors.request.use( (config) => { // Get token from localStorage (will be replaced with proper auth context) if (typeof window !== 'undefined') { const token = localStorage.getItem('access_token') if (token && config.headers) { config.headers.Authorization = `Bearer ${token}` } } return config }, (error) => { return Promise.reject(error) } ) // Response interceptor to handle token refresh apiClient.interceptors.response.use( (response) => response, async (error: AxiosError) => { const originalRequest = error.config as AxiosRequestConfig & { _retry?: boolean } // If 401 and we haven't retried yet, try to refresh token if (error.response?.status === 401 && !originalRequest._retry) { originalRequest._retry = true try { const refreshToken = localStorage.getItem('refresh_token') if (!refreshToken) { throw new Error('No refresh token available') } const response = await axios.post(`${API_BASE_URL}/auth/refresh`, { refresh_token: refreshToken, }) const { access_token } = response.data localStorage.setItem('access_token', access_token) // Retry original request with new token if (originalRequest.headers) { originalRequest.headers.Authorization = `Bearer ${access_token}` } return apiClient(originalRequest) } catch (refreshError) { // Refresh failed, clear tokens and redirect to login localStorage.removeItem('access_token') localStorage.removeItem('refresh_token') if (typeof window !== 'undefined') { window.location.href = '/login' } return Promise.reject(refreshError) } } return Promise.reject(error) } ) export default apiClient