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 +
+
+ e.currentTarget.style.color = '#7C3AED'} + onMouseLeave={(e) => e.currentTarget.style.color = '#9CA3AF'} + > + + GitHub + + © 2025 PicStack. All rights reserved. +
+
+ ); +}; 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 区域 */} +
+
+ +
+ + PicStack + +
+ + {/* 中间导航菜单 */} +
+ +
+ + {/* 右侧操作区 */} +
+ + {/* 通知 */} + + + + + {/* 用户菜单 */} + +
+ } /> + 用户 +
+
+
+
+
+ ); +}; 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 ( + +
+ + + +