all repos — caroster @ 8f7930deb0475683392d3660112a7b737f2b025a

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

frontend/containers/SignUpForm/index.tsx (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, i18n} = 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      const lang = i18n.language.toUpperCase();
 40      await register({
 41        variables: {
 42          user: {
 43            username: email,
 44            email,
 45            password,
 46            firstName,
 47            lastName,
 48            lang,
 49          },
 50        },
 51      });
 52      router.push('/auth/confirm');
 53    } catch (error) {
 54      const strapiError = error.message;
 55      console.error({strapiError});
 56      if (strapiError === 'Email or Username are already taken')
 57        setError(t('signup.errors.email_taken'));
 58      else addToast(t(`generic.errors.unknown`));
 59    }
 60    setIsLoading(false);
 61    return false;
 62  };
 63
 64  return (
 65    <form onSubmit={onSubmit}>
 66      <CardContent className={classes.content}>
 67        <Typography variant="h6">{t('signup.title')}</Typography>
 68        <TextField
 69          label={t('signup.firstName')}
 70          fullWidth
 71          autoFocus
 72          margin="dense"
 73          value={firstName}
 74          required={true}
 75          onChange={({target: {value = ''}}) => setFirstName(value)}
 76          id="SignUpFirstName"
 77          name="firstName"
 78        />
 79        <TextField
 80          label={t('signup.lastName')}
 81          fullWidth
 82          required={true}
 83          margin="dense"
 84          value={lastName}
 85          onChange={({target: {value = ''}}) => setLastName(value)}
 86          id="SignUpLastName"
 87          name="lastName"
 88        />
 89        <TextField
 90          label={t('signup.email')}
 91          fullWidth
 92          required={true}
 93          error={!!error}
 94          helperText={error}
 95          margin="dense"
 96          value={email}
 97          onChange={({target: {value = ''}}) => setEmail(value)}
 98          id="SignUpEmail"
 99          name="email"
100          type="email"
101        />
102        <TextField
103          label={t('signup.password')}
104          fullWidth
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          endIcon={
127            isLoading && (
128              <CircularProgress
129                className={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  try {
145    if (error.message?.[0]?.messages?.[0])
146      return error.message[0].messages[0].id;
147    return error?.graphQLErrors?.[0].extensions.exception.data.message?.[0]
148      ?.messages[0].id;
149  } catch {
150    return 'generic.error';
151  }
152};
153
154const useStyles = makeStyles(theme => ({
155  content: {
156    display: 'flex',
157    flexDirection: 'column',
158    alignItems: 'center',
159  },
160  loader: {
161    marginLeft: '14px',
162    color: theme.palette.background.paper,
163  },
164  actions: {
165    justifyContent: 'center',
166    marginBottom: theme.spacing(2),
167  },
168  button: {
169    margin: theme.spacing(1),
170  },
171}));
172export default SignUp;