diff --git a/src/layouts/MainLayout/Footer.tsx b/src/layouts/MainLayout/Footer.tsx
new file mode 100644
index 0000000..ce038f9
--- /dev/null
+++ b/src/layouts/MainLayout/Footer.tsx
@@ -0,0 +1,36 @@
+import React from 'react';
+import { Layout } from 'antd';
+import { GithubOutlined, HeartFilled } from '@ant-design/icons';
+
+const { Footer: AntFooter } = Layout;
+
+export const Footer: React.FC = () => {
+ return (
+
+
+ Made with by PicStack Team
+
+
+
+ );
+};
diff --git a/src/layouts/MainLayout/Header.tsx b/src/layouts/MainLayout/Header.tsx
new file mode 100644
index 0000000..eeefc13
--- /dev/null
+++ b/src/layouts/MainLayout/Header.tsx
@@ -0,0 +1,168 @@
+import React from 'react';
+import { Layout, Space, Badge, Avatar, Dropdown, Menu } from 'antd';
+import {
+ BellOutlined,
+ SettingOutlined,
+ UserOutlined,
+ LogoutOutlined,
+ CloudUploadOutlined,
+ DashboardOutlined,
+ PictureOutlined,
+ LinkOutlined,
+ ToolOutlined,
+ DatabaseOutlined,
+ BarChartOutlined,
+} from '@ant-design/icons';
+import { useNavigate, useLocation } from 'react-router-dom';
+import type { MenuProps } from 'antd';
+
+const { Header: AntHeader } = Layout;
+
+export const Header: React.FC = () => {
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ // 主导航菜单项
+ const navMenuItems: MenuProps['items'] = [
+ {
+ key: '/dashboard',
+ icon: ,
+ label: '仪表盘',
+ onClick: () => navigate('/dashboard'),
+ },
+ {
+ key: '/upload',
+ icon: ,
+ label: '上传图片',
+ onClick: () => navigate('/upload'),
+ },
+ {
+ key: '/gallery',
+ icon: ,
+ label: '图片库',
+ onClick: () => navigate('/gallery'),
+ },
+ {
+ key: '/links',
+ icon: ,
+ label: '链接管理',
+ onClick: () => navigate('/links'),
+ },
+ {
+ key: '/tools',
+ icon: ,
+ label: '图片工具',
+ onClick: () => navigate('/tools'),
+ },
+ {
+ key: '/storage',
+ icon: ,
+ label: '存储配置',
+ onClick: () => navigate('/storage'),
+ },
+ {
+ key: '/analytics',
+ icon: ,
+ label: '统计分析',
+ onClick: () => navigate('/analytics'),
+ },
+ ];
+
+ // 用户菜单项
+ const userMenuItems: MenuProps['items'] = [
+ {
+ key: 'settings',
+ icon: ,
+ label: '设置',
+ onClick: () => navigate('/settings'),
+ },
+ {
+ type: 'divider',
+ },
+ {
+ key: 'logout',
+ icon: ,
+ label: '退出登录',
+ danger: true,
+ },
+ ];
+
+ // 获取当前选中的菜单项
+ const selectedKey = location.pathname === '/' ? '/dashboard' : location.pathname;
+
+ return (
+
+ {/* Logo 区域 */}
+
+
+ {/* 中间导航菜单 */}
+
+
+
+
+ {/* 右侧操作区 */}
+
+
+ {/* 通知 */}
+
+
+
+
+ {/* 用户菜单 */}
+
+
+
+
+
+
+ );
+};
diff --git a/src/layouts/MainLayout/Sidebar.tsx b/src/layouts/MainLayout/Sidebar.tsx
new file mode 100644
index 0000000..1092599
--- /dev/null
+++ b/src/layouts/MainLayout/Sidebar.tsx
@@ -0,0 +1,98 @@
+import React from 'react';
+import { Layout, Menu } from 'antd';
+import {
+ DashboardOutlined,
+ CloudUploadOutlined,
+ PictureOutlined,
+ LinkOutlined,
+ ToolOutlined,
+ DatabaseOutlined,
+ BarChartOutlined,
+ SettingOutlined,
+} from '@ant-design/icons';
+import { useNavigate, useLocation } from 'react-router-dom';
+import type { MenuProps } from 'antd';
+
+const { Sider } = Layout;
+
+type MenuItem = Required['items'][number];
+
+export const Sidebar: React.FC<{ collapsed: boolean }> = ({ collapsed }) => {
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ const menuItems: MenuItem[] = [
+ {
+ key: '/dashboard',
+ icon: ,
+ label: '仪表盘',
+ onClick: () => navigate('/dashboard'),
+ },
+ {
+ key: '/upload',
+ icon: ,
+ label: '上传图片',
+ onClick: () => navigate('/upload'),
+ },
+ {
+ key: '/gallery',
+ icon: ,
+ label: '图片库',
+ onClick: () => navigate('/gallery'),
+ },
+ {
+ key: '/links',
+ icon: ,
+ label: '链接管理',
+ onClick: () => navigate('/links'),
+ },
+ {
+ key: '/tools',
+ icon: ,
+ label: '图片工具',
+ onClick: () => navigate('/tools'),
+ },
+ {
+ key: '/storage',
+ icon: ,
+ label: '存储配置',
+ onClick: () => navigate('/storage'),
+ },
+ {
+ key: '/analytics',
+ icon: ,
+ label: '统计分析',
+ onClick: () => navigate('/analytics'),
+ },
+ {
+ type: 'divider',
+ },
+ {
+ key: '/settings',
+ icon: ,
+ label: '设置',
+ onClick: () => navigate('/settings'),
+ },
+ ];
+
+ // 获取当前激活的菜单项
+ const selectedKey = location.pathname === '/' ? '/dashboard' : location.pathname;
+
+ return (
+
+
+
+ );
+};
diff --git a/src/layouts/MainLayout/index.tsx b/src/layouts/MainLayout/index.tsx
new file mode 100644
index 0000000..1101841
--- /dev/null
+++ b/src/layouts/MainLayout/index.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import { Layout } from 'antd';
+import { Outlet } from 'react-router-dom';
+import { Header } from './Header';
+import { Footer } from './Footer';
+
+const { Content } = Layout;
+
+export const MainLayout: React.FC = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};