diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.js | 79 | ||||
| -rw-r--r-- | src/CustomThemeProvider.js | 33 | ||||
| -rw-r--r-- | src/components/NavBar/index.js | 196 | ||||
| -rw-r--r-- | src/hooks/useLoginState.js | 16 | ||||
| -rw-r--r-- | src/index.js | 14 | ||||
| -rw-r--r-- | src/pages/Login/index.js | 36 | ||||
| -rw-r--r-- | src/pages/Users/index.js | 7 | ||||
| -rw-r--r-- | src/reportWebVitals.js | 4 | ||||
| -rw-r--r-- | src/setupTests.js | 2 | 
9 files changed, 206 insertions, 181 deletions
| @@ -1,80 +1,81 @@ -import './App.css'; -import { RouterProvider, createBrowserRouter, Navigate } from 'react-router-dom'; -import Login from './pages/Login'; -import Surveys from './pages/Surveys'; -import NewSurvey from './pages/NewSurvey'; -import SurveyResults from './pages/SurveyResults'; -import SurveyAssignees from './pages/SurveyAssignees'; -import Users from './pages/Users'; -import NavBar from './components/NavBar'; -import useLoginState from './hooks/useLoginState'; -import CssBaseline from '@mui/material/CssBaseline'; -import CustomThemeProvider from './CustomThemeProvider'; +import "./App.css"; +import { +  RouterProvider, +  createBrowserRouter, +  Navigate, +} from "react-router-dom"; +import Login from "./pages/Login"; +import Surveys from "./pages/Surveys"; +import NewSurvey from "./pages/NewSurvey"; +import SurveyResults from "./pages/SurveyResults"; +import SurveyAssignees from "./pages/SurveyAssignees"; +import Users from "./pages/Users"; +import NavBar from "./components/NavBar"; +import useLoginState from "./hooks/useLoginState"; +import CssBaseline from "@mui/material/CssBaseline"; +import CustomThemeProvider from "./CustomThemeProvider";  function routes({ login, logout, isLoggedIn }) { -      function withNavBar(component) {      const navbarLinks = [ -      { label: 'Surveys', link: '/surveys' }, -      { label: 'New Survey', link: '/surveys/new' }, -      { label: 'Users', link: '/users' }, +      { label: "Surveys", link: "/surveys" }, +      { label: "New Survey", link: "/surveys/new" }, +      { label: "Users", link: "/users" },      ]; -    return (<> -      <NavBar isLoggedIn={isLoggedIn} pages={navbarLinks} logout={logout} /> -      {component} -    </>); +    return ( +      <> +        <NavBar isLoggedIn={isLoggedIn} pages={navbarLinks} logout={logout} /> +        {component} +      </> +    );    }    if (!isLoggedIn) { -    return ([ +    return [        { -        path: '*', -        element: <Login login={login}/>, +        path: "*", +        element: <Login login={login} />,        }, -    ]); +    ];    } else { -    return ([ +    return [        { -        path: '/', -        element: <Navigate to={{ pathname: '/surveys' }} />, +        path: "/", +        element: <Navigate to={{ pathname: "/surveys" }} />,        },        { -        path: '/surveys', +        path: "/surveys",          element: withNavBar(<Surveys />),        },        { -        path: '/surveys/new', +        path: "/surveys/new",          element: withNavBar(<NewSurvey />),        },        { -        path: '/surveys/:surveyId/results', +        path: "/surveys/:surveyId/results",          element: withNavBar(<SurveyResults />),        },        { -        path: '/surveys/:surveyId/assignees', +        path: "/surveys/:surveyId/assignees",          element: withNavBar(<SurveyAssignees />),        },        { -        path: '/users', +        path: "/users",          element: withNavBar(<Users />),        }, -    ]); +    ];    } -  }  export default function App() {    const { login, logout, isLoggedIn } = useLoginState(); -  const currentRoutes = routes({isLoggedIn, logout, login}); +  const currentRoutes = routes({ isLoggedIn, logout, login });    return (      <>        <CssBaseline />        <CustomThemeProvider> -        <RouterProvider router={ -          createBrowserRouter(currentRoutes) -        }/> +        <RouterProvider router={createBrowserRouter(currentRoutes)} />        </CustomThemeProvider>      </>    );  } - diff --git a/src/CustomThemeProvider.js b/src/CustomThemeProvider.js index f3f4a26..c4234b6 100644 --- a/src/CustomThemeProvider.js +++ b/src/CustomThemeProvider.js @@ -1,45 +1,40 @@ -import {ThemeProvider} from '@mui/material'; -import {createTheme} from '@mui/material'; +import { ThemeProvider } from "@mui/material"; +import { createTheme } from "@mui/material"; -export default function CustomThemeProvider({children}) { -  console.log('theme', theme); -  return <ThemeProvider theme={theme}> -    { children } -  </ThemeProvider>; +export default function CustomThemeProvider({ children }) { +  console.log("theme", theme); +  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;  }  const themeOptions = {    palette: { -    mode: 'light', +    mode: "light",      primary: { -      main: '#0b0b14', +      main: "#0b0b14",      },      secondary: { -      main: '#9c27b0', +      main: "#9c27b0",      },    },    overrides: {      MuiAppBar: {        colorInherit: { -        backgroundColor: '#689f38', -        color: '#fff', +        backgroundColor: "#689f38", +        color: "#fff",        },      },      MuiButton: {        root: { -        background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', +        background: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",          border: 0,          borderRadius: 3, -        boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', -        color: 'white', +        boxShadow: "0 3px 5px 2px rgba(255, 105, 135, .3)", +        color: "white",          height: 48, -        padding: '0 30px', +        padding: "0 30px",        },      },    },  }; -  const theme = createTheme(themeOptions); - - diff --git a/src/components/NavBar/index.js b/src/components/NavBar/index.js index 0bbc550..83ae7e9 100644 --- a/src/components/NavBar/index.js +++ b/src/components/NavBar/index.js @@ -1,7 +1,18 @@ -import {useState} from 'react'; -import { Link } from 'react-router-dom'; -import {AppBar, Box, Button, Drawer, IconButton, List, ListItem, ListItemButton, ListItemText, Toolbar} from '@mui/material'; -import {Menu} from '@mui/icons-material'; +import { useState } from "react"; +import { Link } from "react-router-dom"; +import { +  AppBar, +  Box, +  Button, +  Drawer, +  IconButton, +  List, +  ListItem, +  ListItemButton, +  ListItemText, +  Toolbar, +} from "@mui/material"; +import { Menu } from "@mui/icons-material";  export default function NavBar({ isLoggedIn, pages, logout }) {    const drawerWidth = 200; @@ -12,89 +23,106 @@ export default function NavBar({ isLoggedIn, pages, logout }) {      setMobileOpen(!mobileOpen);    }; -  return isLoggedIn && -    <Box sx={{ display: 'flex' }}> -      <AppBar -        component='nav' -        sx={{position: 'initial'}}> -        <Toolbar> -          <IconButton -            color="inherit" -            aria-label="open drawer" -            edge="start" -            onClick={handleDrawerToggle} -            sx={{ mr: 2, display: { sm: 'none' } }} -          > -            <Menu /> -          </IconButton> -          <Box sx={{ display: { xs: 'none', sm: 'block' } }}> -            {pages.map(p =>  -              p.hidden ||  -<Link key={p.link} to={p.link} style={{textDecorationLine:'none'}}> -  <Button key={p.label} sx={{ textDecorationLine:'none', color: '#ffffff' }}> -    {p.label} -  </Button> -</Link> -            )} -            <Button onClick={logout} sx={{color:'#ffffff'}}> -            Logout -            </Button> -          </Box> -        </Toolbar> -      </AppBar> - +  return ( +    isLoggedIn && ( +      <Box sx={{ display: "flex" }}> +        <AppBar component="nav" sx={{ position: "initial" }}> +          <Toolbar> +            <IconButton +              color="inherit" +              aria-label="open drawer" +              edge="start" +              onClick={handleDrawerToggle} +              sx={{ mr: 2, display: { sm: "none" } }} +            > +              <Menu /> +            </IconButton> +            <Box sx={{ display: { xs: "none", sm: "block" } }}> +              {pages.map( +                (p) => +                  p.hidden || ( +                    <Link +                      key={p.link} +                      to={p.link} +                      style={{ textDecorationLine: "none" }} +                    > +                      <Button +                        key={p.label} +                        sx={{ textDecorationLine: "none", color: "#ffffff" }} +                      > +                        {p.label} +                      </Button> +                    </Link> +                  ), +              )} +              <Button onClick={logout} sx={{ color: "#ffffff" }}> +                Logout +              </Button> +            </Box> +          </Toolbar> +        </AppBar> -      <Box component="nav"> -        <Drawer -          sx={{ -            width: drawerWidth, -            flexShrink: 0, -            '& .MuiDrawer-paper': { +        <Box component="nav"> +          <Drawer +            sx={{                width: drawerWidth, -              boxSizing: 'border-box', -            }, +              flexShrink: 0, +              "& .MuiDrawer-paper": { +                width: drawerWidth, +                boxSizing: "border-box", +              }, -            display: { xs: 'block', sm: 'none' }, -          }} -          variant='temporary' -          anchor='left' -          open={mobileOpen} -          onClose={handleDrawerToggle} -          ModalProps={{ -            keepMounted:true, -          }} -        > -          <Box onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> -            <List> -              {pages.map(({label, link, hidden}) => ( -                hidden ? <div key={link}></div> : -                  <ListItem key={link} disablePadding> - -                    <Link to={link} style={{textDecorationLine:'none', width: '100%'}}> -                      <ListItemButton -                        key={label} -                        sx={{ -                          width:'100%', -                          color: 'primary.main', -                          textAlign: 'left', -                        }} +              display: { xs: "block", sm: "none" }, +            }} +            variant="temporary" +            anchor="left" +            open={mobileOpen} +            onClose={handleDrawerToggle} +            ModalProps={{ +              keepMounted: true, +            }} +          > +            <Box onClick={handleDrawerToggle} sx={{ textAlign: "center" }}> +              <List> +                {pages.map(({ label, link, hidden }) => +                  hidden ? ( +                    <div key={link}></div> +                  ) : ( +                    <ListItem key={link} disablePadding> +                      <Link +                        to={link} +                        style={{ textDecorationLine: "none", width: "100%" }}                        > -                        <ListItemText primary={label} sx={{ width:'100%'}} /> -                      </ListItemButton> -                    </Link> -                  </ListItem> -              ))} -              <ListItem disablePadding> -                <ListItemButton -                  onClick={logout} -                  sx={{width:'100%', color: 'primary.main' }} -                > -                  <ListItemText primary={'Logout'}/> -                </ListItemButton> -              </ListItem> -            </List> -          </Box> -        </Drawer> +                        <ListItemButton +                          key={label} +                          sx={{ +                            width: "100%", +                            color: "primary.main", +                            textAlign: "left", +                          }} +                        > +                          <ListItemText +                            primary={label} +                            sx={{ width: "100%" }} +                          /> +                        </ListItemButton> +                      </Link> +                    </ListItem> +                  ), +                )} +                <ListItem disablePadding> +                  <ListItemButton +                    onClick={logout} +                    sx={{ width: "100%", color: "primary.main" }} +                  > +                    <ListItemText primary={"Logout"} /> +                  </ListItemButton> +                </ListItem> +              </List> +            </Box> +          </Drawer> +        </Box>        </Box> -    </Box>; +    ) +  );  } diff --git a/src/hooks/useLoginState.js b/src/hooks/useLoginState.js index b7c7221..94301ef 100644 --- a/src/hooks/useLoginState.js +++ b/src/hooks/useLoginState.js @@ -1,10 +1,8 @@ -import {useState} from 'react'; +import { useState } from "react";  export default function useLoginState() {    const [userInfo, setUserInfoState] = useState( -    localStorage.userInfo ? -      JSON.parse(localStorage.userInfo) : -      {} +    localStorage.userInfo ? JSON.parse(localStorage.userInfo) : {},    );    function setUserInfo(userInfo) { @@ -16,18 +14,18 @@ export default function useLoginState() {      console.log(`logging in: ${username}, ${password}`);      // const userInfo = await api.login()      const userInfo = { -      username +      username,      }; -    console.log('Login success'); +    console.log("Login success");      setUserInfo(userInfo);      return userInfo; -  }  +  }    function logout() {      setUserInfo({});    }    const isLoggedIn = !!userInfo?.username; -   -  return {userInfo, isLoggedIn, login, logout}; + +  return { userInfo, isLoggedIn, login, logout };  } diff --git a/src/index.js b/src/index.js index d563c0f..902eb7c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,14 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; -import App from './App'; -import reportWebVitals from './reportWebVitals'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; -const root = ReactDOM.createRoot(document.getElementById('root')); +const root = ReactDOM.createRoot(document.getElementById("root"));  root.render(    <React.StrictMode>      <App /> -  </React.StrictMode> +  </React.StrictMode>,  );  // If you want to start measuring performance in your app, pass a function diff --git a/src/pages/Login/index.js b/src/pages/Login/index.js index 1735d8e..6d16936 100644 --- a/src/pages/Login/index.js +++ b/src/pages/Login/index.js @@ -1,20 +1,19 @@ -import React, { useState } from 'react'; -import Box from '@mui/material/Box'; -import TextField from '@mui/material/TextField'; -import Button from '@mui/material/Button'; -import {Stack} from '@mui/system'; +import React, { useState } from "react"; +import Box from "@mui/material/Box"; +import TextField from "@mui/material/TextField"; +import Button from "@mui/material/Button"; +import { Stack } from "@mui/system";  export default function Login({ login }) { -  const [user, setUser] = useState(''); -  const [password, setPassword] = useState(''); +  const [user, setUser] = useState(""); +  const [password, setPassword] = useState("");    const [loginFailed, setLoginFailed] = useState(false);    const getApiKey = () => {      login(user, password) -      .then(ok => { +      .then((ok) => {          setLoginFailed(!ok); -      } -      ) +      })        .catch(console.error);    }; @@ -22,26 +21,26 @@ export default function Login({ login }) {      <Box        component="form"        sx={{ -        '& > :not(style)': { m: 1 }, +        "& > :not(style)": { m: 1 },          flexGrow: 1,        }}        noValidate        autoComplete="off"      > -      <Stack spacing={1} maxWidth='20em'> +      <Stack spacing={1} maxWidth="20em">          <h2>Repeated Surveyer</h2>          <h3>Login</h3>          <TextField -          label='Email Address' -          type='text' +          label="Email Address" +          type="text"            value={user} -          onChange={e => setUser(e.target.value.trim())} +          onChange={(e) => setUser(e.target.value.trim())}          />          <TextField -          label='Password' -          type='password' +          label="Password" +          type="password"            value={password} -          onChange={e => setPassword(e.target.value)} +          onChange={(e) => setPassword(e.target.value)}          />          <Button onClick={() => getApiKey()}>Login</Button>          {loginFailed && <b>Login Failed</b>} @@ -49,4 +48,3 @@ export default function Login({ login }) {      </Box>    );  } - diff --git a/src/pages/Users/index.js b/src/pages/Users/index.js index 43afe5d..1cc20ce 100644 --- a/src/pages/Users/index.js +++ b/src/pages/Users/index.js @@ -1,3 +1,8 @@  export default function Users() { -  return <>Users</>; +  return ( +    <> +      Users +      <div>foo</div> +    </> +  );  } diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js index 5253d3a..9ecd33f 100644 --- a/src/reportWebVitals.js +++ b/src/reportWebVitals.js @@ -1,6 +1,6 @@ -const reportWebVitals = onPerfEntry => { +const reportWebVitals = (onPerfEntry) => {    if (onPerfEntry && onPerfEntry instanceof Function) { -    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { +    import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {        getCLS(onPerfEntry);        getFID(onPerfEntry);        getFCP(onPerfEntry); diff --git a/src/setupTests.js b/src/setupTests.js index 8f2609b..1dd407a 100644 --- a/src/setupTests.js +++ b/src/setupTests.js @@ -2,4 +2,4 @@  // allows you to do things like:  // expect(element).toHaveTextContent(/react/i)  // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; +import "@testing-library/jest-dom"; | 
