/** * 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"); } }; })();