// composables/useQueueAPI.ts // Composable untuk API calls terkait antrian pasien export interface Patient { no: number; jamPanggil: string; barcode: string; noAntrian: string; shift: string; klinik: string; fastTrack: string; pembayaran: string; status: 'waiting' | 'pending' | 'di-loket' | 'di-klinik' | 'selesai' | 'terlambat'; processStage: 'loket' | 'klinik' | 'penunjang'; createdAt: string; registrationType?: 'online' | 'onsite'; visitType?: string; visitDate?: string; } export interface QueueAPIResponse { success: boolean; data?: T; message?: string; error?: string; } export const useQueueAPI = () => { const config = useRuntimeConfig(); const baseURL = config.public.apiBaseUrl || '/api/queue'; /** * Fetch all patients from database */ const fetchAllPatients = async (): Promise => { try { const response = await $fetch>(`${baseURL}/patients`, { method: 'GET', }); if (response.success && response.data) { return response.data; } throw new Error(response.message || 'Failed to fetch patients'); } catch (error: any) { console.error('❌ Error fetching patients:', error); throw error; } }; /** * Fetch single patient by ID or barcode */ const fetchPatient = async (idOrBarcode: string): Promise => { try { const response = await $fetch>(`${baseURL}/patients/${idOrBarcode}`, { method: 'GET', }); if (response.success && response.data) { return response.data; } return null; } catch (error: any) { console.error('❌ Error fetching patient:', error); return null; } }; /** * Create new patient (register from Anjungan) */ const createPatient = async (patientData: Partial): Promise => { try { const response = await $fetch>(`${baseURL}/patients`, { method: 'POST', body: patientData, }); if (response.success && response.data) { return response.data; } throw new Error(response.message || 'Failed to create patient'); } catch (error: any) { console.error('❌ Error creating patient:', error); throw error; } }; /** * Update patient status (check-in, process, etc) */ const updatePatient = async ( idOrBarcode: string, updates: Partial ): Promise => { try { const response = await $fetch>( `${baseURL}/patients/${idOrBarcode}`, { method: 'PATCH', body: updates, } ); if (response.success && response.data) { return response.data; } throw new Error(response.message || 'Failed to update patient'); } catch (error: any) { console.error('❌ Error updating patient:', error); throw error; } }; /** * Check-in patient (update status to di-loket) */ const checkInPatient = async (idOrBarcode: string): Promise => { return updatePatient(idOrBarcode, { status: 'di-loket' }); }; /** * Process patient at loket (update status and processStage) */ const processPatientAtLoket = async ( idOrBarcode: string, updates: { status?: string; processStage?: string } ): Promise => { return updatePatient(idOrBarcode, updates); }; /** * Sync local state with database */ const syncWithDatabase = async (localPatients: Patient[]): Promise => { try { // Fetch latest from database const dbPatients = await fetchAllPatients(); // Merge strategy: prefer database data, but keep local if newer const merged = new Map(); // Add database patients dbPatients.forEach(patient => { merged.set(patient.barcode, patient); }); // Add local patients that don't exist in DB or are newer localPatients.forEach(localPatient => { const existing = merged.get(localPatient.barcode); if (!existing || new Date(localPatient.createdAt) > new Date(existing.createdAt)) { merged.set(localPatient.barcode, localPatient); } }); return Array.from(merged.values()); } catch (error: any) { console.error('❌ Error syncing with database:', error); // Return local patients as fallback return localPatients; } }; /** * Batch sync: save multiple patients to database */ const batchSyncPatients = async (patients: Patient[]): Promise => { try { const response = await $fetch(`${baseURL}/patients/batch`, { method: 'POST', body: { patients }, }); return response.success || false; } catch (error: any) { console.error('❌ Error batch syncing patients:', error); return false; } }; return { fetchAllPatients, fetchPatient, createPatient, updatePatient, checkInPatient, processPatientAtLoket, syncWithDatabase, batchSyncPatients, }; };