diff --git a/app/javascript/controllers/header_controller.js b/app/javascript/controllers/header_controller.js new file mode 100644 index 0000000..4991feb --- /dev/null +++ b/app/javascript/controllers/header_controller.js @@ -0,0 +1,73 @@ +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") + } + } + } +} \ No newline at end of file diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index cc8d1f4..89b7279 100755 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -2,10 +2,8 @@ // Run that command whenever you add a new controller or create them with // ./bin/rails generate stimulus controllerName -// Import the main Stimulus application import { application } from "./application" -// Import all controllers import LogoutController from "./logout_controller"; application.register("logout", LogoutController); @@ -18,6 +16,9 @@ application.register("flash-message", FlashMessageController); import TicketSelectionController from "./ticket_selection_controller" application.register("ticket-selection", TicketSelectionController); +import HeaderController from "./header_controller" +application.register("header", HeaderController); + diff --git a/app/views/components/_header.html.erb b/app/views/components/_header.html.erb index 2844294..a6c9b78 100755 --- a/app/views/components/_header.html.erb +++ b/app/views/components/_header.html.erb @@ -1,5 +1,5 @@
-