127 lines
3.8 KiB
JavaScript
127 lines
3.8 KiB
JavaScript
/**
|
|
* 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;
|
|
}
|