161 lines
3.9 KiB
TypeScript
161 lines
3.9 KiB
TypeScript
// composables/useClinicAPI.ts
|
|
// Composable untuk API calls terkait klinik/poli
|
|
|
|
import { useAPI } from './useAPI';
|
|
|
|
export interface Clinic {
|
|
id: number;
|
|
kode: string;
|
|
name: string;
|
|
subtitle?: string;
|
|
icon?: string;
|
|
shift?: string;
|
|
schedule?: string;
|
|
available?: boolean;
|
|
doctors?: string[];
|
|
shifts?: Array<{ name: string; quota: number }>;
|
|
totalQuota?: number;
|
|
jamShiftList?: Array<{ dari: string; sampai: string; kuota: number }>;
|
|
autoShift?: boolean;
|
|
jadwalKlinik?: string[];
|
|
}
|
|
|
|
export const useClinicAPI = () => {
|
|
const api = useAPI();
|
|
|
|
/**
|
|
* Fetch all clinics from database
|
|
*/
|
|
const fetchAllClinics = async (): Promise<Clinic[]> => {
|
|
try {
|
|
return await api.get<Clinic[]>('/clinics');
|
|
} catch (error: any) {
|
|
console.error('❌ Error fetching clinics:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fetch single clinic by ID
|
|
*/
|
|
const fetchClinic = async (id: number): Promise<Clinic | null> => {
|
|
try {
|
|
return await api.get<Clinic>(`/clinics/${id}`);
|
|
} catch (error: any) {
|
|
console.error('❌ Error fetching clinic:', error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fetch clinics by kode
|
|
*/
|
|
const fetchClinicByKode = async (kode: string): Promise<Clinic | null> => {
|
|
try {
|
|
return await api.get<Clinic>(`/clinics/kode/${kode}`);
|
|
} catch (error: any) {
|
|
console.error('❌ Error fetching clinic by kode:', error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Create new clinic
|
|
*/
|
|
const createClinic = async (clinicData: Partial<Clinic>): Promise<Clinic> => {
|
|
try {
|
|
return await api.post<Clinic>('/clinics', clinicData);
|
|
} catch (error: any) {
|
|
console.error('❌ Error creating clinic:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Update clinic
|
|
*/
|
|
const updateClinic = async (id: number, updates: Partial<Clinic>): Promise<Clinic> => {
|
|
try {
|
|
return await api.patch<Clinic>(`/clinics/${id}`, updates);
|
|
} catch (error: any) {
|
|
console.error('❌ Error updating clinic:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Delete clinic
|
|
*/
|
|
const deleteClinic = async (id: number): Promise<boolean> => {
|
|
try {
|
|
await api.delete(`/clinics/${id}`);
|
|
return true;
|
|
} catch (error: any) {
|
|
console.error('❌ Error deleting clinic:', error);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get clinics for dropdown (formatted for dropdown use)
|
|
*/
|
|
const fetchClinicsForDropdown = async (): Promise<Clinic[]> => {
|
|
try {
|
|
const clinics = await fetchAllClinics();
|
|
// Format sesuai kebutuhan dropdown
|
|
return clinics.map(clinic => ({
|
|
id: clinic.id,
|
|
name: clinic.name,
|
|
kode: clinic.kode,
|
|
icon: clinic.icon,
|
|
available: clinic.available ?? true,
|
|
}));
|
|
} catch (error: any) {
|
|
console.error('❌ Error fetching clinics for dropdown:', error);
|
|
return [];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Sync local clinics with database
|
|
*/
|
|
const syncWithDatabase = async (localClinics: Clinic[]): Promise<Clinic[]> => {
|
|
try {
|
|
const dbClinics = await fetchAllClinics();
|
|
|
|
// Merge strategy: prefer database data
|
|
const merged = new Map<number, Clinic>();
|
|
|
|
// Add database clinics
|
|
dbClinics.forEach(clinic => {
|
|
merged.set(clinic.id, clinic);
|
|
});
|
|
|
|
// Add local clinics that don't exist in DB
|
|
localClinics.forEach(localClinic => {
|
|
if (!merged.has(localClinic.id)) {
|
|
merged.set(localClinic.id, localClinic);
|
|
}
|
|
});
|
|
|
|
return Array.from(merged.values());
|
|
} catch (error: any) {
|
|
console.error('❌ Error syncing clinics with database:', error);
|
|
// Return local clinics as fallback
|
|
return localClinics;
|
|
}
|
|
};
|
|
|
|
return {
|
|
fetchAllClinics,
|
|
fetchClinic,
|
|
fetchClinicByKode,
|
|
createClinic,
|
|
updateClinic,
|
|
deleteClinic,
|
|
fetchClinicsForDropdown,
|
|
syncWithDatabase,
|
|
};
|
|
};
|
|
|