Files
kevisual-center-v1/packages/resources/src/pages/App.tsx
2025-03-20 02:29:01 +08:00

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>
);
};