src/client/routes/dashboard/Frame.tsx
import React, { useState, Suspense, FunctionComponent, useContext, FC, SetStateAction, useCallback,} from 'react';import styled from 'styled-components';import { Switch, Redirect, Route } from 'react-router-dom';import Sidebar from '../../components/Sidebar/Sidebar';import STRINGS from '../../assets/strings.json';import { Title } from '../../components/Text/Title';import routes from '../../assets/routes';import { AuthContext } from '../../contexts/AuthContext';import { SpaceBetweenRow, OverflowContainer } from '../../components/Containers/FlexContainers';import { ActionButtonContext } from '../../contexts/ActionButtonContext';import { UserType } from '../../generated/graphql';import { HackerDash } from './HackerDash';import { SponsorDash } from './SponsorDash'; export const OrganizerDash = React.lazy(() => import('./OrganizerDash')); const Layout = styled.div` position: fixed; height: 100vh; width: 100vw; display: grid; background-color: #212529; grid: 'sidebar . . .' 1.5rem 'sidebar . header .' auto 'sidebar . . .' 1.5rem 'sidebar . content .' 1fr 'sidebar . . .' 1.5rem / 22rem 2rem 1fr 2rem; /* align-items: stretch; */ overflow: hidden; .content { grid-area: content; max-height: 100%; border-radius: 8px; overflow: auto; } .header { grid-area: header; } .sidebar { grid-area: sidebar; } @media only screen and (max-width: 456px) { grid: 'sidebar . . .' 1.5rem 'sidebar . header .' auto 'sidebar . . .' 1.5rem 'sidebar . content .' 1fr 'sidebar . . .' 1.5rem / ${({ sidebar }: { sidebar: boolean }) => (sidebar ? '100% 0 0 0' : '0 2rem 1fr 2rem')}; ${({ sidebar }: { sidebar: boolean }) => (sidebar ? '' : '.sidebar { display: none; }')} }`; const Rectangle = styled.div` height: 0.4rem; width: 7.5rem; background: ${STRINGS.ACCENT_COLOR_DARK}; @media screen and (max-width: 456px) { display: none; }`; const MenuIconButton = styled.button` background-color: rgba(247, 245, 249, 1); border-radius: 4px; z-index: 1; cursor: pointer; border: none; padding: 3px 6px; & div { width: 35px; height: 5px; background-color: ${STRINGS.ACCENT_COLOR_DARK}; margin: 6px 0; } transform: scale(0.9); @media screen and (min-width: 457px) { display: none; }`; const MenuIcon: FC<{ open: boolean; setOpen: React.Dispatch<SetStateAction<boolean>> }> = ({ open, setOpen,}) => { return ( <MenuIconButton type="button" onClick={() => setOpen(!open)}> <div className={`bar1${open ? ' change' : ''}`} /> <div className={`bar2${open ? ' change' : ''}`} /> <div className={`bar3${open ? ' change' : ''}`} /> </MenuIconButton> );}; Function `Frame` has 59 lines of code (exceeds 25 allowed). Consider refactoring.const Frame: FunctionComponent = (): JSX.Element => { const currentUser = useContext(AuthContext); const [ActionButton, setActionButton] = useState<React.ReactNode>(null); const [menuOpen, setMenuOpen] = useState(false); const resetScroll: React.FocusEventHandler<HTMLDivElement> = useCallback(({ currentTarget }) => { // eslint-disable-next-line no-param-reassign currentTarget.scrollTop = 0; // eslint-disable-next-line no-param-reassign currentTarget.scrollTop = 0; }, []); if (window.location.pathname.startsWith('/login')) { return <Redirect to="/dashboard" />; } return ( <ActionButtonContext.Provider value={{ ActionButton, update: setActionButton }}> <Layout onFocus={resetScroll} sidebar={menuOpen}> <div className="header"> <SpaceBetweenRow> <MenuIcon open={menuOpen} setOpen={setMenuOpen} /> <Title style={{ color: '#FF647C' }} margin="1.5rem 0rem 0rem"> <Switch> {routes.map(route => { return route.authLevel.includes(currentUser.userType) ? ( <Route key={route.path} path={route.path} render={() => route.displayText} /> ) : null; })} <Route path="/">Dashboard</Route> </Switch> </Title> {ActionButton || null} </SpaceBetweenRow> <Rectangle /> </div> <Sidebar setMenuOpen={setMenuOpen} /> <OverflowContainer className="content"> <Suspense fallback={<div>Loading...</div>}> <Switch> {routes.map(route => { return route.authLevel.includes(currentUser.userType) ? ( <Route key={route.path} path={route.path} render={() => <route.component />} /> ) : null; })} <Route path="/"> {() => { switch (currentUser.userType) { case UserType.Organizer: return <OrganizerDash />; case UserType.Sponsor: return <SponsorDash />; case UserType.Hacker: return <HackerDash />; default: return <div>Dash not implemented for this user type.</div>; } }} </Route> </Switch> </Suspense> </OverflowContainer> </Layout> </ActionButtonContext.Provider> );}; export default Frame;