Some checks failed
Deploy to Cloudflare Workers (OpenNext) / deploy (push) Has been cancelled
Centralize primary, secondary, tertiary, and neutral tokens and apply them across theme variables and UI components. Co-authored-by: Cursor <cursoragent@cursor.com>
98 lines
3.5 KiB
TypeScript
98 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useState } from "react";
|
|
import { ChevronDown } from "lucide-react";
|
|
import { BrandLogo } from "@/components/brand/BrandLogo";
|
|
import { MobileNavDropdown, MobileNavTrigger } from "@/components/layout/MobileNavSheet";
|
|
import { NavTicketsCta } from "@/components/layout/NavTicketsCta";
|
|
import { programDays } from "@/content/program";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const navPills = [
|
|
{ href: "/speakers", label: "Lineup" },
|
|
{ href: "/pitch-competition", label: "Pitch", badge: "Grants" },
|
|
{ href: "/partners", label: "Partners" },
|
|
{ href: "/exhibit", label: "Exhibit" },
|
|
];
|
|
|
|
const pillClass =
|
|
"inline-flex items-center gap-1.5 rounded-full bg-[#37a47a]/10 px-4 py-2 text-sm font-medium text-[#30614c] transition-colors hover:bg-[#37a47a]/15";
|
|
|
|
export function SiteHeader() {
|
|
const [mobileOpen, setMobileOpen] = useState(false);
|
|
|
|
return (
|
|
<header className="fixed inset-x-0 top-0 z-50 px-3 pt-3 md:px-6 md:pt-4">
|
|
<div className="relative mx-auto max-w-6xl">
|
|
<div
|
|
className={cn(
|
|
"flex items-center gap-2 rounded-full",
|
|
"border border-[#37a47a]/10 bg-white/95 px-2 py-2",
|
|
"shadow-lg shadow-[#37a47a]/10 backdrop-blur-md"
|
|
)}
|
|
>
|
|
<BrandLogo className="min-w-0 shrink pl-0.5" compact />
|
|
|
|
<nav className="hidden flex-1 items-center justify-center gap-1.5 lg:flex">
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<button type="button" className={cn(pillClass, "gap-1")}>
|
|
Program
|
|
<ChevronDown className="size-3.5 opacity-60" />
|
|
</button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="start" className="w-72 rounded-2xl p-2">
|
|
{programDays.map((day) => (
|
|
<DropdownMenuItem key={day.id} asChild>
|
|
<Link href="/program" className="cursor-pointer rounded-xl p-3">
|
|
<p className="text-xs font-medium uppercase text-muted-foreground">
|
|
{day.date}
|
|
</p>
|
|
<p className="font-semibold">{day.title}</p>
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
))}
|
|
<DropdownMenuItem asChild>
|
|
<Link
|
|
href="/pitch-competition"
|
|
className="mt-1 cursor-pointer rounded-xl bg-[#37a47a] p-3 text-white"
|
|
>
|
|
Pitch Competition
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
|
|
{navPills.map((link) => (
|
|
<Link key={link.href} href={link.href} className={pillClass}>
|
|
{link.label}
|
|
{link.badge && (
|
|
<span className="rounded bg-[#37a47a] px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wide text-white">
|
|
{link.badge}
|
|
</span>
|
|
)}
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
|
|
<div className="ml-auto flex items-center gap-2 pr-1">
|
|
<NavTicketsCta className="hidden sm:inline-flex" />
|
|
<MobileNavTrigger
|
|
open={mobileOpen}
|
|
onToggle={() => setMobileOpen((v) => !v)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<MobileNavDropdown open={mobileOpen} onClose={() => setMobileOpen(false)} />
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|