From 58373a15a9cc399e17a91fbc1653490ea48927ae Mon Sep 17 00:00:00 2001 From: purp1e Date: Tue, 10 Mar 2026 17:52:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=B9=B6=E4=BF=AE=E5=A4=8D=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构主页、关于页、演示页和帖子页的UI,使用现代化的卡片设计和布局 - 添加主题切换功能,支持亮色/暗色模式 - 修复后端认证路由路径,从`/api`改为`/api/auth` - 更新页面标题为"HLAE中文站" - 简化Providers组件,移除未使用的主题配置 - 添加Hero组件展示网站主标题和操作按钮 - 优化登录和注册页面的表单验证和UI - 更新全局样式,添加品牌颜色和主题变量 - 改进导航栏,添加图标和更好的响应式设计 - 优化资源管理模态框,添加图标字段支持 --- backend/src/auth.ts | 2 +- backend/src/index.ts | 2 +- web/index.html | 7 +- web/src/app/about/index.tsx | 26 ++- web/src/app/demo/index.tsx | 27 ++- web/src/app/index.tsx | 221 +++++++++++++++++---- web/src/app/login/index.tsx | 74 ++++--- web/src/app/posts/[id]/index.tsx | 46 ++--- web/src/app/posts/index.tsx | 42 ++-- web/src/app/register/index.tsx | 74 ++++--- web/src/components/CreateResourceModal.tsx | 88 +++++--- web/src/components/CustomCard.tsx | 4 + web/src/components/EditResourceModal.tsx | 90 ++++++--- web/src/components/Hero.tsx | 51 +++++ web/src/components/SiteNavbar.tsx | 121 ++++++----- web/src/globals.css | 26 ++- web/src/layout.tsx | 8 +- web/src/providers.tsx | 10 +- web/src/root.tsx | 12 +- 19 files changed, 638 insertions(+), 293 deletions(-) create mode 100644 web/src/components/Hero.tsx diff --git a/backend/src/auth.ts b/backend/src/auth.ts index 0717104..1e96693 100644 --- a/backend/src/auth.ts +++ b/backend/src/auth.ts @@ -6,7 +6,7 @@ export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: 'sqlite' }), - basePath: '/api', + basePath: '/api/auth', emailAndPassword: { enabled: true, }, diff --git a/backend/src/index.ts b/backend/src/index.ts index 3083c29..0a38556 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -14,7 +14,7 @@ const app = new Elysia() allowedHeaders: ['Content-Type', 'Authorization'] }) ) - .mount('/auth', auth.handler) + .mount(auth.handler) .get('/health', () => 'OK') .use(resources) .use(posts) diff --git a/web/index.html b/web/index.html index 2b95fb3..a99fd68 100644 --- a/web/index.html +++ b/web/index.html @@ -3,7 +3,12 @@ - HLAE Site + HLAE中文站 +
diff --git a/web/src/app/about/index.tsx b/web/src/app/about/index.tsx index fd515ec..e17d7b5 100644 --- a/web/src/app/about/index.tsx +++ b/web/src/app/about/index.tsx @@ -1,11 +1,27 @@ -import { Button } from "@heroui/react"; -import { Link as RouterLink } from "react-router-dom"; +import { Button, Card } from "@heroui/react"; +import { useNavigate } from "react-router-dom"; export default function AboutPage() { + const navigate = useNavigate(); + return ( -
-

About

- +
+ + + 关于 HLAE 中文站 + + +

+ HLAE 中文站是一个致力于为 CS 视频制作者提供工具和资源的社区。 + 我们旨在简化创作流程,提供各种实用的工具、录像分析和下载加速服务。 +

+
+ + + +
); } diff --git a/web/src/app/demo/index.tsx b/web/src/app/demo/index.tsx index 323f345..a248fd9 100644 --- a/web/src/app/demo/index.tsx +++ b/web/src/app/demo/index.tsx @@ -1,15 +1,26 @@ -import { Button } from "@heroui/react"; -import { Link, useNavigate } from "react-router"; +import { Button, Card } from "@heroui/react"; +import { useNavigate } from "react-router-dom"; export default function DemoPage() { const navigate = useNavigate(); return ( -
-

Demo Page

- - - Back +
+ + + 击杀生成 (Kill Generation) + + +

+ 这里是击杀生成工具页面。目前正在开发中,敬请期待! +

+
+ + + +
- ) + ); } \ No newline at end of file diff --git a/web/src/app/index.tsx b/web/src/app/index.tsx index 7d6f497..dc4471a 100644 --- a/web/src/app/index.tsx +++ b/web/src/app/index.tsx @@ -1,28 +1,139 @@ import { useState } from 'react'; -import { SiteNavbar } from '../components/SiteNavbar'; -import { useResources, Resource } from '../hooks/useApi'; +import { useResources } from '../hooks/useApi'; import { CustomCard } from '../components/CustomCard'; -import { Button, Link } from '@heroui/react'; +import { Hero } from '../components/Hero'; +import { Button, Link, Chip } from '@heroui/react'; +import { buttonVariants, linkVariants } from '@heroui/styles'; import { CreateResourceModal } from '../components/CreateResourceModal'; import { EditResourceModal } from '../components/EditResourceModal'; import { useSession } from '../lib/auth-client'; +import { + ChatBubbleLeftEllipsisIcon, + BookOpenIcon, + BookmarkIcon, + QuestionMarkCircleIcon, + WrenchScrewdriverIcon, + ListBulletIcon, + VideoCameraIcon, + UserGroupIcon +} from '@heroicons/react/24/outline'; +import { Link as RouterLink } from 'react-router-dom'; + +const PORTALS = [ + { + title: '中文论坛', + description: 'HLAE中文交流社区', + icon: ChatBubbleLeftEllipsisIcon, + url: 'https://bbs.hlae.site', + }, + { + title: '官方Wiki', + description: '权威,但是英文 orz', + icon: BookOpenIcon, + url: 'https://github.com/advancedfx/advancedfx/wiki', + }, + { + title: '新版文档', + description: '新版 advancedfx 文档,建设中', + icon: BookmarkIcon, + url: 'https://docs.hlae.site', + }, + { + title: '官方Discord', + description: '和开发者近距离交流', + icon: UserGroupIcon, + url: 'https://discord.gg/advancedfx', + }, + { + title: '问题与建议提交', + description: 'tnnd 为什么不更新', + icon: QuestionMarkCircleIcon, + url: 'https://github.com/advancedfx/advancedfx/issues', + }, + { + title: 'HUD生成器', + description: '击杀信息和准星生成工具', + icon: WrenchScrewdriverIcon, + url: '/hud-generator', + }, + { + title: '击杀信息生成', + description: 'CS2 · CS 击杀信息生成工具(测试)', + icon: ListBulletIcon, + url: '/demo', + }, + { + title: 'HLTV', + description: 'CSGO新闻、数据、录像', + icon: VideoCameraIcon, + url: 'https://www.hltv.org', + }, +]; export default function HomePage() { const { resources, isLoading } = useResources(); const [isModalOpen, setIsModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); - const [selectedResource, setSelectedResource] = useState(null); + const [selectedResource, setSelectedResource] = useState(null); const { data: session } = useSession(); return ( -
- -
-
-
-

传送门 & 资源

+
+
+ + {/* Portals Section */} +
+

传送门

+
+ {PORTALS.map((portal) => { + const isExternal = portal.url.startsWith('http'); + const Content = ( + +
+
+ +
+
+

{portal.title}

+

{portal.description}

+
+
+
+ ); + + return isExternal ? ( + + {Content} + + ) : ( + + {Content} + + ); + })} +
+
+ + {/* Resources Section */} +
+
+

资源下载

{session && ( - )} @@ -36,41 +147,73 @@ export default function HomePage() { /> {isLoading ? ( -
加载中...
+
加载中...
) : (
{resources?.map((res) => ( - - -
-

{res.title}

- {res.category &&

{res.category}

} + +
+
+ {res.icon ? ( + {res.title} + ) : ( +
+ {res.title[0]} +
+ )}
- - -

{res.description}

-
- - - {session && ( - - )} - +
+
+

{res.title}

+ {res.category && ( + + {res.category} + + )} +
+

{res.description}

+
+
+ +
+ + 加速下载 + + + 原始下载 + + {session && ( + + )} +
))} {!resources?.length && ( -
+
暂无资源
)} diff --git a/web/src/app/login/index.tsx b/web/src/app/login/index.tsx index 1f3ede6..f0b5fc4 100644 --- a/web/src/app/login/index.tsx +++ b/web/src/app/login/index.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { useNavigate, Link } from 'react-router-dom'; -import { Card, Input, Button, Form, toast } from '@heroui/react'; +import { Card, Input, Button, Form, toast, TextField, Label, FieldError } from '@heroui/react'; import { signIn } from '../../lib/auth-client'; export default function LoginPage() { @@ -9,7 +9,7 @@ export default function LoginPage() { const [loading, setLoading] = useState(false); const navigate = useNavigate(); - const handleLogin = async (e: React.FormEvent) => { + const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); try { @@ -32,32 +32,50 @@ export default function LoginPage() { }; return ( -
- -

登录 HLAE 中文站

-
- setEmail(e.target.value)} - /> - setPassword(e.target.value)} - /> - -
- 还没有账号? 去注册 -
+
+ + + 登录 HLAE 中文站 + + + + + + + + + + + + + + + + + + +
+ + ← 返回首页 + +
+
diff --git a/web/src/app/posts/[id]/index.tsx b/web/src/app/posts/[id]/index.tsx index 4dcaa04..72d57d4 100644 --- a/web/src/app/posts/[id]/index.tsx +++ b/web/src/app/posts/[id]/index.tsx @@ -1,8 +1,7 @@ import { useParams, Link as RouterLink } from 'react-router-dom'; -import { SiteNavbar } from '../../../components/SiteNavbar'; import { usePost } from '../../../hooks/useApi'; -import { Card, Button, Avatar, Divider, Skeleton } from '@heroui/react'; -import { Link } from '@heroui/react'; +import { Card, Button, Avatar, Separator, Skeleton } from '@heroui/react'; +import { buttonVariants } from '@heroui/styles'; export default function PostDetailPage() { const { id } = useParams<{ id: string }>(); @@ -10,19 +9,12 @@ export default function PostDetailPage() { if (isLoading) { return ( -
- +
- -
-
- -
-
- -
-
+ + +
@@ -31,44 +23,42 @@ export default function PostDetailPage() { if (isError || !post) { return ( -
- +

帖子未找到

- +
); } return ( -
- +
- + ← 返回帖子列表 - +

{post.title}

- + + + {(post.user?.name || 'U').slice(0, 2).toUpperCase()} + + {post.user?.name || '匿名用户'} {new Date(post.createdAt).toLocaleString()}
- +
{post.content} diff --git a/web/src/app/posts/index.tsx b/web/src/app/posts/index.tsx index 8f1c88f..162684e 100644 --- a/web/src/app/posts/index.tsx +++ b/web/src/app/posts/index.tsx @@ -1,8 +1,7 @@ import { useState } from 'react'; -import { SiteNavbar } from '../../components/SiteNavbar'; import { usePosts } from '../../hooks/useApi'; import { Link as RouterLink } from 'react-router-dom'; -import { Card, Button, Input, TextArea, Form, Link, toast } from '@heroui/react'; +import { Card, Button, Input, TextArea, Form, Link, toast, TextField, Label, FieldError } from '@heroui/react'; import { useSession } from '../../lib/auth-client'; import { api } from '../../api/client'; @@ -13,7 +12,7 @@ export default function PostsPage() { const [content, setContent] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); - const handleSubmit = async (e: React.FormEvent) => { + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!session) return; setIsSubmitting(true); @@ -36,8 +35,7 @@ export default function PostsPage() { }; return ( -
- +
@@ -50,9 +48,9 @@ export default function PostsPage() {
- + {post.title} - +

{post.user?.name || '匿名用户'} - {new Date(post.createdAt).toLocaleDateString()}

@@ -73,21 +71,29 @@ export default function PostsPage() {

发布新帖

- -