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;