all repos — caroster @ c6e862fa2d016fcdef877fadafe6bd11e8e872f7

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