all repos — caroster @ 5ea9dc4f820e432a35dda517e5a4bcb3e2c7a712

[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';
 15import LoginGoogle from '../LoginGoogle';
 16import Divider from '@material-ui/core/Divider';
 17import Box from '@material-ui/core/Box';
 18
 19interface Props {
 20  error?: string;
 21}
 22
 23const SignIn = (props: Props) => {
 24  const {error} = props;
 25  const {t} = useTranslation();
 26  const [email, setEmail] = useState('');
 27  const [password, setPassword] = useState('');
 28  const {saveStoredEvents} = useAddToEvents();
 29  const classes = useStyles();
 30
 31  const canSubmit = useMemo(
 32    () => [email, password].filter(s => s.length < 4).length === 0,
 33    [email, password]
 34  );
 35
 36  const onSubmit = async e => {
 37    e.preventDefault?.();
 38    try {
 39      await signIn('credentials', {
 40        email,
 41        password,
 42        callbackUrl: '/',
 43      });
 44      saveStoredEvents(); // TODO Check it's correctly executed after sign-in
 45    } catch (error) {
 46      console.error(error);
 47    }
 48
 49    return false;
 50  };
 51
 52  return (
 53    <form onSubmit={onSubmit}>
 54      <CardContent className={classes.content}>
 55        <Typography variant="h6" align="center">
 56          {t('signin.title')}
 57        </Typography>
 58        {error && (
 59          <FormHelperText error={true}>
 60            {t(`signin.errors.${error}`)}
 61          </FormHelperText>
 62        )}
 63        <Box className={classes.content}>
 64          <TextField
 65            label={t('signin.email')}
 66            fullWidth
 67            required={true}
 68            margin="dense"
 69            value={email}
 70            onChange={({target: {value = ''}}) => setEmail(value)}
 71            id="SignInEmail"
 72            name="email"
 73            type="email"
 74            error={!!error}
 75          />
 76          <TextField
 77            label={t('signin.password')}
 78            fullWidth
 79            required={true}
 80            margin="dense"
 81            value={password}
 82            onChange={({target: {value = ''}}) => setPassword(value)}
 83            id="SignInEmail"
 84            name="password"
 85            type="password"
 86            error={!!error}
 87          />
 88        </Box>
 89
 90        <Box className={classes.divider}>
 91          <NextLink href="/auth/lost-password" passHref>
 92            <Link>
 93              <Typography align="center" variant="body2">
 94                {t('lost_password.message')}
 95              </Typography>
 96            </Link>
 97          </NextLink>
 98        </Box>
 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        <Box className={classes.divider}>
110          <Typography>{t('signin.or')}</Typography>
111        </Box>
112        <LoginGoogle />
113        <Box className={classes.divider}>
114          <Divider />
115        </Box>
116        <Typography align="center" variant="body2">
117          {t('signin.no_account')}
118        </Typography>
119      </CardContent>
120      <CardActions className={classes.actions} align="center">
121        <NextLink href="/auth/register" passHref>
122          <Button size="small" id="SignInRegister">
123            {t('signin.register')}
124          </Button>
125        </NextLink>
126      </CardActions>
127    </form>
128  );
129};
130
131const useStyles = makeStyles(theme => ({
132  content: {
133    display: 'flex',
134    flexDirection: 'column',
135    padding: theme.spacing(0, 6),
136  },
137  actions: {
138    justifyContent: 'center',
139    marginBottom: theme.spacing(2),
140  },
141  divider: {
142    width: '100%',
143    textAlign: 'center',
144    margin: theme.spacing(2, 0),
145  },
146}));
147export default SignIn;