106 lines
2.7 KiB
JavaScript
106 lines
2.7 KiB
JavaScript
// assets/js/utils/api.js
|
|
const ApiUtils = {
|
|
call: async (endpoint, options = {}) => {
|
|
const token = AuthUtils.getToken();
|
|
const defaultOptions = {
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
...(token && { Authorization: `Bearer ${token}` }),
|
|
},
|
|
};
|
|
|
|
const finalOptions = { ...defaultOptions, ...options };
|
|
if (options.headers) {
|
|
finalOptions.headers = { ...defaultOptions.headers, ...options.headers };
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(
|
|
`${CONFIG.API_URL}${endpoint}`,
|
|
finalOptions
|
|
);
|
|
|
|
// 1. Cek jika Unauthorized (401)
|
|
if (response.status === 401) {
|
|
AuthUtils.clearAuth();
|
|
window.location.href = "/login";
|
|
return;
|
|
}
|
|
|
|
// 2. Cek apakah response valid JSON
|
|
const contentType = response.headers.get("content-type");
|
|
if (!contentType || !contentType.includes("application/json")) {
|
|
// Jika bukan JSON (misal text "200 OK" atau HTML error page)
|
|
const text = await response.text();
|
|
console.error("API Error (Non-JSON Response):", text);
|
|
throw new Error("Server returned invalid response format");
|
|
}
|
|
|
|
// 3. Parse JSON dengan aman
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
throw new Error(data.error || data.message || "Request failed");
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error("Fetch error:", error);
|
|
throw error;
|
|
}
|
|
},
|
|
|
|
get: async (endpoint) => {
|
|
return ApiUtils.call(endpoint, { method: "GET" });
|
|
},
|
|
|
|
post: async (endpoint, body) => {
|
|
return ApiUtils.call(endpoint, {
|
|
method: "POST",
|
|
body: JSON.stringify(body),
|
|
});
|
|
},
|
|
|
|
put: async (endpoint, body) => {
|
|
return ApiUtils.call(endpoint, {
|
|
method: "PUT",
|
|
body: JSON.stringify(body),
|
|
});
|
|
},
|
|
|
|
patch: async (endpoint, body) => {
|
|
return ApiUtils.call(endpoint, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(body),
|
|
});
|
|
},
|
|
|
|
delete: async (endpoint) => {
|
|
return ApiUtils.call(endpoint, { method: "DELETE" });
|
|
},
|
|
|
|
uploadFile: async (endpoint, formData) => {
|
|
const token = AuthUtils.getToken();
|
|
|
|
const response = await fetch(`${CONFIG.API_URL}${endpoint}`, {
|
|
method: "POST",
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
body: formData,
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
if (response.status === 401) {
|
|
AuthUtils.clearAuth();
|
|
window.location.href = "/login";
|
|
}
|
|
throw new Error(data.error || "Upload failed");
|
|
}
|
|
|
|
return data;
|
|
},
|
|
};
|