app/src/containers/SignInForm/index.js (view raw)
1import React, {useCallback, useState, useMemo, useEffect} from 'react';
2import {Redirect, Link as RouterLink} from 'react-router-dom';
3import {useTranslation} from 'react-i18next';
4import {useAuth} from 'strapi-react-context';
5import TextField from '@material-ui/core/TextField';
6import {useLocation} from 'react-router-dom';
7import Button from '@material-ui/core/Button';
8import Link from '@material-ui/core/Link';
9import Typography from '@material-ui/core/Typography';
10import CardContent from '@material-ui/core/CardContent';
11import {CircularProgress} from '@material-ui/core';
12import CardActions from '@material-ui/core/CardActions';
13import {makeStyles} from '@material-ui/core/styles';
14import {useToast} from '../../contexts/Toast';
15
16const SignIn = () => {
17 const {t} = useTranslation();
18 const classes = useStyles();
19 const location = useLocation();
20 const {login, token, authState, loginWithProvider} = useAuth();
21 const [isLoading, setIsLoading] = useState(false);
22 const [error, setError] = useState('');
23 const [email, setEmail] = useState('');
24 const [password, setPassword] = useState('');
25 const {addToast} = useToast();
26
27 const canSubmit = useMemo(
28 () => [email, password].filter(s => s.length < 4).length === 0,
29 [email, password]
30 );
31
32 const onSubmit = useCallback(
33 async evt => {
34 if (evt.preventDefault) evt.preventDefault();
35 if (isLoading) {
36 return;
37 }
38 setIsLoading(true);
39 try {
40 await login(email, password);
41 // TODO add to my event if saved in local storage
42 // TODO remove from local storage.
43 } catch (error) {
44 console.log('ERROR', {error});
45 if (error.kind === 'bad_data') {
46 setError(t('signin.errors'));
47 addToast(t('signin.errors'));
48 }
49 }
50
51 setIsLoading(false);
52 return false;
53 },
54 [email, password, login, isLoading, addToast, t]
55 );
56
57 // If an access token is given in URL params, login with auth provider
58 useEffect(() => {
59 const authWithGoogle = async search => {
60 try {
61 await loginWithProvider('google', search);
62 } catch (error) {
63 console.log('ERROR', {error});
64 addToast(t('signin.errors'));
65 }
66 };
67
68 if (location.search) authWithGoogle(location.search);
69 }, [location.search]); // eslint-disable-line react-hooks/exhaustive-deps
70
71 if (token) return <Redirect to="/dashboard" />;
72 if (authState?.user && !authState.user.confirmed)
73 return <Redirect to="/confirm" />;
74
75 return (
76 <form onSubmit={onSubmit}>
77 <CardContent className={classes.content}>
78 <Typography variant="h6">{t('signin.title')}</Typography>
79 <TextField
80 label={t('signin.email')}
81 fullWidth
82 required={true}
83 margin="dense"
84 value={email}
85 onChange={({target: {value = ''}}) => setEmail(value)}
86 id="SignInEmail"
87 name="email"
88 type="email"
89 error={!!error}
90 helperText={error}
91 />
92 <TextField
93 label={t('signin.password')}
94 fullWidth
95 required={true}
96 margin="dense"
97 value={password}
98 onChange={({target: {value = ''}}) => setPassword(value)}
99 id="SignInEmail"
100 name="password"
101 type="password"
102 error={!!error}
103 helperText={
104 error && (
105 <RouterLink to="/lost-password" component={Link}>
106 {t('lost_password.message')}
107 </RouterLink>
108 )
109 }
110 />
111 </CardContent>
112 <CardActions className={classes.actions}>
113 <Button
114 color="primary"
115 variant="contained"
116 type="submit"
117 disabled={!canSubmit}
118 aria-disabled={!canSubmit}
119 id="SignInSubmit"
120 fullWidth
121 >
122 {isLoading ? (
123 <CircularProgress className={classes.loader} size={20} />
124 ) : (
125 t('signin.login')
126 )}
127 </Button>
128 <Button id="SignInRegister" href="/register" fullWidth size="small">
129 {t('signin.register')}
130 </Button>
131 </CardActions>
132 </form>
133 );
134};
135
136const useStyles = makeStyles(theme => ({
137 content: {
138 display: 'flex',
139 flexDirection: 'column',
140 alignItems: 'center',
141 },
142 loader: {
143 marginLeft: '14px',
144 },
145 actions: {
146 display: 'flex',
147 flexDirection: 'column',
148 alignItems: 'center',
149 },
150}));
151export default SignIn;