From 081e6d5017c4806e236f42443529f227f90214ca Mon Sep 17 00:00:00 2001 From: Asia Date: Sun, 28 Mar 2021 12:46:12 +0200 Subject: [PATCH] [#72] login register views (#83) --- client/package-lock.json | 50 ++++++++ client/package.json | 5 +- .../FancyComponent/FancyComponent.tsx | 17 --- .../src/components/FancyComponent/styles.tsx | 19 --- client/src/components/Form/Form.tsx | 117 ++++++++++++++++++ client/src/components/Form/styles.tsx | 97 +++++++++++++++ client/src/views/App/App.tsx | 6 +- client/src/views/Login/Login.tsx | 36 ++++++ client/src/views/Register/Register.tsx | 44 +++++++ server/src/routes/register.ts | 2 +- server/src/server.tsx | 2 +- 11 files changed, 355 insertions(+), 40 deletions(-) delete mode 100644 client/src/components/FancyComponent/FancyComponent.tsx delete mode 100644 client/src/components/FancyComponent/styles.tsx create mode 100644 client/src/components/Form/Form.tsx create mode 100644 client/src/components/Form/styles.tsx create mode 100644 client/src/views/Login/Login.tsx create mode 100644 client/src/views/Register/Register.tsx diff --git a/client/package-lock.json b/client/package-lock.json index dc4b031..6fbca47 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -2368,6 +2368,48 @@ "@babel/runtime": "^7.12.5" } }, + "@trejgun/material-ui-icons-google": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@trejgun/material-ui-icons-google/-/material-ui-icons-google-0.0.3.tgz", + "integrity": "sha512-9ZTFBt8kwKBoNSu5SA7kLvxiHTXwuuMqEHLwmIVtjiAsgeh09grrcSJEkdFUq7tlgpk9szZk5rZXM1TZD7w7lg==", + "requires": { + "@material-ui/core": "^4.9.3", + "react": "^16.12.0", + "react-dom": "^16.12.0" + }, + "dependencies": { + "react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -3293,6 +3335,14 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.2.tgz", "integrity": "sha512-V+Nq70NxKhYt89ArVcaNL9FDryB3vQOd+BFXZIfO3RP6rwtj+2yqqqdHEkacutglPaZLkJeuXKCjCJDMGPtPqg==" }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", diff --git a/client/package.json b/client/package.json index 6b32c68..f9d52a5 100644 --- a/client/package.json +++ b/client/package.json @@ -12,10 +12,12 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^12.7.1", + "@trejgun/material-ui-icons-google": "0.0.3", "@types/jest": "^26.0.20", "@types/node": "^12.20.4", "@types/react-dom": "^17.0.1", "@types/react-router-dom": "^5.1.7", + "axios": "^0.21.1", "react": "^17.0.1", "react-dom": "^17.0.1", "react-router-dom": "^5.2.0", @@ -53,5 +55,6 @@ "react-app-rewired": "^2.1.8", "@types/react-router-dom": "^5.1.7", "react-router-dom": "^5.2.0" - } + }, + "proxy": "http://localhost:3001" } diff --git a/client/src/components/FancyComponent/FancyComponent.tsx b/client/src/components/FancyComponent/FancyComponent.tsx deleted file mode 100644 index 68db2b7..0000000 --- a/client/src/components/FancyComponent/FancyComponent.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Typography } from '@material-ui/core'; -import React from 'react'; -import StyledButton from './styles'; - -const FancyComponent = () => { - return ( - - - Click me! - - Do not clik me! - Custom header - - ); -}; - -export default FancyComponent; diff --git a/client/src/components/FancyComponent/styles.tsx b/client/src/components/FancyComponent/styles.tsx deleted file mode 100644 index a5b07f6..0000000 --- a/client/src/components/FancyComponent/styles.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import styled from '@emotion/styled'; -import { Button } from '@material-ui/core'; - -type StyledButtonProps = { - test?: boolean; -}; - -const StyledButton = styled(Button)` -&& { - padding: 50px; - font-size: 24px; - border-radius: 4px; - font-weight: ${(props: StyledButtonProps) => (props.test ? '400' : '500')}; - &:hover { - color: white; - } -`; - -export default StyledButton; diff --git a/client/src/components/Form/Form.tsx b/client/src/components/Form/Form.tsx new file mode 100644 index 0000000..f8b228a --- /dev/null +++ b/client/src/components/Form/Form.tsx @@ -0,0 +1,117 @@ +import { Checkbox, FormControlLabel, Icon, Theme } from '@material-ui/core'; +import { + StyledButtonGoogle, + StyledForm, + StyledTextField, + StyledLink, + StyledButton, + orParagraph, + StyledFormControlLabel +} from './styles'; +import React, { FormEvent } from 'react'; +import { css } from '@emotion/react'; +import { Grid } from './styles'; +import { Search } from '@trejgun/material-ui-icons-google'; +import { Container } from '@material-ui/core'; + +interface FormProps { + isregister?: boolean; + onUsernameChange?: (e: string) => void; + onEmailChange: (e: string) => void; + onPasswordChange: (e: string) => void; + onSubmit: (e: FormEvent) => void; +} + +const handleGoogleRedirect = () => { + const requestOptions = { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + mode: 'no-cors' as RequestMode + }; + + fetch(`/api/google`, requestOptions) + .then((response) => { + window.location.href = `/`; + }) + .catch((err) => { + console.error(err); + }); +}; + +const Form = ({ isregister, onUsernameChange, onEmailChange, onPasswordChange, onSubmit }: FormProps) => { + return ( + <> + + + + handleGoogleRedirect()} variant="outlined"> + + Kontynuuj przez Google + +

LUB

+ onSubmit(e)} noValidate autoComplete="off"> + onUsernameChange && onUsernameChange(e.target.value)} + /> + onEmailChange(e.target.value)} + /> + onPasswordChange(e.target.value)} + /> + + } + label="Akceptuję warunki korzystania i politykę prywatności FiszQI" + /> + + {isregister ? `ZAREJESTRUJ` : 'ZALOGUJ SIĘ'} + + + + {isregister ? `Masz już konto? Zaloguj się` : `Nie masz konta? Zarejestruj się`} + +
+
+
+ + ); +}; + +export default Form; diff --git a/client/src/components/Form/styles.tsx b/client/src/components/Form/styles.tsx new file mode 100644 index 0000000..82f2134 --- /dev/null +++ b/client/src/components/Form/styles.tsx @@ -0,0 +1,97 @@ +import styled from '@emotion/styled'; +import { Button, Checkbox, TextField, Icon, FormControlLabel } from '@material-ui/core'; +import { Link } from 'react-router-dom'; +import MuiGrid from '@material-ui/core/Grid'; +import { spacing } from '@material-ui/system'; +import React from 'react'; +import { css } from '@emotion/react'; + +interface FormStylesProps { + isdisplay?: string; +} + +export const StyledTextField = styled(TextField)` + && { + width: 90%; + margin: 1vh; + + input { + font-size: 16px; + } + + &.test { + display: ${(props: FormStylesProps) => + props.isdisplay && props.isdisplay === 'true' ? 'inline-flex' : 'none'}; + } + } +`; + +export const StyledFormControlLabel = styled(FormControlLabel)` + && { + ${(props: FormStylesProps) => (props.isdisplay === 'true' ? '' : 'display: none')}; + width: 80%; + text-align: center; + padding: 5px; + } +`; + +export const StyledForm = styled.form` + text-align: center; + width: 100%; +`; + +export const StyledButton = styled(Button)` + && { + width: 90%; + margin: 1vh; + background-color: #2f2e41; + text-transform: uppercase; + color: #ffff; + padding: 6px; + font-size: 14px; + font-weight: 500; + line-height: 24px; + font-family: Roboto; + } +`; + +export const StyledLink = styled(Link)` + && { + text-align: right; + float: right; + margin-right: 10%; + margin-top: 10px; + color: #1976d2; + text-decoration: none; + } +`; + +export const StyledCheckbox = styled(Checkbox)` + && { + margin-left: 5%; + } +`; + +export const StyledButtonGoogle = styled(Button)` + && { + margin-top: 1vh; + width: 90%; + margin: 1vh; + font-size: 16px; + text-align: center; + margin-left: 5%; + padding-top: 10.5px; + padding-bottom: 10.5px; + text-transform: none; + } +`; + +export const orParagraph = css` + text-transform: uppercase; + margin: 2vh; + font-weight: 700; + font-weight: 16px; + text-align: center; +`; + +export const Grid = styled(MuiGrid)(spacing); diff --git a/client/src/views/App/App.tsx b/client/src/views/App/App.tsx index 3b9f458..75c3c85 100644 --- a/client/src/views/App/App.tsx +++ b/client/src/views/App/App.tsx @@ -5,8 +5,10 @@ import { Home } from '../../components/Home'; import { TopNavBar } from '../../components/NavBars/TopNavBar'; import { BottomNavBar } from '../../components/NavBars/BottomNavBar'; import NotFound from '../../components/NotFound'; +import Login from '../Login/Login'; +import Register from '../Register/Register'; -export const App: FC = () => { +const App = () => { return (
@@ -16,6 +18,8 @@ export const App: FC = () => { + + diff --git a/client/src/views/Login/Login.tsx b/client/src/views/Login/Login.tsx new file mode 100644 index 0000000..2506e23 --- /dev/null +++ b/client/src/views/Login/Login.tsx @@ -0,0 +1,36 @@ +import React, { useState } from 'react'; +import Form from '../../components/Form/Form'; +import axios from 'axios'; + +const Login = () => { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + const user = { + email: email, + password: password + }; + + axios('/api/register', { + method: 'POST', + headers: { + 'content-type': 'application/json' + }, + data: user + }) + .then((response) => (window.location.href = `/`)) + .catch((error) => { + throw error; + }); + }; + + return ( + <> +
+ + ); +}; + +export default Login; diff --git a/client/src/views/Register/Register.tsx b/client/src/views/Register/Register.tsx new file mode 100644 index 0000000..db2fc19 --- /dev/null +++ b/client/src/views/Register/Register.tsx @@ -0,0 +1,44 @@ +import React, { useState } from 'react'; +import Form from '../../components/Form/Form'; +import axios from 'axios'; + +const Register = () => { + const [username, setUsername] = useState(''); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + const user = { + username: username, + email: email, + password: password + }; + + axios('/api/register', { + method: 'POST', + headers: { + 'content-type': 'application/json' + }, + data: user + }) + .then((response) => (window.location.href = `/login`)) + .catch((error) => { + throw error; + }); + }; + + return ( + <> + + + ); +}; + +export default Register; diff --git a/server/src/routes/register.ts b/server/src/routes/register.ts index 0647b8d..e16969d 100644 --- a/server/src/routes/register.ts +++ b/server/src/routes/register.ts @@ -23,7 +23,7 @@ router.post('/', async (req: Request, res: Response, next: NextFunction) => { }); await user.save(); - res.redirect('/api/login'); + res.send(200); } catch (error) { next(error); } diff --git a/server/src/server.tsx b/server/src/server.tsx index 284f89b..a142d0d 100644 --- a/server/src/server.tsx +++ b/server/src/server.tsx @@ -13,7 +13,7 @@ import './middleware/passport'; import swaggerDocument from './swaggerWrap'; const app = express(); -const port = process.env.PORT || 3000; +const port = process.env.PORT || 3001; const env = process.env.NODE_ENV || 'development'; let connection_uri = process.env.MONGODB_DEV_URI || 'mongodb://localhost/playground';