Download src/components/SiteHeader.tsx from incname/web: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/spaces/incname/web/resolve/main/src/components/SiteHeader.tsx
- Command line
-
hf download hf://spaces/incname/web/src/components/SiteHeader.tsx
-
curl -L -o SiteHeader.tsx https://huggingface.co/spaces/incname/web/resolve/main/src/components/SiteHeader.tsx
3.89 kB
| import { Link, useRouterState } from "@tanstack/react-router"; | |
| import { useState } from "react"; | |
| import { Menu, X, Eye } from "lucide-react"; | |
| import { Button } from "@/components/ui/button"; | |
| const navLinks = [ | |
| { to: "/", label: "Home" }, | |
| { to: "/how-it-works", label: "How It Works" }, | |
| { to: "/why-safesight", label: "Why SafeSight" }, | |
| { to: "/about", label: "About" }, | |
| { to: "/pricing", label: "Pricing" }, | |
| { to: "/download", label: "Download" }, | |
| { to: "/contact", label: "Contact" }, | |
| ]; | |
| export function SiteHeader() { | |
| const [mobileOpen, setMobileOpen] = useState(false); | |
| const pathname = useRouterState({ select: (s) => s.location.pathname }); | |
| return ( | |
| <header className="sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"> | |
| <div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6 lg:px-8"> | |
| <Link to="/" className="flex items-center gap-2"> | |
| <Eye className="h-8 w-8 text-accent" /> | |
| <span className="text-xl font-bold tracking-tight text-foreground"> | |
| SafeSight | |
| </span> | |
| </Link> | |
| {/* Desktop nav */} | |
| <nav className="hidden items-center gap-1 lg:flex"> | |
| {navLinks.map((link) => ( | |
| <Link | |
| key={link.to} | |
| to={link.to} | |
| activeProps={{ className: "text-primary font-medium" }} | |
| inactiveProps={{ className: "text-muted-foreground hover:text-foreground" }} | |
| activeOptions={{ exact: link.to === "/" }} | |
| className="rounded-md px-3 py-2 text-sm transition-colors" | |
| > | |
| {link.label} | |
| </Link> | |
| ))} | |
| </nav> | |
| <div className="hidden items-center gap-3 lg:flex"> | |
| <Link to="/pricing"> | |
| <Button variant="outline" className="text-sm"> | |
| Pricing | |
| </Button> | |
| </Link> | |
| <Link to="/download"> | |
| <Button className="bg-accent text-accent-foreground hover:bg-accent/90 text-sm"> | |
| Get the App | |
| </Button> | |
| </Link> | |
| </div> | |
| {/* Mobile menu button */} | |
| <button | |
| className="lg:hidden inline-flex items-center justify-center rounded-md p-2 text-foreground" | |
| onClick={() => setMobileOpen(!mobileOpen)} | |
| aria-label="Toggle menu" | |
| > | |
| {mobileOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />} | |
| </button> | |
| </div> | |
| {/* Mobile nav */} | |
| {mobileOpen && ( | |
| <div className="border-t border-border bg-background lg:hidden"> | |
| <div className="mx-auto max-w-7xl space-y-1 px-4 py-4"> | |
| {navLinks.map((link) => ( | |
| <Link | |
| key={link.to} | |
| to={link.to} | |
| onClick={() => setMobileOpen(false)} | |
| className={`block rounded-md px-3 py-2 text-base ${ | |
| pathname === link.to || (link.to !== "/" && pathname.startsWith(link.to)) | |
| ? "bg-muted font-medium text-foreground" | |
| : "text-muted-foreground hover:bg-muted hover:text-foreground" | |
| }`} | |
| > | |
| {link.label} | |
| </Link> | |
| ))} | |
| <div className="flex flex-col gap-2 pt-2"> | |
| <Link to="/pricing" onClick={() => setMobileOpen(false)}> | |
| <Button variant="outline" className="w-full"> | |
| Pricing | |
| </Button> | |
| </Link> | |
| <Link to="/download" onClick={() => setMobileOpen(false)}> | |
| <Button className="w-full bg-accent text-accent-foreground hover:bg-accent/90"> | |
| Get the App | |
| </Button> | |
| </Link> | |
| </div> | |
| </div> | |
| </div> | |
| )} | |
| </header> | |
| ); | |
| } | |