Add initial desktop register screen
This commit is contained in:
parent
7ef0b98c8e
commit
5085c05623
6 changed files with 354 additions and 3 deletions
|
@ -2,6 +2,7 @@ import { Container } from '@mui/material';
|
|||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
|
||||
import Login from '../screens/Login';
|
||||
import Register from '../screens/Register';
|
||||
import UnauthenticatedHome from '../screens/UnauthenticatedHome';
|
||||
|
||||
function UnauthenticatedApp() {
|
||||
|
@ -10,6 +11,7 @@ function UnauthenticatedApp() {
|
|||
<Routes>
|
||||
<Route path="/" element={<UnauthenticatedHome />} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/register" element={<Register />} />
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Routes>
|
||||
</Container>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { getUser } from '../services/user-service';
|
||||
import { getUser, registerUser } from '../services/user-service';
|
||||
|
||||
const AuthContext = createContext();
|
||||
|
||||
|
@ -20,6 +20,20 @@ function AuthProvider(props) {
|
|||
bootstrapUser();
|
||||
}, []);
|
||||
|
||||
const register = data => {
|
||||
setState({ ...state, status: 'pending' });
|
||||
let shouldFail =
|
||||
data.email !== 'leo@gmail.com' && data.password !== '#leo1234';
|
||||
|
||||
return registerUser(data, shouldFail).then(data => {
|
||||
if (shouldFail) {
|
||||
return setState({ status: 'error', user: null, error: data });
|
||||
} else {
|
||||
return setState({ status: 'success', user: data, error: null });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const login = (email, password) => {
|
||||
setState({ ...state, status: 'pending' });
|
||||
let shouldFail = email !== 'leo@gmail.com' && password !== '#leo1234';
|
||||
|
@ -38,11 +52,16 @@ function AuthProvider(props) {
|
|||
window.localStorage.clear();
|
||||
};
|
||||
|
||||
return <AuthContext.Provider value={{ state, login, logout }} {...props} />;
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{ state, register, login, logout }}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function useAuthState() {
|
||||
const { state, login, logout } = useContext(AuthContext);
|
||||
const { state, register, login, logout } = useContext(AuthContext);
|
||||
const isPending = state.status === 'pending';
|
||||
const isError = state.status === 'error';
|
||||
const isSuccess = state.status === 'success';
|
||||
|
@ -55,6 +74,7 @@ function useAuthState() {
|
|||
isError,
|
||||
isSuccess,
|
||||
isAuthenticated,
|
||||
register,
|
||||
login,
|
||||
logout,
|
||||
};
|
||||
|
|
179
src/screens/Register/View.js
Normal file
179
src/screens/Register/View.js
Normal file
|
@ -0,0 +1,179 @@
|
|||
import { Fragment } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Container,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
Link,
|
||||
MenuItem,
|
||||
Paper,
|
||||
Select,
|
||||
Stack,
|
||||
TextField,
|
||||
} from '@mui/material';
|
||||
|
||||
import SnackbarIndicator from '../../components/SnackbarIndicator';
|
||||
import LoadingIndicator from '../../components/LoadingIndicator';
|
||||
|
||||
import logoImage from '../../assets/if-salas-logo.svg';
|
||||
|
||||
import styles from './styles';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
function View({
|
||||
isPending,
|
||||
isError,
|
||||
error,
|
||||
layoutType,
|
||||
data,
|
||||
onChangeInput,
|
||||
onTryRegister,
|
||||
}) {
|
||||
const { paper, boxLogo, boxForm, logoContainer } = styles[layoutType];
|
||||
const currentYear = dayjs().year();
|
||||
console.log(currentYear);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Paper sx={paper} elevation={4} variant="elevation">
|
||||
<Box sx={boxForm}>
|
||||
<h1>Criar conta</h1>
|
||||
<p>Crie sua conta digitando os dados abaixo.</p>
|
||||
<Stack spacing={4} component="form">
|
||||
<TextField
|
||||
id="firstName"
|
||||
name="firstName"
|
||||
label="Primeiro nome"
|
||||
variant="standard"
|
||||
type="text"
|
||||
value={data.firstName}
|
||||
onChange={onChangeInput}
|
||||
autoFocus
|
||||
/>
|
||||
<TextField
|
||||
id="lastName"
|
||||
name="lastName"
|
||||
label="Sobrenome"
|
||||
variant="standard"
|
||||
type="text"
|
||||
value={data.lastName}
|
||||
onChange={onChangeInput}
|
||||
/>
|
||||
<TextField
|
||||
id="ra"
|
||||
name="ra"
|
||||
label="RA (Registro Acadêmico)"
|
||||
variant="standard"
|
||||
type="text"
|
||||
value={data.ra}
|
||||
onChange={onChangeInput}
|
||||
/>
|
||||
<FormControl sx={{ textAlign: 'start' }} fullWidth>
|
||||
<InputLabel variant="standard" id="course">
|
||||
Curso
|
||||
</InputLabel>
|
||||
<Select
|
||||
variant="standard"
|
||||
labelId="course"
|
||||
id="course"
|
||||
name="course"
|
||||
value={data.course}
|
||||
label="Curso"
|
||||
onChange={onChangeInput}
|
||||
>
|
||||
<MenuItem value={0}>
|
||||
Bacharelado em Sistemas de Informação
|
||||
</MenuItem>
|
||||
<MenuItem value={1}>
|
||||
Tecnologia em Processos Gerenciais
|
||||
</MenuItem>
|
||||
<MenuItem value={2}>Tecnologia em Logística</MenuItem>
|
||||
<MenuItem value={3}>
|
||||
Engenharia de Controle e Automação
|
||||
</MenuItem>
|
||||
<MenuItem value={4}>Bacharelado em Administração</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl sx={{ textAlign: 'start' }} fullWidth>
|
||||
<InputLabel variant="standard" id="course">
|
||||
Ano da turma
|
||||
</InputLabel>
|
||||
<Select
|
||||
variant="standard"
|
||||
labelId="year"
|
||||
id="year"
|
||||
name="year"
|
||||
value={data.year}
|
||||
label="Ano da turma"
|
||||
onChange={onChangeInput}
|
||||
>
|
||||
<MenuItem value={0}>{currentYear}</MenuItem>
|
||||
<MenuItem value={1}>{currentYear - 1}</MenuItem>
|
||||
<MenuItem value={2}>{currentYear - 2}</MenuItem>
|
||||
<MenuItem value={3}>{currentYear - 3}</MenuItem>
|
||||
<MenuItem value={4}>{currentYear - 4}</MenuItem>
|
||||
<MenuItem value={5}>{currentYear - 5}</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
{/* TODO: Add field mask */}
|
||||
<TextField
|
||||
id="phone"
|
||||
name="phone"
|
||||
label="Telefone"
|
||||
variant="standard"
|
||||
type="phone"
|
||||
value={data.phone}
|
||||
onChange={onChangeInput}
|
||||
/>
|
||||
<TextField
|
||||
id="email"
|
||||
name="email"
|
||||
label="E-mail"
|
||||
variant="standard"
|
||||
type="email"
|
||||
value={data.email}
|
||||
onChange={onChangeInput}
|
||||
/>
|
||||
<TextField
|
||||
id="password"
|
||||
name="password"
|
||||
label="Senha"
|
||||
variant="standard"
|
||||
type="password"
|
||||
value={data.password}
|
||||
onChange={onChangeInput}
|
||||
/>
|
||||
<Button
|
||||
// disabled={!isSubmitable}
|
||||
onClick={onTryRegister}
|
||||
variant="contained"
|
||||
>
|
||||
Entrar
|
||||
</Button>
|
||||
<Link href="#">Esqueci minha senha</Link>
|
||||
<Link href="#">Cadastre-se</Link>
|
||||
</Stack>
|
||||
</Box>
|
||||
<Box sx={boxLogo}>
|
||||
<Container sx={logoContainer}>
|
||||
<img
|
||||
src={logoImage}
|
||||
width={layoutType === 'desktop' ? '130' : '70'}
|
||||
alt="Logotipo"
|
||||
/>
|
||||
<p>A plataforma de ensino de código aberto.</p>
|
||||
</Container>
|
||||
</Box>
|
||||
</Paper>
|
||||
<LoadingIndicator isLoading={isPending} />
|
||||
<SnackbarIndicator
|
||||
isOpen={isError}
|
||||
severity="error"
|
||||
message={error && error.message}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default View;
|
49
src/screens/Register/index.js
Normal file
49
src/screens/Register/index.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { Button } from '@mui/material';
|
||||
import { useState } from 'react';
|
||||
import { useAuthState } from '../../context/auth';
|
||||
import { useDocumentTitle } from '../../hooks/useDocumentTitle';
|
||||
import useLayoutType from '../../hooks/useLayoutType';
|
||||
|
||||
import View from './View';
|
||||
|
||||
function Register() {
|
||||
useDocumentTitle('Entrar');
|
||||
const { register, isPending, isError, error } = useAuthState();
|
||||
const layoutType = useLayoutType();
|
||||
const [data, setData] = useState({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
ra: '',
|
||||
course: 0,
|
||||
year: 0,
|
||||
phone: '',
|
||||
email: '',
|
||||
password: '',
|
||||
termsAgreed: false,
|
||||
});
|
||||
|
||||
const onTryRegister = () => {
|
||||
register(data);
|
||||
};
|
||||
|
||||
const onChangeInput = e => {
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
setData(prev => ({ ...prev, [name]: value }));
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
isPending={isPending}
|
||||
isError={isError}
|
||||
error={error}
|
||||
layoutType={layoutType}
|
||||
data={data}
|
||||
onChangeInput={onChangeInput}
|
||||
onTryRegister={onTryRegister}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default Register;
|
89
src/screens/Register/styles.js
Normal file
89
src/screens/Register/styles.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
// ========== Desktop ==========
|
||||
const desktopPaper = {
|
||||
width: '1500px',
|
||||
height: '70%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
color: 'white',
|
||||
textAlign: 'center',
|
||||
};
|
||||
|
||||
const baseBox = {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
padding: '0 70px',
|
||||
};
|
||||
|
||||
const desktopBoxLogo = {
|
||||
...baseBox,
|
||||
backgroundColor: 'secondary.main',
|
||||
};
|
||||
|
||||
const desktopBoxForm = {
|
||||
...baseBox,
|
||||
'> h1, p ': {
|
||||
textAlign: 'initial',
|
||||
},
|
||||
'> h1': {
|
||||
color: 'primary.black',
|
||||
margin: 0,
|
||||
},
|
||||
'> p': {
|
||||
color: 'primary.lightGray',
|
||||
},
|
||||
};
|
||||
|
||||
const logoContainerDesktop = {};
|
||||
|
||||
const desktop = {
|
||||
paper: desktopPaper,
|
||||
boxLogo: desktopBoxLogo,
|
||||
boxForm: desktopBoxForm,
|
||||
logoContainer: logoContainerDesktop,
|
||||
};
|
||||
|
||||
// ========== Mobile ==========
|
||||
const mobilePaper = {
|
||||
...desktopPaper,
|
||||
flexDirection: 'column',
|
||||
height: '700px',
|
||||
marginLeft: '10px',
|
||||
marginRight: '10px',
|
||||
};
|
||||
|
||||
const mobileBoxLogo = {
|
||||
...desktopBoxLogo,
|
||||
height: '50%',
|
||||
padding: '0',
|
||||
};
|
||||
|
||||
const mobileBoxForm = {
|
||||
...desktopBoxForm,
|
||||
padding: '0 15px',
|
||||
width: 'fit-content',
|
||||
};
|
||||
|
||||
const logoContainerMobile = {
|
||||
padding: '20px 16px',
|
||||
};
|
||||
|
||||
const mobile = {
|
||||
paper: mobilePaper,
|
||||
boxLogo: mobileBoxLogo,
|
||||
boxForm: mobileBoxForm,
|
||||
logoContainer: logoContainerMobile,
|
||||
};
|
||||
|
||||
// ========== Unset ==========
|
||||
const unset = {
|
||||
paper: null,
|
||||
boxLogo: null,
|
||||
boxForm: null,
|
||||
logoContainer: null,
|
||||
};
|
||||
|
||||
const styles = { desktop, mobile, unset };
|
||||
export default styles;
|
|
@ -86,6 +86,17 @@ const getUser = shouldFail =>
|
|||
}
|
||||
});
|
||||
|
||||
const registerUser = (data, shouldFail) =>
|
||||
sleep(3000).then(() => {
|
||||
if (shouldFail) {
|
||||
return authFailure;
|
||||
} else {
|
||||
console.log(data);
|
||||
window.localStorage.setItem('$USER', JSON.stringify(data));
|
||||
return data;
|
||||
}
|
||||
});
|
||||
|
||||
export {
|
||||
getClassrooms,
|
||||
getClassroomById,
|
||||
|
@ -96,4 +107,5 @@ export {
|
|||
getPeopleByClassId,
|
||||
getFaq,
|
||||
getUser,
|
||||
registerUser,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue