app.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { PropsWithChildren, useState, useEffect } from 'react';
  2. import { useLaunch } from '@tarojs/taro';
  3. import { IntlProvider } from 'react-intl';
  4. import { ConfigProvider, Button } from 'antd';
  5. import { Provider } from 'react-redux';
  6. import store from './states/store';
  7. import { initializeProductState } from './states/productSlice';
  8. import './app.css';
  9. import { lightTheme, darkTheme } from './themes';
  10. import ProductSelector from './components/ProductSelector';
  11. import QuotaAlertModal from './pages/security/QuotaAlertModal';
  12. const locale = (window.navigator.language || 'en').toLowerCase().split('-')[0]; // Get locale from browser or default to 'en'
  13. import messages_en from './assets/i18n/messages/en';
  14. import messages_zh from './assets/i18n/messages/zh';
  15. import AcquisitionTracer from './pages/exam/components/acquisitionTracer';
  16. import { logger } from './log/logger';
  17. console.log = logger.log;
  18. console.warn = logger.warn;
  19. console.error = logger.error;
  20. const messages = locale === 'zh' ? messages_zh : messages_en;
  21. console.log(`process.env.USE_MSW: ${process.env.USE_MSW}`);
  22. console.log(`process.env.NODE_ENV: ${process.env.NODE_ENV}`);
  23. if (process.env.NODE_ENV === 'development' && process.env.USE_MSW === 'true') {
  24. import('../mocks/server')
  25. .then(({ server }) => {
  26. server.start({
  27. onUnhandledRequest: 'error', // 未处理的请求触发网络错误
  28. });
  29. console.log(`启动了MSW`);
  30. })
  31. .catch((err) => {
  32. console.warn('Mock server module not found:', err);
  33. });
  34. }
  35. function App({ children }: PropsWithChildren<React.ReactNode>) {
  36. useLaunch(() => {
  37. console.log('App launched.');
  38. });
  39. const [currentTheme, setCurrentTheme] = useState(lightTheme); // 默认使用 light 主题
  40. const changeTheme = (themeConfig: typeof lightTheme) => {
  41. setCurrentTheme(themeConfig);
  42. };
  43. useEffect(() => {
  44. store.dispatch(initializeProductState());
  45. }, []);
  46. // children 是将要会渲染的页面
  47. // return children
  48. return (
  49. <Provider store={store}>
  50. <ConfigProvider theme={currentTheme}>
  51. <IntlProvider locale={locale} messages={messages}>
  52. <style>
  53. {/*把theme中的colorPrimary转换成变量--color-primary,变量被tailwindcss使用*/}
  54. {`:root {
  55. --color-primary: ${currentTheme.token.colorPrimary};
  56. }`}
  57. </style>
  58. <div
  59. style={{
  60. backgroundColor: currentTheme.token.colorBgLayout,
  61. color: currentTheme.token.colorText,
  62. borderRadius: '8px',
  63. boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
  64. }}
  65. >
  66. <AcquisitionTracer />
  67. <QuotaAlertModal />
  68. {children}
  69. {process.env.NODE_ENV === 'development' && <ProductSelector />}
  70. <div
  71. style={{
  72. position: 'fixed',
  73. top: '50%',
  74. right: 16,
  75. transform: 'translateY(-50%)',
  76. display: 'flex',
  77. flexDirection: 'column',
  78. gap: 8, // 按钮间距
  79. zIndex: 1000,
  80. }}
  81. >
  82. <Button
  83. type="primary"
  84. shape="circle"
  85. size="large"
  86. onClick={() => changeTheme(darkTheme)}
  87. title="Switch to Dark Theme"
  88. >
  89. 🌙
  90. </Button>
  91. <Button
  92. type="primary"
  93. shape="circle"
  94. size="large"
  95. onClick={() => changeTheme(lightTheme)}
  96. title="Switch to Light Theme"
  97. >
  98. ☀️
  99. </Button>
  100. </div>
  101. </div>
  102. </IntlProvider>
  103. </ConfigProvider>
  104. </Provider>
  105. );
  106. }
  107. export default App;