Skip to content

Commit 855f99e

Browse files
author
Emile Frey
committed
updated login and password update to display validation error messages
1 parent b82877d commit 855f99e

File tree

5 files changed

+89
-55
lines changed

5 files changed

+89
-55
lines changed

frontend/src/App.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Snackbar, ThemeProvider } from '@material-ui/core';
88
import { theme } from './Theme'
99
import { AlertContext } from './contexts/AlertContext';
1010
import Alert from '@material-ui/lab/Alert';
11+
import { AxiosError } from './interfaces/axios/AxiosError'
1112
export interface AuthProps {
1213
logout: Function
1314
setAuthenticatedIfRequired: Function
@@ -52,14 +53,7 @@ function App(props: AppProps) {
5253
interface MapStateToPropsInterface {
5354
auth: {
5455
token: string,
55-
error: {
56-
message: string
57-
response: {
58-
data: {
59-
non_field_errors: string[]
60-
}
61-
}
62-
}
56+
error: AxiosError
6357
}
6458
}
6559

frontend/src/components/Login/Login.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function Login(props: AppProps) {
4747
const classes = useStyles();
4848
const [username, setuserName] = useState("");
4949
const [password, setPassword] = useState("");
50+
const [validationErrors, setValidationErrors] = useState<string[]>([])
5051

5152
let history = useHistory();
5253
let location = useLocation<LocationState>();
@@ -56,12 +57,17 @@ function Login(props: AppProps) {
5657
if (props.isAuthenticated) { history.replace(from) };
5758
});
5859

60+
useEffect(() => {
61+
setValidationErrors(props.error ? props.error.response.data.non_field_errors : [])
62+
}, [props.error])
63+
5964
const handleFormFieldChange = (event: React.ChangeEvent<HTMLInputElement>) => {
6065
switch (event.target.id) {
6166
case 'username': setuserName(event.target.value); break;
6267
case 'password': setPassword(event.target.value); break;
6368
default: return null;
6469
}
70+
setValidationErrors([])
6571
};
6672

6773
const handleSubmit = (e: React.ChangeEvent<HTMLFormElement>) => {
@@ -104,7 +110,7 @@ function Login(props: AppProps) {
104110
autoComplete="current-password"
105111
onChange={handleFormFieldChange}
106112
/>
107-
{validationErrorMessages(props.error ? props.error.response.data.non_field_errors : [])}
113+
{validationErrorMessages(validationErrors)}
108114
<Button
109115
type="submit"
110116
fullWidth
@@ -120,6 +126,7 @@ function Login(props: AppProps) {
120126
);
121127
}
122128

129+
123130
const mapDispatchToProps = (dispatch: Dispatch<any>) => {
124131
return {
125132
onAuth: (username: string, password: string) => dispatch(actions.authLogin(username, password))

frontend/src/components/Login/PasswordUpdate.tsx

Lines changed: 61 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { makeStyles } from '@material-ui/core/styles';
66
import { Avatar, Button, Container, CssBaseline, TextField, Typography } from '@material-ui/core';
77
import VpnKeyIcon from '@material-ui/icons/VpnKey';
88
import { AuthProps } from '../../App';
9-
9+
import { PasswordUpdateError } from '../../interfaces/axios/AxiosError';
10+
import validationErrorMessages from '../../helpers/validationErrorMessages'
1011

1112
const useStyles = makeStyles((theme) => ({
1213
paper: {
@@ -37,6 +38,7 @@ function PasswordUpdate(props: AuthProps) {
3738
const [new_password1, setNewPassword1] = useState("");
3839
const [new_password2, setNewPassword2] = useState("");
3940
const [success, setSuccess] = useState(false);
41+
const [validationErrors, setValidationErrors] = useState<string[]>([])
4042

4143
const handleFormFieldChange = (event: React.ChangeEvent<HTMLInputElement>) => {
4244
setSuccess(false);
@@ -45,30 +47,33 @@ function PasswordUpdate(props: AuthProps) {
4547
case 'new_password2': setNewPassword2(event.target.value); break;
4648
default: return null;
4749
}
48-
50+
setValidationErrors([])
4951
};
5052

5153
const handleSubmit = (e: React.ChangeEvent<HTMLFormElement>) => {
5254
e.preventDefault();
5355
if (new_password1 !== new_password2) {
54-
alert("Passwords don't match")
55-
} else {
56+
setValidationErrors(["Passwords don't match!"])
57+
} else if (new_password1 === "") {
58+
setValidationErrors(["Password can't be blank!"])
59+
}
60+
else {
5661
let headers = { 'Authorization': `Token ${props.token}` };
5762
const method = 'POST';
5863
let url = settings.API_SERVER + '/api/auth/update_password/';
5964
let passwordFormData = new FormData();
6065
passwordFormData.append("new_password1", new_password1);
6166
passwordFormData.append("new_password2", new_password2);
62-
let config: AxiosRequestConfig = { headers, method, url, data: passwordFormData};
67+
let config: AxiosRequestConfig = { headers, method, url, data: passwordFormData };
6368
//Axios update_password API call
6469
axios(config).then((res: any) => {
6570
setSuccess(true);
6671
}).catch(
67-
(error: string) => {
68-
alert(error)
72+
(error: PasswordUpdateError) => {
73+
console.log(error.response.data.new_password2)
74+
setValidationErrors(error.response.data.new_password2)
6975
})
7076
}
71-
7277
}
7378

7479
return (
@@ -79,48 +84,59 @@ function PasswordUpdate(props: AuthProps) {
7984
<Avatar className={classes.avatar}>
8085
<VpnKeyIcon />
8186
</Avatar>
82-
<Typography component="h1" variant="h5">
83-
Update Password
87+
{!success ?
88+
<>
89+
<Typography component="h1" variant="h5">
90+
Update Password
8491
</Typography>
85-
<form className={classes.form} noValidate onSubmit={handleSubmit}>
86-
<TextField
87-
variant="outlined"
88-
margin="normal"
89-
required
90-
fullWidth
91-
name="new_password1"
92-
label="Enter New Password"
93-
type="password"
94-
id="new_password1"
95-
onChange={handleFormFieldChange}
96-
error={new_password1 !== new_password2}
97-
helperText={new_password1 !== new_password2 ? "Passwords don't match" : null}
98-
/>
99-
<TextField
100-
variant="outlined"
101-
margin="normal"
102-
required
103-
fullWidth
104-
name="new_password2"
105-
label="Enter Your Password Again"
106-
type="password"
107-
id="new_password2"
108-
onChange={handleFormFieldChange}
109-
error={new_password1 !== new_password2}
110-
helperText={new_password1 !== new_password2 ? "Passwords don't match" : null}
111-
/>
92+
<form className={classes.form} noValidate onSubmit={handleSubmit}>
93+
<TextField
94+
variant="outlined"
95+
margin="normal"
96+
required
97+
fullWidth
98+
name="new_password1"
99+
label="Enter New Password"
100+
type="password"
101+
id="new_password1"
102+
onChange={handleFormFieldChange}
103+
error={new_password1 !== new_password2}
104+
helperText={new_password1 !== new_password2 ? "Passwords don't match" : null}
105+
/>
106+
<TextField
107+
variant="outlined"
108+
margin="normal"
109+
required
110+
fullWidth
111+
name="new_password2"
112+
label="Enter Your Password Again"
113+
type="password"
114+
id="new_password2"
115+
onChange={handleFormFieldChange}
116+
error={new_password1 !== new_password2}
117+
helperText={new_password1 !== new_password2 ? "Passwords don't match" : null}
118+
/>
119+
{validationErrorMessages(validationErrors)}
120+
<Button
121+
type="submit"
122+
fullWidth
123+
variant="contained"
124+
color="primary"
125+
className={classes.submit}
126+
>
127+
Update Password
128+
</Button>
129+
</form>
130+
</> :
112131
<Button
113-
type="submit"
114132
fullWidth
115133
variant="contained"
116134
color="primary"
117-
className={classes.submit}
118-
>
119-
Update Password
120-
</Button>
121-
</form>
122-
</div>
123-
</Container>
135+
href="/"> Return Home
136+
</Button>
137+
}
138+
</div >
139+
</Container >
124140
);
125141
}
126142

frontend/src/helpers/validationErrorMessages.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import MuiAlert from '@material-ui/lab/Alert';
33

44
const validationErrorMessages = (validationErrors: string[]) =>
55
validationErrors.map((value, index) =>
6-
<MuiAlert key={index} elevation={6} variant="filled" severity="warning" id="Validation-Message">{value}</MuiAlert>
6+
<MuiAlert key={index} style={{margin: 10}} elevation={6} variant="filled" severity="warning" id="Validation-Message">{value}</MuiAlert>
77
);
88

99
export default validationErrorMessages
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export interface AxiosError {
2+
message: string
3+
response: {
4+
data: {
5+
non_field_errors: string[]
6+
}
7+
}
8+
}
9+
10+
export interface PasswordUpdateError {
11+
message: string
12+
response: {
13+
data: {
14+
new_password2: string[]
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)