import { BrowserRouter, useRoutes } from 'react-router-dom'; import routesConfig from '../config/routesConfig'; import Navbar from './Navbar'; import { Suspense, useState, useEffect } from 'react'; import Loading from './Loading'; import { CssBaseline, Theme, ThemeProvider } from '@mui/material'; import { CustomSnackBarProvider } from '../contexts/CustomSnackBarContext'; import { SnackbarProvider } from 'notistack'; import { tools } from '../tools'; import './index.css'; import { darkTheme, lightTheme } from '../config/muiConfig'; import ScrollToTopButton from './ScrollToTopButton'; export type Mode = 'dark' | 'light' | 'system'; const AppRoutes = () => { const updatedRoutesConfig = [...routesConfig]; tools.forEach((tool) => { updatedRoutesConfig.push({ path: tool.path, element: tool.component() }); }); return useRoutes(updatedRoutesConfig); }; function App() { const [mode, setMode] = useState( () => (localStorage.getItem('theme') || 'system') as Mode ); const [theme, setTheme] = useState(() => getTheme(mode)); useEffect(() => setTheme(getTheme(mode)), [mode]); // Make sure to update the theme when the mode changes useEffect(() => { const systemDarkModeQuery = window.matchMedia( '(prefers-color-scheme: dark)' ); const handleThemeChange = (e: MediaQueryListEvent) => { setTheme(e.matches ? darkTheme : lightTheme); }; systemDarkModeQuery.addEventListener('change', handleThemeChange); return () => { systemDarkModeQuery.removeEventListener('change', handleThemeChange); }; }, []); return ( { setMode((prev) => nextMode(prev)); localStorage.setItem('theme', nextMode(mode)); }} /> }> ); } function getTheme(mode: Mode): Theme { switch (mode) { case 'dark': return darkTheme; case 'light': return lightTheme; default: return window.matchMedia('(prefers-color-scheme: dark)').matches ? darkTheme : lightTheme; } } function nextMode(mode: Mode): Mode { return mode === 'light' ? 'dark' : mode === 'dark' ? 'system' : 'light'; } export default App;