all repos — caroster @ 3305d6f0b36993b4459c0e235b35274a1dda4b51

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