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