all repos — caroster @ 3305d6f0b36993b4459c0e235b35274a1dda4b51

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

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;