UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

525 lines (522 loc) 17.4 kB
'use client'; import { jsx } from 'react/jsx-runtime'; import { useState, useCallback, createContext, useContext } from 'react'; const EcommerceContext = /*#__PURE__*/createContext(null); // Mock AI recommendation engine const mockRecommendationEngine = { async generateRecommendations(productId, products) { await new Promise(resolve => setTimeout(resolve, 1000)); // Simulate API call const product = products.find(p => p.id === productId); if (!product) return []; // Generate different types of recommendations const recommendations = []; // Similar products (same category) const similarProducts = products.filter(p => p.id !== productId && p.category === product.category && Math.abs(p.price - product.price) / product.price < 0.5).slice(0, 3); similarProducts.forEach(p => { recommendations.push({ productId: p.id, product: p, score: 0.8 + Math.random() * 0.2, reason: 'similar', explanation: `Similar to ${product.name} in ${product.category} category`, confidence: 0.75 + Math.random() * 0.2 }); }); // Trending products const trendingProducts = products.filter(p => p.id !== productId && (p.isBestseller || p.isNew)).slice(0, 2); trendingProducts.forEach(p => { recommendations.push({ productId: p.id, product: p, score: 0.7 + Math.random() * 0.2, reason: 'trending', explanation: p.isBestseller ? 'Bestseller in our store' : 'New arrival that\'s gaining popularity', confidence: 0.8 + Math.random() * 0.15 }); }); // Frequently bought together (mock) const complementaryProducts = products.filter(p => p.id !== productId && p.category !== product.category && p.price < product.price * 0.5).slice(0, 2); complementaryProducts.forEach(p => { recommendations.push({ productId: p.id, product: p, score: 0.6 + Math.random() * 0.3, reason: 'bought-together', explanation: `Frequently purchased with ${product.name}`, confidence: 0.6 + Math.random() * 0.3 }); }); return recommendations.sort((a, b) => b.score - a.score).slice(0, 8); } }; const EcommerceProvider = ({ children }) => { const [products, setProducts] = useState([]); const [cart, setCart] = useState([]); const [wishlist, setWishlist] = useState([]); const [recommendations, setRecommendations] = useState({}); const [comparisons, setComparisons] = useState([]); const [reviews, setReviews] = useState({}); const [priceHistory, setPriceHistory] = useState({}); const [searchQuery, setSearchQuery] = useState(''); const [filters, setFilters] = useState({}); const [sortBy, setSortBy] = useState('relevance'); const [selectedShipping, setSelectedShipping] = useState(); const [selectedPayment, setSelectedPayment] = useState(); // Mock shipping and payment options const shippingOptions = [{ id: 'standard', name: 'Standard Shipping', description: 'Free shipping on orders over $50', price: 0, estimatedDays: 5, trackingAvailable: true, insuranceIncluded: false }, { id: 'express', name: 'Express Shipping', description: 'Fast delivery with tracking', price: 9.99, estimatedDays: 2, trackingAvailable: true, insuranceIncluded: true }, { id: 'overnight', name: 'Overnight Delivery', description: 'Next business day delivery', price: 24.99, estimatedDays: 1, trackingAvailable: true, insuranceIncluded: true }]; const paymentMethods = [{ id: 'credit-card', type: 'credit-card', name: 'Credit Card', icon: '💳', acceptedCurrencies: ['USD', 'EUR', 'GBP'] }, { id: 'paypal', type: 'paypal', name: 'PayPal', icon: '🅿️', acceptedCurrencies: ['USD', 'EUR', 'GBP'] }, { id: 'apple-pay', type: 'apple-pay', name: 'Apple Pay', icon: '🍎', acceptedCurrencies: ['USD', 'EUR', 'GBP'] }]; // Cart calculations const cartSubtotal = cart.reduce((total, item) => total + item.product.price * item.quantity, 0); const cartTax = cartSubtotal * 0.08; // 8% tax const cartShipping = selectedShipping?.price || 0; const cartTotal = cartSubtotal + cartTax + cartShipping; const addProduct = useCallback(product => { setProducts(prev => [...prev, product]); }, []); const updateProduct = useCallback((id, updates) => { setProducts(prev => prev.map(product => product.id === id ? { ...product, ...updates } : product)); }, []); const removeProduct = useCallback(id => { setProducts(prev => prev.filter(product => product.id !== id)); }, []); const getProduct = useCallback(id => { return products.find(product => product.id === id); }, [products]); const getProductsByCategory = useCallback(category => { return products.filter(product => product.category === category); }, [products]); const searchProducts = useCallback((query, searchFilters) => { let filtered = products; // Text search if (query) { const lowercaseQuery = query.toLowerCase(); filtered = filtered.filter(product => product.name.toLowerCase().includes(lowercaseQuery) || product.description.toLowerCase().includes(lowercaseQuery) || product.tags.some(tag => tag.toLowerCase().includes(lowercaseQuery)) || product.brand?.toLowerCase().includes(lowercaseQuery)); } // Apply filters const activeFilters = searchFilters || filters; if (activeFilters.category?.length) { filtered = filtered.filter(product => activeFilters.category.includes(product.category)); } if (activeFilters.brand?.length) { filtered = filtered.filter(product => product.brand && activeFilters.brand.includes(product.brand)); } if (activeFilters.priceRange) { const [min, max] = activeFilters.priceRange; filtered = filtered.filter(product => product.price >= min && product.price <= max); } if (activeFilters.rating) { filtered = filtered.filter(product => product.rating >= activeFilters.rating); } if (activeFilters.onSale) { filtered = filtered.filter(product => product.isOnSale); } if (activeFilters.inStock) { filtered = filtered.filter(product => product.availability === 'in-stock'); } // Apply sorting switch (sortBy) { case 'price-low-high': filtered.sort((a, b) => a.price - b.price); break; case 'price-high-low': filtered.sort((a, b) => b.price - a.price); break; case 'rating': filtered.sort((a, b) => b.rating - a.rating); break; case 'name-az': filtered.sort((a, b) => a.name.localeCompare(b.name)); break; case 'name-za': filtered.sort((a, b) => b.name.localeCompare(a.name)); break; case 'bestseller': filtered.sort((a, b) => (b.isBestseller ? 1 : 0) - (a.isBestseller ? 1 : 0)); break; } return filtered; }, [products, filters, sortBy]); const addToCart = useCallback((productId, quantity = 1, variants) => { const product = getProduct(productId); if (!product) return; setCart(prev => { const existingItem = prev.find(item => item.productId === productId && JSON.stringify(item.selectedVariants) === JSON.stringify(variants)); if (existingItem) { return prev.map(item => item.id === existingItem.id ? { ...item, quantity: item.quantity + quantity } : item); } else { const newItem = { id: `cart_${Date.now()}_${Math.random()}`, productId, product, quantity, selectedVariants: variants, addedAt: new Date() }; return [...prev, newItem]; } }); }, [getProduct]); const updateCartItem = useCallback((itemId, quantity) => { if (quantity <= 0) { removeFromCart(itemId); return; } setCart(prev => prev.map(item => item.id === itemId ? { ...item, quantity } : item)); }, []); const removeFromCart = useCallback(itemId => { setCart(prev => prev.filter(item => item.id !== itemId)); }, []); const clearCart = useCallback(() => { setCart([]); }, []); const getCartTotal = useCallback(() => { return cart.reduce((total, item) => total + item.product.price * item.quantity, 0); }, [cart]); const getCartItemCount = useCallback(() => { return cart.reduce((count, item) => count + item.quantity, 0); }, [cart]); const addToWishlist = useCallback((productId, priority = 'medium') => { const product = getProduct(productId); if (!product) return; const existingItem = wishlist.find(item => item.productId === productId); if (existingItem) return; const newItem = { id: `wishlist_${Date.now()}_${Math.random()}`, productId, product, addedAt: new Date(), priority }; setWishlist(prev => [...prev, newItem]); }, [getProduct, wishlist]); const removeFromWishlist = useCallback(itemId => { setWishlist(prev => prev.filter(item => item.id !== itemId)); }, []); const moveToCart = useCallback(wishlistItemId => { const wishlistItem = wishlist.find(item => item.id === wishlistItemId); if (!wishlistItem) return; addToCart(wishlistItem.productId, 1); removeFromWishlist(wishlistItemId); }, [wishlist, addToCart, removeFromWishlist]); const shareWishlist = useCallback(() => { const wishlistData = JSON.stringify(wishlist.map(item => item.productId)); return `${window.location.origin}/wishlist?items=${encodeURIComponent(wishlistData)}`; }, [wishlist]); const getRecommendations = useCallback((productId, type) => { return recommendations[productId] || []; }, [recommendations]); const generateRecommendations = useCallback(async productId => { const recs = await mockRecommendationEngine.generateRecommendations(productId, products); setRecommendations(prev => ({ ...prev, [productId]: recs })); return recs; }, [products]); const createComparison = useCallback((productIds, title) => { const comparisonProducts = productIds.map(id => getProduct(id)).filter(Boolean); if (comparisonProducts.length < 2) throw new Error('At least 2 products required for comparison'); const comparisonMatrix = compareProducts(productIds); const comparison = { id: `comparison_${Date.now()}`, products: comparisonProducts, comparisonMatrix, createdAt: new Date(), title: title || `Comparison of ${comparisonProducts.length} products` }; setComparisons(prev => [...prev, comparison]); return comparison; }, [getProduct]); const updateComparison = useCallback((id, updates) => { setComparisons(prev => prev.map(comp => comp.id === id ? { ...comp, ...updates } : comp)); }, []); const removeComparison = useCallback(id => { setComparisons(prev => prev.filter(comp => comp.id !== id)); }, []); const compareProducts = useCallback(productIds => { const comparisonProducts = productIds.map(id => getProduct(id)).filter(Boolean); const features = []; // Price comparison features.push({ name: 'Price', category: 'General', values: comparisonProducts.map(p => `$${p.price.toFixed(2)}`), importance: 'high', winner: comparisonProducts.indexOf(comparisonProducts.reduce((min, p) => p.price < min.price ? p : min)) }); // Rating comparison features.push({ name: 'Rating', category: 'General', values: comparisonProducts.map(p => p.rating), importance: 'high', winner: comparisonProducts.indexOf(comparisonProducts.reduce((max, p) => p.rating > max.rating ? p : max)) }); // Stock comparison features.push({ name: 'Stock', category: 'Availability', values: comparisonProducts.map(p => p.stock), importance: 'medium' }); return features; }, [getProduct]); const addReview = useCallback((productId, review) => { const newReview = { ...review, id: `review_${Date.now()}_${Math.random()}`, productId, createdAt: new Date() }; setReviews(prev => ({ ...prev, [productId]: [...(prev[productId] || []), newReview] })); }, []); const updateReview = useCallback((reviewId, updates) => { setReviews(prev => { const newReviews = { ...prev }; Object.keys(newReviews).forEach(productId => { newReviews[productId] = newReviews[productId].map(review => review.id === reviewId ? { ...review, ...updates } : review); }); return newReviews; }); }, []); const removeReview = useCallback(reviewId => { setReviews(prev => { const newReviews = { ...prev }; Object.keys(newReviews).forEach(productId => { newReviews[productId] = newReviews[productId].filter(review => review.id !== reviewId); }); return newReviews; }); }, []); const getProductReviews = useCallback(productId => { return reviews[productId] || []; }, [reviews]); const getAverageRating = useCallback(productId => { const productReviews = getProductReviews(productId); if (productReviews.length === 0) return 0; const sum = productReviews.reduce((total, review) => total + review.rating, 0); return sum / productReviews.length; }, [getProductReviews]); const trackPrice = useCallback(productId => { const product = getProduct(productId); if (!product) return; const historyEntry = { date: new Date(), price: product.price, source: 'tracking' }; setPriceHistory(prev => ({ ...prev, [productId]: [...(prev[productId] || []), historyEntry] })); }, [getProduct]); const untrackPrice = useCallback(productId => { setPriceHistory(prev => { const newHistory = { ...prev }; delete newHistory[productId]; return newHistory; }); }, []); const getPriceHistory = useCallback(productId => { return priceHistory[productId] || []; }, [priceHistory]); const getPriceAlerts = useCallback(() => { // Mock price alerts return []; }, []); const viewProduct = useCallback(productId => { // Track product view for analytics trackEvent('product_view', { productId }); }, []); const trackEvent = useCallback((event, data) => { // Mock analytics tracking console.log('Analytics event:', event, data); }, []); const getAnalytics = useCallback(() => { // Mock analytics data return { totalViews: 1250, totalPurchases: 89, conversionRate: 7.1, averageOrderValue: 156.78, popularProducts: products.slice(0, 5).map(p => ({ productId: p.id, views: Math.floor(Math.random() * 500) + 100, purchases: Math.floor(Math.random() * 50) + 10 })), categoryPerformance: products.reduce((acc, p) => { if (!acc[p.category]) { acc[p.category] = { views: 0, purchases: 0 }; } acc[p.category].views += Math.floor(Math.random() * 100) + 50; acc[p.category].purchases += Math.floor(Math.random() * 20) + 5; return acc; }, {}), searchQueries: [{ query: 'wireless headphones', count: 45, results: 12 }, { query: 'laptop stand', count: 38, results: 8 }, { query: 'smartphone case', count: 32, results: 15 }] }; }, [products]); const setShippingOption = useCallback(option => { setSelectedShipping(option); }, []); const setPaymentMethod = useCallback(method => { setSelectedPayment(method); }, []); const value = { products, addProduct, updateProduct, removeProduct, getProduct, getProductsByCategory, searchProducts, cart, addToCart, updateCartItem, removeFromCart, clearCart, getCartTotal, getCartItemCount, cartSubtotal, cartTax, cartShipping, cartTotal, wishlist, addToWishlist, removeFromWishlist, moveToCart, shareWishlist, recommendations, getRecommendations, generateRecommendations, comparisons, createComparison, updateComparison, removeComparison, compareProducts, reviews, addReview, updateReview, removeReview, getProductReviews, getAverageRating, priceHistory, trackPrice, untrackPrice, getPriceHistory, getPriceAlerts, searchQuery, setSearchQuery, filters, setFilters, sortBy, setSortBy, viewProduct, trackEvent, getAnalytics, shippingOptions, paymentMethods, selectedShipping, selectedPayment, setShippingOption, setPaymentMethod }; return jsx(EcommerceContext.Provider, { "data-glass-component": true, value: value, children: children }); }; const useEcommerce = () => { const context = useContext(EcommerceContext); if (!context) { throw new Error('useEcommerce must be used within an EcommerceProvider'); } return context; }; export { EcommerceProvider, EcommerceProvider as GlassEcommerceProvider, useEcommerce }; //# sourceMappingURL=GlassEcommerceProvider.js.map