diff --git a/frontend/src/components/AppRouter.js b/frontend/src/components/AppRouter.js deleted file mode 100644 index 1208f28..0000000 --- a/frontend/src/components/AppRouter.js +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import App from "./App"; -import { BrowserRouter, Switch, Redirect, Route } from "react-router-dom"; -import { useTuitioToken } from "@flare/tuitio-client-react"; -import LoginContainer from "../features/login/components/LoginContainer"; - -const PrivateRoute = ({ component, ...rest }) => { - const { valid } = useTuitioToken(); - - return ( - - valid ? ( - React.createElement(component, props) - ) : ( - - ) - } - /> - ); -}; - -PrivateRoute.propTypes = { - component: PropTypes.func.isRequired, - location: PropTypes.object -}; - -const PublicRoute = ({ component, ...rest }) => { - const { valid } = useTuitioToken(); - return ( - - valid ? ( - - ) : ( - React.createElement(component, props) - ) - } - /> - ); -}; - -PublicRoute.propTypes = { - component: PropTypes.func.isRequired -}; - -const AppRouter = () => { - return ( - - - } /> - - - - - ); -}; - -export default AppRouter; diff --git a/frontend/src/components/AppRouter.tsx b/frontend/src/components/AppRouter.tsx new file mode 100644 index 0000000..053a506 --- /dev/null +++ b/frontend/src/components/AppRouter.tsx @@ -0,0 +1,70 @@ +import React, { useMemo } from "react"; +import App from "./App"; +import { BrowserRouter, Navigate, Route, Routes, useLocation } from "react-router-dom"; +import { useTuitioToken } from "@flare/tuitio-client-react"; +import LoginContainer from "../features/login/components/LoginContainer"; + +const PrivateRoute = ({ children }: { children: JSX.Element }): JSX.Element => { + const { valid } = useTuitioToken(); + const location = useLocation(); + return valid ? ( + children + ) : ( + + ); +}; + +const PublicRoute = ({ children }: { children: JSX.Element }): JSX.Element => { + const location = useLocation(); + const { valid } = useTuitioToken(); + const to = useMemo(() => { + if (location.state?.from) { + return location.state.from + location.state.search; + } + return "/"; + }, [location.state?.from, location.state?.search]); + return valid ? ( + + ) : ( + children + ); +}; + +const AppRouter: React.FC = () => { + return ( + + + } /> + + + + } + /> + + + + } + /> + + + ); +}; + +export default AppRouter; diff --git a/frontend/src/components/layout/AppRoutes.js b/frontend/src/components/layout/AppRoutes.tsx similarity index 51% rename from frontend/src/components/layout/AppRoutes.js rename to frontend/src/components/layout/AppRoutes.tsx index 0c072b6..7f5da1a 100644 --- a/frontend/src/components/layout/AppRoutes.js +++ b/frontend/src/components/layout/AppRoutes.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Route, Switch } from "react-router-dom"; +import { Route, Routes } from "react-router-dom"; import PageNotFound from "./PageNotFound"; import NetworkContainer from "../../features/network/components/NetworkContainer"; import SystemContainer from "../../features/system/SystemContainer"; @@ -8,17 +8,17 @@ import DashboardContainer from "../../features/dashboard/DashboardContainer"; import UserProfileContainer from "../../features/user/profile/card/UserProfileContainer"; import AboutContainer from "../../features/about/AboutContainer"; -const AppRoutes = () => { +const AppRoutes: React.FC = () => { return ( - - - - - - - - - + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + ); }; diff --git a/frontend/src/components/layout/ProfileButton.js b/frontend/src/components/layout/ProfileButton.js index fbff053..0061f34 100644 --- a/frontend/src/components/layout/ProfileButton.js +++ b/frontend/src/components/layout/ProfileButton.js @@ -1,16 +1,10 @@ import React, { useState } from "react"; -import { - IconButton, - Menu, - MenuItem, - Typography, - ListItemIcon -} from "@material-ui/core"; +import { IconButton, Menu, MenuItem, Typography, ListItemIcon } from "@material-ui/core"; import AccountCircle from "@material-ui/icons/AccountCircle"; import ExitToAppIcon from "@material-ui/icons/ExitToApp"; import AccountBoxIcon from "@material-ui/icons/AccountBox"; import SettingsIcon from "@material-ui/icons/Settings"; -import { useHistory } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { useTuitioClient } from "@flare/tuitio-client-react"; import { useToast } from "../../hooks"; import styles from "./styles"; @@ -20,7 +14,7 @@ import { useTranslation } from "react-i18next"; const useStyles = makeStyles(styles); const ProfileButton = () => { - const history = useHistory(); + const navigate = useNavigate(); const { error } = useToast(); const classes = useStyles(); const { t } = useTranslation(); @@ -69,7 +63,7 @@ const ProfileButton = () => { > { - history.push("/user-profile"); + navigate("/user-profile"); handleClose(); }} > @@ -80,7 +74,7 @@ const ProfileButton = () => { { - history.push("/settings"); + navigate("/settings"); handleClose(); }} > diff --git a/frontend/src/components/layout/Sidebar.js b/frontend/src/components/layout/Sidebar.js index 038eba2..ed1889c 100644 --- a/frontend/src/components/layout/Sidebar.js +++ b/frontend/src/components/layout/Sidebar.js @@ -2,14 +2,7 @@ import React, { useState } from "react"; import PropTypes from "prop-types"; import clsx from "clsx"; import { makeStyles, useTheme } from "@material-ui/core/styles"; -import { - Drawer, - List, - Divider, - IconButton, - ListItemIcon, - ListItemText -} from "@material-ui/core"; +import { Drawer, List, Divider, IconButton, ListItemIcon, ListItemText } from "@material-ui/core"; import ChevronLeftIcon from "@material-ui/icons/ChevronLeft"; import ChevronRightIcon from "@material-ui/icons/ChevronRight"; import ListItem from "@material-ui/core/ListItem"; @@ -19,7 +12,7 @@ import DeviceHubIcon from "@material-ui/icons/DeviceHub"; import SettingsIcon from "@material-ui/icons/Settings"; import DashboardIcon from "@material-ui/icons/Dashboard"; import FeaturedPlayListIcon from "@material-ui/icons/FeaturedPlayList"; -import { useHistory } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import styles from "./styles"; @@ -92,12 +85,12 @@ const Sidebar = ({ open, handleDrawerClose }) => { const classes = useStyles(); const theme = useTheme(); - const history = useHistory(); + const navigate = useNavigate(); const { t } = useTranslation(); const handleClick = route => () => { setSelected(route); - history.push(route); + navigate(route); }; const isSelected = key => selected === key; @@ -118,11 +111,7 @@ const Sidebar = ({ open, handleDrawerClose }) => { >
- {theme.direction === "rtl" ? ( - - ) : ( - - )} + {theme.direction === "rtl" ? : }
@@ -135,12 +124,7 @@ const Sidebar = ({ open, handleDrawerClose }) => { {menu.items .sort((i1, i2) => i1 - i2) .map(item => ( - + {item.icon} diff --git a/frontend/src/features/network/components/NetworkContainer.js b/frontend/src/features/network/components/NetworkContainer.tsx similarity index 86% rename from frontend/src/features/network/components/NetworkContainer.js rename to frontend/src/features/network/components/NetworkContainer.tsx index 41cfc47..4f54dc7 100644 --- a/frontend/src/features/network/components/NetworkContainer.js +++ b/frontend/src/features/network/components/NetworkContainer.tsx @@ -4,10 +4,10 @@ import NetworkStateProvider from "../state/NetworkStateProvider"; import { usePermissions } from "../../../hooks"; import NotAllowed from "../../../components/common/NotAllowed"; -const NetworkContainer = () => { +const NetworkContainer = (): JSX.Element | null => { const { loading, viewMachines } = usePermissions(); - if (loading) return ""; + if (loading) return null; if (!viewMachines) return ; return ( diff --git a/frontend/src/providers/ThemeProvider.js b/frontend/src/providers/ThemeProvider.js index bcbef66..8f52728 100644 --- a/frontend/src/providers/ThemeProvider.js +++ b/frontend/src/providers/ThemeProvider.js @@ -13,13 +13,10 @@ const COLOR_SCHEME = { }; const colorScheme = localStorage.getItem(LOCAL_STORAGE_COLOR_SCHEME_KEY); -const prefersDarkMode = window.matchMedia( - "(prefers-color-scheme: dark)" -).matches; +const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; const initialState = { - scheme: - colorScheme ?? (prefersDarkMode ? COLOR_SCHEME.DARK : COLOR_SCHEME.LIGHT) + scheme: colorScheme ?? (prefersDarkMode ? COLOR_SCHEME.DARK : COLOR_SCHEME.LIGHT) }; const reducer = (state = initialState, action) => { @@ -48,8 +45,7 @@ const useApplicationTheme = () => { const { onColorSchemeChanged } = actions; const { scheme } = state; - const onDarkModeChanged = active => - onColorSchemeChanged(active ? COLOR_SCHEME.DARK : COLOR_SCHEME.LIGHT); + const onDarkModeChanged = active => onColorSchemeChanged(active ? COLOR_SCHEME.DARK : COLOR_SCHEME.LIGHT); return { isDark: scheme === COLOR_SCHEME.DARK, onDarkModeChanged }; }; @@ -57,10 +53,7 @@ const useApplicationTheme = () => { const ThemeProvider = ({ children }) => { const [state, dispatch] = useReducer(reducer, initialState); const actions = useMemo(() => dispatchActions(dispatch), [dispatch]); - const themes = useMemo( - () => getThemes(state.scheme === COLOR_SCHEME.DARK), - [state.scheme] - ); + const themes = useMemo(() => getThemes(state.scheme === COLOR_SCHEME.DARK), [state.scheme]); return (