2018-08-24 17:03:08 +00:00
|
|
|
import * as React from "react";
|
|
|
|
|
|
|
|
import Typography from "@material-ui/core/Typography";
|
|
|
|
import Paper from "@material-ui/core/Paper";
|
|
|
|
import TextField from "@material-ui/core/TextField";
|
|
|
|
import Grid from "@material-ui/core/Grid";
|
|
|
|
import Button from "@material-ui/core/Button";
|
|
|
|
import LinearProgress from "@material-ui/core/LinearProgress";
|
|
|
|
import Snackbar from "@material-ui/core/Snackbar";
|
|
|
|
|
2018-09-19 16:00:38 +00:00
|
|
|
import { withRouter } from "react-router-dom";
|
2018-08-26 14:23:48 +00:00
|
|
|
|
2018-09-16 15:16:24 +00:00
|
|
|
import { IUser } from "../models/user";
|
2018-09-20 18:26:40 +00:00
|
|
|
import { IResponse } from "../models/server";
|
2018-09-16 15:16:24 +00:00
|
|
|
|
2018-08-24 17:03:08 +00:00
|
|
|
interface IProps {
|
2018-09-20 18:26:40 +00:00
|
|
|
login: (username: string, password: string) => Promise<IUser | IResponse>;
|
2018-09-18 16:59:15 +00:00
|
|
|
authenticated: boolean;
|
2018-09-19 16:00:38 +00:00
|
|
|
history: any;
|
2018-08-24 17:03:08 +00:00
|
|
|
|
2018-09-23 14:30:14 +00:00
|
|
|
didLogin: boolean;
|
2018-09-18 16:59:15 +00:00
|
|
|
setLoading: (state: boolean) => void;
|
|
|
|
setSnackbar: (state: boolean, msg: string) => void;
|
2018-08-24 17:03:08 +00:00
|
|
|
loading: boolean;
|
2018-09-18 16:59:15 +00:00
|
|
|
snackOpen: boolean;
|
|
|
|
snackMsg: string;
|
2018-08-24 17:03:08 +00:00
|
|
|
}
|
2018-09-18 16:59:15 +00:00
|
|
|
|
2018-09-19 16:00:38 +00:00
|
|
|
const LoginPageWithRouter = withRouter(
|
|
|
|
class LoginPage extends React.Component<IProps> {
|
|
|
|
private usernameRef: any = undefined;
|
|
|
|
private passwordRef: any = undefined;
|
2018-09-18 16:59:15 +00:00
|
|
|
|
2018-09-19 16:00:38 +00:00
|
|
|
performLogin = () => {
|
|
|
|
this.props.setLoading(true);
|
2018-09-18 16:59:15 +00:00
|
|
|
|
2018-09-19 16:00:38 +00:00
|
|
|
const username = this.usernameRef.value || "";
|
|
|
|
const password = this.passwordRef.value || "";
|
|
|
|
this.props.login(username, password).then((res: IUser) => {
|
2018-09-20 18:26:40 +00:00
|
|
|
// Stop the loading animation
|
|
|
|
this.props.setLoading(false);
|
|
|
|
|
2018-09-20 15:34:01 +00:00
|
|
|
if (res.showWelcome) {
|
|
|
|
// If the user logs in for the first time, a welcome
|
|
|
|
// screen should be shown
|
|
|
|
this.props.history.push("/welcome");
|
|
|
|
} else {
|
|
|
|
this.props.history.push("/dashboard");
|
|
|
|
}
|
2018-09-23 14:14:14 +00:00
|
|
|
}).catch((err: IResponse) => {
|
2018-09-19 16:00:38 +00:00
|
|
|
this.props.setLoading(false);
|
|
|
|
this.props.setSnackbar(true, "Failed to log in");
|
|
|
|
});
|
|
|
|
}
|
2018-08-24 17:03:08 +00:00
|
|
|
|
2018-09-19 16:00:38 +00:00
|
|
|
componentDidMount() {
|
|
|
|
// If we're already authenticated, we can skip the login page
|
2018-09-23 14:30:14 +00:00
|
|
|
// NOTE: The '!this.props.didLogin' is here, as the Component gets
|
|
|
|
// remounted, when the auth status changes. Thus we would
|
|
|
|
// redirect to /dashboard, redirect back to /welcome
|
|
|
|
// (or /dashboard again) and cause mulitple API calls!
|
|
|
|
if (this.props.authenticated && !this.props.didLogin) {
|
2018-09-19 16:00:38 +00:00
|
|
|
this.props.history.push("/dashboard");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2018-09-30 11:08:14 +00:00
|
|
|
// Trigger a login when return is pressed
|
|
|
|
const onEnter = (event: any) => {
|
|
|
|
if (event.key === "Enter") {
|
|
|
|
this.performLogin();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-09-19 16:00:38 +00:00
|
|
|
return <div>
|
|
|
|
<Grid
|
|
|
|
container
|
|
|
|
spacing={0}
|
|
|
|
direction="column"
|
|
|
|
alignItems="center"
|
|
|
|
justify="center"
|
|
|
|
style={{ minHeight: '100vh' }}>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
<Paper className="paper">
|
|
|
|
<Typography variant="title">Login</Typography>
|
|
|
|
<Grid container direction="column" spacing={8}>
|
|
|
|
<Grid item>
|
|
|
|
<TextField
|
|
|
|
label="Username"
|
2018-09-30 11:08:14 +00:00
|
|
|
onKeyPress={onEnter}
|
2018-09-19 16:00:38 +00:00
|
|
|
inputRef={node => this.usernameRef = node} />
|
|
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
|
|
<TextField
|
|
|
|
label="Passwort"
|
|
|
|
type="password"
|
2018-09-30 11:08:14 +00:00
|
|
|
onKeyPress={onEnter}
|
2018-09-19 16:00:38 +00:00
|
|
|
inputRef={node => this.passwordRef = node} />
|
|
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
|
|
<Button
|
|
|
|
variant="contained"
|
|
|
|
color="primary"
|
|
|
|
className="login-btn"
|
|
|
|
onClick={() => this.performLogin()}>
|
|
|
|
Login
|
2018-08-24 17:03:08 +00:00
|
|
|
</Button>
|
2018-09-19 16:00:38 +00:00
|
|
|
{
|
|
|
|
this.props.loading ? (
|
|
|
|
<LinearProgress />
|
|
|
|
) : undefined
|
|
|
|
}
|
|
|
|
</Grid>
|
2018-08-24 17:03:08 +00:00
|
|
|
</Grid>
|
2018-09-19 16:00:38 +00:00
|
|
|
</Paper>
|
|
|
|
</Grid>
|
2018-08-24 17:03:08 +00:00
|
|
|
</Grid>
|
2018-09-19 16:00:38 +00:00
|
|
|
<Snackbar
|
|
|
|
open={this.props.snackOpen}
|
|
|
|
onClose={() => this.props.setSnackbar(false, "")}
|
|
|
|
message={this.props.snackMsg}
|
|
|
|
autoHideDuration={6000} />
|
|
|
|
</div>;
|
|
|
|
}
|
2018-08-24 17:03:08 +00:00
|
|
|
}
|
2018-09-19 16:00:38 +00:00
|
|
|
);
|
|
|
|
export default LoginPageWithRouter;
|