import axios from 'axios' // Create axios instance with base URL from environment variable const api = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || 'https://dev.servicefinder.hu', headers: { 'Content-Type': 'application/json', }, }) // Request interceptor to add auth token api.interceptors.request.use( (config) => { console.group('📤 Axios Request Interceptor - Flight Recorder'); console.log('📊 Request Details:'); console.log(' • URL:', config.url); console.log(' • Method:', config.method); console.log(' • Base URL:', config.baseURL); // Get token from localStorage (check both 'token' and 'access_token' for compatibility) if (typeof window !== 'undefined') { let token = localStorage.getItem('token'); if (!token) { token = localStorage.getItem('access_token'); if (token) { console.log('⚠️ Using access_token (legacy) instead of token'); } } if (token) { console.log('🔐 Adding Authorization header with token'); console.log(' • Token present:', token.substring(0, 20) + '...'); config.headers.Authorization = `Bearer ${token}`; } else { console.log('⚠️ No auth token found in localStorage'); console.log(' • token key:', localStorage.getItem('token') ? 'PRESENT' : 'MISSING'); console.log(' • access_token key:', localStorage.getItem('access_token') ? 'PRESENT' : 'MISSING'); } } else { console.log('🌐 Window not available (SSR)'); } console.groupEnd(); return config; }, (error) => { console.error('❌ Request interceptor error:', error); return Promise.reject(error); } ) // Response interceptor for error handling api.interceptors.response.use( (response) => response, (error) => { console.group('🚨 Axios Response Interceptor - Flight Recorder'); console.log('📊 Interceptor triggered for error:', error); if (error.response) { console.log('📡 Response Details:'); console.log(' • Status:', error.response.status); console.log(' • URL:', error.config?.url); console.log(' • Method:', error.config?.method); console.log(' • Headers:', error.config?.headers); if (error.response.status === 401) { console.warn('🔐 401 UNAUTHORIZED DETECTED!'); console.warn(' ↳ This will trigger logout and redirect'); // Log current auth state before clearing const token = localStorage.getItem('token'); const accessToken = localStorage.getItem('access_token'); console.log(' ↳ Current localStorage state:'); console.log(' - token:', token ? `YES (${token.substring(0, 20)}...)` : 'NO'); console.log(' - access_token:', accessToken ? `YES (${accessToken.substring(0, 20)}...)` : 'NO'); // Handle unauthorized - clear ALL auth tokens and redirect to login if (typeof window !== 'undefined') { console.log(' ↳ Clearing auth tokens from localStorage...'); localStorage.removeItem('token'); localStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); localStorage.removeItem('is_admin'); localStorage.removeItem('user_email'); localStorage.removeItem('user_role'); // Also try to call auth store logout if available try { const authStore = window.__pinia?.state.value?.auth; if (authStore && authStore.logout) { console.log(' ↳ Calling auth store logout()...'); // We can't call the function directly from here, but we can dispatch an event window.dispatchEvent(new CustomEvent('force-logout')); } } catch (e) { console.warn(' ↳ Could not access auth store:', e.message); } console.warn(' ↳ Redirecting to /login'); window.location.href = '/login'; } } else if (error.response.status === 403) { console.warn('🔒 403 FORBIDDEN DETECTED'); console.warn(' ↳ User lacks permissions for this resource'); } else if (error.response.status === 404) { console.warn('🔍 404 NOT FOUND DETECTED'); console.warn(' ↳ API endpoint or resource not found'); } else if (error.response.status >= 500) { console.error('💥 SERVER ERROR DETECTED (5xx)'); console.error(' ↳ Backend server issue'); } } else if (error.request) { console.error('🌐 NETWORK ERROR: Request was made but no response received'); console.error(' ↳ Possible network issue or CORS problem'); } else { console.error('⚙️ SETUP ERROR: Error in request configuration'); console.error(' ↳', error.message); } console.groupEnd(); return Promise.reject(error); } ) export default api // Catalog API functions export const catalogApi = { async getMakes() { const response = await api.get('/catalog/makes') return response.data }, async getModels(make) { const response = await api.get('/catalog/models', { params: { make } }) return response.data }, async getGenerations(make, model) { const response = await api.get('/catalog/generations', { params: { make, model } }) return response.data }, async getEngines(make, model, gen) { const response = await api.get('/catalog/engines', { params: { make, model, gen } }) return response.data } }