feat(web): 搭建应用骨架并完善开发环境配置
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Outlet, useLocation } from 'react-router-dom';
|
||||
import { Drawer, Layout } from 'antd';
|
||||
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
|
||||
import SidebarMenu from './SidebarMenu';
|
||||
import { getPageInfo } from './menuConfig';
|
||||
import './MainLayout.css';
|
||||
|
||||
const { Header, Sider, Content } = Layout;
|
||||
|
||||
const MainLayout = () => {
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
const location = useLocation();
|
||||
|
||||
const pageInfo = useMemo(() => getPageInfo(location.pathname), [location.pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
const checkMobile = () => {
|
||||
setIsMobile(window.innerWidth < 768);
|
||||
if (window.innerWidth >= 768) setMobileMenuOpen(false);
|
||||
};
|
||||
checkMobile();
|
||||
window.addEventListener('resize', checkMobile);
|
||||
return () => window.removeEventListener('resize', checkMobile);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Layout className="main-layout">
|
||||
{!isMobile && (
|
||||
<Sider
|
||||
className="main-sider"
|
||||
width={200}
|
||||
collapsedWidth={60}
|
||||
collapsed={collapsed}
|
||||
theme="dark"
|
||||
style={{
|
||||
overflow: 'auto',
|
||||
height: '100vh',
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<div className="sidebar-header">
|
||||
<div className="logo">{collapsed ? 'A' : 'Atlas Kit'}</div>
|
||||
{!collapsed && <div className="logo-subtitle">商品工作台</div>}
|
||||
</div>
|
||||
<SidebarMenu collapsed={collapsed} />
|
||||
</Sider>
|
||||
)}
|
||||
|
||||
{isMobile && (
|
||||
<Drawer
|
||||
title="Atlas Kit"
|
||||
placement="left"
|
||||
onClose={() => setMobileMenuOpen(false)}
|
||||
open={mobileMenuOpen}
|
||||
styles={{ body: { padding: 0, background: 'var(--sider-bg)' } }}
|
||||
width={200}
|
||||
>
|
||||
<SidebarMenu collapsed={false} onMenuClick={() => setMobileMenuOpen(false)} />
|
||||
</Drawer>
|
||||
)}
|
||||
|
||||
<Layout
|
||||
className="main-content-layout"
|
||||
style={{
|
||||
marginLeft: isMobile ? 0 : collapsed ? 60 : 200,
|
||||
transition: 'margin-left 0.2s',
|
||||
}}
|
||||
>
|
||||
<Header className="main-header">
|
||||
<div className="header-left">
|
||||
{isMobile && (
|
||||
<MenuFoldOutlined
|
||||
className="mobile-menu-trigger"
|
||||
onClick={() => setMobileMenuOpen(true)}
|
||||
/>
|
||||
)}
|
||||
{!isMobile && (
|
||||
<div className="collapse-trigger" onClick={() => setCollapsed(!collapsed)}>
|
||||
{collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
|
||||
</div>
|
||||
)}
|
||||
<div className="page-title-group">
|
||||
<div className="page-title">{pageInfo.title}</div>
|
||||
<div className="page-subtitle">{pageInfo.subtitle}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Header>
|
||||
|
||||
<Content className="main-content">
|
||||
<Outlet />
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default MainLayout;
|
||||
Reference in New Issue
Block a user