frontend/containers/SignUpForm/index.js (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} = 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 await register({
40 variables: {
41 email,
42 password,
43 username: `${firstName} ${lastName}`,
44 },
45 });
46 router.push('/auth/confirm');
47 } catch (error) {
48 const strapiError = getStrapiError(error);
49 console.error({strapiError});
50 if (strapiError === 'Auth.form.error.email.taken')
51 setError(t('signup.errors.email_taken'));
52 else addToast(t(`generic.errors.unknown`));
53 }
54 setIsLoading(false);
55 return false;
56 };
57
58 return (
59 <form onSubmit={onSubmit}>
60 <CardContent className={classes.content}>
61 <Typography variant="h6">{t('signup.title')}</Typography>
62 <TextField
63 label={t('signup.firstName')}
64 fullWidth
65 autoFocus
66 margin="dense"
67 value={firstName}
68 required={true}
69 onChange={({target: {value = ''}}) => setFirstName(value)}
70 id="SignUpFirstName"
71 name="firstName"
72 />
73 <TextField
74 label={t('signup.lastName')}
75 fullWidth
76 required={true}
77 margin="dense"
78 value={lastName}
79 onChange={({target: {value = ''}}) => setLastName(value)}
80 id="SignUpLastName"
81 name="lastName"
82 />
83 <TextField
84 label={t('signup.email')}
85 fullWidth
86 required={true}
87 error={!!error}
88 helperText={error}
89 margin="dense"
90 value={email}
91 onChange={({target: {value = ''}}) => setEmail(value)}
92 id="SignUpEmail"
93 name="email"
94 type="email"
95 />
96 <TextField
97 label={t('signup.password')}
98 fullWidth
99 required={true}
100 margin="dense"
101 value={password}
102 onChange={({target: {value = ''}}) => setPassword(value)}
103 id="SignUpEmail"
104 name="password"
105 type="password"
106 />
107 </CardContent>
108 <CardActions className={classes.actions}>
109 <Button id="SignUpLogin" href="/auth/login" variant="text">
110 {t('signup.login')}
111 </Button>
112 <Button
113 color="primary"
114 variant="contained"
115 type="submit"
116 disabled={!canSubmit}
117 className={classes.button}
118 aria-disabled={!canSubmit}
119 id="SignUpSubmit"
120 endIcon={
121 isLoading && (
122 <CircularProgress
123 class={classes.loader}
124 size={20}
125 color="secondary"
126 />
127 )
128 }
129 >
130 {t('signup.submit')}
131 </Button>
132 </CardActions>
133 </form>
134 );
135};
136
137const getStrapiError = error => {
138 if (error.message?.[0]?.messages?.[0]) return error.message[0].messages[0].id;
139 return error?.graphQLErrors?.[0].extensions.exception.data.message[0]
140 .messages[0].id;
141};
142
143const useStyles = makeStyles(theme => ({
144 content: {
145 display: 'flex',
146 flexDirection: 'column',
147 alignItems: 'center',
148 },
149 loader: {
150 marginLeft: '14px',
151 color: theme.palette.background.paper,
152 },
153 actions: {
154 justifyContent: 'center',
155 marginBottom: theme.spacing(2),
156 },
157 button: {
158 margin: theme.spacing(1),
159 },
160}));
161export default SignUp;