diff --git a/backend/index.js b/backend/index.js index 2314b46..59c02b1 100644 --- a/backend/index.js +++ b/backend/index.js @@ -73,7 +73,7 @@ app.use(passport.session()); app.get("*", function (req, res, next) { if (!serverStartupComplete) - return res.send("Server is starting..."); + return res.send("Server is starting... Please try again soon."); else return next(); }); @@ -108,7 +108,7 @@ passport.use('local-login', new LocalStrategy({ email = mysql.escape(email); connection.query(`SELECT * from user WHERE email = ${email} AND deactivated = 0`, function (err, rows) { if (err) { - return done(null, false); + return res.status(static.INTERNAL_SERVER_ERROR).send("error querying the database - Please contact sys admin"); } if (!rows.length) { return done(null, false); @@ -144,7 +144,7 @@ passport.deserializeUser(function (id, done) { }); app.post("/API/user/login", passport.authenticate('local-login'), function (req, res) { - res.status(status.OK).send(); + res.status(status.OK).send("login success"); }); app.put("/API/user/create", function (req, res) { @@ -155,11 +155,11 @@ app.put("/API/user/create", function (req, res) { if (DEBUG) return res.status(status.OK).send(); connection.query(`INSERT INTO user (deactivated, email, password) values (1, ${email}, ${password})`, function (err, rows) { if (err) - return res.status(status.INTERNAL_SERVER_ERROR).send(); - return res.status(status.OK).send(); + return res.send(status.INTERNAL_SERVER_ERROR).send("the user seems to exist already - if you think this is an error contact the sys admin"); + return res.status(status.OK).send("account successfully created"); }); } else { - res.status(status.BAD_REQUEST).send(); + res.status(status.BAD_REQUEST).send("invalid data supplied"); } }); @@ -168,7 +168,7 @@ app.all("*", function (req, res, next) { return next(); } else { - res.status(status.UNAUTHORIZED).send(); + res.status(status.UNAUTHORIZED).send("please log in before using this site"); } }); @@ -196,7 +196,7 @@ app.get('/API/day', function (req, res) { }); } else - res.status(status.BAD_REQUEST).send("invalid data provided"); + res.status(status.BAD_REQUEST).send("invalid data range provided"); } else @@ -207,4 +207,4 @@ app.get('/API/resourcelist', function (req, res) { res.send(resourceList); }); -app.listen(3001); \ No newline at end of file +app.listen(3001); diff --git a/backend/package.json b/backend/package.json index 536bbf7..6fd2b7a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -27,4 +27,4 @@ "devDependencies": { "cross-env": "^7.0.2" } -} \ No newline at end of file +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 482ba0f..0c7b100 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1292,6 +1292,18 @@ "@babel/runtime": "^7.4.4" } }, + "@material-ui/lab": { + "version": "4.0.0-alpha.51", + "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.51.tgz", + "integrity": "sha512-X/qv/sZQGhXhKDn83L94gNahGDQj2Rd6r7/9tPpQbSn2A1LAt1+jlTiWD1HUgDXZEPqTsJMajOjWSEmTL7/q7w==", + "requires": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.9.6", + "clsx": "^1.0.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0" + } + }, "@material-ui/styles": { "version": "4.9.10", "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.10.tgz", diff --git a/frontend/package.json b/frontend/package.json index e197578..870a97b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,41 +1,42 @@ { - "name": "simcompanies-dashboard", - "version": "0.1.0", - "homepage": "https://projects.oliver.boehlk.io/simcompanies/", - "private": true, - "dependencies": { - "@material-ui/core": "^4.9.8", - "@material-ui/icons": "^4.9.1", - "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.4.0", - "@testing-library/user-event": "^7.2.1", - "react": "^16.12.0", - "react-dom": "^16.12.0", - "react-router-dom": "^5.1.2", - "react-scripts": "3.4.0", - "typeface-roboto": "0.0.75", - "recharts": "^1.8.5" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": "react-app" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "proxy": "http://127.0.0.1:3001" -} \ No newline at end of file + "name": "simcompanies-dashboard", + "version": "0.1.0", + "homepage": "https://projects.oliver.boehlk.io/simcompanies/", + "private": true, + "dependencies": { + "@material-ui/core": "^4.9.8", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.51", + "@testing-library/jest-dom": "^4.2.4", + "@testing-library/react": "^9.4.0", + "@testing-library/user-event": "^7.2.1", + "react": "^16.12.0", + "react-dom": "^16.12.0", + "react-router-dom": "^5.1.2", + "react-scripts": "3.4.0", + "recharts": "^1.8.5", + "typeface-roboto": "0.0.75" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": "react-app" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "proxy": "http://127.0.0.1:3001" +} diff --git a/frontend/src/components/login/createAccount.js b/frontend/src/components/login/createAccount.js index 541ea5c..3f3ed5f 100644 --- a/frontend/src/components/login/createAccount.js +++ b/frontend/src/components/login/createAccount.js @@ -10,6 +10,7 @@ import Logo from "../../img/logo.png"; import TextField from '@material-ui/core/TextField'; import Grid from '@material-ui/core/Grid'; import { Redirect } from "react-router-dom"; +import LoginFeedback from './loginfeedback'; const url = "/simcompanies/API/user/create" @@ -33,7 +34,7 @@ const useStyles = makeStyles(theme => ({ const CssTextField = withStyles({ root: { '& label.Mui-focused': { - color: 'white', + color: '#FFC800', }, '&:hover label': { color: '#FFC800', @@ -53,20 +54,20 @@ const CssTextField = withStyles({ borderColor: "#FFC800", }, '&.Mui-focused fieldset': { - borderColor: 'white', + borderColor: '#FFC800', }, }, }, })(TextField); - - export default function CreateAccount() { const classes = useStyles(); const [username, setUsername] = React.useState(""); const [password, setPassword] = React.useState(""); const [login, setLogin] = React.useState(true); - + const [status, setStatus] = React.useState(null); + const [statusText, setStatusText] = React.useState(null); + const [disabled, setDisabled] = React.useState(false); const putCreateAccount = async (url, data) => { const response = await fetch(url, { @@ -80,20 +81,36 @@ export default function CreateAccount() { referrerPolicy: 'no-referrer', body: JSON.stringify(data) }); - + const text = await response.text() + await setStatusText(text) + setStatus(response.status) if (response.status == "200") { - setLogin(false) + setTimeout(() => { setLogin(false) }, 2000) } + setDisabled(false) + setTimeout(() => { setStatus(null) }, 2000) } const handleClick = (e) => { - if (username !== "" && password !== "") { + setDisabled(true) putCreateAccount(url, { email: username, password: password }) setUsername("") setPassword("") } } + + const handleKeyDown = (e) => { + if (e.key === "Enter") { + if (username !== "" && password !== "") { + setDisabled(true) + putCreateAccount(url, { email: username, password: password }) + + setUsername("") + setPassword("") + } + } + } const handleChangeUSR = (e) => { setUsername(e.target.value) } @@ -122,18 +139,22 @@ export default function CreateAccount() { - @@ -157,6 +180,7 @@ export default function CreateAccount() { + : ) diff --git a/frontend/src/components/login/login.js b/frontend/src/components/login/login.js index 3dc4036..6afb83e 100644 --- a/frontend/src/components/login/login.js +++ b/frontend/src/components/login/login.js @@ -11,6 +11,7 @@ import TextField from '@material-ui/core/TextField'; import Grid from '@material-ui/core/Grid'; import Link1 from '@material-ui/core/Link'; import { Redirect } from "react-router-dom"; +import LoginFeedback from './loginfeedback'; const useStyles = makeStyles(theme => ({ @@ -33,7 +34,7 @@ const useStyles = makeStyles(theme => ({ const CssTextField = withStyles({ root: { '& label.Mui-focused': { - color: 'white', + color: "#FFC800", }, '&:hover label': { color: '#FFC800', @@ -53,7 +54,7 @@ const CssTextField = withStyles({ borderColor: "#FFC800", }, '&.Mui-focused fieldset': { - borderColor: 'white', + borderColor: "#FFC800", }, }, }, @@ -66,9 +67,12 @@ export default function Login() { const [username, setUsername] = React.useState(""); const [password, setPassword] = React.useState(""); const [login, setLogin] = React.useState(true); - + const [status, setStatus] = React.useState(null); + const [disabled, setDisabled] = React.useState(false); + const [statusText, setStatusText] = React.useState(null); const postLogin = async (url, data) => { + const response = await fetch(url, { method: 'POST', mode: 'cors', @@ -81,20 +85,40 @@ export default function Login() { body: JSON.stringify(data) }); + const text = await response.text() + await setStatusText(text) + setStatus(response.status) if (response.status == "200") { - setLogin(false) + setTimeout(() => { setLogin(false) }, 2000) + } + setDisabled(false) + setTimeout(() => { setStatus(null) }, 2000) } const handleClick = (e) => { if (username !== "" && password !== "") { + setDisabled(true) postLogin(url, { email: username, password: password }) setUsername("") setPassword("") } } + + const handleKeyDown = (e) => { + if (e.key === "Enter") { + if (username !== "" && password !== "") { + setDisabled(true) + postLogin(url, { email: username, password: password }) + + setUsername("") + setPassword("") + } + } + } + const handleChangeUSR = (e) => { setUsername(e.target.value) } @@ -125,18 +149,22 @@ export default function Login() { @@ -159,9 +189,9 @@ export default function Login() { - + @@ -169,6 +199,7 @@ export default function Login() { + : ) diff --git a/frontend/src/components/login/loginfeedback.js b/frontend/src/components/login/loginfeedback.js new file mode 100644 index 0000000..cecdfa5 --- /dev/null +++ b/frontend/src/components/login/loginfeedback.js @@ -0,0 +1,66 @@ +import React, { useEffect } from 'react'; +import Snackbar from '@material-ui/core/Snackbar'; +import MuiAlert from '@material-ui/lab/Alert'; + +function Alert(props) { + return ; +} + +export default function LoginFeedback(props) { + const [login, setLogin] = React.useState(null); + const [open, setOpen] = React.useState(true); + const [open1, setOpen1] = React.useState(true); + const [output, setOutput] = React.useState(null); + const [change, setChange] = React.useState(false); + + useEffect(() => { + if (login != props.login) { + setChange(true) + setOpen(true) + setOpen1(true) + setLogin(props.login) + } + }, [login, setLogin, props.login]); + + const handleClose = (event, reason) => { + + setOpen(false); + }; + const handleClose1 = (event, reason) => { + setOpen1(false); + }; + + const snack = (login) => { + if (login == "200") { + setOutput( + + + {props.text} + + ) + } else if (login != null) { + setOutput( + + + {props.text} + + + ) + } else { + setOutput(null) + } + setChange(false) + } + + if (change == true) { + snack(login) + } + + return ( + + {output} + + + ) + +}