frontend/pages/auth/login.tsx (view raw)
1import {useTranslation} from 'react-i18next';
2import Layout from '../../layouts/Centered';
3import {
4 Button,
5 Card,
6 CardContent,
7 CardMedia,
8 Container,
9 Stack,
10 TextField,
11 Typography,
12 FormHelperText,
13} from '@mui/material';
14import Logo from '../../components/Logo';
15import {getSession} from 'next-auth/react';
16import pageUtils from '../../lib/pageUtils';
17import Cookies from 'cookies';
18import {useState} from 'react';
19import LoginGoogle from '../../containers/LoginGoogle';
20import {useSendMagicLinkMutation} from '../../generated/graphql';
21
22interface Props {
23 error?: string;
24}
25
26const Login = (props: Props) => {
27 const {error} = props;
28 const {t, i18n} = useTranslation();
29 const [email, setEmail] = useState('');
30 const [sent, setSent] = useState(false);
31 const [sendMagicLink] = useSendMagicLinkMutation();
32
33 const handleSubmit = async (e: React.FormEvent<HTMLButtonElement>) => {
34 try {
35 if (email) await sendMagicLink({variables: {email, lang: i18n.language}});
36 setSent(true);
37 } catch (error) {
38 console.error(error);
39 }
40 };
41
42 return (
43 <Layout menuTitle={t('signin.title')} displayMenu={false}>
44 <Container maxWidth="xs">
45 <Card sx={{pt: 2, width: '100%'}}>
46 <CardMedia component={Logo} />
47
48 <CardContent>
49 <Stack spacing={2}>
50 <Typography variant="h6" align="center">
51 {t('signin.title')}
52 </Typography>
53 {error && (
54 <FormHelperText error sx={{textAlign: 'center'}}>
55 {t(errorsMap[error])}
56 </FormHelperText>
57 )}
58 {!sent && (
59 <>
60 <TextField
61 label={t`signin.email`}
62 fullWidth
63 required
64 value={email}
65 onChange={e => setEmail(e.target.value)}
66 type="email"
67 />
68 <Button
69 fullWidth
70 color="primary"
71 variant="contained"
72 disabled={!email}
73 onClick={handleSubmit}
74 >
75 {t('signin.login')}
76 </Button>
77 <Typography align="center">{t('signin.or')}</Typography>
78 <LoginGoogle />
79 </>
80 )}
81 {sent && (
82 <Typography
83 variant="body2"
84 align="center"
85 >{t`signin.check_email`}</Typography>
86 )}
87 </Stack>
88 </CardContent>
89 </Card>
90 </Container>
91 </Layout>
92 );
93};
94
95const errorsMap = {
96 CredentialsSignin: 'signin.errors.CredentialsSignin',
97};
98
99export const getServerSideProps = async (context: any) => {
100 const session = await getSession(context);
101
102 if (session)
103 return {
104 redirect: {
105 destination: '/',
106 permanent: false,
107 },
108 };
109 else
110 return pageUtils.getServerSideProps(async ctx => {
111 const error = ctx.query?.error || null;
112 const redirectPath = ctx.query?.redirectPath;
113
114 if (redirectPath) {
115 const cookies = new Cookies(ctx.req, ctx.res);
116 cookies.set('redirectPath', redirectPath);
117 }
118
119 return {props: {error}};
120 })(context);
121};
122
123export default Login;