// Simplified API client that handles all the complexity in one place // Use empty string for relative URLs when no API URL is specified const API_BASE_URL = import.meta.env.VITE_API_URL || ''; class ApiClient { private baseURL: string; constructor(baseURL: string) { this.baseURL = baseURL; } private getAuthHeaders(): HeadersInit { const token = localStorage.getItem('authToken'); return { 'Content-Type': 'application/json', ...(token && { Authorization: `Bearer ${token}` }) }; } private async handleResponse(response: Response): Promise { if (!response.ok) { const error = await response.json().catch(() => ({ error: response.statusText })); throw new Error(error.error?.message || error.error || `Request failed: ${response.status}`); } return response.json(); } // Generic request method private async request(endpoint: string, options: RequestInit = {}): Promise { const url = `${this.baseURL}${endpoint}`; const response = await fetch(url, { ...options, headers: { ...this.getAuthHeaders(), ...options.headers } }); return this.handleResponse(response); } // Convenience methods async get(endpoint: string): Promise { return this.request(endpoint); } async post(endpoint: string, data?: any): Promise { return this.request(endpoint, { method: 'POST', body: data ? JSON.stringify(data) : undefined }); } async put(endpoint: string, data?: any): Promise { return this.request(endpoint, { method: 'PUT', body: data ? JSON.stringify(data) : undefined }); } async delete(endpoint: string): Promise { return this.request(endpoint, { method: 'DELETE' }); } async patch(endpoint: string, data?: any): Promise { return this.request(endpoint, { method: 'PATCH', body: data ? JSON.stringify(data) : undefined }); } } // Export a singleton instance export const api = new ApiClient(API_BASE_URL); // Export specific API methods for better type safety and convenience export const vipApi = { list: () => api.get('/api/vips'), get: (id: string) => api.get(`/api/vips/${id}`), create: (data: any) => api.post('/api/vips', data), update: (id: string, data: any) => api.put(`/api/vips/${id}`, data), delete: (id: string) => api.delete(`/api/vips/${id}`), getSchedule: (id: string) => api.get(`/api/vips/${id}/schedule`) }; export const driverApi = { list: () => api.get('/api/drivers'), get: (id: string) => api.get(`/api/drivers/${id}`), create: (data: any) => api.post('/api/drivers', data), update: (id: string, data: any) => api.put(`/api/drivers/${id}`, data), delete: (id: string) => api.delete(`/api/drivers/${id}`), getSchedule: (id: string) => api.get(`/api/drivers/${id}/schedule`) }; export const scheduleApi = { create: (vipId: string, data: any) => api.post(`/api/vips/${vipId}/schedule`, data), update: (vipId: string, eventId: string, data: any) => api.put(`/api/vips/${vipId}/schedule/${eventId}`, data), delete: (vipId: string, eventId: string) => api.delete(`/api/vips/${vipId}/schedule/${eventId}`), updateStatus: (vipId: string, eventId: string, status: string) => api.patch(`/api/vips/${vipId}/schedule/${eventId}/status`, { status }) }; export const authApi = { me: () => api.get('/auth/me'), logout: () => api.post('/auth/logout'), setup: () => api.get('/auth/setup'), googleCallback: (code: string) => api.post('/auth/google/callback', { code }) };