From 7c9345f41d9c86142019cce05ca0495408b01730 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 28 Aug 2023 10:55:50 -0400 Subject: feat: skeleton of app --- src/App.js | 93 +++++++++++++++++++++++++++------- src/App.test.js | 8 --- src/CustomThemeProvider.js | 45 +++++++++++++++++ src/components/NavBar/index.js | 100 +++++++++++++++++++++++++++++++++++++ src/hooks/useLoginState.js | 33 ++++++++++++ src/pages/Login/index.js | 52 +++++++++++++++++++ src/pages/NewSurvey/index.js | 3 ++ src/pages/SurveyAssignees/index.js | 3 ++ src/pages/SurveyResults/index.js | 3 ++ src/pages/Surveys/index.js | 3 ++ src/pages/Users/index.js | 3 ++ 11 files changed, 319 insertions(+), 27 deletions(-) delete mode 100644 src/App.test.js create mode 100644 src/CustomThemeProvider.js create mode 100644 src/components/NavBar/index.js create mode 100644 src/hooks/useLoginState.js create mode 100644 src/pages/Login/index.js create mode 100644 src/pages/NewSurvey/index.js create mode 100644 src/pages/SurveyAssignees/index.js create mode 100644 src/pages/SurveyResults/index.js create mode 100644 src/pages/Surveys/index.js create mode 100644 src/pages/Users/index.js (limited to 'src') diff --git a/src/App.js b/src/App.js index 3784575..9d9ee58 100644 --- a/src/App.js +++ b/src/App.js @@ -1,25 +1,80 @@ -import logo from './logo.svg'; 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 App() { +function routes({ login, logout, isLoggedIn }) { + + function withNavBar(component) { + const navbarLinks = [ + { label: 'Surveys', link: '/surveys' }, + { label: 'New Survey', link: '/surveys/new' }, + { label: 'Users', link: '/users' }, + ]; + return (<> + + {component} + ); + } + + if (!isLoggedIn) { + return ([ + { + path: '*', + element: , + }, + ]); + } else { + return ([ + { + path: '/', + element: , + }, + { + path: '/surveys', + element: withNavBar(), + }, + { + path: '/surveys/new', + element: withNavBar(), + }, + { + path: '/surveys/:surveyId/results', + element: withNavBar(), + }, + { + path: '/surveys/:surveyId/assignees', + element: withNavBar(), + }, + { + path: '/users', + element: withNavBar(), + }, + ]); + } + +} + +export default function App() { + const { login, logout, isLoggedIn } = useLoginState(); + const currentRoutes = routes({isLoggedIn, logout, login}); return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
+ <> + + + + + ); } -export default App; diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index 1f03afe..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/src/CustomThemeProvider.js b/src/CustomThemeProvider.js new file mode 100644 index 0000000..f3f4a26 --- /dev/null +++ b/src/CustomThemeProvider.js @@ -0,0 +1,45 @@ +import {ThemeProvider} from '@mui/material'; +import {createTheme} from '@mui/material'; + +export default function CustomThemeProvider({children}) { + console.log('theme', theme); + return + { children } + ; +} + +const themeOptions = { + palette: { + mode: 'light', + primary: { + main: '#0b0b14', + }, + secondary: { + main: '#9c27b0', + }, + }, + overrides: { + MuiAppBar: { + colorInherit: { + backgroundColor: '#689f38', + color: '#fff', + }, + }, + MuiButton: { + root: { + background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', + border: 0, + borderRadius: 3, + boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', + color: 'white', + height: 48, + padding: '0 30px', + }, + }, + }, +}; + + +const theme = createTheme(themeOptions); + + diff --git a/src/components/NavBar/index.js b/src/components/NavBar/index.js new file mode 100644 index 0000000..0bbc550 --- /dev/null +++ b/src/components/NavBar/index.js @@ -0,0 +1,100 @@ +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; + + const [mobileOpen, setMobileOpen] = useState(false); + + const handleDrawerToggle = () => { + setMobileOpen(!mobileOpen); + }; + + return isLoggedIn && + + + + + + + + {pages.map(p => + p.hidden || + + + + )} + + + + + + + + + + + {pages.map(({label, link, hidden}) => ( + hidden ?
: + + + + + + + + + ))} + + + + + +
+
+
+
+ ; +} diff --git a/src/hooks/useLoginState.js b/src/hooks/useLoginState.js new file mode 100644 index 0000000..b7c7221 --- /dev/null +++ b/src/hooks/useLoginState.js @@ -0,0 +1,33 @@ +import {useState} from 'react'; + +export default function useLoginState() { + const [userInfo, setUserInfoState] = useState( + localStorage.userInfo ? + JSON.parse(localStorage.userInfo) : + {} + ); + + function setUserInfo(userInfo) { + setUserInfoState(userInfo); + localStorage.userInfo = JSON.stringify(userInfo || {}); + } + + async function login(username, password) { + console.log(`logging in: ${username}, ${password}`); + // const userInfo = await api.login() + const userInfo = { + username + }; + console.log('Login success'); + setUserInfo(userInfo); + return userInfo; + } + + function logout() { + setUserInfo({}); + } + + const isLoggedIn = !!userInfo?.username; + + return {userInfo, isLoggedIn, login, logout}; +} diff --git a/src/pages/Login/index.js b/src/pages/Login/index.js new file mode 100644 index 0000000..1735d8e --- /dev/null +++ b/src/pages/Login/index.js @@ -0,0 +1,52 @@ +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 [loginFailed, setLoginFailed] = useState(false); + + const getApiKey = () => { + login(user, password) + .then(ok => { + setLoginFailed(!ok); + } + ) + .catch(console.error); + }; + + return ( + :not(style)': { m: 1 }, + flexGrow: 1, + }} + noValidate + autoComplete="off" + > + +

Repeated Surveyer

+

Login

+ setUser(e.target.value.trim())} + /> + setPassword(e.target.value)} + /> + + {loginFailed && Login Failed} +
+
+ ); +} + diff --git a/src/pages/NewSurvey/index.js b/src/pages/NewSurvey/index.js new file mode 100644 index 0000000..a4b711a --- /dev/null +++ b/src/pages/NewSurvey/index.js @@ -0,0 +1,3 @@ +export default function NewSurvey() { + return <>NewSurvey; +} diff --git a/src/pages/SurveyAssignees/index.js b/src/pages/SurveyAssignees/index.js new file mode 100644 index 0000000..3623217 --- /dev/null +++ b/src/pages/SurveyAssignees/index.js @@ -0,0 +1,3 @@ +export default function SurveyAssignees() { + return <>SurveyAssignees; +} diff --git a/src/pages/SurveyResults/index.js b/src/pages/SurveyResults/index.js new file mode 100644 index 0000000..82d41c6 --- /dev/null +++ b/src/pages/SurveyResults/index.js @@ -0,0 +1,3 @@ +export default function SurveyResults() { + return <>SurveyResults; +} diff --git a/src/pages/Surveys/index.js b/src/pages/Surveys/index.js new file mode 100644 index 0000000..69e854f --- /dev/null +++ b/src/pages/Surveys/index.js @@ -0,0 +1,3 @@ +export default function Surveys() { + return <>Surveys; +} diff --git a/src/pages/Users/index.js b/src/pages/Users/index.js new file mode 100644 index 0000000..43afe5d --- /dev/null +++ b/src/pages/Users/index.js @@ -0,0 +1,3 @@ +export default function Users() { + return <>Users; +} -- cgit v1.2.3