All checks were successful
CI / lint-and-test (push) Successful in 9m52s
Co-authored-by: Cursor <cursoragent@cursor.com>
106 lines
3.0 KiB
TypeScript
106 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const navItems = [
|
|
{ label: "Dashboard", href: "/" },
|
|
{ label: "Receive", href: "/receive" },
|
|
{ label: "Send", href: "/send" },
|
|
{ label: "Transfer", href: "/transfer" },
|
|
{ label: "Approvals", href: "/approvals" },
|
|
{ label: "Activity", href: "/activity" },
|
|
{ label: "Settings", href: "/settings" },
|
|
];
|
|
|
|
function NavLink({
|
|
href,
|
|
label,
|
|
isActive,
|
|
onNavigate,
|
|
}: {
|
|
href: string;
|
|
label: string;
|
|
isActive: boolean;
|
|
onNavigate?: () => void;
|
|
}) {
|
|
return (
|
|
<Link
|
|
href={href}
|
|
onClick={onNavigate}
|
|
className={cn(
|
|
"px-4 py-3 sm:py-4 text-sm font-medium transition-colors border-b-2 whitespace-nowrap",
|
|
isActive
|
|
? "border-blue-500 text-blue-400 bg-blue-950/30 sm:bg-transparent"
|
|
: "border-transparent text-gray-400 hover:text-gray-200 hover:border-gray-700 hover:bg-gray-800/50 sm:hover:bg-transparent"
|
|
)}
|
|
>
|
|
{label}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
export function Navigation() {
|
|
const pathname = usePathname();
|
|
const [mobileOpen, setMobileOpen] = useState(false);
|
|
|
|
const closeMobile = () => setMobileOpen(false);
|
|
|
|
return (
|
|
<nav
|
|
className="bg-gray-900 border-b border-gray-800 shrink-0"
|
|
aria-label="Main navigation"
|
|
>
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-8">
|
|
{/* Mobile: menu toggle + horizontal scroll fallback on sm */}
|
|
<div className="flex items-center justify-between sm:hidden py-2">
|
|
<span className="text-sm text-gray-400">
|
|
{navItems.find((item) => item.href === pathname)?.label ?? "Menu"}
|
|
</span>
|
|
<button
|
|
type="button"
|
|
onClick={() => setMobileOpen((open) => !open)}
|
|
className="px-3 py-2 text-sm font-medium text-gray-200 bg-gray-800 hover:bg-gray-700 rounded-lg transition-colors"
|
|
aria-expanded={mobileOpen}
|
|
aria-controls="mobile-nav-menu"
|
|
>
|
|
{mobileOpen ? "Close" : "Menu"}
|
|
</button>
|
|
</div>
|
|
|
|
{/* Desktop nav */}
|
|
<div className="hidden sm:flex items-center gap-2 lg:gap-4 overflow-x-auto">
|
|
{navItems.map((item) => (
|
|
<NavLink
|
|
key={item.href}
|
|
href={item.href}
|
|
label={item.label}
|
|
isActive={pathname === item.href}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
{/* Mobile dropdown */}
|
|
{mobileOpen && (
|
|
<div
|
|
id="mobile-nav-menu"
|
|
className="sm:hidden flex flex-col border-t border-gray-800"
|
|
>
|
|
{navItems.map((item) => (
|
|
<NavLink
|
|
key={item.href}
|
|
href={item.href}
|
|
label={item.label}
|
|
isActive={pathname === item.href}
|
|
onNavigate={closeMobile}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</nav>
|
|
);
|
|
}
|