- Create new TicketsController with actions for name collection, creation, and checkout - Add dedicated ticket views (new.html.erb, checkout.html.erb, show.html.erb) - Update ticket_selection_controller.js to handle form submission via AJAX - Add store_cart endpoint in EventsController for session-based cart management - Update routes to support new ticket flow: /tickets/new, /create, /checkout - Fix attribute name consistency across views (title→name, starts_at→start_time) - Add Stripe checkout integration with proper error handling - Remove deprecated collect_names flow in favor of streamlined approach The flow is now: Event selection → AJAX cart storage → Name collection → Checkout → Payment
74 lines
2.4 KiB
JavaScript
74 lines
2.4 KiB
JavaScript
import { Controller } from "@hotwired/stimulus"
|
|
|
|
// Controller for handling the header navigation
|
|
// Manages mobile menu toggle and user dropdown menu
|
|
export default class extends Controller {
|
|
static targets = ["mobileMenu", "mobileMenuButton", "userMenu", "userMenuButton"]
|
|
|
|
connect() {
|
|
// Initialize menu states
|
|
this.mobileMenuOpen = false
|
|
this.userMenuOpen = false
|
|
|
|
// Add click outside listener for user menu
|
|
this.clickOutsideHandler = this.handleClickOutside.bind(this)
|
|
document.addEventListener("click", this.clickOutsideHandler)
|
|
}
|
|
|
|
disconnect() {
|
|
// Clean up event listener
|
|
document.removeEventListener("click", this.clickOutsideHandler)
|
|
}
|
|
|
|
// Toggle mobile menu visibility
|
|
toggleMobileMenu() {
|
|
this.mobileMenuOpen = !this.mobileMenuOpen
|
|
this.mobileMenuTarget.classList.toggle("hidden", !this.mobileMenuOpen)
|
|
|
|
// Update button icon based on state
|
|
const iconOpen = this.mobileMenuButtonTarget.querySelector('[data-menu-icon="open"]')
|
|
const iconClose = this.mobileMenuButtonTarget.querySelector('[data-menu-icon="close"]')
|
|
|
|
if (iconOpen && iconClose) {
|
|
iconOpen.classList.toggle("hidden", this.mobileMenuOpen)
|
|
iconClose.classList.toggle("hidden", !this.mobileMenuOpen)
|
|
}
|
|
}
|
|
|
|
// Toggle user dropdown menu visibility
|
|
toggleUserMenu() {
|
|
this.userMenuOpen = !this.userMenuOpen
|
|
if (this.hasUserMenuTarget) {
|
|
this.userMenuTarget.classList.toggle("hidden", !this.userMenuOpen)
|
|
}
|
|
}
|
|
|
|
// Close menus when clicking outside
|
|
handleClickOutside(event) {
|
|
// Close user menu if clicked outside
|
|
if (this.userMenuOpen && this.hasUserMenuTarget &&
|
|
!this.userMenuTarget.contains(event.target) &&
|
|
!this.userMenuButtonTarget.contains(event.target)) {
|
|
this.userMenuOpen = false
|
|
this.userMenuTarget.classList.add("hidden")
|
|
}
|
|
|
|
// Close mobile menu if clicked outside
|
|
if (this.mobileMenuOpen &&
|
|
!this.mobileMenuTarget.contains(event.target) &&
|
|
!this.mobileMenuButtonTarget.contains(event.target)) {
|
|
this.mobileMenuOpen = false
|
|
this.mobileMenuTarget.classList.add("hidden")
|
|
|
|
// Update button icon
|
|
const iconOpen = this.mobileMenuButtonTarget.querySelector('[data-menu-icon="open"]')
|
|
const iconClose = this.mobileMenuButtonTarget.querySelector('[data-menu-icon="close"]')
|
|
|
|
if (iconOpen && iconClose) {
|
|
iconOpen.classList.remove("hidden")
|
|
iconClose.classList.add("hidden")
|
|
}
|
|
}
|
|
}
|
|
}
|