"use client"; import { useState, useEffect } from "react"; import Link from "next/link"; import { Menu, X, ArrowUpRight, ArrowRight, Search } from "lucide-react"; import { usePersistentBoolean } from "@/hooks/use-persistent-boolean"; import { usePathname } from "next/navigation"; import { cn } from "@/lib/utils"; import { formatCompact } from "@/lib/format"; import { SearchDialog } from "./search-dialog"; import { GitHubIcon } from "@/components/icons/github"; import { DiscordIcon } from "@/components/icons/discord"; import { NAV_ITEMS } from "@/lib/constants"; import { CloudButton, cloudButtonVariants, } from "@/components/shared/cloud-button"; import { useAssistantPanel } from "@/components/docs/assistant/context"; import { NavItems } from "@/components/shared/nav-items"; import { HeaderBrandLink } from "@/components/shared/header-brand-link"; function SearchButton({ onToggle }: { onToggle: () => void }) { useEffect(() => { const down = (e: KeyboardEvent) => { if (e.key === "k" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); e.stopPropagation(); onToggle(); } }; document.addEventListener("keydown", down, true); return () => document.removeEventListener("keydown", down, true); }, [onToggle]); return ( ); } function HiringBanner({ onDismiss }: { onDismiss: () => void }) { return (
We're hiring. Build the future of agentic UI.
); } export function Header() { const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const [searchOpen, setSearchOpen] = useState(false); const [mounted, setMounted] = useState(false); const [stars, setStars] = useState(null); const pathname = usePathname(); const { toggle } = useAssistantPanel(); const [dismissed, setDismissed] = usePersistentBoolean( "homepage-hiring-banner-dismissed", ); const [visited, setVisited] = usePersistentBoolean("homepage-visited"); const [returningVisitor, setReturningVisitor] = useState(false); useEffect(() => { setMounted(true); }, []); useEffect(() => { if (pathname !== "/") return; // Show the banner only from the second homepage visit onward. setReturningVisitor(visited); if (!visited) setVisited(true); // oxlint-disable-next-line react/exhaustive-deps }, [pathname]); useEffect(() => { fetch("/api/github/repo") .then((res) => (res.ok ? res.json() : null)) .then((data) => { if (data && typeof data.stars === "number") { setStars(data.stars); } }) .catch(console.error); }, []); const isHome = pathname === "/"; const showBanner = mounted && isHome && returningVisitor && !dismissed; return (
{!isHome && ( <> setSearchOpen((prev) => !prev)} /> )} {isHome && ( )} {stars !== null && ( {formatCompact(stars)} )} {!isHome && ( )}
{showBanner && (
setDismissed(true)} />
)}
); }