import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["quantity", "cartCount", "cartTotal", "checkoutButton"] static values = { eventId: String } connect() { this.cart = {} this.updateCartDisplay() // Check for pending cart in session storage (after login) this.checkForPendingCart() } increaseQuantity(event) { const ticketTypeId = event.params.ticketTypeId const max = parseInt(event.params.max) const input = this.quantityTargetFor(ticketTypeId) const current = parseInt(input.value) || 0 if (current < max) { input.value = current + 1 this.updateCartItem(ticketTypeId, input) } } decreaseQuantity(event) { const ticketTypeId = event.params.ticketTypeId const input = this.quantityTargetFor(ticketTypeId) const current = parseInt(input.value) || 0 if (current > 0) { input.value = current - 1 this.updateCartItem(ticketTypeId, input) } } updateQuantityFromInput(event) { const input = event.target const ticketTypeId = input.dataset.ticketTypeId const max = parseInt(input.max) const quantity = parseInt(input.value) || 0 // Validate input if (quantity < 0) { input.value = 0 } else if (quantity > max) { input.value = max } this.updateCartItem(ticketTypeId, input) } updateCartItem(ticketTypeId, input) { const name = input.dataset.name const price = parseInt(input.dataset.price) const quantity = parseInt(input.value) || 0 if (quantity > 0) { this.cart[ticketTypeId] = { name: name, price: price, quantity: quantity } } else { delete this.cart[ticketTypeId] } this.updateCartDisplay() } updateCartDisplay() { let totalTickets = 0 let totalPrice = 0 for (let ticketTypeId in this.cart) { totalTickets += this.cart[ticketTypeId].quantity totalPrice += (this.cart[ticketTypeId].price * this.cart[ticketTypeId].quantity) / 100 } // Update cart count and total if (this.hasCartCountTarget) { this.cartCountTarget.textContent = totalTickets } if (this.hasCartTotalTarget) { this.cartTotalTarget.textContent = totalPrice.toFixed(2) } // Update checkout button state if (this.hasCheckoutButtonTarget) { const checkoutBtn = this.checkoutButtonTarget if (totalTickets > 0) { checkoutBtn.disabled = false checkoutBtn.classList.remove('opacity-50', 'cursor-not-allowed') } else { checkoutBtn.disabled = true checkoutBtn.classList.add('opacity-50', 'cursor-not-allowed') } } } proceedToCheckout() { if (Object.keys(this.cart).length === 0) { alert('Veuillez sélectionner au moins un billet') return } // Check if user is authenticated const isAuthenticated = document.body.dataset.userAuthenticated === "true" if (!isAuthenticated) { if (confirm('Vous devez être connecté pour acheter des billets. Souhaitez-vous vous connecter maintenant ?')) { // Store cart in session storage sessionStorage.setItem('pending_cart', JSON.stringify({ eventId: this.eventIdValue, cart: this.cart })) window.location.href = '/auth/sign_in' } return } // Create form and submit to checkout const form = document.createElement('form') form.method = 'POST' form.action = `/events/${document.body.dataset.eventSlug}.${this.eventIdValue}/checkout` // Add CSRF token const csrfToken = document.querySelector('meta[name="csrf-token"]').content const csrfInput = document.createElement('input') csrfInput.type = 'hidden' csrfInput.name = 'authenticity_token' csrfInput.value = csrfToken form.appendChild(csrfInput) // Add cart data const cartInput = document.createElement('input') cartInput.type = 'hidden' cartInput.name = 'cart' cartInput.value = JSON.stringify(this.cart) form.appendChild(cartInput) document.body.appendChild(form) form.submit() } checkForPendingCart() { const pendingCart = sessionStorage.getItem('pending_cart') if (pendingCart) { try { const cartData = JSON.parse(pendingCart) if (cartData.eventId == this.eventIdValue) { this.cart = cartData.cart this.updateCartDisplay() // Restore quantities in inputs for (let ticketTypeId in this.cart) { const input = this.quantityTargetFor(ticketTypeId) if (input) { input.value = this.cart[ticketTypeId].quantity } } } sessionStorage.removeItem('pending_cart') } catch (e) { console.error('Error restoring pending cart:', e) sessionStorage.removeItem('pending_cart') } } } // Helper method to find quantity input by ticket type ID quantityTargetFor(ticketTypeId) { return document.querySelector(`#quantity_${ticketTypeId}`) } }