/** * API Helper for Physiotherapy Clinic Management System * Handles all API calls with centralized error handling */ class ApiClient { constructor() { this.baseUrl = '/api'; this.token = document.querySelector('meta[name="api-token"]')?.content; } getHeaders() { const headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content }; if (this.token) { headers['Authorization'] = `Bearer ${this.token}`; } return headers; } async request(url, options = {}) { const fullUrl = url.startsWith('http') ? url : `${this.baseUrl}${url}`; try { const response = await fetch(fullUrl, { ...options, headers: { ...this.getHeaders(), ...options.headers } }); const data = await response.json(); if (!response.ok) { this.handleError(data, response.status); throw new Error(data.message || 'Request failed'); } return data; } catch (error) { console.error('API Error:', error); throw error; } } handleError(data, status) { let message = data.message || 'An error occurred'; if (data.errors) { const errorMessages = Object.values(data.errors).flat(); message = errorMessages.join('\n'); } // Show AdminLTE toast $(document).Toasts('create', { class: status >= 500 ? 'bg-danger' : 'bg-warning', title: 'Error', body: message }); } showSuccess(message) { $(document).Toasts('create', { class: 'bg-success', title: 'Success', body: message }); } // Auth async login(credentials) { return this.request('/login', { method: 'POST', body: JSON.stringify(credentials) }); } async logout() { return this.request('/logout', { method: 'POST' }); } // Patients async getPatients(params = {}) { const query = new URLSearchParams(params).toString(); return this.request(`/patients?${query}`); } async getPatient(id) { return this.request(`/patients/${id}`); } async createPatient(data) { return this.request('/patients', { method: 'POST', body: JSON.stringify(data) }); } async updatePatient(id, data) { return this.request(`/patients/${id}`, { method: 'PUT', body: JSON.stringify(data) }); } async deletePatient(id) { return this.request(`/patients/${id}`, { method: 'DELETE' }); } // Appointments async getAppointments(params = {}) { const query = new URLSearchParams(params).toString(); return this.request(`/appointments?${query}`); } async createAppointment(data) { return this.request('/appointments', { method: 'POST', body: JSON.stringify(data) }); } async updateAppointment(id, data) { return this.request(`/appointments/${id}`, { method: 'PUT', body: JSON.stringify(data) }); } async getAvailableSlots(therapistId, date, duration = 60) { return this.request(`/appointments/available-slots?therapist_id=${therapistId}&date=${date}&duration=${duration}`); } // Dashboard async getDashboard() { return this.request('/dashboard'); } // Invoices async getInvoices(params = {}) { const query = new URLSearchParams(params).toString(); return this.request(`/invoices?${query}`); } // Payments async createPayment(data) { return this.request('/payments', { method: 'POST', body: JSON.stringify(data) }); } // Ledger async getLedgerSummary(startDate, endDate) { return this.request(`/ledger/summary/pl?date_from=${startDate}&date_to=${endDate}`); } } // Global instance window.api = new ApiClient();