frontend/containers/SignInForm/index.tsx (view raw)
1import {useState, useMemo} from 'react';
2import NextLink from 'next/link';
3import {makeStyles} from '@material-ui/core/styles';
4import TextField from '@material-ui/core/TextField';
5import Button from '@material-ui/core/Button';
6import Link from '@material-ui/core/Link';
7import Typography from '@material-ui/core/Typography';
8import CardContent from '@material-ui/core/CardContent';
9import FormHelperText from '@material-ui/core/FormHelperText';
10import CardActions from '@material-ui/core/CardActions';
11import {useTranslation} from 'react-i18next';
12import {signIn} from 'next-auth/react';
13import useAddToEvents from '../../hooks/useAddToEvents';
14import useRedirectUrlStore from '../../stores/useRedirectUrl';
15
16interface Props {
17 error?: string;
18}
19
20const SignIn = (props: Props) => {
21 const {error} = props;
22 const {t} = useTranslation();
23 const [email, setEmail] = useState('');
24 const [password, setPassword] = useState('');
25 const {saveStoredEvents} = useAddToEvents();
26 const classes = useStyles();
27 const getRedirectUrl = useRedirectUrlStore(s => s.getRedirectUrl);
28
29 const canSubmit = useMemo(
30 () => [email, password].filter(s => s.length < 4).length === 0,
31 [email, password]
32 );
33
34 const onSubmit = async e => {
35 e.preventDefault?.();
36 try {
37 const callbackUrl = getRedirectUrl() || '/';
38 await signIn('credentials', {
39 email,
40 password,
41 callbackUrl,
42 });
43 saveStoredEvents(); // TODO Check it's correctly executed after sign-in
44 } catch (error) {
45 console.error(error);
46 }
47
48 return false;
49 };
50
51 return (
52 <form onSubmit={onSubmit}>
53 <CardContent className={classes.content}>
54 <Typography variant="h6">{t('signin.title')}</Typography>
55 {error && (
56 <FormHelperText error={true}>
57 {t(`signin.errors.${error}`)}
58 </FormHelperText>
59 )}
60 <TextField
61 label={t('signin.email')}
62 fullWidth
63 required={true}
64 margin="dense"
65 value={email}
66 onChange={({target: {value = ''}}) => setEmail(value)}
67 id="SignInEmail"
68 name="email"
69 type="email"
70 error={!!error}
71 />
72 <TextField
73 label={t('signin.password')}
74 fullWidth
75 required={true}
76 margin="dense"
77 value={password}
78 onChange={({target: {value = ''}}) => setPassword(value)}
79 id="SignInEmail"
80 name="password"
81 type="password"
82 error={!!error}
83 />
84 <NextLink href="/auth/lost-password" passHref>
85 <Link>
86 <Typography align="center" variant="body2">
87 {t('lost_password.message')}
88 </Typography>
89 </Link>
90 </NextLink>
91 </CardContent>
92 <CardActions className={classes.actions} align="center">
93 <NextLink href="/auth/register" passHref>
94 <Button size="small" id="SignInRegister">
95 {t('signin.register')}
96 </Button>
97 </NextLink>
98
99 <Button
100 color="primary"
101 variant="contained"
102 type="submit"
103 disabled={!canSubmit}
104 aria-disabled={!canSubmit}
105 id="SignInSubmit"
106 >
107 {t('signin.login')}
108 </Button>
109 </CardActions>
110 </form>
111 );
112};
113
114const useStyles = makeStyles(theme => ({
115 content: {
116 display: 'flex',
117 flexDirection: 'column',
118 },
119 actions: {
120 justifyContent: 'center',
121 marginBottom: theme.spacing(2),
122 },
123}));
124export default SignIn;