1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
import React, { useState } from 'react';
import { Grid, useMediaQuery, makeStyles, InputLabel, Select, MenuItem, FormControl, Button, TextField, Link } from '@material-ui/core';
import { useTheme } from '@material-ui/core/styles';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { sessionActions } from './../store';
import t from './../common/localization';
import RegisterForm from './RegisterForm';
import ResetPasswordForm from './ResetPasswordForm';
const useStyles = makeStyles(theme => ({
logoContainer: {
textAlign: 'center',
},
resetPassword: {
cursor: 'pointer',
}
}));
const forms = {
register: () => RegisterForm,
resetPassword: () => ResetPasswordForm,
};
const LoginForm = ({ setCurrentForm }) => {
const classes = useStyles();
const dispatch = useDispatch();
const history = useHistory();
const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down('md'));
const [failed, setFailed] = useState(false);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const registrationEnabled = useSelector(state => state.session.server ? state.session.server['registration'] : false);
const handleEmailChange = (event) => {
setEmail(event.target.value);
}
const handlePasswordChange = (event) => {
setPassword(event.target.value);
}
const handleLogin = async (event) => {
event.preventDefault();
const response = await fetch('/api/session', { method: 'POST', body: new URLSearchParams(`email=${email}&password=${password}`) });
if (response.ok) {
const user = await response.json();
dispatch(sessionActions.updateUser(user));
history.push('/');
} else {
setFailed(true);
setPassword('');
}
}
return (
<Grid container direction='column' spacing={3}>
<Grid item className={classes.logoContainer}>
{matches && <img src='/logo.svg' alt='Traccar' />}
</Grid>
<Grid item>
<TextField
required
fullWidth
error={failed}
label={t('userEmail')}
name='email'
value={email}
autoComplete='email'
autoFocus
onChange={handleEmailChange}
helperText={failed && 'Invalid username or password'}
variant='filled' />
</Grid>
<Grid item>
<TextField
required
fullWidth
error={failed}
label={t('userPassword')}
name='password'
value={password}
type='password'
autoComplete='current-password'
onChange={handlePasswordChange}
variant='filled' />
</Grid>
<Grid item>
<Button
onClick={handleLogin}
variant='contained'
color='secondary'
disabled={!email || !password}
fullWidth>
{t('loginLogin')}
</Button>
</Grid>
<Grid item container>
<Grid item>
<Button onClick={() => setCurrentForm(forms.register)} disabled={!registrationEnabled} color="secondary">
{t('loginRegister')}
</Button>
</Grid>
<Grid item xs>
<FormControl variant="filled" fullWidth>
<InputLabel>{t('loginLanguage')}</InputLabel>
<Select>
<MenuItem value="en">English</MenuItem>
</Select>
</FormControl>
</Grid>
</Grid>
<Grid item container justify="flex-end">
<Grid item>
<Link onClick={() => setCurrentForm(forms.resetPassword)} className={classes.resetPassword} underline="none">{t('loginReset')}</Link>
</Grid>
</Grid>
</Grid>
)
}
export default LoginForm;
|