import axios, { AxiosError } from 'axios' import type { LoginRequest, TokenResponse, UserRegister, RegistrationResponse, EmailVerificationRequest, VerificationResponse, Space, User, Settings, Booking, BookingCreate, BookingUpdate, BookingAdminCreate, BookingTemplate, BookingTemplateCreate, Notification, AuditLog, Attachment, RecurringBookingCreate, RecurringBookingResult, SpaceUsageReport, TopUsersReport, ApprovalRateReport } from '@/types' const api = axios.create({ baseURL: '/api', headers: { 'Content-Type': 'application/json' } }) // Add token to requests api.interceptors.request.use((config) => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) // Auth API export const authApi = { login: async (credentials: LoginRequest): Promise => { const response = await api.post('/auth/login', credentials) return response.data }, register: async (data: UserRegister): Promise => { const response = await api.post('/auth/register', data) return response.data }, verifyEmail: async (data: EmailVerificationRequest): Promise => { const response = await api.post('/auth/verify', data) return response.data }, resendVerification: async (email: string): Promise<{ message: string }> => { const response = await api.post<{ message: string }>('/auth/resend-verification', null, { params: { email } }) return response.data } } // Users API export const usersApi = { me: async (): Promise => { const response = await api.get('/users/me') return response.data }, list: async (params?: { role?: string; organization?: string }): Promise => { const response = await api.get('/admin/users', { params }) return response.data }, create: async ( data: Omit & { password: string } ): Promise => { const response = await api.post('/admin/users', data) return response.data }, update: async ( id: number, data: Partial> ): Promise => { const response = await api.put(`/admin/users/${id}`, data) return response.data }, updateStatus: async (id: number, is_active: boolean): Promise => { const response = await api.patch(`/admin/users/${id}/status`, { is_active }) return response.data }, resetPassword: async (id: number, new_password: string): Promise => { const response = await api.post(`/admin/users/${id}/reset-password`, { new_password }) return response.data }, getTimezones: async (): Promise => { const response = await api.get('/users/timezones') return response.data }, updateTimezone: async (timezone: string): Promise<{ message: string; timezone: string }> => { const response = await api.put<{ message: string; timezone: string }>('/users/me/timezone', { timezone }) return response.data } } // Spaces API export const spacesApi = { list: async (): Promise => { const response = await api.get('/spaces') return response.data }, create: async (data: Omit): Promise => { const response = await api.post('/admin/spaces', data) return response.data }, update: async (id: number, data: Omit): Promise => { const response = await api.put(`/admin/spaces/${id}`, data) return response.data }, updateStatus: async (id: number, is_active: boolean): Promise => { const response = await api.patch(`/admin/spaces/${id}/status`, { is_active }) return response.data } } // Settings API export const settingsApi = { get: async (): Promise => { const response = await api.get('/admin/settings') return response.data }, update: async (data: Omit): Promise => { const response = await api.put('/admin/settings', data) return response.data } } // Bookings API export const bookingsApi = { getForSpace: async (spaceId: number, start: string, end: string): Promise => { const response = await api.get(`/spaces/${spaceId}/bookings`, { params: { start, end } }) return response.data }, checkAvailability: async (params: { space_id: number start_datetime: string end_datetime: string }) => { return api.get('/bookings/check-availability', { params }) }, create: async (data: BookingCreate): Promise => { const response = await api.post('/bookings', data) return response.data }, getMy: async (status?: string): Promise => { const response = await api.get('/bookings/my', { params: status ? { status } : {} }) return response.data }, update: async (id: number, data: BookingUpdate): Promise => { const response = await api.put(`/bookings/${id}`, data) return response.data }, createRecurring: async (data: RecurringBookingCreate): Promise => { const response = await api.post('/bookings/recurring', data) return response.data }, getMyCalendar: async (start: string, end: string): Promise => { const response = await api.get('/bookings/my/calendar', { params: { start, end } }) return response.data } } // Admin Bookings API export const adminBookingsApi = { getAll: async (params?: { status?: string space_id?: number user_id?: number start?: string limit?: number }): Promise => { const response = await api.get('/admin/bookings/all', { params }) return response.data }, getPending: async (filters?: { space_id?: number; user_id?: number }): Promise => { const response = await api.get('/admin/bookings/pending', { params: filters }) return response.data }, approve: async (id: number): Promise => { const response = await api.put(`/admin/bookings/${id}/approve`) return response.data }, reject: async (id: number, reason?: string): Promise => { const response = await api.put(`/admin/bookings/${id}/reject`, { reason }) return response.data }, update: async (id: number, data: BookingUpdate): Promise => { const response = await api.put(`/admin/bookings/${id}`, data) return response.data }, reschedule: async ( id: number, data: { start_datetime: string; end_datetime: string } ): Promise => { const response = await api.put(`/admin/bookings/${id}/reschedule`, data) return response.data }, create: async (data: BookingAdminCreate): Promise => { const response = await api.post('/admin/bookings', data) return response.data } } // Notifications API export const notificationsApi = { getAll: async (isRead?: boolean): Promise => { const params = isRead !== undefined ? { is_read: isRead } : {} const response = await api.get('/notifications', { params }) return response.data }, markAsRead: async (id: number): Promise => { const response = await api.put(`/notifications/${id}/read`) return response.data } } // Audit Log API export const auditLogApi = { getAll: async (params?: { action?: string start_date?: string end_date?: string page?: number limit?: number }): Promise => { const response = await api.get('/admin/audit-log', { params }) return response.data } } // Booking Templates API export const bookingTemplatesApi = { getAll: async (): Promise => { const response = await api.get('/booking-templates') return response.data }, create: async (data: BookingTemplateCreate): Promise => { const response = await api.post('/booking-templates', data) return response.data }, delete: async (id: number): Promise => { await api.delete(`/booking-templates/${id}`) }, createBookingFromTemplate: async ( templateId: number, startDatetime: string ): Promise => { const response = await api.post( `/booking-templates/from-template/${templateId}`, null, { params: { start_datetime: startDatetime } } ) return response.data } } // Attachments API export const attachmentsApi = { upload: async (bookingId: number, file: File): Promise => { const formData = new FormData() formData.append('file', file) const response = await api.post(`/bookings/${bookingId}/attachments`, formData, { headers: { 'Content-Type': 'multipart/form-data' } }) return response.data }, list: async (bookingId: number): Promise => { const response = await api.get(`/bookings/${bookingId}/attachments`) return response.data }, download: (attachmentId: number): string => { return `/api/attachments/${attachmentId}/download` }, delete: async (attachmentId: number): Promise => { await api.delete(`/attachments/${attachmentId}`) } } // Reports API export const reportsApi = { getUsage: async (params?: { start_date?: string end_date?: string space_id?: number }): Promise => { const response = await api.get('/admin/reports/usage', { params }) return response.data }, getTopUsers: async (params?: { start_date?: string end_date?: string limit?: number }): Promise => { const response = await api.get('/admin/reports/top-users', { params }) return response.data }, getApprovalRate: async (params?: { start_date?: string end_date?: string }): Promise => { const response = await api.get('/admin/reports/approval-rate', { params }) return response.data } } // Google Calendar API export const googleCalendarApi = { connect: async (): Promise<{ authorization_url: string; state: string }> => { const response = await api.get<{ authorization_url: string; state: string }>( '/integrations/google/connect' ) return response.data }, disconnect: async (): Promise<{ message: string }> => { const response = await api.post<{ message: string }>('/integrations/google/disconnect') return response.data }, sync: async (): Promise<{ synced: number; created: number; updated: number; failed: number; total_bookings: number }> => { const response = await api.post<{ synced: number; created: number; updated: number; failed: number; total_bookings: number }>( '/integrations/google/sync' ) return response.data }, status: async (): Promise<{ connected: boolean; expires_at: string | null }> => { const response = await api.get<{ connected: boolean; expires_at: string | null }>( '/integrations/google/status' ) return response.data } } // Helper to handle API errors export const handleApiError = (error: unknown): string => { if (error instanceof AxiosError) { return error.response?.data?.detail || error.message } return 'An unexpected error occurred' } export default api