all repos — caroster @ e3dd820256e0c4ea2c317a33c8fc29f9a83f3711

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