Files
SkyArtShop/website/public/assets/js/api-client.js
Local Server 1919f6f8bb updateweb
2026-01-01 22:24:30 -06:00

112 lines
2.6 KiB
JavaScript

/**
* API Client
* Centralized API communication with error handling
*/
(function () {
"use strict";
class APIClient {
constructor(baseURL = "") {
this.baseURL = baseURL;
this.defaultHeaders = {
"Content-Type": "application/json",
};
}
async request(endpoint, options = {}) {
const url = `${this.baseURL}${endpoint}`;
const config = {
...options,
headers: {
...this.defaultHeaders,
...options.headers,
},
};
try {
const response = await fetch(url, config);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
return await response.json();
}
return await response.text();
} catch (error) {
console.error(`API Error (${endpoint}):`, error);
throw error;
}
}
async get(endpoint, params = {}) {
const queryString = new URLSearchParams(params).toString();
const url = queryString ? `${endpoint}?${queryString}` : endpoint;
return this.request(url, { method: "GET" });
}
async post(endpoint, data = {}) {
return this.request(endpoint, {
method: "POST",
body: JSON.stringify(data),
});
}
async put(endpoint, data = {}) {
return this.request(endpoint, {
method: "PUT",
body: JSON.stringify(data),
});
}
async delete(endpoint) {
return this.request(endpoint, { method: "DELETE" });
}
// Product endpoints
async getProducts(params = {}) {
return this.get("/api/products", params);
}
async getProduct(id) {
return this.get(`/api/products/${id}`);
}
async getCategories() {
return this.get("/api/categories");
}
// Menu endpoints
async getMenu() {
return this.get("/api/menu");
}
// Homepage endpoints
async getHomepageSettings() {
return this.get("/api/homepage-settings");
}
}
// Create global instance
window.API = window.API || new APIClient();
// Helper function for loading states
window.withLoading = async function (element, asyncFn) {
if (!element) return asyncFn();
element.classList.add("loading");
element.setAttribute("aria-busy", "true");
try {
return await asyncFn();
} finally {
element.classList.remove("loading");
element.setAttribute("aria-busy", "false");
}
};
})();