chore: 统一代码格式并配置开发工具

- 添加 ESLint 和 Prettier 配置以统一代码风格
- 配置项目级 TypeScript 设置
- 更新前后端依赖版本
- 修复代码格式问题(引号、分号、尾随逗号等)
- 优化文件结构和导入路径
This commit is contained in:
2026-03-10 18:24:19 +08:00
parent 58373a15a9
commit 35d835f68c
58 changed files with 14240 additions and 922 deletions

View File

@@ -1,80 +1,92 @@
import {
Link,
Button,
Avatar,
Dropdown,
Label
} from "@heroui/react";
import { linkVariants, buttonVariants } from "@heroui/styles";
import { useEffect, useState } from "react";
import { useSession, signOut } from "../lib/auth-client";
import { SunIcon, MoonIcon } from "@heroicons/react/24/outline";
import { Link as RouterLink } from "react-router-dom";
import { Button, Avatar, Dropdown, Label } from '@heroui/react'
import { buttonVariants } from '@heroui/styles'
import { useEffect, useState } from 'react'
import { useSession, signOut } from '../lib/auth-client'
import { SunIcon, MoonIcon } from '@heroicons/react/24/outline'
import { Link as RouterLink } from 'react-router-dom'
export function SiteNavbar() {
const { data: session } = useSession();
const [theme, setTheme] = useState<"light" | "dark">("light");
const { data: session } = useSession()
const [theme, setTheme] = useState<'light' | 'dark'>(() => {
if (typeof window !== 'undefined') {
return document.documentElement.classList.contains('dark')
? 'dark'
: 'light'
}
return 'light'
})
useEffect(() => {
const currentTheme = document.documentElement.classList.contains("dark") ? "dark" : "light";
setTheme(currentTheme);
}, []);
// Sync theme on mount if needed, but the state is already initialized
}, [])
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);
};
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-8 py-4 bg-background/70 backdrop-blur-md border-b border-default-100 sticky top-0 z-50 w-full">
<nav className="bg-background/70 border-default-100 sticky top-0 z-50 flex w-full items-center justify-between border-b px-8 py-4 backdrop-blur-md">
<div className="flex items-center gap-4">
<RouterLink to="/" className="font-bold text-inherit text-xl no-underline text-foreground">
<RouterLink
to="/"
className="text-foreground text-xl font-bold text-inherit no-underline"
>
HLAE中文站
</RouterLink>
</div>
<div className="flex items-center gap-8">
<div className="hidden sm:flex gap-8 items-center">
<RouterLink to="/" className="text-foreground/80 hover:text-foreground font-medium transition-colors">
<div className="hidden items-center gap-8 sm:flex">
<RouterLink
to="/"
className="text-foreground/80 hover:text-foreground font-medium transition-colors"
>
</RouterLink>
<RouterLink to="/demo" className="text-foreground/80 hover:text-foreground font-medium transition-colors">
<RouterLink
to="/demo"
className="text-foreground/80 hover:text-foreground font-medium transition-colors"
>
</RouterLink>
<RouterLink to="/about" className="text-foreground/80 hover:text-foreground font-medium transition-colors">
<RouterLink
to="/about"
className="text-foreground/80 hover:text-foreground font-medium transition-colors"
>
</RouterLink>
</div>
<div className="flex items-center gap-4">
<Button
isIconOnly
variant="light"
<Button
isIconOnly
variant="ghost"
onPress={toggleTheme}
className="text-foreground/80"
>
{theme === "dark" ? (
<SunIcon className="w-5 h-5" />
{theme === 'dark' ? (
<SunIcon className="h-5 w-5" />
) : (
<MoonIcon className="w-5 h-5" />
<MoonIcon className="h-5 w-5" />
)}
</Button>
{session ? (
<Dropdown>
<Dropdown.Trigger>
<Button isIconOnly variant="tertiary" className="rounded-full">
<Avatar size="sm" color="accent">
<Avatar.Image
alt={session.user.name || "用户头像"}
src={session.user.image || ""}
alt={session.user.name || '用户头像'}
src={session.user.image || ''}
/>
<Avatar.Fallback>
{(session.user.name || "U").slice(0, 2).toUpperCase()}
{(session.user.name || 'U').slice(0, 2).toUpperCase()}
</Avatar.Fallback>
</Avatar>
</Button>
@@ -82,17 +94,30 @@ export function SiteNavbar() {
<Dropdown.Popover>
<Dropdown.Menu aria-label="Profile Actions">
<Dropdown.Item id="profile" textValue="Profile">
<Label className="font-semibold"> {session.user.email}</Label>
<Label className="font-semibold">
{session.user.email}
</Label>
</Dropdown.Item>
<Dropdown.Item id="logout" textValue="Logout" onPress={() => signOut()}>
<Dropdown.Item
id="logout"
textValue="Logout"
variant="danger"
onPress={() => signOut()}
>
<Label className="text-danger">退</Label>
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown.Popover>
</Dropdown>
) : (
<div className="flex gap-4 items-center">
<RouterLink to="/login" className={buttonVariants({ variant: "light", className: "text-foreground font-medium" })}>
<div className="flex items-center gap-4">
<RouterLink
to="/login"
className={buttonVariants({
variant: 'ghost',
className: 'text-foreground font-medium',
})}
>
</RouterLink>
</div>
@@ -100,5 +125,5 @@ export function SiteNavbar() {
</div>
</div>
</nav>
);
)
}