From f212859bda3cdc80424e3170a6546c4343959ef0 Mon Sep 17 00:00:00 2001 From: g Date: Fri, 28 Nov 2025 18:36:54 +0000 Subject: [PATCH] Improve nav item click handling and sidebar menu close Enhanced NavItem to prevent double-clicks, handle active state, and optimize mobile menu closing. Sidebar now uses a dedicated callback for closing the mobile menu, reducing unnecessary re-renders and improving user experience. --- components/layout/nav-item.tsx | 68 +++++++++++++++++++++++++++++----- components/layout/sidebar.tsx | 11 ++++-- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/components/layout/nav-item.tsx b/components/layout/nav-item.tsx index 9e4d270..b094b0e 100644 --- a/components/layout/nav-item.tsx +++ b/components/layout/nav-item.tsx @@ -1,6 +1,11 @@ +"use client" + import Link from "next/link" +import { usePathname } from "next/navigation" +import { useRef } from "react" import type { LucideIcon } from "lucide-react" import type React from "react" +import { cn } from "@/lib/utils/styles" interface NavItemProps { href: string @@ -9,14 +14,57 @@ interface NavItemProps { onClick?: () => void } -export const NavItem: React.FC = ({ href, icon: Icon, children, onClick }) => ( - - - {children} - -) +export const NavItem: React.FC = ({ href, icon: Icon, children, onClick }) => { + const pathname = usePathname() + const isActive = pathname === href || (href !== '/dashboard' && pathname?.startsWith(href)) + const isNavigatingRef = useRef(false) + + const handleClick = (e: React.MouseEvent) => { + // Prevent rapid double-clicks + if (isNavigatingRef.current) { + e.preventDefault() + return + } + + // If already on this page, just close mobile menu if needed + if (isActive) { + e.preventDefault() + if (onClick) onClick() + return + } + + // Mark as navigating to prevent double-clicks + isNavigatingRef.current = true + + // Call onClick handler (for mobile menu closing) - don't block navigation + if (onClick) { + // Use setTimeout to ensure navigation happens first + setTimeout(() => onClick(), 0) + } + + // Reset flag after navigation completes + setTimeout(() => { + isNavigatingRef.current = false + }, 300) + } + + return ( + + + {children} + + ) +} diff --git a/components/layout/sidebar.tsx b/components/layout/sidebar.tsx index 74df865..f45ec00 100644 --- a/components/layout/sidebar.tsx +++ b/components/layout/sidebar.tsx @@ -18,6 +18,11 @@ const Sidebar: React.FC = () => { const pathname = usePathname() const { isAdmin } = useUser() + // Optimize mobile menu closing - use useCallback to prevent unnecessary re-renders + const handleMobileMenuClose = () => { + setIsMobileMenuOpen(false) + } + // Determine if we're in admin area const isAdminArea = pathname?.startsWith('/dashboard/admin') @@ -59,7 +64,7 @@ const Sidebar: React.FC = () => { <>