diff --git a/frontend/src/components/Navbar.tsx b/frontend/src/components/Navbar.tsx index 7f424b9..3646a88 100644 --- a/frontend/src/components/Navbar.tsx +++ b/frontend/src/components/Navbar.tsx @@ -1,5 +1,5 @@ -import React, { useState, useEffect } from "react"; -import { Link, useNavigate } from "react-router-dom"; +import React, { useState, useEffect, useRef, useCallback } from "react"; +import { Link, useNavigate, useLocation } from "react-router-dom"; import { useAuth } from "../contexts/AuthContext"; import { useSocket } from "../contexts/SocketContext"; import { rentalAPI, messageAPI } from "../services/api"; @@ -9,9 +9,55 @@ const Navbar: React.FC = () => { const { user, logout, openAuthModal } = useAuth(); const { onNewMessage, onMessageRead } = useSocket(); const navigate = useNavigate(); + const location = useLocation(); const [searchTerm, setSearchTerm] = useState(""); const [pendingRequestsCount, setPendingRequestsCount] = useState(0); const [unreadMessagesCount, setUnreadMessagesCount] = useState(0); + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); + const dropdownRef = useRef(null); + const mobileMenuRef = useRef(null); + const mobileToggleRef = useRef(null); + + const closeDropdown = useCallback(() => { + setIsDropdownOpen(false); + }, []); + + const closeMobileMenu = useCallback(() => { + setIsMobileMenuOpen(false); + }, []); + + // Close menus when route changes + useEffect(() => { + closeDropdown(); + closeMobileMenu(); + }, [location.pathname, closeDropdown, closeMobileMenu]); + + // Close dropdown when clicking outside + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + // Desktop dropdown + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsDropdownOpen(false); + } + // Mobile menu + if ( + isMobileMenuOpen && + mobileMenuRef.current && + mobileToggleRef.current && + !mobileMenuRef.current.contains(event.target as Node) && + !mobileToggleRef.current.contains(event.target as Node) + ) { + setIsMobileMenuOpen(false); + } + }; + + document.addEventListener("click", handleClickOutside, true); + + return () => { + document.removeEventListener("click", handleClickOutside, true); + }; + }, [isMobileMenuOpen]); // Fetch pending rental requests count when user logs in useEffect(() => { @@ -109,31 +155,16 @@ const Navbar: React.FC = () => { <> @@ -170,13 +201,16 @@ const Navbar: React.FC = () => { {/* Mobile menu toggle */} -