feat: complete Phase 1 infrastructure
- erp-core: error types, shared types, event bus, ErpModule trait - erp-server: config loading, database/Redis connections, migrations - erp-server/migration: tenants table with SeaORM - apps/web: Vite + React 18 + TypeScript + Ant Design 5 + TailwindCSS - Web frontend: main layout with sidebar, header, routing - Docker: PostgreSQL 16 + Redis 7 development environment - All workspace crates compile successfully (cargo check passes)
This commit is contained in:
87
apps/web/src/layouts/MainLayout.tsx
Normal file
87
apps/web/src/layouts/MainLayout.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import { Layout, Menu, theme, Button, Avatar, Badge, Space } from 'antd';
|
||||
import {
|
||||
HomeOutlined,
|
||||
UserOutlined,
|
||||
SafetyOutlined,
|
||||
BellOutlined,
|
||||
SettingOutlined,
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { useAppStore } from '../stores/app';
|
||||
|
||||
const { Header, Sider, Content, Footer } = Layout;
|
||||
|
||||
const menuItems = [
|
||||
{ key: '/', icon: <HomeOutlined />, label: '首页' },
|
||||
{ key: '/users', icon: <UserOutlined />, label: '用户管理' },
|
||||
{ key: '/roles', icon: <SafetyOutlined />, label: '权限管理' },
|
||||
{ key: '/settings', icon: <SettingOutlined />, label: '系统设置' },
|
||||
];
|
||||
|
||||
export default function MainLayout({ children }: { children: React.ReactNode }) {
|
||||
const { sidebarCollapsed, toggleSidebar, tenantName } = useAppStore();
|
||||
const { token } = theme.useToken();
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh' }}>
|
||||
<Sider trigger={null} collapsible collapsed={sidebarCollapsed} width={220}>
|
||||
<div
|
||||
style={{
|
||||
height: 48,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#fff',
|
||||
fontSize: sidebarCollapsed ? 16 : 18,
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{sidebarCollapsed ? 'E' : 'ERP Platform'}
|
||||
</div>
|
||||
<Menu theme="dark" mode="inline" items={menuItems} defaultSelectedKeys={['/']} />
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Header
|
||||
style={{
|
||||
padding: '0 16px',
|
||||
background: token.colorBgContainer,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
borderBottom: `1px solid ${token.colorBorderSecondary}`,
|
||||
}}
|
||||
>
|
||||
<Space>
|
||||
<Button
|
||||
type="text"
|
||||
icon={sidebarCollapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
|
||||
onClick={toggleSidebar}
|
||||
/>
|
||||
</Space>
|
||||
<Space size="middle">
|
||||
<Badge count={5}>
|
||||
<BellOutlined style={{ fontSize: 18 }} />
|
||||
</Badge>
|
||||
<Avatar icon={<UserOutlined />} />
|
||||
<span>Admin</span>
|
||||
</Space>
|
||||
</Header>
|
||||
<Content
|
||||
style={{
|
||||
margin: 16,
|
||||
padding: 24,
|
||||
background: token.colorBgContainer,
|
||||
borderRadius: token.borderRadiusLG,
|
||||
minHeight: 280,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center', padding: '8px 16px' }}>
|
||||
{tenantName || 'ERP Platform'} · v0.1.0
|
||||
</Footer>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user