diff --git a/src/client/components/TopNav.tsx b/src/client/components/TopNav.tsx new file mode 100644 index 0000000..b15b26a --- /dev/null +++ b/src/client/components/TopNav.tsx @@ -0,0 +1,129 @@ +import { Link, useMatchRoute } from "@tanstack/react-router"; +import { useAuth } from "../hooks/useAuth"; +import { LucideIcon } from "../lib/iconData"; +import { useUIStore } from "../stores/uiStore"; +import { UserMenu } from "./UserMenu"; + +interface NavLinkOrButtonProps { + to: string; + isActive: boolean; + isProtected: boolean; + isAuthenticated: boolean; + onAuthPrompt: () => void; + children: React.ReactNode; +} + +function NavLinkOrButton({ + to, + isActive, + isProtected, + isAuthenticated, + onAuthPrompt, + children, +}: NavLinkOrButtonProps) { + const activeClass = "text-gray-900 font-medium"; + const inactiveClass = "text-gray-500 hover:text-gray-700 transition-colors"; + const className = `text-sm ${isActive ? activeClass : inactiveClass}`; + + if (isProtected && !isAuthenticated) { + return ( + + ); + } + + return ( + + {children} + + ); +} + +export function TopNav() { + const { data: auth } = useAuth(); + const isAuthenticated = !!auth?.user; + const openCatalogSearch = useUIStore((s) => s.openCatalogSearch); + const openAuthPrompt = useUIStore((s) => s.openAuthPrompt); + const matchRoute = useMatchRoute(); + + const isHome = !!matchRoute({ to: "/" }); + const isCollection = !!matchRoute({ to: "/collection", fuzzy: true }); + const isSetups = !!matchRoute({ to: "/setups", fuzzy: true }); + + return ( +
+
+
+ {/* Left: Logo */} + + + GearBox + + + {/* Center: Desktop nav links */} + + + {/* Right: Search bar (desktop only) + User section */} +
+ {/* Search bar — desktop only */} + + + {/* User section */} + {isAuthenticated ? ( + + ) : ( + + Sign in + + )} +
+
+
+
+ ); +}