all repos — caroster @ 116dd85d56ab607173ef9b2215698b7d24adb3fb

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

frontend/containers/MailSignUpForm/index.tsx (view raw)

  1import {useState, useMemo} from 'react';
  2import Box from '@material-ui/core/Box';
  3import Divider from '@material-ui/core/Divider';
  4import Checkbox from '@material-ui/core/Checkbox';
  5import FormControlLabel from '@material-ui/core/FormControlLabel';
  6import TextField from '@material-ui/core/TextField';
  7import Button from '@material-ui/core/Button';
  8import CardContent from '@material-ui/core/CardContent';
  9import Typography from '@material-ui/core/Typography';
 10import CircularProgress from '@material-ui/core/CircularProgress';
 11import {useTranslation} from 'react-i18next';
 12import {useRouter} from 'next/router';
 13import {makeStyles} from '@material-ui/core/styles';
 14import useToastsStore from '../../stores/useToastStore';
 15import {useRegisterMutation} from '../../generated/graphql';
 16import SignUpActions from './SignupActions';
 17
 18const SignUp = () => {
 19  const {t, i18n} = useTranslation();
 20  const classes = useStyles();
 21  const addToast = useToastsStore(s => s.addToast);
 22  const router = useRouter();
 23  const [isLoading, setIsLoading] = useState(false);
 24  const [error, setError] = useState('');
 25  const [firstName, setFirstName] = useState('');
 26  const [lastName, setLastName] = useState('');
 27  const [email, setEmail] = useState('');
 28  const [password, setPassword] = useState('');
 29  const [newsletterConsent, setNewsletterConsent] = useState(false);
 30  const [register] = useRegisterMutation();
 31
 32  const canSubmit = useMemo(
 33    () =>
 34      [firstName, lastName, email, password].filter(s => s.length < 2)
 35        .length === 0,
 36    [firstName, lastName, email, password]
 37  );
 38
 39  const onSubmit = async e => {
 40    e.preventDefault?.();
 41    if (isLoading) return;
 42    setIsLoading(true);
 43    try {
 44      const lang = i18n.language.toUpperCase();
 45      await register({
 46        variables: {
 47          user: {
 48            username: email,
 49            email,
 50            password,
 51            firstName,
 52            lastName,
 53            newsletterConsent,
 54            lang,
 55          },
 56        },
 57      });
 58      router.push('/auth/confirm');
 59    } catch (error) {
 60      const strapiError = error.message;
 61      console.error({strapiError});
 62      if (strapiError === 'Email or Username are already taken')
 63        setError(t('signup.errors.email_taken'));
 64      else addToast(t(`generic.errors.unknown`));
 65    }
 66    setIsLoading(false);
 67    return false;
 68  };
 69
 70  return (
 71    <form onSubmit={onSubmit}>
 72      <CardContent className={classes.content}>
 73        <Typography
 74          variant="overline"
 75          component="h5"
 76          align="center"
 77          className={classes.lineBreak}
 78        >
 79          {t('signup.createForm')}
 80        </Typography>
 81        <Box className={classes.content}>
 82          <TextField
 83            label={t('signup.firstName')}
 84            fullWidth
 85            autoFocus
 86            margin="dense"
 87            value={firstName}
 88            required={true}
 89            onChange={({target: {value = ''}}) => setFirstName(value)}
 90            id="SignUpFirstName"
 91            name="firstName"
 92          />
 93          <TextField
 94            label={t('signup.lastName')}
 95            fullWidth
 96            required={true}
 97            margin="dense"
 98            value={lastName}
 99            onChange={({target: {value = ''}}) => setLastName(value)}
100            id="SignUpLastName"
101            name="lastName"
102          />
103          <TextField
104            label={t('signup.email')}
105            fullWidth
106            required={true}
107            error={!!error}
108            helperText={error}
109            margin="dense"
110            value={email}
111            onChange={({target: {value = ''}}) => setEmail(value)}
112            id="SignUpEmail"
113            name="email"
114            type="email"
115          />
116          <TextField
117            label={t('signup.password')}
118            fullWidth
119            required={true}
120            margin="dense"
121            value={password}
122            onChange={({target: {value = ''}}) => setPassword(value)}
123            id="SignUpEmail"
124            name="password"
125            type="password"
126          />
127        </Box>
128        <FormControlLabel
129          className={classes.newsletter}
130          control={
131            <Checkbox
132              className={classes.checkbox}
133              color="primary"
134              value={newsletterConsent}
135              onChange={({target: {checked = false}}) =>
136                setNewsletterConsent(checked)
137              }
138            />
139          }
140          label={t('signup.newsletter.consent')}
141        />
142
143        <Box className={classes.content}>
144          <Button
145            color="primary"
146            variant="contained"
147            fullWidth
148            type="submit"
149            disabled={!canSubmit}
150            className={classes.button}
151            aria-disabled={!canSubmit}
152            id="SignUpSubmit"
153            endIcon={
154              isLoading && (
155                <CircularProgress
156                  className={classes.loader}
157                  size={20}
158                  color="secondary"
159                />
160              )
161            }
162          >
163            {t('signup.submit')}
164          </Button>
165        </Box>
166        <Box className={classes.divider}>
167          <Divider />
168        </Box>
169        <Typography align="center" variant="body2">
170          {t('signup.account_already')}
171        </Typography>
172      </CardContent>
173      <SignUpActions />
174    </form>
175  );
176};
177
178const useStyles = makeStyles(theme => ({
179  content: {
180    display: 'flex',
181    flexDirection: 'column',
182    alignItems: 'center',
183    width: '100%',
184    padding: theme.spacing(0, 4),
185  },
186  lineBreak: {
187    whiteSpace: 'pre-line',
188    lineHeight: 1.8,
189    paddingBottom: theme.spacing(4),
190  },
191  loader: {
192    marginLeft: '14px',
193    color: theme.palette.background.paper,
194  },
195  button: {
196    margin: theme.spacing(1),
197  },
198  divider: {
199    width: '100%',
200    textAlign: 'center',
201    margin: theme.spacing(2, 0),
202  },
203  newsletter: {
204    width: '100%',
205    margin: theme.spacing(2, 0),
206  },
207  checkbox: {
208    padding: 0,
209    marginRight: theme.spacing(2),
210  },
211}));
212
213export default SignUp;