106 lines
2.6 KiB
TypeScript
106 lines
2.6 KiB
TypeScript
// composables/useAPI.ts
|
|
// Generic API composable untuk semua API calls
|
|
// Base composable yang bisa di-extend untuk specific resources
|
|
|
|
export interface APIResponse<T = any> {
|
|
success: boolean;
|
|
data?: T;
|
|
message?: string;
|
|
error?: string;
|
|
}
|
|
|
|
export const useAPI = () => {
|
|
const config = useRuntimeConfig();
|
|
const baseURL = config.public.apiBaseUrl || '/api';
|
|
|
|
/**
|
|
* Generic GET request
|
|
*/
|
|
const get = async <T = any>(endpoint: string, options: any = {}): Promise<T> => {
|
|
try {
|
|
const response = await $fetch<APIResponse<T>>(`${baseURL}${endpoint}`, {
|
|
method: 'GET',
|
|
...options,
|
|
});
|
|
|
|
if (response.success && response.data !== undefined) {
|
|
return response.data;
|
|
}
|
|
throw new Error(response.message || 'Failed to fetch data');
|
|
} catch (error: any) {
|
|
console.error(`❌ Error GET ${endpoint}:`, error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Generic POST request
|
|
*/
|
|
const post = async <T = any>(endpoint: string, body: any, options: any = {}): Promise<T> => {
|
|
try {
|
|
const response = await $fetch<APIResponse<T>>(`${baseURL}${endpoint}`, {
|
|
method: 'POST',
|
|
body,
|
|
...options,
|
|
});
|
|
|
|
if (response.success && response.data !== undefined) {
|
|
return response.data;
|
|
}
|
|
throw new Error(response.message || 'Failed to create data');
|
|
} catch (error: any) {
|
|
console.error(`❌ Error POST ${endpoint}:`, error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Generic PATCH request
|
|
*/
|
|
const patch = async <T = any>(endpoint: string, body: any, options: any = {}): Promise<T> => {
|
|
try {
|
|
const response = await $fetch<APIResponse<T>>(`${baseURL}${endpoint}`, {
|
|
method: 'PATCH',
|
|
body,
|
|
...options,
|
|
});
|
|
|
|
if (response.success && response.data !== undefined) {
|
|
return response.data;
|
|
}
|
|
throw new Error(response.message || 'Failed to update data');
|
|
} catch (error: any) {
|
|
console.error(`❌ Error PATCH ${endpoint}:`, error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Generic DELETE request
|
|
*/
|
|
const del = async <T = any>(endpoint: string, options: any = {}): Promise<T> => {
|
|
try {
|
|
const response = await $fetch<APIResponse<T>>(`${baseURL}${endpoint}`, {
|
|
method: 'DELETE',
|
|
...options,
|
|
});
|
|
|
|
if (response.success) {
|
|
return response.data as T;
|
|
}
|
|
throw new Error(response.message || 'Failed to delete data');
|
|
} catch (error: any) {
|
|
console.error(`❌ Error DELETE ${endpoint}:`, error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
return {
|
|
get,
|
|
post,
|
|
patch,
|
|
delete: del,
|
|
};
|
|
};
|
|
|