88 lines
2.3 KiB
TypeScript
88 lines
2.3 KiB
TypeScript
import { Theme } from '@/app/enum';
|
|
import { useAppSelector } from '@/app/hooks';
|
|
import globalMessage from '@/app/message';
|
|
import { SettingOutlined } from '@ant-design/icons';
|
|
import { App, Button, Image, Popover } from '@toco-design/components';
|
|
import classNames from 'classnames';
|
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import styles from './index.module.css';
|
|
import { HeaderOnly, HeaderSider, SiderOnly } from './layouts';
|
|
import Settings from './settings';
|
|
import SuspenseLayout from './suspense-layout';
|
|
|
|
export enum LayoutType {
|
|
Default = 0,
|
|
Header = 1 << 1,
|
|
Sider = 1 << 2,
|
|
}
|
|
|
|
type LayoutProps = {
|
|
type?: LayoutType;
|
|
};
|
|
|
|
const Layout: React.FC<LayoutProps> = (props) => {
|
|
const { type: typeProp } = props;
|
|
const theme = useAppSelector((state) => state.common.theme);
|
|
const navigate = useNavigate();
|
|
const { message } = App.useApp();
|
|
|
|
useEffect(() => {
|
|
globalMessage.setMessage(message);
|
|
}, [message]);
|
|
|
|
const Component = useMemo(() => {
|
|
const type = typeProp ?? LayoutType.Default;
|
|
const hasHeader = type & LayoutType.Header;
|
|
const hasSider = type & LayoutType.Sider;
|
|
if (hasHeader && hasSider) {
|
|
return HeaderSider;
|
|
} else if (hasHeader) {
|
|
return HeaderOnly;
|
|
} else if (hasSider) {
|
|
return SiderOnly;
|
|
}
|
|
return HeaderSider;
|
|
}, [typeProp]);
|
|
|
|
const gotoHome = useCallback(() => {
|
|
navigate('/');
|
|
}, [navigate]);
|
|
|
|
return (
|
|
<SuspenseLayout>
|
|
<Component
|
|
theme={theme}
|
|
siderWidth={250}
|
|
logo={
|
|
<div
|
|
className={classNames(styles.logo, { dark: theme === Theme.DARK })}
|
|
onClick={gotoHome}
|
|
>
|
|
<Image
|
|
className={styles.icon}
|
|
preview={false}
|
|
src={
|
|
process.env.PUBLIC_URL +
|
|
(theme === Theme.DEFAULT ? '/logo.png' : '/logo_dark.png')
|
|
}
|
|
/>
|
|
</div>
|
|
}
|
|
extra={
|
|
<div
|
|
className={classNames(styles.extra, { dark: theme === Theme.DARK })}
|
|
>
|
|
<Popover content={<Settings />}>
|
|
<Button type="text">
|
|
<SettingOutlined />
|
|
</Button>
|
|
</Popover>
|
|
</div>
|
|
}
|
|
/>
|
|
</SuspenseLayout>
|
|
);
|
|
};
|
|
export default Layout;
|