frontend/containers/SignInForm/index.tsx (view raw)
1import {useState, useMemo} from 'react';
2import NextLink from 'next/link';
3import TextField from '@mui/material/TextField';
4import Button from '@mui/material/Button';
5import Typography from '@mui/material/Typography';
6import CardContent from '@mui/material/CardContent';
7import FormHelperText from '@mui/material/FormHelperText';
8import CardActions from '@mui/material/CardActions';
9import Divider from '@mui/material/Divider';
10import Box from '@mui/material/Box';
11import {useTheme} from '@mui/material/styles';
12import {useTranslation} from 'next-i18next';
13import {signIn} from 'next-auth/react';
14import useAddToEvents from '../../hooks/useAddToEvents';
15import LoginGoogle from '../LoginGoogle';
16import {useRouter} from 'next/router';
17
18interface Props {
19 error?: string;
20}
21
22const errorsMap = {
23 CredentialsSignin: 'signin.errors.CredentialsSignin',
24 EmailNotConfirmed: 'signin.errors.EmailNotConfirmed',
25};
26
27const SignIn = (props: Props) => {
28 const {error} = props;
29 const {t} = useTranslation();
30 const router = useRouter();
31
32 const theme = useTheme();
33 const [email, setEmail] = useState('');
34 const [password, setPassword] = useState('');
35 const {saveStoredEvents} = useAddToEvents();
36
37 const canSubmit = useMemo(
38 () => [email, password].filter(s => s.length < 4).length === 0,
39 [email, password]
40 );
41
42 const onSubmit = async e => {
43 e.preventDefault?.();
44 try {
45 await signIn('credentials', {
46 email,
47 password,
48 callbackUrl: (router.query?.redirectPath as string) || '/dashboard',
49 });
50 saveStoredEvents();
51 } catch (error) {
52 console.error(error);
53 }
54
55 return false;
56 };
57
58 const spaceAround = {
59 width: '100%',
60 textAlign: 'center',
61 margin: theme.spacing(2, 0),
62 };
63
64 return (
65 <form onSubmit={onSubmit}>
66 <CardContent
67 sx={{
68 display: 'flex',
69 flexDirection: 'column',
70 px: 2,
71 }}
72 >
73 <Typography variant="h6" align="center">
74 {t('signin.title')}
75 </Typography>
76 {error && (
77 <FormHelperText error sx={{textAlign: 'center'}}>
78 {t(errorsMap[error])}
79 </FormHelperText>
80 )}
81 <Box
82 sx={{
83 display: 'flex',
84 flexDirection: 'column',
85 }}
86 >
87 <TextField
88 label={t('signin.email')}
89 fullWidth
90 required={true}
91 InputLabelProps={{required: false}}
92 margin="dense"
93 value={email}
94 onChange={({target: {value = ''}}) => setEmail(value)}
95 name="email"
96 type="email"
97 error={!!error}
98 />
99 <TextField
100 label={t('signin.password')}
101 fullWidth
102 InputLabelProps={{required: false}}
103 required={true}
104 margin="dense"
105 value={password}
106 onChange={({target: {value = ''}}) => setPassword(value)}
107 id="SignInEmail"
108 name="password"
109 type="password"
110 error={!!error}
111 />
112 </Box>
113
114 <Box sx={spaceAround}>
115 <NextLink href="/auth/lost-password" passHref>
116 <Typography
117 align="center"
118 variant="body2"
119 color="primary"
120 sx={{
121 textDecoration: 'underline',
122 textDecorationColor: 'primary',
123 }}
124 >
125 {t('lost_password.message')}
126 </Typography>
127 </NextLink>
128 </Box>
129 <Box
130 sx={{
131 display: 'flex',
132 flexDirection: 'column',
133 alignItems: 'center',
134 width: '100%',
135 pb: 1,
136 }}
137 >
138 <Button
139 color="primary"
140 variant="contained"
141 fullWidth
142 type="submit"
143 disabled={!canSubmit}
144 aria-disabled={!canSubmit}
145 >
146 {t('signin.login')}
147 </Button>
148 <Box sx={spaceAround}>
149 <Typography>{t('signin.or')}</Typography>
150 </Box>
151 <LoginGoogle />
152 </Box>
153 </CardContent>
154 <Divider />
155 <CardActions
156 sx={{
157 flexDirection: 'column',
158 justifyContent: 'center',
159 marginBottom: theme.spacing(2),
160 textAlign: 'center',
161 px: 2,
162 }}
163 >
164 <Typography align="center" variant="body2" sx={{pt: 2}}>
165 {t('signin.no_account')}
166 </Typography>
167 <NextLink href="/auth/register" passHref>
168 <Button size="small">{t('signin.register')}</Button>
169 </NextLink>
170 </CardActions>
171 </form>
172 );
173};
174
175export default SignIn;