feat: port SiteHeader với branding Như Quỳnh

This commit is contained in:
tuyenio
2026-06-23 11:08:17 +07:00
parent 459e1d271a
commit fcd002d9af
+109
View File
@@ -0,0 +1,109 @@
"use client";
import Link from "next/link";
import { Landmark, Menu, PlayCircle, X } from "lucide-react";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { activeTour, navigation } from "@/app/content";
export function SiteHeader() {
const pathname = usePathname();
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
return (
<header className="public-header sticky top-0 z-50 border-b border-[var(--surface-border)] bg-[rgb(255_255_255_/_0.82)] shadow-[0_16px_46px_rgb(37_75_54_/_0.08)] backdrop-blur-[18px]">
<nav className="mx-auto flex h-[72px] max-w-7xl items-center justify-between gap-5 px-4 sm:px-6">
<Link
href="/"
className="flex min-w-0 items-center gap-3"
aria-label="VR360 Di sản Như Quỳnh"
>
<span className="public-logo-mark grid h-11 w-11 shrink-0 place-items-center overflow-hidden rounded-full border border-[rgb(142_95_11_/_0.24)] bg-[linear-gradient(135deg,rgb(255_255_255_/_0.94),rgb(232_219_176_/_0.74))] shadow-[0_10px_24px_rgb(37_75_54_/_0.1),inset_0_1px_0_rgb(255_255_255_/_0.92)]">
<Landmark className="h-5 w-5 text-[var(--primary)]" strokeWidth={1.8} />
</span>
<span className="min-w-0">
<span className="block truncate text-sm font-bold leading-tight text-[var(--tour-ink)] sm:text-base">
VR360 Như Quỳnh
</span>
<span className="hidden truncate text-xs leading-5 text-[var(--muted-foreground)] sm:block">
Di sản văn hóa Như Quỳnh
</span>
</span>
</Link>
<div className="hidden items-center gap-6 lg:flex">
{navigation.map((item) => {
const isActive = item.href === "/" ? pathname === item.href : pathname.startsWith(item.href);
return (
<Link
key={item.href}
className={`public-nav-link text-sm font-semibold transition-colors ${
isActive
? "text-[var(--primary)]"
: "text-[var(--muted-foreground)] hover:text-[var(--tour-ink)]"
}`}
href={item.href}
aria-current={isActive ? "page" : undefined}
>
{item.label}
</Link>
);
})}
</div>
<div className="flex items-center gap-3">
<Link
href={activeTour.href}
className="public-header-cta hidden min-h-10 items-center gap-2 rounded-full border border-[rgb(214_180_104_/_0.42)] bg-[rgb(16_57_43_/_0.94)] px-4 text-sm font-bold text-[var(--primary-foreground)] shadow-[0_10px_28px_rgb(37_75_54_/_0.12)] transition-all hover:-translate-y-0.5 hover:shadow-[0_14px_34px_rgb(37_75_54_/_0.18)] sm:inline-flex"
>
<PlayCircle className="h-4 w-4 text-[var(--tour-gold-light)]" strokeWidth={1.8} />
Khám phá VR360
</Link>
<button
onClick={() => setMobileMenuOpen((open) => !open)}
className="grid h-10 w-10 place-items-center rounded-[8px] border border-[var(--surface-border)] bg-[rgb(255_255_255_/_0.8)] text-[var(--tour-ink)] shadow-[0_10px_28px_rgb(37_75_54_/_0.08)] transition-transform active:scale-[0.98] lg:hidden"
aria-label="Menu"
aria-expanded={mobileMenuOpen}
>
{mobileMenuOpen ? <X className="h-5 w-5" strokeWidth={1.8} /> : <Menu className="h-5 w-5" strokeWidth={1.8} />}
</button>
</div>
</nav>
<div
className={`overflow-hidden border-t border-[var(--surface-border)] bg-[rgb(255_255_255_/_0.9)] transition-[max-height] duration-240 lg:hidden ${
mobileMenuOpen ? "max-h-80" : "max-h-0"
}`}
>
<div className="grid gap-2 px-4 py-4">
{navigation.map((item) => {
const isActive = item.href === "/" ? pathname === item.href : pathname.startsWith(item.href);
return (
<Link
key={item.href}
href={item.href}
onClick={() => setMobileMenuOpen(false)}
className={`rounded-[8px] border px-4 py-3 text-sm font-medium transition-colors ${
isActive
? "border-[var(--primary)]/35 bg-[var(--surface-glass-strong)] text-[var(--primary)]"
: "border-[var(--surface-border)] bg-[var(--surface-glass)] text-[var(--tour-ink)] hover:bg-[var(--surface-glass-strong)]"
}`}
>
{item.label}
</Link>
);
})}
<Link
href={activeTour.href}
onClick={() => setMobileMenuOpen(false)}
className="inline-flex items-center justify-center gap-2 rounded-full border border-[rgb(214_180_104_/_0.42)] bg-[rgb(16_57_43_/_0.94)] px-4 py-3 text-sm font-bold text-[var(--primary-foreground)]"
>
<PlayCircle className="h-4 w-4 text-[var(--tour-gold-light)]" strokeWidth={1.8} />
Khám phá VR360
</Link>
</div>
</div>
</header>
);
}