diff options
author | dan <[email protected]> | 2023-08-28 11:40:36 -0400 |
---|---|---|
committer | dan <[email protected]> | 2023-08-28 11:40:36 -0400 |
commit | 38217a7101b50e7aa0a0d543cad737a011d5fac0 (patch) | |
tree | 730865f5822e6d95f655aa85959ae7086061fb7c | |
parent | 7c9345f41d9c86142019cce05ca0495408b01730 (diff) | |
download | draggable-form-demo-38217a7101b50e7aa0a0d543cad737a011d5fac0.tar.gz draggable-form-demo-38217a7101b50e7aa0a0d543cad737a011d5fac0.tar.bz2 draggable-form-demo-38217a7101b50e7aa0a0d543cad737a011d5fac0.zip |
refactor: setup and run eslint+prettier
-rw-r--r-- | .eslintrc.js | 34 | ||||
-rw-r--r-- | package.json | 6 | ||||
-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 |
11 files changed, 240 insertions, 187 deletions
diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..56d1c38 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,34 @@ +module.exports = { + env: { + browser: true, + es2021: true, + }, + extends: [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:prettier/recommended", + ], + overrides: [ + { + env: { + node: true, + }, + files: [".eslintrc.{js,cjs}"], + parserOptions: { + sourceType: "script", + }, + }, + ], + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + }, + plugins: ["react", "prettier", "react-hooks"], + rules: { + "linebreak-style": ["error", "unix"], + semi: ["error", "always"], + "react/react-in-jsx-scope": "off", + "react/jsx-filename-extension": [1, { extensions: [".js", ".jsx"] }], + "react/prop-types": "off", + }, +}; diff --git a/package.json b/package.json index 6ca7e08..72a5caa 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,6 @@ "react-app/jest" ] }, - "prettier": { - "singleQuote": true, - "semi": true, - "tabWidth": 2, - "useTabs": false - }, "browserslist": { "production": [ ">0.2%", @@ -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"; |