| <x-app-layout> | |
| <div class="min-h-screen bg-gradient-to-br from-gray-900 via-purple-900/10 to-blue-900/10"> | |
| <!-- Hero Section --> | |
| <div class="relative overflow-hidden py-12"> | |
| <div class="absolute inset-0"> | |
| <div class="absolute top-20 left-10 w-72 h-72 bg-purple-500/5 rounded-full blur-3xl"></div> | |
| <div class="absolute bottom-20 right-10 w-96 h-96 bg-blue-500/5 rounded-full blur-3xl"></div> | |
| </div> | |
| <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
| <!-- Breadcrumb --> | |
| <nav class="flex items-center space-x-2 text-sm mb-8"> | |
| <a href="{{ route('categories') }}" class="text-white/60 hover:text-white transition-colors flex items-center"> | |
| <i class="fas fa-store mr-2"></i>Store | |
| </a> | |
| <i class="fas fa-chevron-right text-white/40 mx-2"></i> | |
| <a href="{{ route('store.category', $product->game) }}" class="text-white/60 hover:text-white transition-colors"> | |
| {{ $product->game }} | |
| </a> | |
| <i class="fas fa-chevron-right text-white/40 mx-2"></i> | |
| <span class="text-white font-medium">{{ $product->name }}</span> | |
| </nav> | |
| <!-- Back to Store Button --> | |
| <div class="mb-8"> | |
| <a href="{{ route('store.category', $product->game) }}" class="inline-flex items-center px-6 py-3 bg-gradient-to-r from-purple-600/20 to-blue-600/20 hover:from-purple-600/40 hover:to-blue-600/40 border border-purple-500/30 hover:border-purple-500/60 rounded-xl text-white font-semibold text-lg transition-all duration-300 group shadow-lg hover:shadow-purple-500/25 transform hover:scale-105"> | |
| <i class="fas fa-arrow-left mr-3 group-hover:-translate-x-2 transition-transform duration-300 text-purple-400"></i> | |
| <span>Back to {{ $product->game }}</span> | |
| </a> | |
| </div> | |
| <!-- Main Product Section --> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-12"> | |
| <!-- Product Image --> | |
| <div class="space-y-6"> | |
| <div class="product-image-container"> | |
| <div class="relative aspect-square overflow-hidden rounded-2xl bg-white/5 border border-white/10"> | |
| @if($product->image) | |
| <img src="{{ $product->image }}" alt="{{ $product->name }}" | |
| class="w-full h-full object-cover transition-all duration-700 hover:scale-110 hover:rotate-2 hover:brightness-110 hover:contrast-110"> | |
| @else | |
| <div class="w-full h-full bg-gradient-to-br from-gray-700 to-gray-800 flex items-center justify-center"> | |
| <i class="fas fa-image text-white/30 text-6xl"></i> | |
| </div> | |
| @endif | |
| <!-- Stock Badge --> | |
| <div class="absolute top-4 right-4"> | |
| @if($product->Amount === 0) | |
| <span class="status-badge bg-red-500/90 border-red-400/50"> | |
| <i class="fas fa-times-circle mr-1"></i>Sold Out | |
| </span> | |
| @elseif($product->Amount <= 5) | |
| <span class="status-badge bg-orange-500/90 border-orange-400/50 animate-pulse"> | |
| <i class="fas fa-exclamation-triangle mr-1"></i>{{ $product->Amount }} Left | |
| </span> | |
| @else | |
| <span class="status-badge bg-green-500/90 border-green-400/50"> | |
| <i class="fas fa-check-circle mr-1"></i>Available | |
| </span> | |
| @endif | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Sales Counter Below Image --> | |
| <div class="mt-6"> | |
| <div class="glass-bg border border-white/10 rounded-xl p-6 text-center hover:border-yellow-500/30 transition-all duration-300 group"> | |
| <div class="w-16 h-16 bg-gradient-to-r from-yellow-500 to-orange-600 rounded-full flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform duration-300 shadow-lg"> | |
| <i class="fas fa-fire text-white text-2xl"></i> | |
| </div> | |
| <div class="text-3xl font-bold text-white mb-2"> | |
| @php | |
| // Sales count - only count completed orders that contain this product | |
| $salesCount = \App\Models\Order::where('cart_data', 'LIKE', '%"product_id":' . $product->id . '%') | |
| ->where('status', 'completed') | |
| ->count(); | |
| @endphp | |
| <span class="counter" data-target="{{ $salesCount }}">0</span> | |
| </div> | |
| <h4 class="text-white/80 font-medium text-lg mb-1">Total Sales</h4> | |
| <p class="text-white/60 text-sm">People have purchased this item</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Product Info --> | |
| <div class="space-y-6 animate-slide-in-right"> | |
| <!-- Title & Price --> | |
| <div class="animate-fade-in-up"> | |
| <div class="mb-6"> | |
| <h1 class="text-4xl md:text-5xl font-bold text-white leading-tight mb-3 professional-title"> | |
| {{ $product->name }} | |
| </h1> | |
| <div class="flex items-center gap-3"> | |
| <div class="h-1 bg-gradient-to-r from-purple-500 to-blue-500 rounded-full flex-1 animate-expand-width"></div> | |
| <div class="px-3 py-1 bg-gradient-to-r from-purple-500/20 to-blue-500/20 rounded-full border border-purple-500/30"> | |
| <span class="text-purple-300 text-sm font-medium">Premium Product</span> | |
| </div> | |
| <div class="h-1 bg-gradient-to-r from-blue-500 to-purple-500 rounded-full flex-1 animate-expand-width animation-delay-300"></div> | |
| </div> | |
| </div> | |
| <!-- Price Section --> | |
| <div class="bg-gradient-to-r from-purple-600/20 to-blue-600/20 rounded-2xl p-6 mb-6 border border-purple-500/30 hover:border-purple-500/50 transition-all duration-300 group"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <div class="text-4xl md:text-5xl font-black text-white group-hover:scale-105 transition-transform duration-300 drop-shadow-lg"> | |
| ฿{{ number_format($product->price, 2) }} | |
| </div> | |
| <p class="text-white/60 text-lg mt-2 font-medium">Premium Quality Product</p> | |
| </div> | |
| <div class="text-right"> | |
| @if($product->Amount === 0) | |
| <div class="flex items-center text-red-400 text-xl font-bold"> | |
| <i class="fas fa-exclamation-triangle mr-3 text-2xl"></i> | |
| <span>Out of Stock</span> | |
| </div> | |
| @elseif($product->Amount <= 5) | |
| <div class="flex items-center text-orange-400 text-xl font-bold animate-pulse"> | |
| <i class="fas fa-clock mr-3 text-2xl"></i> | |
| <span>Only {{ $product->Amount }} left</span> | |
| </div> | |
| <p class="text-white/60 text-lg mt-1">Hurry! Limited stock</p> | |
| @else | |
| <div class="flex items-center text-green-400 text-xl font-bold"> | |
| <i class="fas fa-check-circle mr-3 text-2xl"></i> | |
| <span>In Stock</span> | |
| </div> | |
| <p class="text-white/60 text-lg mt-1">{{ $product->Amount }} available</p> | |
| @endif | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Description --> | |
| <div class="glass-bg border border-white/10 rounded-2xl p-6 hover:border-white/20 transition-all duration-300 animate-fade-in-up animation-delay-200"> | |
| <div class="flex items-center mb-4"> | |
| <div class="w-10 h-10 bg-gradient-to-r from-blue-500 to-purple-500 rounded-xl flex items-center justify-center mr-3 shadow-lg"> | |
| <i class="fas fa-info-circle text-white"></i> | |
| </div> | |
| <h3 class="text-xl font-bold text-white">Product Description</h3> | |
| </div> | |
| <p class="text-white/90 leading-relaxed text-lg">{{ $product->description }}</p> | |
| </div> | |
| <!-- Add to Cart --> | |
| @if($product->Amount > 0) | |
| <div class="glass-bg border border-white/10 rounded-2xl p-6 hover:border-purple-500/30 transition-all duration-300 animate-fade-in-up animation-delay-400"> | |
| <div class="flex items-center mb-6"> | |
| <div class="w-10 h-10 bg-gradient-to-r from-green-500 to-blue-500 rounded-xl flex items-center justify-center mr-3 shadow-lg"> | |
| <i class="fas fa-shopping-cart text-white"></i> | |
| </div> | |
| <h3 class="text-xl font-bold text-white">Add to Cart</h3> | |
| </div> | |
| <form id="addToCartForm" data-product-id="{{ $product->id }}" data-product-name="{{ $product->name }}"> | |
| @csrf | |
| <!-- Quantity Selector --> | |
| <div class="flex items-center justify-between mb-6"> | |
| <span class="text-white/80 font-semibold text-lg">Quantity:</span> | |
| <div class="flex items-center bg-black/40 rounded-xl border border-white/20 hover:border-purple-500/40 transition-all duration-300"> | |
| <button type="button" id="decreaseBtn" class="p-4 text-white/60 hover:text-white transition-colors hover:bg-white/10 rounded-l-xl"> | |
| <i class="fas fa-minus text-lg"></i> | |
| </button> | |
| <span id="quantityDisplay" class="w-20 text-center text-white font-bold text-xl">1</span> | |
| <button type="button" id="increaseBtn" class="p-4 text-white/60 hover:text-white transition-colors hover:bg-white/10 rounded-r-xl"> | |
| <i class="fas fa-plus text-lg"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Total Price --> | |
| <div class="bg-black/40 rounded-xl p-6 mb-6 border border-purple-500/30 hover:border-purple-500/50 transition-all duration-300"> | |
| <div class="flex items-center justify-between"> | |
| <span class="text-white/80 text-xl font-semibold">Total Price:</span> | |
| <div class="text-3xl font-black text-white drop-shadow-lg" id="totalPrice"> | |
| ฿{{ number_format($product->price, 2) }} | |
| </div> | |
| </div> | |
| </div> | |
| <input type="hidden" name="quantity" id="quantityInput" value="1"> | |
| <button type="submit" class="w-full py-6 px-8 bg-gradient-to-r from-purple-600 to-blue-600 hover:from-purple-500 hover:to-blue-500 text-white rounded-2xl font-bold text-xl transition-all duration-300 shadow-2xl hover:shadow-purple-500/40 transform hover:scale-105 hover:-translate-y-1 active:scale-95"> | |
| <i class="fas fa-cart-plus mr-3 text-xl"></i>Add to Cart | |
| </button> | |
| </form> | |
| </div> | |
| @else | |
| <div class="glass-bg border border-red-500/30 rounded-2xl p-6 text-center animate-fade-in-up animation-delay-400"> | |
| <div class="w-20 h-20 bg-gradient-to-r from-red-500 to-red-600 rounded-full flex items-center justify-center mx-auto mb-6 shadow-2xl animate-pulse"> | |
| <i class="fas fa-times-circle text-3xl text-white"></i> | |
| </div> | |
| <h3 class="text-2xl font-bold text-red-400 mb-4">Out of Stock</h3> | |
| <p class="text-white/60 text-lg">This product is currently unavailable. Please check back later.</p> | |
| </div> | |
| @endif | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Cart Success Popup --> | |
| <div id="cartPopup" class="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center opacity-0 invisible transition-all duration-300"> | |
| <div class="bg-gradient-to-br from-gray-900 via-purple-900/20 to-blue-900/20 border border-white/20 rounded-3xl p-8 max-w-md w-full mx-4 transform scale-90 transition-all duration-300 relative" id="popupContent"> | |
| <!-- Close Button --> | |
| <button id="closePopup" class="absolute top-4 right-4 w-10 h-10 bg-white/10 hover:bg-white/20 rounded-full flex items-center justify-center transition-all duration-300 group"> | |
| <i class="fas fa-times text-white/60 group-hover:text-white text-lg"></i> | |
| </button> | |
| <!-- Success Icon --> | |
| <div class="text-center mb-6"> | |
| <div class="w-20 h-20 bg-gradient-to-r from-green-500 to-emerald-600 rounded-full flex items-center justify-center mx-auto mb-4 animate-bounce"> | |
| <i class="fas fa-check text-white text-3xl"></i> | |
| </div> | |
| <h3 class="text-2xl font-bold text-white mb-2">Added to Cart!</h3> | |
| <p class="text-white/80" id="popupMessage">Item has been added to your cart</p> | |
| </div> | |
| <!-- Action Buttons --> | |
| <div class="space-y-3"> | |
| <a href="{{ route('cart.index') }}" class="w-full py-4 px-6 bg-gradient-to-r from-purple-600 to-blue-600 hover:from-purple-500 hover:to-blue-500 text-white rounded-xl font-bold text-lg transition-all duration-300 shadow-lg hover:shadow-purple-500/40 transform hover:scale-105 flex items-center justify-center"> | |
| <i class="fas fa-shopping-cart mr-3"></i>View Cart | |
| </a> | |
| <a href="{{ route('categories') }}" class="w-full py-4 px-6 bg-white/10 hover:bg-white/20 text-white rounded-xl font-bold text-lg transition-all duration-300 border border-white/20 hover:border-white/40 flex items-center justify-center"> | |
| <i class="fas fa-gamepad mr-3"></i>Check More Games | |
| </a> | |
| <button id="continueShopping" class="w-full py-4 px-6 bg-transparent hover:bg-white/5 text-white/80 hover:text-white rounded-xl font-medium text-lg transition-all duration-300 border border-white/10 hover:border-white/30"> | |
| Continue Shopping | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <style> | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| @keyframes slideInLeft { | |
| from { opacity: 0; transform: translateX(-50px); } | |
| to { opacity: 1; transform: translateX(0); } | |
| } | |
| @keyframes slideInRight { | |
| from { opacity: 0; transform: translateX(50px); } | |
| to { opacity: 1; transform: translateX(0); } | |
| } | |
| @keyframes slideInDown { | |
| from { opacity: 0; transform: translateY(-20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| @keyframes fadeInUp { | |
| from { opacity: 0; transform: translateY(30px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .animate-fade-in { animation: fadeIn 0.8s ease-out; } | |
| .animate-slide-in-left { animation: slideInLeft 0.8s ease-out; } | |
| .animate-slide-in-right { animation: slideInRight 0.8s ease-out; } | |
| .animate-slide-in-down { animation: slideInDown 0.6s ease-out; } | |
| .animate-fade-in-up { animation: fadeInUp 0.6s ease-out; } | |
| .animation-delay-200 { animation-delay: 0.2s; } | |
| .animation-delay-400 { animation-delay: 0.4s; } | |
| .animation-delay-600 { animation-delay: 0.6s; } | |
| /* Floating animation for badges */ | |
| @keyframes float { | |
| 0%, 100% { transform: translateY(0px); } | |
| 50% { transform: translateY(-5px); } | |
| } | |
| .animate-float { animation: float 3s ease-in-out infinite; } | |
| /* Glow effect */ | |
| .glow-purple { | |
| box-shadow: 0 0 20px rgba(168, 85, 247, 0.3); | |
| } | |
| /* Quantity bounce animation */ | |
| .quantity-bounce { | |
| animation: quantityBounce 0.4s ease-out; | |
| } | |
| @keyframes quantityBounce { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.3); } | |
| 100% { transform: scale(1); } | |
| } | |
| /* Price update animation */ | |
| .price-update { | |
| animation: priceUpdate 0.5s ease-out; | |
| } | |
| @keyframes priceUpdate { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.1); color: #a855f7; text-shadow: 0 0 20px rgba(168, 85, 247, 0.5); } | |
| 100% { transform: scale(1); } | |
| } | |
| /* Shake animation for disabled buttons */ | |
| @keyframes shake { | |
| 0%, 100% { transform: translateX(0); } | |
| 25% { transform: translateX(-8px); } | |
| 75% { transform: translateX(8px); } | |
| } | |
| .shake { animation: shake 0.5s ease-in-out; } | |
| /* Professional Title Styles */ | |
| .professional-title { | |
| text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); | |
| transition: all 0.3s ease; | |
| cursor: default; | |
| } | |
| .professional-title:hover { | |
| color: #a855f7; | |
| text-shadow: 0 0 20px rgba(168, 85, 247, 0.5); | |
| transform: translateY(-1px); | |
| } | |
| @keyframes expandWidth { | |
| from { width: 0%; } | |
| to { width: 100%; } | |
| } | |
| .animate-expand-width { | |
| animation: expandWidth 1.5s ease-out forwards; | |
| } | |
| .animation-delay-300 { | |
| animation-delay: 0.3s; | |
| } | |
| /* Tilted image animation */ | |
| @keyframes tiltFloat { | |
| 0%, 100% { transform: rotate(-2deg) translateY(0px); } | |
| 50% { transform: rotate(-2deg) translateY(-10px); } | |
| } | |
| /* Slow bounce animation */ | |
| @keyframes bounceSlow { | |
| 0%, 100% { transform: translateY(0px); } | |
| 50% { transform: translateY(-15px); } | |
| } | |
| .animate-bounce-slow { animation: bounceSlow 3s ease-in-out infinite; } | |
| /* Slide in up animation */ | |
| @keyframes slideInUp { | |
| from { opacity: 0; transform: translateY(50px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .animate-slide-in-up { animation: slideInUp 0.8s ease-out; } | |
| /* Additional animation delays */ | |
| .animation-delay-800 { animation-delay: 0.8s; } | |
| .animation-delay-900 { animation-delay: 0.9s; } | |
| .animation-delay-1000 { animation-delay: 1.0s; } | |
| .animation-delay-1100 { animation-delay: 1.1s; } | |
| .animation-delay-1200 { animation-delay: 1.2s; } | |
| .animation-delay-1300 { animation-delay: 1.3s; } | |
| .animation-delay-1400 { animation-delay: 1.4s; } | |
| .animation-delay-1500 { animation-delay: 1.5s; } | |
| /* Gradient text effect */ | |
| .gradient-text { | |
| background: linear-gradient(45deg, #a855f7, #3b82f6, #06b6d4); | |
| background-size: 200% 200%; | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| animation: gradientShift 3s ease infinite; | |
| } | |
| @keyframes gradientShift { | |
| 0%, 100% { background-position: 0% 50%; } | |
| 50% { background-position: 100% 50%; } | |
| } | |
| /* Enhanced image hover effects */ | |
| .product-image-container img { | |
| filter: brightness(1) contrast(1) saturate(1); | |
| transition: all 0.7s cubic-bezier(0.4, 0, 0.2, 1); | |
| } | |
| .product-image-container:hover img { | |
| filter: brightness(1.1) contrast(1.1) saturate(1.2); | |
| box-shadow: 0 25px 50px rgba(168, 85, 247, 0.3); | |
| } | |
| /* Popup animations */ | |
| #cartPopup.show { | |
| opacity: 1 !important; | |
| visibility: visible !important; | |
| } | |
| #popupContent.show { | |
| transform: scale(1) !important; | |
| } | |
| </style> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const decreaseBtn = document.getElementById('decreaseBtn'); | |
| const increaseBtn = document.getElementById('increaseBtn'); | |
| const quantityDisplay = document.getElementById('quantityDisplay'); | |
| const quantityInput = document.getElementById('quantityInput'); | |
| const totalPrice = document.getElementById('totalPrice'); | |
| const productPrice = {{ $product->price }}; | |
| const maxStock = {{ $product->Amount }}; | |
| let quantity = 1; | |
| function updateQuantity(newQuantity) { | |
| if (newQuantity >= 1 && newQuantity <= maxStock) { | |
| quantity = newQuantity; | |
| // Animate quantity change | |
| quantityDisplay.classList.add('quantity-bounce'); | |
| setTimeout(() => quantityDisplay.classList.remove('quantity-bounce'), 400); | |
| quantityDisplay.textContent = quantity; | |
| quantityInput.value = quantity; | |
| // Animate price change | |
| totalPrice.classList.add('price-update'); | |
| setTimeout(() => totalPrice.classList.remove('price-update'), 500); | |
| totalPrice.textContent = '฿' + (productPrice * quantity).toLocaleString('en-US', {minimumFractionDigits: 2}); | |
| } | |
| } | |
| // Enhanced button interactions | |
| decreaseBtn.addEventListener('click', () => { | |
| if (quantity > 1) { | |
| updateQuantity(quantity - 1); | |
| } else { | |
| decreaseBtn.classList.add('shake'); | |
| setTimeout(() => decreaseBtn.classList.remove('shake'), 500); | |
| } | |
| }); | |
| increaseBtn.addEventListener('click', () => { | |
| if (quantity < maxStock) { | |
| updateQuantity(quantity + 1); | |
| } else { | |
| increaseBtn.classList.add('shake'); | |
| setTimeout(() => increaseBtn.classList.remove('shake'), 500); | |
| } | |
| }); | |
| // Add floating animation to badges after page load | |
| setTimeout(() => { | |
| const badges = document.querySelectorAll('.absolute'); | |
| badges.forEach((badge, index) => { | |
| setTimeout(() => { | |
| badge.classList.add('animate-float'); | |
| }, index * 200); | |
| }); | |
| }, 1000); | |
| // Counter animation for sold items | |
| function animateCounter(element, target, duration = 2000) { | |
| let start = 0; | |
| const increment = target / (duration / 16); | |
| const timer = setInterval(() => { | |
| start += increment; | |
| if (start >= target) { | |
| element.textContent = Math.floor(target); | |
| clearInterval(timer); | |
| } else { | |
| element.textContent = Math.floor(start); | |
| } | |
| }, 16); | |
| } | |
| // Start counter animation after a delay | |
| setTimeout(() => { | |
| const counter = document.querySelector('.counter'); | |
| if (counter) { | |
| const target = parseInt(counter.getAttribute('data-target')); | |
| animateCounter(counter, target); | |
| } | |
| }, 1500); | |
| // Observer options for scroll animations | |
| const observerOptions = { | |
| threshold: 0.1, | |
| rootMargin: '0px 0px -50px 0px' | |
| }; | |
| const scrollObserver = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| const target = entry.target; | |
| if (entry.isIntersecting) { | |
| // Reveal animations | |
| if (target.classList.contains('scroll-reveal')) { | |
| target.classList.add('revealed'); | |
| // Add particle effect | |
| setTimeout(() => { | |
| target.style.position = 'relative'; | |
| }, 500); | |
| } | |
| // Staggered card reveals with unique animations | |
| if (target.id === 'purchaseProcess') { | |
| const cards = target.querySelectorAll('.scroll-reveal-card'); | |
| cards.forEach((card, index) => { | |
| setTimeout(() => { | |
| card.classList.add('revealed'); | |
| // Add random rotation on reveal | |
| const randomRotation = (Math.random() - 0.5) * 4; | |
| card.style.setProperty('--random-rotation', `${randomRotation}deg`); | |
| // Add click effect | |
| card.addEventListener('click', () => { | |
| card.style.transform = 'scale(0.95)'; | |
| setTimeout(() => { | |
| card.style.transform = ''; | |
| }, 150); | |
| }); | |
| }, index * 300); | |
| }); | |
| } | |
| } else { | |
| // Hide animations when scrolling up | |
| if (target.classList.contains('scroll-reveal')) { | |
| target.classList.remove('revealed'); | |
| } | |
| if (target.id === 'purchaseProcess') { | |
| const cards = target.querySelectorAll('.scroll-reveal-card'); | |
| cards.forEach((card, index) => { | |
| setTimeout(() => { | |
| card.classList.remove('revealed'); | |
| }, index * 100); | |
| }); | |
| } | |
| } | |
| }); | |
| }, observerOptions); | |
| // Observe scroll reveal elements | |
| const scrollElements = document.querySelectorAll('.scroll-reveal'); | |
| scrollElements.forEach(element => { | |
| scrollObserver.observe(element); | |
| }); | |
| // Add mouse parallax effect to cards | |
| document.addEventListener('mousemove', (e) => { | |
| const cards = document.querySelectorAll('.scroll-reveal-card.revealed'); | |
| const mouseX = e.clientX / window.innerWidth; | |
| const mouseY = e.clientY / window.innerHeight; | |
| cards.forEach((card, index) => { | |
| const intensity = (index + 1) * 0.5; | |
| const rotateX = (mouseY - 0.5) * intensity * 10; | |
| const rotateY = (mouseX - 0.5) * intensity * 10; | |
| card.style.transform = ` | |
| perspective(1000px) | |
| rotateX(${rotateX}deg) | |
| rotateY(${rotateY}deg) | |
| translateZ(${intensity * 20}px) | |
| `; | |
| }); | |
| }); | |
| // Reset card transforms when mouse leaves | |
| document.addEventListener('mouseleave', () => { | |
| const cards = document.querySelectorAll('.scroll-reveal-card.revealed'); | |
| cards.forEach(card => { | |
| card.style.transform = ''; | |
| }); | |
| }); | |
| // Cart popup functionality | |
| const cartPopup = document.getElementById('cartPopup'); | |
| const popupContent = document.getElementById('popupContent'); | |
| const closePopup = document.getElementById('closePopup'); | |
| const continueShopping = document.getElementById('continueShopping'); | |
| const addToCartForm = document.getElementById('addToCartForm'); | |
| const popupMessage = document.getElementById('popupMessage'); | |
| // Handle form submission | |
| if (addToCartForm) { | |
| addToCartForm.addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| console.log('Form submitted'); // Debug | |
| const productId = this.dataset.productId; | |
| const productName = this.dataset.productName; | |
| const quantity = document.getElementById('quantityInput').value; | |
| console.log('Product ID:', productId, 'Name:', productName, 'Quantity:', quantity); // Debug | |
| // Create form data | |
| const formData = new FormData(); | |
| formData.append('_token', document.querySelector('input[name="_token"]').value); | |
| formData.append('quantity', quantity); | |
| // Send AJAX request | |
| fetch(`/cart/add/${productId}`, { | |
| method: 'POST', | |
| body: formData, | |
| headers: { | |
| 'X-Requested-With': 'XMLHttpRequest' | |
| } | |
| }) | |
| .then(response => { | |
| console.log('Response received:', response); // Debug | |
| return response.json(); | |
| }) | |
| .then(data => { | |
| console.log('Data received:', data); // Debug | |
| if (data.success) { | |
| // Update popup message | |
| if (popupMessage) { | |
| popupMessage.textContent = `${productName} added to cart!`; | |
| } | |
| // Show popup | |
| showCartPopup(); | |
| } else { | |
| alert('Error: ' + (data.message || 'Could not add item to cart')); | |
| } | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| alert('Error adding item to cart'); | |
| }); | |
| }); | |
| } else { | |
| console.error('Add to cart form not found'); | |
| } | |
| function showCartPopup() { | |
| console.log('Showing cart popup'); // Debug | |
| if (cartPopup) { | |
| cartPopup.classList.remove('opacity-0', 'invisible'); | |
| setTimeout(() => { | |
| if (popupContent) { | |
| popupContent.classList.remove('scale-90'); | |
| popupContent.classList.add('scale-100'); | |
| } | |
| }, 50); | |
| } else { | |
| console.error('Cart popup element not found'); | |
| } | |
| } | |
| function hideCartPopup() { | |
| console.log('Hiding cart popup'); // Debug | |
| if (popupContent) { | |
| popupContent.classList.remove('scale-100'); | |
| popupContent.classList.add('scale-90'); | |
| } | |
| setTimeout(() => { | |
| if (cartPopup) { | |
| cartPopup.classList.add('opacity-0', 'invisible'); | |
| } | |
| }, 200); | |
| } | |
| // Close popup events | |
| if (closePopup) { | |
| closePopup.addEventListener('click', hideCartPopup); | |
| } | |
| if (continueShopping) { | |
| continueShopping.addEventListener('click', hideCartPopup); | |
| } | |
| // Close popup when clicking outside | |
| if (cartPopup) { | |
| cartPopup.addEventListener('click', function(e) { | |
| if (e.target === cartPopup) { | |
| hideCartPopup(); | |
| } | |
| }); | |
| } | |
| // Close popup with Escape key | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'Escape' && cartPopup && !cartPopup.classList.contains('invisible')) { | |
| hideCartPopup(); | |
| } | |
| }); | |
| // Debug: Check if all elements are found | |
| console.log('Elements found:', { | |
| cartPopup: !!cartPopup, | |
| popupContent: !!popupContent, | |
| closePopup: !!closePopup, | |
| continueShopping: !!continueShopping, | |
| addToCartForm: !!addToCartForm, | |
| popupMessage: !!popupMessage | |
| }); | |
| // Test popup function (remove this after testing) | |
| window.testPopup = function() { | |
| console.log('Testing popup...'); | |
| if (popupMessage) { | |
| popupMessage.textContent = 'Test item added to cart!'; | |
| } | |
| showCartPopup(); | |
| }; | |
| }); | |
| </script> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <style> | |
| .product-image-container { | |
| position: relative; | |
| } | |
| .game-badge { | |
| background: rgba(255, 255, 255, 0.1); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| color: white; | |
| padding: 0.5rem 1rem; | |
| border-radius: 0.75rem; | |
| font-size: 0.875rem; | |
| font-weight: 600; | |
| } | |
| .status-badge { | |
| padding: 0.5rem 1rem; | |
| border-radius: 0.75rem; | |
| font-size: 0.875rem; | |
| font-weight: 600; | |
| color: white; | |
| border: 1px solid; | |
| backdrop-filter: blur(4px); | |
| } | |
| .price-section { | |
| background: rgba(16, 185, 129, 0.1); | |
| border: 1px solid rgba(16, 185, 129, 0.2); | |
| border-radius: 1rem; | |
| padding: 1.5rem; | |
| margin-top: 1rem; | |
| } | |
| .info-card { | |
| background: rgba(255, 255, 255, 0.05); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| border-radius: 1rem; | |
| padding: 1.5rem; | |
| } | |
| .quantity-selector { | |
| display: flex; | |
| align-items: center; | |
| background: rgba(255, 255, 255, 0.05); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| border-radius: 0.75rem; | |
| overflow: hidden; | |
| } | |
| .quantity-btn { | |
| background: none; | |
| border: none; | |
| color: rgba(255, 255, 255, 0.6); | |
| padding: 0.75rem; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| } | |
| .quantity-btn:hover { | |
| background: rgba(255, 255, 255, 0.1); | |
| color: white; | |
| } | |
| .quantity-display { | |
| color: white; | |
| font-weight: 600; | |
| padding: 0 1rem; | |
| min-width: 3rem; | |
| text-align: center; | |
| } | |
| .total-price-card { | |
| background: rgba(16, 185, 129, 0.1); | |
| border: 1px solid rgba(16, 185, 129, 0.2); | |
| border-radius: 0.75rem; | |
| padding: 1rem; | |
| } | |
| .purchase-btn { | |
| width: 100%; | |
| background: linear-gradient(135deg, #10b981 0%, #059669 100%); | |
| color: white; | |
| padding: 1rem 2rem; | |
| border-radius: 1rem; | |
| font-weight: 700; | |
| font-size: 1.125rem; | |
| border: none; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .purchase-btn:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 20px 40px rgba(16, 185, 129, 0.3); | |
| } | |
| .btn-secondary { | |
| background: rgba(255, 255, 255, 0.1); | |
| color: white; | |
| padding: 0.75rem 1.5rem; | |
| border-radius: 0.75rem; | |
| font-weight: 600; | |
| transition: all 0.3s ease; | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| text-decoration: none; | |
| } | |
| </style> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const decreaseBtn = document.getElementById('decreaseBtn'); | |
| const increaseBtn = document.getElementById('increaseBtn'); | |
| const quantityDisplay = document.getElementById('quantityDisplay'); | |
| const quantityInput = document.getElementById('quantityInput'); | |
| const totalPrice = document.getElementById('totalPrice'); | |
| const productPrice = {{ $product->price }}; | |
| const maxStock = {{ $product->Amount }}; | |
| let quantity = 1; | |
| function updateQuantity(newQuantity) { | |
| if (newQuantity >= 1 && newQuantity <= maxStock) { | |
| quantity = newQuantity; | |
| quantityDisplay.textContent = quantity; | |
| quantityInput.value = quantity; | |
| const total = (productPrice * quantity).toFixed(2); | |
| totalPrice.textContent = `฿${parseFloat(total).toLocaleString()}`; | |
| } | |
| } | |
| decreaseBtn.addEventListener('click', () => updateQuantity(quantity - 1)); | |
| increaseBtn.addEventListener('click', () => updateQuantity(quantity + 1)); | |
| }); | |
| </script> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const decreaseBtn = document.getElementById('decreaseBtn'); | |
| const increaseBtn = document.getElementById('increaseBtn'); | |
| const quantityDisplay = document.getElementById('quantityDisplay'); | |
| const quantityInput = document.getElementById('quantityInput'); | |
| const totalPrice = document.getElementById('totalPrice'); | |
| const productPrice = {{ $product->price }}; | |
| const maxStock = {{ $product->Amount }}; | |
| let quantity = 1; | |
| function updateQuantity(newQuantity) { | |
| if (newQuantity >= 1 && newQuantity <= maxStock) { | |
| quantity = newQuantity; | |
| quantityDisplay.textContent = quantity; | |
| quantityInput.value = quantity; | |
| const total = (productPrice * quantity).toFixed(2); | |
| totalPrice.textContent = `฿${parseFloat(total).toLocaleString()}`; | |
| } | |
| } | |
| decreaseBtn.addEventListener('click', () => updateQuantity(quantity - 1)); | |
| increaseBtn.addEventListener('click', () => updateQuantity(quantity + 1)); | |
| }); | |
| </script> | |
| </x-app-layout> |