130 lines
3.5 KiB
TypeScript
130 lines
3.5 KiB
TypeScript
import { useEffect, useMemo } from 'react';
|
|
import { CustomThemeProvider } from '@kevisual/center-components/theme/index.tsx';
|
|
import { Left } from './layout/Left';
|
|
import { Main } from './main/index';
|
|
import { ToastContainer } from 'react-toastify';
|
|
import { useSettingsStore } from './store/settings';
|
|
import { CircularProgress, useTheme } from '@mui/material';
|
|
import { useResourceStore } from './store/resource';
|
|
import dayjs from 'dayjs';
|
|
import 'dayjs/locale/zh-cn';
|
|
|
|
import zhCN from 'antd/locale/zh_CN';
|
|
import ConfigProvider from 'antd/es/config-provider';
|
|
|
|
dayjs.locale('zh-cn');
|
|
export const AntdConfigProvider = ({ children }: { children: React.ReactNode }) => {
|
|
const theme = useTheme();
|
|
const primaryColor = theme.palette.primary.main;
|
|
const secondaryColor = theme.palette.secondary.main;
|
|
return (
|
|
<ConfigProvider
|
|
locale={zhCN}
|
|
theme={{
|
|
token: {
|
|
colorPrimary: primaryColor,
|
|
colorPrimaryHover: secondaryColor,
|
|
colorPrimaryActive: primaryColor,
|
|
borderRadius: 4,
|
|
colorBorder: primaryColor,
|
|
// colorText: primaryColor,
|
|
colorIcon: primaryColor,
|
|
colorIconHover: secondaryColor,
|
|
colorInfoHover: secondaryColor,
|
|
},
|
|
components: {
|
|
DatePicker: {
|
|
colorPrimary: primaryColor,
|
|
colorPrimaryHover: secondaryColor,
|
|
colorPrimaryActive: primaryColor,
|
|
},
|
|
},
|
|
}}>
|
|
{children}
|
|
</ConfigProvider>
|
|
);
|
|
};
|
|
export const InitProvider = ({ children }: { children: React.ReactNode }) => {
|
|
const { init, mounted, settings } = useSettingsStore();
|
|
const { setPrefix, init: initResource } = useResourceStore();
|
|
useEffect(() => {
|
|
init();
|
|
initResource();
|
|
}, []);
|
|
useEffect(() => {
|
|
if (settings.prefix && mounted === 'success') {
|
|
setPrefix(settings.prefix);
|
|
}
|
|
}, [mounted, settings.prefix]);
|
|
|
|
const handleRetry = () => {
|
|
init();
|
|
initResource();
|
|
};
|
|
|
|
if (mounted === 'loading') {
|
|
return (
|
|
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
|
|
<CircularProgress />
|
|
</div>
|
|
);
|
|
} else if (mounted === 'error') {
|
|
return (
|
|
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '100vh', color: 'red' }}>
|
|
<h2>出现问题</h2>
|
|
<p>加载设置时遇到错误。请重试。</p>
|
|
<button
|
|
onClick={handleRetry}
|
|
style={{
|
|
marginTop: '20px',
|
|
padding: '10px 20px',
|
|
backgroundColor: '#f44336',
|
|
color: '#fff',
|
|
border: 'none',
|
|
borderRadius: '4px',
|
|
cursor: 'pointer',
|
|
}}>
|
|
重试
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
return <>{children}</>;
|
|
};
|
|
|
|
type AppProvider = {
|
|
key: string;
|
|
use: boolean;
|
|
};
|
|
export type AppProps = {
|
|
providers?: AppProvider[];
|
|
noProvider?: boolean;
|
|
/**
|
|
* 是否是单个应用
|
|
* 默认是单个应用模块。
|
|
*/
|
|
isSingleApp?: boolean;
|
|
};
|
|
export const App = ({ providers, noProvider, isSingleApp = true }: AppProps) => {
|
|
const children = useMemo(() => {
|
|
return (
|
|
<InitProvider>
|
|
<Left>
|
|
<Main />
|
|
</Left>
|
|
</InitProvider>
|
|
);
|
|
}, []);
|
|
if (noProvider) {
|
|
return <>{children}</>;
|
|
}
|
|
return (
|
|
<CustomThemeProvider>
|
|
<AntdConfigProvider>
|
|
{children}
|
|
<ToastContainer />
|
|
</AntdConfigProvider>
|
|
</CustomThemeProvider>
|
|
);
|
|
};
|