Files
portal-api/resources/js/cart-skeleton.js
T
2025-07-29 08:53:41 +07:00

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;
}