all repos — caroster @ 3e13ed81f9961ed582333d0e9296921db2ed91d9

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

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

  1import {useState, useMemo} from 'react';
  2import Box from '@mui/material/Box';
  3import Divider from '@mui/material/Divider';
  4import Checkbox from '@mui/material/Checkbox';
  5import FormControlLabel from '@mui/material/FormControlLabel';
  6import TextField from '@mui/material/TextField';
  7import Button from '@mui/material/Button';
  8import CardContent from '@mui/material/CardContent';
  9import Typography from '@mui/material/Typography';
 10import CircularProgress from '@mui/material/CircularProgress';
 11import {useTheme} from '@mui/material/styles';
 12import {useTranslation} from 'react-i18next';
 13import {useRouter} from 'next/router';
 14import useToastsStore from '../../stores/useToastStore';
 15import SignUpActions from './SignupActions';
 16import {useRegisterMutation} from '../../generated/graphql';
 17
 18const SignUp = () => {
 19  const {t, i18n} = useTranslation();
 20  const theme = useTheme();
 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;
 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  const contentSx = {
 71    display: 'flex',
 72    flexDirection: 'column',
 73    alignItems: 'center',
 74    width: '100%',
 75    padding: theme.spacing(0, 4),
 76  };
 77
 78  return (
 79    <form onSubmit={onSubmit}>
 80      <CardContent sx={contentSx}>
 81        <Typography
 82          variant="h6"
 83          align="center"
 84          sx={{
 85            whiteSpace: 'pre-line',
 86            paddingBottom: theme.spacing(4),
 87          }}
 88        >
 89          {t('signup.createForm')}
 90        </Typography>
 91        <Box sx={contentSx}>
 92          <TextField
 93            label={t('signup.firstName')}
 94            fullWidth
 95            autoFocus
 96            margin="dense"
 97            value={firstName}
 98            InputLabelProps={{required: false}}
 99            required={true}
100            onChange={({target: {value = ''}}) => setFirstName(value)}
101            id="SignUpFirstName"
102            name="firstName"
103          />
104          <TextField
105            label={t('signup.lastName')}
106            fullWidth
107            InputLabelProps={{required: false}}
108            required={true}
109            margin="dense"
110            value={lastName}
111            onChange={({target: {value = ''}}) => setLastName(value)}
112            id="SignUpLastName"
113            name="lastName"
114          />
115          <TextField
116            label={t('signup.email')}
117            fullWidth
118            InputLabelProps={{required: false}}
119            required={true}
120            error={!!error}
121            helperText={error}
122            margin="dense"
123            value={email}
124            onChange={({target: {value = ''}}) => setEmail(value)}
125            id="SignUpEmail"
126            name="email"
127            type="email"
128          />
129          <TextField
130            label={t('signup.password')}
131            fullWidth
132            InputLabelProps={{required: false}}
133            required={true}
134            margin="dense"
135            value={password}
136            onChange={({target: {value = ''}}) => setPassword(value)}
137            id="SignUpEmail"
138            name="password"
139            type="password"
140          />
141        </Box>
142        <FormControlLabel
143          sx={{width: '100%', margin: theme.spacing(2, 0), padding: theme.spacing(0, 4)}}
144          componentsProps={{typography: {align: 'left', variant: 'body2'}}}
145          control={
146            <Checkbox
147              sx={{padding: 0, marginRight: theme.spacing(2)}}
148              color="primary"
149              value={newsletterConsent}
150              onChange={({target: {checked = false}}) =>
151                setNewsletterConsent(checked)
152              }
153            />
154          }
155          label={t('signup.newsletter.consent')}
156        />
157
158        <Box sx={contentSx}>
159          <Button
160            color="primary"
161            variant="contained"
162            fullWidth
163            type="submit"
164            disabled={!canSubmit}
165            sx={{margin: theme.spacing(1)}}
166            aria-disabled={!canSubmit}
167            id="SignUpSubmit"
168            endIcon={
169              isLoading && (
170                <CircularProgress
171                  sx={{
172                    marginLeft: '14px',
173                    color: theme.palette.background.paper,
174                  }}
175                  size={20}
176                  color="secondary"
177                />
178              )
179            }
180          >
181            {t('signup.submit')}
182          </Button>
183        </Box>
184        <Box
185          sx={{width: '100%', textAlign: 'center', margin: theme.spacing(2, 0)}}
186        >
187          <Divider />
188        </Box>
189        <Typography align="center" variant="body2">
190          {t('signup.account_already')}
191        </Typography>
192      </CardContent>
193      <SignUpActions />
194    </form>
195  );
196};
197
198export default SignUp;