|
|
import axios, { AxiosInstance, AxiosError, InternalAxiosRequestConfig } from "axios"; |
|
|
import { toast } from "react-hot-toast"; |
|
|
|
|
|
|
|
|
|
|
|
const API_URL = process.env.NEXT_PUBLIC_API_URL === "" |
|
|
? "" |
|
|
: (process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"); |
|
|
|
|
|
|
|
|
const apiClient: AxiosInstance = axios.create({ |
|
|
baseURL: API_URL, |
|
|
timeout: 300000, |
|
|
headers: { |
|
|
"Content-Type": "application/json", |
|
|
}, |
|
|
}); |
|
|
|
|
|
|
|
|
apiClient.interceptors.request.use( |
|
|
(config: InternalAxiosRequestConfig) => { |
|
|
|
|
|
if (typeof window !== "undefined") { |
|
|
const authStorage = localStorage.getItem("auth-storage"); |
|
|
if (authStorage) { |
|
|
try { |
|
|
const auth = JSON.parse(authStorage); |
|
|
if (auth.state?.token) { |
|
|
config.headers.Authorization = `Bearer ${auth.state.token}`; |
|
|
} |
|
|
} catch (e) { |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
return config; |
|
|
}, |
|
|
(error) => { |
|
|
return Promise.reject(error); |
|
|
} |
|
|
); |
|
|
|
|
|
|
|
|
apiClient.interceptors.response.use( |
|
|
(response) => response, |
|
|
(error: AxiosError) => { |
|
|
if (error.response) { |
|
|
|
|
|
const status = error.response.status; |
|
|
const message = (error.response.data as any)?.detail || error.message || "An error occurred"; |
|
|
|
|
|
|
|
|
if (status === 401) { |
|
|
if (typeof window !== "undefined" && !window.location.pathname.includes("/login")) { |
|
|
|
|
|
localStorage.removeItem("auth-storage"); |
|
|
|
|
|
window.location.href = "/login"; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (status !== 404 && status !== 401) { |
|
|
toast.error(message); |
|
|
} |
|
|
} else if (error.request) { |
|
|
|
|
|
toast.error("Network error. Please check your connection."); |
|
|
} else { |
|
|
|
|
|
toast.error("An unexpected error occurred"); |
|
|
} |
|
|
|
|
|
return Promise.reject(error); |
|
|
} |
|
|
); |
|
|
|
|
|
export default apiClient; |
|
|
|