App.tsx 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import React, { Suspense } from 'react';
  2. import { Routes, Route, Navigate } from 'react-router-dom';
  3. import {
  4. accessErrorPage,
  5. clusterPath,
  6. errorPage,
  7. getNonExactPath,
  8. clusterNewConfigPath,
  9. } from 'lib/paths';
  10. import PageLoader from 'components/common/PageLoader/PageLoader';
  11. import Dashboard from 'components/Dashboard/Dashboard';
  12. import ClusterPage from 'components/ClusterPage/ClusterPage';
  13. import { ThemeProvider } from 'styled-components';
  14. import { theme, darkTheme } from 'theme/theme';
  15. import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
  16. import { showServerError } from 'lib/errorHandling';
  17. import { Toaster } from 'react-hot-toast';
  18. import GlobalCSS from 'components/globalCss';
  19. import * as S from 'components/App.styled';
  20. import ClusterConfigForm from 'widgets/ClusterConfigForm';
  21. import ConfirmationModal from './common/ConfirmationModal/ConfirmationModal';
  22. import { ConfirmContextProvider } from './contexts/ConfirmContext';
  23. import { GlobalSettingsProvider } from './contexts/GlobalSettingsContext';
  24. import ErrorPage from './ErrorPage/ErrorPage';
  25. import { UserInfoRolesAccessProvider } from './contexts/UserInfoRolesAccessContext';
  26. import PageContainer from './PageContainer/PageContainer';
  27. const queryClient = new QueryClient({
  28. defaultOptions: {
  29. queries: {
  30. suspense: true,
  31. onError(error) {
  32. showServerError(error as Response);
  33. },
  34. },
  35. mutations: {
  36. onError(error) {
  37. showServerError(error as Response);
  38. },
  39. },
  40. },
  41. });
  42. const App: React.FC = () => {
  43. const [isDarkMode, setDarkMode] = React.useState<boolean>(false);
  44. return (
  45. <QueryClientProvider client={queryClient}>
  46. <GlobalSettingsProvider>
  47. <ThemeProvider theme={isDarkMode ? darkTheme : theme}>
  48. <Suspense fallback={<PageLoader />}>
  49. <UserInfoRolesAccessProvider>
  50. <ConfirmContextProvider>
  51. <GlobalCSS />
  52. <S.Layout>
  53. <PageContainer setDarkMode={setDarkMode}>
  54. <Routes>
  55. {['/', '/ui', '/ui/clusters'].map((path) => (
  56. <Route
  57. key="Home" // optional: avoid full re-renders on route changes
  58. path={path}
  59. element={<Dashboard />}
  60. />
  61. ))}
  62. <Route
  63. path={getNonExactPath(clusterNewConfigPath)}
  64. element={<ClusterConfigForm />}
  65. />
  66. <Route
  67. path={getNonExactPath(clusterPath())}
  68. element={<ClusterPage />}
  69. />
  70. <Route
  71. path={accessErrorPage}
  72. element={
  73. <ErrorPage status={403} text="Access is Denied" />
  74. }
  75. />
  76. <Route path={errorPage} element={<ErrorPage />} />
  77. <Route
  78. path="*"
  79. element={<Navigate to={errorPage} replace />}
  80. />
  81. </Routes>
  82. </PageContainer>
  83. <Toaster position="bottom-right" />
  84. </S.Layout>
  85. <ConfirmationModal />
  86. </ConfirmContextProvider>
  87. </UserInfoRolesAccessProvider>
  88. </Suspense>
  89. </ThemeProvider>
  90. </GlobalSettingsProvider>
  91. </QueryClientProvider>
  92. );
  93. };
  94. export default App;