Refactored admin users page to use client-side fetching, loading states, and search functionality. Enhanced AdminAnalytics with a best month (YTD) card and removed debug logging. Improved SystemStatusCard formatting and removed console logs. Fixed profit chart period selection logic. Minor formatting fix in nav-item component.
68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
"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
|
|
icon: LucideIcon
|
|
children: React.ReactNode
|
|
onClick?: () => void
|
|
}
|
|
|
|
export const NavItem: React.FC<NavItemProps> = ({ href, icon: Icon, children, onClick }) => {
|
|
const pathname = usePathname()
|
|
// More precise active state detection:
|
|
// - Exact match: pathname === href
|
|
// - Sub-path match: pathname starts with href + '/' (but exclude /dashboard and /dashboard/admin from matching sub-paths)
|
|
const isExactMatch = pathname === href
|
|
const isSubPathMatch = pathname?.startsWith(href + '/')
|
|
// Exclude parent routes that should only match exactly
|
|
const shouldOnlyMatchExactly = href === '/dashboard' || href === '/dashboard/admin'
|
|
const isActive = isExactMatch || (isSubPathMatch && !shouldOnlyMatchExactly)
|
|
const isNavigatingRef = useRef(false)
|
|
|
|
const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
// Prevent rapid double-clicks
|
|
if (isNavigatingRef.current) {
|
|
e.preventDefault()
|
|
return
|
|
}
|
|
|
|
// Mark as navigating to prevent double-clicks
|
|
isNavigatingRef.current = true
|
|
|
|
// Always allow navigation - close mobile menu if needed
|
|
if (onClick) {
|
|
onClick()
|
|
}
|
|
|
|
// Reset flag after navigation completes
|
|
setTimeout(() => {
|
|
isNavigatingRef.current = false
|
|
}, 500)
|
|
}
|
|
|
|
return (
|
|
<Link
|
|
href={href}
|
|
onClick={handleClick}
|
|
className={cn(
|
|
"flex items-center px-3 py-2 text-sm rounded-md transition-colors",
|
|
"text-muted-foreground hover:text-foreground hover:bg-accent",
|
|
"active:scale-[0.98] transition-transform duration-75",
|
|
"touch-manipulation will-change-transform",
|
|
isActive && "bg-accent text-foreground font-medium"
|
|
)}
|
|
prefetch={true}
|
|
style={{ WebkitTapHighlightColor: 'transparent' }}
|
|
>
|
|
<Icon className="h-4 w-4 mr-3 flex-shrink-0" />
|
|
{children}
|
|
</Link>
|
|
)
|
|
} |