Browse Source

added user creation

feature/qrscanner
Nareshkumar Rao 3 years ago
parent
commit
2349e24726
  1. 1
      .prettierrc.json
  2. 3
      package.json
  3. 14
      src/App.js
  4. 12
      src/app/store.js
  5. 26
      src/features/auth/authSlice.js
  6. 129
      src/screens/CreateScreen.js
  7. 74
      src/screens/HomeScreen.js
  8. 170
      src/screens/LoginScreen.js
  9. 5
      yarn.lock

1
.prettierrc.json

@ -0,0 +1 @@
{}

3
package.json

@ -42,5 +42,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"prettier": "2.3.2"
}
}

14
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() {
<Route path="/login">
<Login />
</Route>
<Route path="/validate">
<Route path="/create">
<Create />
</Route>
<Route path="/">
<Redirect to="/home" />

12
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,
},
})
reducer: {
auth: authSlice,
},
});

26
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;
export default authSlice.reducer;

129
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 (
<option value={name}>{name}</option>
)
});
return (
<Select placeholder={props.placeholder} onChange={props.onChange}>
{orgOptions}
</Select>
);
}
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 (
<Flex
height="100vh"
background="teal.100"
alignItems="center"
justifyContent="center"
>
<Flex direction="column" background="white" p={12} rounded={6}>
<Heading mb={6}>
Create Account
</Heading>
<form onSubmit={handleSubmit}>
<FormControl mb={6}>
<FormLabel>Name:</FormLabel>
<Input onChange={e => setName(e.target.value)} />
</FormControl>
<FormControl mb={6}>
<FormLabel >Email:</FormLabel>
<Input type="email" onChange={e => setEmail(e.target.value)} />
</FormControl>
<FormControl mb={6}>
<FormLabel>Phone Number:</FormLabel>
<Input onChange={e => setPhoneNumber(e.target.value)} />
</FormControl>
<FormControl mb={6}>
<FormLabel>Organization:</FormLabel>
<OrgSelect placeholder="Select Organization" onChange={e => setOrg(e.target.value)} />
</FormControl>
<FormControl mb={6}>
<FormLabel>Password:</FormLabel>
<Input type="password" onChange={e => setPassword(e.target.value)} />
</FormControl>
<Button type="submit">Create!</Button>
</form>
</Flex>
</Flex>
)
}
export default Create;

74
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 (
<Image src={url} />
)
}else{
return (
<Box />
)
}
}
function Home() {
const isAuthenticated = useSelector((state) => state.auth.isAuthenticated);
if (!isAuthenticated) return <Redirect to="/login" />
return (
<Flex height="100vh" background="teal.100" alignItems="center" justifyContent="center">
<Flex direction="column" background="white" p={12} rounded={6}>
<QRCode/>
</Flex>
</Flex>
);
if (url) {
return <Image src={url} />;
} else {
return <Box />;
}
}
function Home() {
const isAuthenticated = useSelector(state => state.auth.isAuthenticated);
if (!isAuthenticated) return <Redirect to="/login" />;
return (
<Flex
height="100vh"
background="teal.100"
alignItems="center"
justifyContent="center"
>
<Flex direction="column" background="white" p={12} rounded={6}>
<QRCode />
</Flex>
</Flex>
);
}
export default Home;
export default Home;

170
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 <Redirect to="/home" />;
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 (
<Flex height="100vh" background="teal.100" alignItems="center" justifyContent="center">
<Flex direction="column" background="white" p={12} rounded={6}>
<Heading size="xl" mb={6}>SSR Covid Tracing</Heading>
<Heading size="lg" mb={4}>Login</Heading>
<form onSubmit={handleSubmit}>
<FormControl mb={6}>
<FormLabel>Email address</FormLabel>
<Input type="email" colorScheme="teal" onChange={(event)=>setEmail(event.target.value)}/>
</FormControl>
<FormControl mb={6}>
<FormLabel>Password</FormLabel>
<Input type="password" colorScheme="teal" onChange={(event)=>setPassword(event.target.value)}/>
</FormControl>
<Button mb={6} type="submit">Login!</Button>
</form>
<Divider mb={6} />
<Button onClick={() => { history.push("/validate") }}>Get Validated!</Button>
</Flex>
e.preventDefault();
};
return (
<Flex
height="100vh"
background="teal.100"
alignItems="center"
justifyContent="center"
>
<Flex direction="column" background="white" p={12} rounded={6}>
<Heading size="xl" mb={6}>
SSR Covid Tracing
</Heading>
<Heading size="lg" mb={4}>
Login
</Heading>
<form onSubmit={handleSubmit}>
<FormControl mb={6}>
<FormLabel>Email address</FormLabel>
<Input
type="email"
colorScheme="teal"
onChange={event => setEmail(event.target.value)}
/>
</FormControl>
<FormControl mb={6}>
<FormLabel>Password</FormLabel>
<Input
type="password"
colorScheme="teal"
onChange={event => setPassword(event.target.value)}
/>
</FormControl>
<Button mb={6} type="submit">
Login!
</Button>
</form>
<Divider mb={6} />
<Button
onClick={() => {
history.push('/validate');
}}
>
Get Validated!
</Button>
</Flex>
);
}
</Flex>
);
}
export default Login;
export default Login;

5
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"

Loading…
Cancel
Save