all repos — caroster @ e5ab2b72830ceac154edfa35c7106a508edebebc

[Octree] Group carpool to your event https://caroster.io

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;