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