WordClockESP/interface/src/SignIn.tsx

144 lines
4.3 KiB
TypeScript
Raw Normal View History

2019-05-14 21:47:04 +00:00
import React, { Component } from 'react';
import { withSnackbar, WithSnackbarProps } from 'notistack';
2019-05-14 21:47:04 +00:00
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
import { withStyles, createStyles, Theme, WithStyles } from '@material-ui/core/styles';
import { Paper, Typography, Fab } from '@material-ui/core';
2019-05-14 21:47:04 +00:00
import ForwardIcon from '@material-ui/icons/Forward';
import { withAuthenticationContext, AuthenticationContextProps } from './authentication/AuthenticationContext';
import {PasswordValidator} from './components';
import { PROJECT_NAME, SIGN_IN_ENDPOINT } from './api';
const styles = (theme: Theme) => createStyles({
loginPage: {
display: "flex",
height: "100vh",
margin: "auto",
padding: theme.spacing(2),
justifyContent: "center",
flexDirection: "column",
maxWidth: theme.breakpoints.values.sm
},
loginPanel: {
textAlign: "center",
padding: theme.spacing(2),
paddingTop: "200px",
backgroundImage: 'url("/app/icon.png")',
backgroundRepeat: "no-repeat",
backgroundPosition: "50% " + theme.spacing(2) + "px",
backgroundSize: "auto 150px",
width: "100%"
},
extendedIcon: {
marginRight: theme.spacing(0.5),
},
button: {
marginRight: theme.spacing(2),
marginTop: theme.spacing(2),
2019-05-14 21:47:04 +00:00
}
});
2019-05-14 21:47:04 +00:00
type SignInPageProps = WithSnackbarProps & WithStyles<typeof styles> & AuthenticationContextProps;
interface SignInPageState {
username: string,
password: string,
processing: boolean
}
class SignInPage extends Component<SignInPageProps, SignInPageState> {
2019-05-14 21:47:04 +00:00
constructor(props: SignInPageProps) {
2019-05-14 21:47:04 +00:00
super(props);
this.state = {
username: '',
2019-05-14 22:18:24 +00:00
password: '',
processing: false
2019-05-14 21:47:04 +00:00
};
}
updateInputElement = (event: React.ChangeEvent<HTMLInputElement>): void => {
const { name, value } = event.currentTarget;
this.setState(prevState => ({
...prevState,
[name]: value,
}))
2019-05-14 21:47:04 +00:00
};
2019-05-14 22:18:24 +00:00
onSubmit = () => {
const { username, password } = this.state;
const { authenticationContext } = this.props;
this.setState({ processing: true });
2019-05-14 22:18:24 +00:00
fetch(SIGN_IN_ENDPOINT, {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({
'Content-Type': 'application/json'
})
})
.then(response => {
if (response.status === 200) {
return response.json();
} else if (response.status === 401) {
throw Error("Invalid login details.");
2019-05-14 22:18:24 +00:00
} else {
throw Error("Invalid status code: " + response.status);
}
}).then(json => {
2019-05-14 22:18:24 +00:00
authenticationContext.signIn(json.access_token);
})
.catch(error => {
this.props.enqueueSnackbar(error.message, {
variant: 'warning',
});
this.setState({ processing: false });
2019-05-14 22:18:24 +00:00
});
2019-05-14 21:47:04 +00:00
};
render() {
const { username, password, processing } = this.state;
2019-05-14 21:47:04 +00:00
const { classes } = this.props;
return (
<div className={classes.loginPage}>
<Paper className={classes.loginPanel}>
2019-07-06 22:56:30 +00:00
<Typography variant="h4">{PROJECT_NAME}</Typography>
2019-05-14 21:47:04 +00:00
<ValidatorForm onSubmit={this.onSubmit}>
<TextValidator
disabled={processing}
2019-05-14 21:47:04 +00:00
validators={['required']}
errorMessages={['Username is required']}
name="username"
label="Username"
fullWidth
variant="outlined"
2019-05-14 21:47:04 +00:00
value={username}
onChange={this.updateInputElement}
2019-05-14 21:47:04 +00:00
margin="normal"
/>
<PasswordValidator
disabled={processing}
2019-05-14 21:47:04 +00:00
validators={['required']}
errorMessages={['Password is required']}
name="password"
label="Password"
fullWidth
variant="outlined"
2019-05-14 21:47:04 +00:00
value={password}
onChange={this.updateInputElement}
2019-05-14 21:47:04 +00:00
margin="normal"
/>
<Fab variant="extended" color="primary" className={classes.button} type="submit" disabled={processing}>
2019-05-14 21:47:04 +00:00
<ForwardIcon className={classes.extendedIcon} />
2019-05-14 22:18:24 +00:00
Sign In
2019-05-14 21:47:04 +00:00
</Fab>
</ValidatorForm>
</Paper>
</div>
);
}
}
export default withAuthenticationContext(withSnackbar(withStyles(styles)(SignInPage)));