/** * Cart Skeleton Loading Utility * Manages loading states for cart components */ class CartSkeletonManager { constructor() { this.loadingStates = new Map(); this.defaultLoadingTime = 1000; // 1 second } /** * Show skeleton loading for a component * @param {string} componentId - Component identifier * @param {number} duration - Loading duration in ms */ showSkeleton(componentId, duration = this.defaultLoadingTime) { this.loadingStates.set(componentId, true); this.updateComponentState(componentId, true); // Auto hide after duration setTimeout(() => { this.hideSkeleton(componentId); }, duration); } /** * Hide skeleton loading for a component * @param {string} componentId - Component identifier */ hideSkeleton(componentId) { this.loadingStates.set(componentId, false); this.updateComponentState(componentId, false); } /** * Update component loading state * @param {string} componentId - Component identifier * @param {boolean} isLoading - Loading state */ updateComponentState(componentId, isLoading) { const component = document.querySelector(`[data-skeleton-id="${componentId}"]`); if (component && component._x_dataStack) { const alpineData = component._x_dataStack[0]; if (alpineData && typeof alpineData.loading !== 'undefined') { alpineData.loading = isLoading; } } } /** * Show skeleton for multiple components * @param {Array} componentIds - Array of component identifiers * @param {number} duration - Loading duration in ms */ showMultipleSkeletons(componentIds, duration = this.defaultLoadingTime) { componentIds.forEach(id => this.showSkeleton(id, duration)); } /** * Hide skeleton for multiple components * @param {Array} componentIds - Array of component identifiers */ hideMultipleSkeletons(componentIds) { componentIds.forEach(id => this.hideSkeleton(id)); } /** * Check if component is loading * @param {string} componentId - Component identifier * @returns {boolean} Loading state */ isLoading(componentId) { return this.loadingStates.get(componentId) || false; } /** * Simulate loading for cart initialization */ simulateCartLoading() { const components = ['domain-input', 'product-details', 'os-selection', 'addons-summary']; this.showMultipleSkeletons(components, 800); } /** * Simulate loading for OS selection */ simulateOsLoading() { this.showSkeleton('os-selection', 600); } /** * Simulate loading for addons */ simulateAddonsLoading() { this.showSkeleton('addons-summary', 500); } } // Global instance window.cartSkeleton = new CartSkeletonManager(); // Alpine.js plugin for skeleton loading document.addEventListener('alpine:init', () => { Alpine.plugin('skeleton', (Alpine) => { Alpine.magic('skeleton', () => ({ show: (componentId, duration) => window.cartSkeleton.showSkeleton(componentId, duration), hide: (componentId) => window.cartSkeleton.hideSkeleton(componentId), isLoading: (componentId) => window.cartSkeleton.isLoading(componentId) })); }); }); // Auto-initialize skeleton loading for cart page document.addEventListener('DOMContentLoaded', () => { if (document.querySelector('[data-cart-page]')) { // Simulate initial loading setTimeout(() => { window.cartSkeleton.simulateCartLoading(); }, 100); } }); // Export for module usage if (typeof module !== 'undefined' && module.exports) { module.exports = CartSkeletonManager; }