all repos — caroster @ 71f58f6653388edb7455a935a96e099959eb5edd

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