all repos — caroster @ 9ce866648000343d9681be1a31185970c359b52d

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

frontend/containers/SignUpForm/index.js (view raw)

  1import {useState, useMemo} from 'react';
  2import {useTranslation} from 'react-i18next';
  3import TextField from '@material-ui/core/TextField';
  4import {useRouter} from 'next/router';
  5import Button from '@material-ui/core/Button';
  6import CardContent from '@material-ui/core/CardContent';
  7import CardActions from '@material-ui/core/CardActions';
  8import Typography from '@material-ui/core/Typography';
  9import CircularProgress from '@material-ui/core/CircularProgress';
 10import {makeStyles} from '@material-ui/core/styles';
 11import useToastsStore from '../../stores/useToastStore';
 12import {useRegisterMutation} from '../../generated/graphql';
 13import useAuthStore from '../../stores/useAuthStore';
 14
 15const SignUp = () => {
 16  const {t} = useTranslation();
 17  const classes = useStyles();
 18  const addToast = useToastsStore(s => s.addToast);
 19  const router = useRouter();
 20  const setToken = useAuthStore(s => s.setToken);
 21  const setUser = useAuthStore(s => s.setUser);
 22  const [isLoading, setIsLoading] = useState(false);
 23  const [error, setError] = useState('');
 24  const [firstName, setFirstName] = useState('');
 25  const [lastName, setLastName] = useState('');
 26  const [email, setEmail] = useState('');
 27  const [password, setPassword] = useState('');
 28  const [register] = useRegisterMutation();
 29
 30  const canSubmit = useMemo(
 31    () =>
 32      [firstName, lastName, email, password].filter(s => s.length < 2)
 33        .length === 0,
 34    [firstName, lastName, email, password]
 35  );
 36
 37  const onSubmit = async e => {
 38    e.preventDefault?.();
 39    if (isLoading) return;
 40    setIsLoading(true);
 41    try {
 42      const {data} = await register({
 43        variables: {
 44          email,
 45          password,
 46          username: `${firstName} ${lastName}`,
 47        },
 48      });
 49      setToken(data.register.jwt);
 50      setUser(data.register.user);
 51      router.push('/dashboard');
 52    } catch (error) {
 53      const strapiError = getStrapiError(error);
 54      console.error({strapiError});
 55      if (strapiError === 'Auth.form.error.email.taken')
 56        setError(t('signup.errors.email_taken'));
 57      else addToast(t(`generic.errors.unknown`));
 58    }
 59    setIsLoading(false);
 60    return false;
 61  };
 62
 63  return (
 64    <form onSubmit={onSubmit}>
 65      <CardContent className={classes.content}>
 66        <Typography variant="h6">{t('signup.title')}</Typography>
 67        <TextField
 68          label={t('signup.firstName')}
 69          fullWidth
 70          autoFocus
 71          margin="dense"
 72          value={firstName}
 73          required={true}
 74          onChange={({target: {value = ''}}) => setFirstName(value)}
 75          id="SignUpFirstName"
 76          name="firstName"
 77        />
 78        <TextField
 79          label={t('signup.lastName')}
 80          fullWidth
 81          required={true}
 82          margin="dense"
 83          value={lastName}
 84          onChange={({target: {value = ''}}) => setLastName(value)}
 85          id="SignUpLastName"
 86          name="lastName"
 87        />
 88        <TextField
 89          label={t('signup.email')}
 90          fullWidth
 91          required={true}
 92          error={!!error}
 93          helperText={error}
 94          margin="dense"
 95          value={email}
 96          onChange={({target: {value = ''}}) => setEmail(value)}
 97          id="SignUpEmail"
 98          name="email"
 99          type="email"
100        />
101        <TextField
102          label={t('signup.password')}
103          fullWidth
104          gutterBottom
105          required={true}
106          margin="dense"
107          value={password}
108          onChange={({target: {value = ''}}) => setPassword(value)}
109          id="SignUpEmail"
110          name="password"
111          type="password"
112        />
113      </CardContent>
114      <CardActions className={classes.actions}>
115        <Button id="SignUpLogin" href="/auth/login" variant="text">
116          {t('signup.login')}
117        </Button>
118        <Button
119          color="primary"
120          variant="contained"
121          type="submit"
122          disabled={!canSubmit}
123          className={classes.button}
124          aria-disabled={!canSubmit}
125          id="SignUpSubmit"
126          iconEnd={
127            isLoading && (
128              <CircularProgress
129                class={classes.loader}
130                size={20}
131                color="secondary"
132              />
133            )
134          }
135        >
136          {t('signup.submit')}
137        </Button>
138      </CardActions>
139    </form>
140  );
141};
142
143const getStrapiError = error =>
144  error?.graphQLErrors?.[0].extensions.exception.data.message[0].messages[0].id;
145
146const useStyles = makeStyles(theme => ({
147  content: {
148    display: 'flex',
149    flexDirection: 'column',
150    alignItems: 'center',
151  },
152  loader: {
153    marginLeft: '14px',
154    color: theme.palette.background.paper,
155  },
156  actions: {
157    justifyContent: 'center',
158    marginBottom: theme.spacing(2),
159  },
160  button: {
161    margin: theme.spacing(1),
162  },
163}));
164export default SignUp;