import { Resource, Reservation, CreateReservationRequest } from '../types'; export interface LibreBookingAPIConfig { baseURL: string; apiKey?: string; timeout?: number; } class LibreBookingAPIClient { private config: LibreBookingAPIConfig; private baseUrl: string; constructor(config: LibreBookingAPIConfig) { this.config = config; this.baseUrl = config.baseURL.replace(/\/$/, ''); // Remove trailing slash } private async makeRequest( endpoint: string, options: RequestInit = {} ): Promise { const url = `${this.baseUrl}${endpoint}`; const headers: Record = { 'Content-Type': 'application/json', ...(options.headers as Record || {}), }; if (this.config.apiKey) { headers['Authorization'] = `Bearer ${this.config.apiKey}`; } try { const response = await fetch(url, { ...options, headers, signal: AbortSignal.timeout(this.config.timeout || 10000), }); if (!response.ok) { throw new Error(`API Error: ${response.status} ${response.statusText}`); } const contentType = response.headers.get('content-type'); if (contentType && contentType.includes('application/json')) { return await response.json(); } else { return response.text() as unknown as T; } } catch (error) { if (error instanceof Error) { throw new Error(`Network error: ${error.message}`); } throw error; } } // Resources async getResources(): Promise { return this.makeRequest('/api/resources'); } async getResource(id: string): Promise { return this.makeRequest(`/api/resources/${id}`); } // Reservations async getReservations(resourceId?: string): Promise { const params = resourceId ? `?resourceId=${resourceId}` : ''; return this.makeRequest(`/api/reservations${params}`); } async getReservation(id: string): Promise { return this.makeRequest(`/api/reservations/${id}`); } async createReservation(data: CreateReservationRequest): Promise { return this.makeRequest('/api/reservations', { method: 'POST', body: JSON.stringify(data), }); } async updateReservationStatus( id: string, status: 'confirmed' | 'cancelled' ): Promise { return this.makeRequest(`/api/reservations/${id}/status`, { method: 'PATCH', body: JSON.stringify({ status }), }); } async cancelReservation(id: string): Promise { return this.makeRequest(`/api/reservations/${id}/cancel`, { method: 'POST', }); } // Users (if needed for admin functions) async getUsers(): Promise { return this.makeRequest('/api/users'); } async getUserReservations(userId: string): Promise { return this.makeRequest(`/api/users/${userId}/reservations`); } } // Factory function to create API client with environment variables export function createLibreBookingClient( config?: Partial ): LibreBookingAPIClient { const defaultConfig: LibreBookingAPIConfig = { baseURL: process.env.REACT_APP_LIBREBOOKING_API_URL || 'http://localhost:8080', apiKey: process.env.REACT_APP_LIBREBOOKING_API_KEY, timeout: 10000, }; const finalConfig = { ...defaultConfig, ...config }; return new LibreBookingAPIClient(finalConfig); } // Example of how to integrate with the existing mock API export function integrateWithMockAPI(mockAPI: any) { return { getResources: mockAPI.getResources, getResource: mockAPI.getResource, getReservations: mockAPI.getReservations, createReservation: mockAPI.createReservation, updateReservationStatus: mockAPI.updateReservationStatus, }; }