import { Controller } from "@hotwired/stimulus" // Controller for handling ticket selection on the event show page // Manages quantity inputs, calculates totals, and enables/disables the checkout button export default class extends Controller { static targets = ["quantityInput", "totalQuantity", "totalAmount", "checkoutButton", "form"] static values = { eventSlug: String, eventId: String } // Initialize the controller and update the cart summary connect() { this.updateCartSummary() this.bindFormSubmission() } // Bind form submission to handle cart storage bindFormSubmission() { if (this.hasFormTarget) { this.formTarget.addEventListener('submit', this.submitCart.bind(this)) } } // Increment the quantity for a specific ticket type increment(event) { const ticketTypeId = event.currentTarget.dataset.target const input = this.quantityInputTargets.find(input => input.dataset.target === ticketTypeId) const value = parseInt(input.value) || 0 const max = parseInt(input.max) || 0 if (value < max) { input.value = value + 1 this.updateCartSummary() } } // Decrement the quantity for a specific ticket type decrement(event) { const ticketTypeId = event.currentTarget.dataset.target const input = this.quantityInputTargets.find(input => input.dataset.target === ticketTypeId) const value = parseInt(input.value) || 0 if (value > 0) { input.value = value - 1 this.updateCartSummary() } } // Update quantity when directly edited in the input field updateQuantity(event) { const input = event.currentTarget let value = parseInt(input.value) || 0 const max = parseInt(input.max) || 0 // Ensure value is within valid range (0 to max available) if (value < 0) value = 0 if (value > max) value = max input.value = value this.updateCartSummary() } // Calculate and update the cart summary (total quantity and amount) updateCartSummary() { let totalQuantity = 0 let totalAmount = 0 // Sum up quantities and calculate total amount this.quantityInputTargets.forEach(input => { const quantity = parseInt(input.value) || 0 const price = parseInt(input.dataset.price) || 0 totalQuantity += quantity totalAmount += quantity * price }) // Update the displayed total quantity and amount this.totalQuantityTarget.textContent = totalQuantity this.totalAmountTarget.textContent = `€${(totalAmount / 100).toFixed(2)}` // Enable/disable checkout button based on whether any tickets are selected if (totalQuantity > 0) { this.checkoutButtonTarget.classList.remove('opacity-50', 'cursor-not-allowed') this.checkoutButtonTarget.disabled = false } else { this.checkoutButtonTarget.classList.add('opacity-50', 'cursor-not-allowed') this.checkoutButtonTarget.disabled = true } } // Handle form submission - store cart in session before proceeding async submitCart(event) { event.preventDefault() const cartData = this.buildCartData() if (Object.keys(cartData).length === 0) { alert('Veuillez sélectionner au moins un billet') return } try { // Store cart data in session await this.storeCartInSession(cartData) // Redirect to tickets/new page const ticketNewUrl = `/events/${this.eventSlugValue}.${this.eventIdValue}/tickets/new` window.location.href = ticketNewUrl } catch (error) { console.error('Error storing cart:', error) alert('Une erreur est survenue. Veuillez réessayer.') } } // Build cart data from current form state buildCartData() { const cartData = {} this.quantityInputTargets.forEach(input => { const quantity = parseInt(input.value) || 0 if (quantity > 0) { const ticketTypeId = input.dataset.target cartData[ticketTypeId] = { quantity: quantity } } }) return cartData } // Store cart data in session via AJAX async storeCartInSession(cartData) { const storeCartUrl = `/events/${this.eventSlugValue}.${this.eventIdValue}/store_cart` const response = await fetch(storeCartUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content') }, body: JSON.stringify({ cart: cartData }) }) if (!response.ok) { throw new Error(`Failed to store cart data: ${response.status} ${response.statusText}`) } return response.json() } }