Refactor Login and add responsive layout

This commit is contained in:
Leonardo Murça 2022-06-01 13:13:15 -03:00
parent d9bb329cf7
commit c1bde64266
6 changed files with 212 additions and 122 deletions

View file

@ -0,0 +1,17 @@
import { useMediaQuery } from '@mui/material';
import { useEffect, useState } from 'react';
export default function useLayoutType() {
const [layoutType, setLayoutType] = useState('desktop');
const isMediaQueryRuleActive = useMediaQuery('(max-width:800px)');
useEffect(() => {
if (isMediaQueryRuleActive) {
setLayoutType('mobile');
} else {
setLayoutType('desktop');
}
}, [isMediaQueryRuleActive]);
return layoutType;
}

View file

@ -3,6 +3,7 @@ body {
font-family: 'Fira Code', monospace; font-family: 'Fira Code', monospace;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
height: 100vh;
} }
code { code {

View file

@ -1,122 +0,0 @@
import { Fragment, useState } from 'react';
import {
Box,
Button,
Container,
Link,
Paper,
Stack,
TextField,
} from '@mui/material';
import { useAuthState } from '../context/auth';
import LoadingIndicator from '../components/LoadingIndicator';
import SnackbarIndicator from '../components/SnackbarIndicator';
import logoImage from '../assets/if-salas-logo.svg';
function Login() {
const { login, isPending, isError, error } = useAuthState();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const isSubmitable = email.length !== 0 && password.length !== 0;
const onTryLogin = () => {
isSubmitable && login(email, password);
};
return (
<Fragment>
<Paper sx={paper} elevation={4} variant="elevation">
<Box sx={boxLogo}>
<Container>
<img src={logoImage} width="100" alt="Logotipo" />
<p>A plataforma de ensino de código aberto.</p>
</Container>
</Box>
<Box sx={boxForm}>
<h1>Login</h1>
<p>Bem-vindo de volta. Faça o login digitando os dados abaixo.</p>
<Stack spacing={4} sx={stack} component="form">
<TextField
id="email"
label="E-mail"
variant="standard"
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<TextField
id="password"
label="Senha"
variant="standard"
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
<Button
disabled={!isSubmitable}
onClick={onTryLogin}
variant="contained"
>
Entrar
</Button>
<Link href="#">Esqueci minha senha</Link>
<Link href="#">Cadastre-se</Link>
</Stack>
</Box>
</Paper>
<LoadingIndicator isLoading={isPending} />
<SnackbarIndicator
isOpen={isError}
severity="error"
message={error && error.message}
/>
</Fragment>
);
}
const paper = {
width: '950px',
height: '500px',
display: 'flex',
justifyContent: 'center',
color: 'white',
textAlign: 'center',
};
const baseBox = {
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
};
const boxLogo = {
...baseBox,
backgroundColor: 'secondary.main',
};
const boxForm = {
...baseBox,
'> h1, p ': {
paddingLeft: '70px',
paddingRight: '70px',
textAlign: 'initial',
},
'> h1': {
color: 'primary.black',
margin: 0,
},
'> p': {
color: 'primary.lightGray',
},
};
const stack = {
padding: '0 70px',
};
export default Login;

88
src/screens/Login/View.js Normal file
View file

@ -0,0 +1,88 @@
import { Fragment } from 'react';
import {
Box,
Button,
Container,
Link,
Paper,
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';
function View({
email,
password,
onChangeEmail,
onChangePassword,
isSubmitable,
onTryLogin,
isPending,
isError,
error,
layoutType,
}) {
const { paper, boxLogo, boxForm } = styles[layoutType];
return (
<Fragment>
<Paper sx={paper} elevation={4} variant="elevation">
<Box sx={boxLogo}>
<Container>
<img
src={logoImage}
width={layoutType === 'desktop' ? '100' : '70'}
alt="Logotipo"
/>
<p>A plataforma de ensino de código aberto.</p>
</Container>
</Box>
<Box sx={boxForm}>
<h1>Login</h1>
<p>Bem-vindo de volta. Faça o login digitando os dados abaixo.</p>
<Stack spacing={4} component="form">
<TextField
id="email"
label="E-mail"
variant="standard"
type="email"
value={email}
onChange={e => onChangeEmail(e.target.value)}
/>
<TextField
id="password"
label="Senha"
variant="standard"
type="password"
value={password}
onChange={e => onChangePassword(e.target.value)}
/>
<Button
disabled={!isSubmitable}
onClick={onTryLogin}
variant="contained"
>
Entrar
</Button>
<Link href="#">Esqueci minha senha</Link>
<Link href="#">Cadastre-se</Link>
</Stack>
</Box>
</Paper>
<LoadingIndicator isLoading={isPending} />
<SnackbarIndicator
isOpen={isError}
severity="error"
message={error && error.message}
/>
</Fragment>
);
}
export default View;

View file

@ -0,0 +1,35 @@
import { useState } from 'react';
import { useAuthState } from '../../context/auth';
import useLayoutType from '../../hooks/useLayoutType';
import View from './View';
function Login() {
const { login, isPending, isError, error } = useAuthState();
const layoutType = useLayoutType();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const isSubmitable = email.length !== 0 && password.length !== 0;
const onTryLogin = () => {
isSubmitable && login(email, password);
};
return (
<View
email={email}
password={password}
onChangeEmail={setEmail}
onChangePassword={setPassword}
isSubmitable={isSubmitable}
onTryLogin={onTryLogin}
isPending={isPending}
isError={isError}
error={error}
layoutType={layoutType}
/>
);
}
export default Login;

View file

@ -0,0 +1,71 @@
const desktopPaper = {
width: '950px',
height: '500px',
display: 'flex',
justifyContent: 'center',
color: 'white',
textAlign: 'center',
};
const mobilePaper = {
...desktopPaper,
flexDirection: 'column',
height: '700px',
marginLeft: '10px',
marginRight: '10px',
};
const baseBox = {
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
padding: '0 70px',
};
const desktopBoxLogo = {
...baseBox,
backgroundColor: 'secondary.main',
};
const mobileBoxLogo = {
...desktopBoxLogo,
height: '45%',
padding: '0',
};
const desktopBoxForm = {
...baseBox,
'> h1, p ': {
textAlign: 'initial',
},
'> h1': {
color: 'primary.black',
margin: 0,
},
'> p': {
color: 'primary.lightGray',
},
};
const mobileBoxForm = {
...desktopBoxForm,
padding: '0 15px',
width: 'fit-content',
};
const desktop = {
paper: desktopPaper,
boxLogo: desktopBoxLogo,
boxForm: desktopBoxForm,
};
const mobile = {
paper: mobilePaper,
boxLogo: mobileBoxLogo,
boxForm: mobileBoxForm,
};
const styles = { desktop, mobile };
export default styles;