import axios from "axios"; import { useAuthStore } from "@/stores/auth"; import { useToast } from "vue-toastification"; // Get the API base URL const getApiBaseUrl = () => { // If VITE_API_URL is set, use it if (import.meta.env.VITE_API_URL) { return import.meta.env.VITE_API_URL; } // In production, use the api subdomain if (import.meta.env.PROD) { const currentHost = window.location.hostname; const protocol = window.location.protocol; // If on turbotrades.dev, use api.turbotrades.dev if ( currentHost === "turbotrades.dev" || currentHost === "www.turbotrades.dev" ) { return `${protocol}//api.turbotrades.dev/api`; } // For other domains, try api subdomain return `${protocol}//api.${currentHost}/api`; } // In development, use relative path (Vite proxy handles it) return "/api"; }; // Create axios instance const axiosInstance = axios.create({ baseURL: getApiBaseUrl(), timeout: 15000, withCredentials: true, headers: { "Content-Type": "application/json", }, }); // Request interceptor axiosInstance.interceptors.request.use( (config) => { // You can add auth token to headers here if needed // const token = localStorage.getItem('token') // if (token) { // config.headers.Authorization = `Bearer ${token}` // } return config; }, (error) => { return Promise.reject(error); } ); // Response interceptor axiosInstance.interceptors.response.use( (response) => { return response; }, async (error) => { const toast = useToast(); const authStore = useAuthStore(); if (error.response) { const { status, data } = error.response; switch (status) { case 401: // Unauthorized - token expired or invalid if (data.code === "TokenExpired") { // Try to refresh token try { const refreshed = await authStore.refreshToken(); if (refreshed) { // Retry the original request return axiosInstance.request(error.config); } } catch (refreshError) { // Refresh failed, logout user authStore.clearUser(); window.location.href = "/"; } } else { authStore.clearUser(); toast.error("Please login to continue"); } break; case 403: // Forbidden toast.error(data.message || "Access denied"); break; case 404: // Not found toast.error(data.message || "Resource not found"); break; case 429: // Too many requests toast.error("Too many requests. Please slow down."); break; case 500: // Server error toast.error("Server error. Please try again later."); break; case 503: // Service unavailable - maintenance mode if (data.maintenance) { // Only redirect if user is not admin if (!authStore.isAdmin) { window.location.href = "/maintenance"; } // Don't show toast for maintenance, page will handle it return Promise.reject(error); } else { toast.error("Service temporarily unavailable"); } break; default: // Other errors if (data.message) { toast.error(data.message); } } } else if (error.request) { // Request made but no response toast.error("Network error. Please check your connection."); } else { // Something else happened toast.error("An unexpected error occurred"); } return Promise.reject(error); } ); export default axiosInstance;