feat(auth): 实现登录注册功能并重构 App 组件

- 新增登录和注册页面组件
- 实现用户认证和权限管理逻辑
- 重构 App 组件,使用 Router 和 AuthProvider
- 添加管理员面板和论坛页面组件

Change-Id: Iaa4502616970e75e3268537f73c75dac8f60e24d
diff --git a/src/layouts/MainLayout.jsx b/src/layouts/MainLayout.jsx
new file mode 100644
index 0000000..fa4ccd4
--- /dev/null
+++ b/src/layouts/MainLayout.jsx
@@ -0,0 +1,141 @@
+import React from "react";
+import { Layout, Menu, Avatar, Dropdown } from "antd";
+import {
+  UserOutlined,
+  LogoutOutlined,
+  HomeOutlined,
+  AppstoreOutlined,
+  SettingOutlined,
+  CommentOutlined,
+  CloudDownloadOutlined,
+  UploadOutlined,
+  ToolOutlined,
+} from "@ant-design/icons";
+import { useNavigate, Link, useLocation } from "react-router-dom";
+import { useAuth } from "../features/auth/contexts/AuthContext";
+
+const { Header, Content, Footer } = Layout;
+
+// 路径与菜单key的映射
+const pathToMenuKey = {
+  "/": "1",
+  "/forum": "2",
+  "/pt": "3",
+  "/torrents": "4",
+  "/upload": "5",
+  "/tools": "6",
+  "/admin": "7",
+  "/profile": "profile",
+};
+
+const MainLayout = ({ children }) => {
+  const { user, logout } = useAuth();
+  const location = useLocation();
+
+  // 根据当前路径获取对应的菜单key
+  const getSelectedKey = () => {
+    const path = location.pathname;
+    return pathToMenuKey[path] || "1"; // 默认选中首页
+  };
+
+  const handleLogout = async () => {
+    await logout(); // logout 函数内已有消息提示和导航逻辑
+  };
+
+  // 用户菜单项
+  const userMenuItems = [
+    {
+      key: "profile",
+      icon: <UserOutlined />,
+      label: <Link to="/profile">个人资料</Link>,
+    },
+    {
+      type: "divider",
+    },
+    {
+      key: "logout",
+      icon: <LogoutOutlined />,
+      label: "退出登录",
+      onClick: handleLogout,
+    },
+  ];
+
+  // 主导航菜单项
+  const menuItems = [
+    {
+      key: "1",
+      icon: <HomeOutlined />,
+      label: <Link to="/">首页</Link>,
+    },
+    {
+      key: "2",
+      icon: <CommentOutlined />,
+      label: <Link to="/forum">论坛</Link>,
+    },
+    {
+      key: "3",
+      icon: <CloudDownloadOutlined />,
+      label: <Link to="/pt">PT</Link>,
+    },
+    {
+      key: "4",
+      icon: <AppstoreOutlined />,
+      label: <Link to="/torrents">种子列表</Link>,
+    },
+    {
+      key: "5",
+      icon: <UploadOutlined />,
+      label: <Link to="/upload">发布种子</Link>,
+    },
+    {
+      key: "6",
+      icon: <ToolOutlined />,
+      label: <Link to="/tools">工具箱</Link>,
+    }
+  ];
+
+  // 如果用户是管理员,添加管理面板菜单项
+  if (user?.role === "admin") {
+    menuItems.push({
+      key: "7",
+      icon: <SettingOutlined />,
+      label: <Link to="/admin">管理面板</Link>,
+    });
+  }
+
+  return (
+    <Layout className="min-h-screen">
+      <Header className="flex items-center justify-between px-6">
+        <div className="text-white text-xl font-bold">PT网站</div>
+        <Menu
+          theme="dark"
+          mode="horizontal"
+          selectedKeys={[getSelectedKey()]}
+          className="flex-1 justify-center"
+          style={{ maxWidth: "800px" }}
+          overflowedIndicator={null}
+          items={menuItems}
+        />
+        <div>
+          <Dropdown menu={{ items: userMenuItems }} placement="bottomRight">
+            <span className="flex items-center cursor-pointer text-white">
+              <Avatar src={user?.avatar} icon={<UserOutlined />} />
+              <span className="ml-2">{user?.username || "用户"}</span>
+              <span className="ml-1 text-xs opacity-80">
+                ({user?.role || "游客"})
+              </span>
+            </span>
+          </Dropdown>
+        </div>
+      </Header>
+      <Content className="p-6">
+        <div className="bg-white p-6 min-h-[280px] rounded">{children}</div>
+      </Content>
+      <Footer style={{ textAlign: "center" }}>
+        PT网站 ©{new Date().getFullYear()} Created by G12-Team
+      </Footer>
+    </Layout>
+  );
+};
+
+export default MainLayout;