diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1 @@ +{} diff --git a/package.json b/package.json index 9e54366..e7988ab 100644 --- a/package.json +++ b/package.json @@ -42,5 +42,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "prettier": "2.3.2" } } diff --git a/src/App.js b/src/App.js index 9ed49a8..15e0140 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,9 @@ -import { - ChakraProvider, - theme -} from '@chakra-ui/react'; +import { ChakraProvider, theme } from '@chakra-ui/react'; import { React } from 'react'; import { Redirect, Route, Switch } from 'react-router-dom'; -import Home from './screens/HomeScreen' -import Login from './screens/LoginScreen' - +import Home from './screens/HomeScreen'; +import Login from './screens/LoginScreen'; +import Create from './screens/CreateScreen'; function App() { return ( @@ -18,7 +15,8 @@ function App() { - + + diff --git a/src/app/store.js b/src/app/store.js index 236f660..1457d32 100644 --- a/src/app/store.js +++ b/src/app/store.js @@ -1,8 +1,8 @@ -import { configureStore } from "@reduxjs/toolkit"; -import authSlice from "../features/auth/authSlice"; +import { configureStore } from '@reduxjs/toolkit'; +import authSlice from '../features/auth/authSlice'; export const store = configureStore({ - reducer: { - auth: authSlice, - }, -}) \ No newline at end of file + reducer: { + auth: authSlice, + }, +}); diff --git a/src/features/auth/authSlice.js b/src/features/auth/authSlice.js index b5f1136..5823c91 100644 --- a/src/features/auth/authSlice.js +++ b/src/features/auth/authSlice.js @@ -1,23 +1,23 @@ -import { createSlice } from '@reduxjs/toolkit' +import { createSlice } from '@reduxjs/toolkit'; import Cookies from 'js-cookie'; const initialState = { - isAuthenticated: Cookies.get("authorized"), + isAuthenticated: Cookies.get('authorized'), }; export const authSlice = createSlice({ - name: 'auth', - initialState, - reducers: { - authLogin: (state, action) => { - state.isAuthenticated = true; - }, - authLogout: (state) => { - state.isAuthenticated = false; - }, + name: 'auth', + initialState, + reducers: { + authLogin: (state, action) => { + state.isAuthenticated = true; }, + authLogout: state => { + state.isAuthenticated = false; + }, + }, }); -export const {authLogin, authLogout} = authSlice.actions; +export const { authLogin, authLogout } = authSlice.actions; -export default authSlice.reducer; \ No newline at end of file +export default authSlice.reducer; diff --git a/src/screens/CreateScreen.js b/src/screens/CreateScreen.js new file mode 100644 index 0000000..a27553c --- /dev/null +++ b/src/screens/CreateScreen.js @@ -0,0 +1,129 @@ +import { FormControl, Box, Flex, Image, FormLabel, Input, Select, Heading, Button, useToast } from '@chakra-ui/react'; +import axios from 'axios'; +import { useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import { authLogin } from '../features/auth/authSlice'; + +function OrgSelect(props) { + const orgs = ["MISI: Solidariti", "UNDI18"]; + const orgOptions = orgs.map((name) => { + return ( + + ) + }); + + return ( + + ); +} + +function Create() { + + const dispatch = useDispatch(); + const toast = useToast(); + const history = useHistory(); + + const [name, setName] = useState(null); + const [email, setEmail] = useState(null); + const [phoneNumber, setPhoneNumber] = useState(null); + const [org, setOrg] = useState(null); + const [password, setPassword] = useState(null); + + const handleSubmit = (e) => { + e.preventDefault(); + + if (!name | !email | !phoneNumber | !org | !password) { + toast({ + title: 'Problem!', + description: 'Please fill in all the fields', + status: 'error', + duration: 2000, + isClosable: true, + }); + return; + } + + axios + .post( + `${process.env.REACT_APP_API_URL}/create`, + { + name: name, + email: email, + org: org, + phoneNumber: org, + password: password, + }, + { + withCredentials: true, + } + ) + .then(response => { + if (response.data.success) { + dispatch(authLogin()); + history.push('/home'); + } else { + toast({ + title: 'An error occurred', + description: response.data.message, + status: 'error', + duration: 5000, + isClosable: true, + }); + } + }) + .catch(e=>{ + if(e.response.status === 401){ + toast({ + title: 'Verification Error', + description: "You couldn't be verified. Please try scanning the verification QR Code again.", + status: 'error', + duration: 9000, + isClosable: true, + }); + } + }); + } + + return ( + + + + Create Account + +
+ + Name: + setName(e.target.value)} /> + + + Email: + setEmail(e.target.value)} /> + + + Phone Number: + setPhoneNumber(e.target.value)} /> + + + Organization: + setOrg(e.target.value)} /> + + + Password: + setPassword(e.target.value)} /> + + +
+
+
+ ) +} + +export default Create; \ No newline at end of file diff --git a/src/screens/HomeScreen.js b/src/screens/HomeScreen.js index cc94993..86c432f 100644 --- a/src/screens/HomeScreen.js +++ b/src/screens/HomeScreen.js @@ -1,54 +1,52 @@ -import { - Box, Flex, Image -} from '@chakra-ui/react'; +import { Box, Flex, Image } from '@chakra-ui/react'; import axios from 'axios'; import { React, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Redirect } from 'react-router-dom'; import { authLogout } from '../features/auth/authSlice'; -function QRCode(){ +function QRCode() { + const [url, setURL] = useState(null); + const dispatch = useDispatch(); - const [url, setURL] = useState(null); - const dispatch = useDispatch(); - - if(!url){ - axios.get(`${process.env.REACT_APP_API_URL}/code`,{withCredentials:true}) - .then(response =>{ - if(!response.data.error){ + if (!url) { + axios + .get(`${process.env.REACT_APP_API_URL}/code`, { withCredentials: true }) + .then(response => { + if (!response.data.error) { setURL(response.data.data); } }) - .catch((err)=>{ - if(err.response.status === 401){ + .catch(err => { + if (err.response.status === 401) { dispatch(authLogout()); } }); - - } - - if(url){ - return ( - - ) - }else{ - return ( - - ) - } } - - function Home() { - const isAuthenticated = useSelector((state) => state.auth.isAuthenticated); - if (!isAuthenticated) return - - return ( - - - - - - ); + + if (url) { + return ; + } else { + return ; } +} + +function Home() { + const isAuthenticated = useSelector(state => state.auth.isAuthenticated); + if (!isAuthenticated) return ; + + return ( + + + + + + ); +} - export default Home; \ No newline at end of file +export default Home; diff --git a/src/screens/LoginScreen.js b/src/screens/LoginScreen.js index 70802fe..35dcafa 100644 --- a/src/screens/LoginScreen.js +++ b/src/screens/LoginScreen.js @@ -1,89 +1,125 @@ import { - Button, Divider, Flex, FormControl, - FormLabel, Heading, Input, useToast + Button, + Divider, + Flex, + FormControl, + FormLabel, + Heading, + Input, + useToast, } from '@chakra-ui/react'; import axios from 'axios'; import { React, useState } from 'react'; -import { useDispatch } from 'react-redux'; -import { useHistory } from 'react-router-dom'; +import { useDispatch, useSelector } from 'react-redux'; +import { Redirect, useHistory } from 'react-router-dom'; import { authLogin } from '../features/auth/authSlice'; function Login() { - const [email, setEmail] = useState(null); - const [password, setPassword] = useState(null); - const toast = useToast(); - const history = useHistory(); - const dispatch = useDispatch(); - - const handleSubmit = (e) => { - - if(!email | !password){ - toast({ - title: "Invalid Login", - description: "Please fill in email and password", - status: "error", - duration: 9000, - isClosable: true, - }); - return; - } - - axios.post(`${process.env.REACT_APP_API_URL}/login`,{ - email: email, - password: password, - }, - { - withCredentials: true, - }) - .then(response =>{ - if(response.data.authorized){ + const [email, setEmail] = useState(null); + const [password, setPassword] = useState(null); + const toast = useToast(); + const history = useHistory(); + const dispatch = useDispatch(); + + const isAuthenticated = useSelector(state => state.auth.isAuthenticated); + if (isAuthenticated) return ; + + const handleSubmit = e => { + if (!email | !password) { + toast({ + title: 'Invalid Login', + description: 'Please fill in email and password', + status: 'error', + duration: 9000, + isClosable: true, + }); + return; + } + + axios + .post( + `${process.env.REACT_APP_API_URL}/login`, + { + email: email, + password: password, + }, + { + withCredentials: true, + } + ) + .then(response => { + if (response.data.authorized) { dispatch(authLogin()); - history.push("/home"); - - }else{ + history.push('/home'); + } else { toast({ - title: "An error occurred", + title: 'An error occurred', description: response.data.message, - status: "error", + status: 'error', duration: 9000, isClosable: true, }); } }) - .catch((err)=>{ + .catch(err => { toast({ - title: "An error occurred", - description: "Sorry, an error occurred on our side.", - status: "error", + title: 'An error occurred', + description: 'Sorry, an error occurred on our side.', + status: 'error', duration: 9000, isClosable: true, }); }); - - e.preventDefault(); - }; - - return ( - - - SSR Covid Tracing - Login -
- - Email address - setEmail(event.target.value)}/> - - - Password - setPassword(event.target.value)}/> - - -
- - -
+ + e.preventDefault(); + }; + + return ( + + + + SSR Covid Tracing + + + Login + +
+ + Email address + setEmail(event.target.value)} + /> + + + Password + setPassword(event.target.value)} + /> + + +
+ +
- ); - } +
+ ); +} - export default Login; \ No newline at end of file +export default Login; diff --git a/yarn.lock b/yarn.lock index 170fa4d..4830fb3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9601,6 +9601,11 @@ prepend-http@^1.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +prettier@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== + pretty-bytes@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"