99 lines
3.7 KiB
TypeScript
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();
|
|
setAuthed(false);
|
|
setOpen(false);
|
|
} 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>
|
|
);
|
|
}
|