first commit
This commit is contained in:
93
web/src/components/SiteNavbar.tsx
Normal file
93
web/src/components/SiteNavbar.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
import {
|
||||
Link,
|
||||
Button,
|
||||
Avatar,
|
||||
Dropdown,
|
||||
Label
|
||||
} from "@heroui/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSession, signOut } from "../lib/auth-client";
|
||||
|
||||
export function SiteNavbar() {
|
||||
const { data: session } = useSession();
|
||||
const [theme, setTheme] = useState<"light" | "dark">("light");
|
||||
|
||||
useEffect(() => {
|
||||
const currentTheme = document.documentElement.classList.contains("dark") ? "dark" : "light";
|
||||
setTheme(currentTheme);
|
||||
}, []);
|
||||
|
||||
const toggleTheme = () => {
|
||||
const nextTheme = theme === "dark" ? "light" : "dark";
|
||||
document.documentElement.classList.remove("light", "dark");
|
||||
document.documentElement.classList.add(nextTheme);
|
||||
document.documentElement.setAttribute("data-theme", nextTheme);
|
||||
localStorage.setItem("theme", nextTheme);
|
||||
setTheme(nextTheme);
|
||||
};
|
||||
|
||||
return (
|
||||
<nav className="flex items-center justify-between px-6 py-3 bg-background/70 backdrop-blur-md border-b border-white/10 sticky top-0 z-50 w-full">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link className="font-bold text-inherit text-lg no-underline text-foreground" href="/">
|
||||
HLAE 中文站
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="hidden sm:flex gap-6 justify-center flex-1">
|
||||
<Link className="text-foreground hover:text-primary transition-colors" href="/">
|
||||
首页
|
||||
</Link>
|
||||
<Link className="text-foreground hover:text-primary transition-colors" href="/posts">
|
||||
帖子
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4 justify-end">
|
||||
<Button variant="ghost" onPress={toggleTheme}>
|
||||
{theme === "dark" ? "☀️" : "🌙"}
|
||||
</Button>
|
||||
{session ? (
|
||||
<Dropdown>
|
||||
<Dropdown.Trigger>
|
||||
<button className="outline-none focus:outline-none rounded-full">
|
||||
<Avatar size="sm">
|
||||
<Avatar.Image
|
||||
alt={session.user.name || "用户头像"}
|
||||
src={session.user.image || ""}
|
||||
/>
|
||||
<Avatar.Fallback>
|
||||
{(session.user.name || "U").slice(0, 2).toUpperCase()}
|
||||
</Avatar.Fallback>
|
||||
</Avatar>
|
||||
</button>
|
||||
</Dropdown.Trigger>
|
||||
<Dropdown.Popover>
|
||||
<Dropdown.Menu aria-label="Profile Actions">
|
||||
<Dropdown.Item id="profile" textValue="Profile">
|
||||
<Label className="font-semibold">登录为 {session.user.email}</Label>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item id="logout" textValue="Logout" onPress={() => signOut()}>
|
||||
<Label className="text-danger">退出登录</Label>
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown.Popover>
|
||||
</Dropdown>
|
||||
) : (
|
||||
<div className="flex gap-4 items-center">
|
||||
<Link href="/login">
|
||||
<Button variant="ghost" className="text-foreground hover:text-primary">
|
||||
登录
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href="/register">
|
||||
<Button variant="primary" className="text-foreground hover:text-primary">
|
||||
注册
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user