- Add ticket selection functionality to event show page using Stimulus - Create ticket_selection_controller.js for handling ticket quantity changes - Update ticket card component and event show view to work with Stimulus - Add comprehensive comments to all JavaScript files for better maintainability - Remove dependent: :destroy from event ticket_types association
79 lines
2.6 KiB
JavaScript
79 lines
2.6 KiB
JavaScript
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"]
|
|
|
|
// Initialize the controller and update the cart summary
|
|
connect() {
|
|
this.updateCartSummary()
|
|
}
|
|
|
|
// 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
|
|
}
|
|
}
|
|
} |