"use client" import { AnimatePresence, motion } from "motion/react" import logo from "@/app/icon.png" import Image from "next/image" import Link from "next/link" import { useEffect, useRef, useState } from "react" import { CircleXIcon, Gamepad2Icon, MenuIcon, XIcon } from "lucide-react" import { routes } from "@/lib/routes" import { usePathname, useRouter, useSearchParams } from "next/navigation" import { useDebounce } from "@/lib/hooks/useDebounce" export default function Navbar() { const pathname = usePathname() const router = useRouter() const searchParams = useSearchParams() const isLanding = pathname === "/" const [searchQuery, setSearchQuery] = useState("") const debouncedQuery = useDebounce(searchQuery, 300) const [mobileMenuOpen, setMobileMenuOpen] = useState(false) const [isFocused, setIsFocused] = useState(false) const [forceFocusStyles, setForceFocusStyles] = useState(false) const inputRef = useRef(null) // Sync search query with URL ?q= param useEffect(() => { const q = searchParams.get("q") || "" setSearchQuery(q) }, [searchParams]) // Update URL when debounced query changes (skip if already matches) useEffect(() => { if (isLanding) return const currentQ = searchParams.get("q") || "" if (debouncedQuery === currentQ) return const params = new URLSearchParams(searchParams.toString()) if (debouncedQuery) { params.set("q", debouncedQuery) } else { params.delete("q") } router.replace(`/search?${params.toString()}`, { scroll: false }) }, [debouncedQuery, isLanding, router, searchParams]) // Maintain focus & styles when flying from landing page search useEffect(() => { if ( !isLanding && searchQuery && sessionStorage.getItem("focusSearch") === "true" ) { sessionStorage.removeItem("focusSearch") setForceFocusStyles(true) // Focus the input after the layout animation element mounts requestAnimationFrame(() => { inputRef.current?.focus() }) const timer = setTimeout(() => setForceFocusStyles(false), 450) return () => clearTimeout(timer) } }, [isLanding, searchQuery]) const handleSearchChange = (e: React.ChangeEvent) => { setSearchQuery(e.target.value) } const handleSearchSubmit = () => { if (searchQuery.trim()) { router.push(`/search?q=${encodeURIComponent(searchQuery.trim())}`) } } const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { handleSearchSubmit() } } const navbarRoutes = routes.filter( (route) => route.href !== "/" && route.href !== "/search", ) return ( <> DeckyVault Logo {!isLanding && ( DeckyVault )} {!isLanding && ( setIsFocused(true)} onBlur={() => setIsFocused(false)} className='flex-1 outline-none bg-transparent text-sm min-w-0' /> { setSearchQuery("") if (!isLanding) { const params = new URLSearchParams( searchParams.toString(), ) params.delete("q") router.replace( `/search?${params.toString()}`, { scroll: false, }, ) } }} className={`h-3 w-3 transition-color cursor-default hover:stroke-accent transition-all ${ isFocused || forceFocusStyles ? "opacity-100" : "opacity-0" }`} /> )} {/* Desktop Navigation Links */}
    {navbarRoutes.map((route) => ( {route.title} ))}
{/* Mobile Hamburger Button */}
{/* Mobile Sidebar Overlay */} {mobileMenuOpen && ( <> setMobileMenuOpen(false)} />
Menu
)}
) }