www_site/components/site-header.tsx

99 lines
3.7 KiB
TypeScript

"use client";
import Link from "next/link";
import { useEffect, useState } from "react";
import { CloseIcon, MenuIcon } from "@/components/icons";
import { navigation } from "@/lib/content";
import { getMe, logout } from "@/lib/admin";
import { BrandMark } from "@/components/brand-mark";
import { BrandIcon } from "@/components/brand-icon";
export function SiteHeader() {
const [open, setOpen] = useState(false);
const [authed, setAuthed] = useState(false);
useEffect(() => {
getMe()
.then(() => setAuthed(true))
.catch(() => setAuthed(false));
}, []);
async function handleLogout() {
try {
await logout();
window.location.assign("/");
return;
} catch {
window.location.href = "/login";
}
}
return (
<header className="sticky top-0 z-50 border-b border-white/5 bg-ink/90 backdrop-blur-xl">
<div className="container-shell flex h-[82px] items-center justify-between gap-6">
<Link aria-label="返回考町科技首页" href="/" onClick={() => setOpen(false)}>
<BrandMark compact />
</Link>
<nav aria-label="主导航" className="desktop-nav items-center gap-8">
{navigation.map((item) => (
<Link className="text-sm text-muted transition-colors hover:text-copy" href={item.href} key={item.href}>
{item.label}
</Link>
))}
</nav>
<div className="desktop-nav items-center gap-6">
{authed ? (
<>
<Link className="button-ghost min-h-10 px-4 py-2 text-sm" href="/account">
<BrandIcon />
</Link>
<button className="button-ghost min-h-10 px-4 py-2 text-sm" onClick={() => void handleLogout()} type="button">
<BrandIcon />退
</button>
</>
) : (
<Link className="button-ghost min-h-10 px-4 py-2 text-sm" href="/login">
<BrandIcon />
</Link>
)}
<Link className="button-primary min-h-10 px-4 py-2 text-sm" href="/contact">
<BrandIcon />
</Link>
</div>
<button aria-expanded={open} aria-label={open ? "关闭导航" : "打开导航"} className="button-ghost mobile-nav-trigger min-h-10 p-2" onClick={() => setOpen((current) => !current)} type="button">
{open ? <CloseIcon /> : <MenuIcon />}
</button>
</div>
{open ? (
<div className="border-t border-line bg-panel md:hidden">
<nav aria-label="移动端主导航" className="container-shell flex flex-col gap-1 py-4">
{navigation.map((item) => (
<Link className="rounded-lg px-3 py-3 text-sm text-muted hover:bg-panel-raised hover:text-copy" href={item.href} key={item.href} onClick={() => setOpen(false)}>
{item.label}
</Link>
))}
{authed ? (
<>
<Link className="mt-2 rounded-lg border-t border-line px-3 py-3 text-sm text-copy" href="/account" onClick={() => setOpen(false)}>
</Link>
<button
className="mt-1 rounded-lg border-t border-line px-3 py-4 text-left text-sm text-copy hover:bg-panel-raised"
onClick={() => void handleLogout()}
type="button"
>
退
</button>
</>
) : (
<Link className="mt-2 rounded-lg border-t border-line px-3 py-4 text-sm text-copy" href="/login" onClick={() => setOpen(false)}>
/
</Link>
)}
</nav>
</div>
) : null}
</header>
);
}