1 import * as React from 'react';
2 import { withRouter, RouteComponentProps } from 'react-router-dom';
4 import Avatar from '@material-ui/core/Avatar';
5 import Button from '@material-ui/core/Button';
6 import Dialog from '@material-ui/core/Dialog';
7 import DialogActions from '@material-ui/core/DialogActions';
8 import DialogContent from '@material-ui/core/DialogContent';
9 import DialogContentText from '@material-ui/core/DialogContentText';
10 import DialogTitle from '@material-ui/core/DialogTitle';
11 import CssBaseline from '@material-ui/core/CssBaseline';
12 import FormControl from '@material-ui/core/FormControl';
13 import FormControlLabel from '@material-ui/core/FormControlLabel';
14 import Checkbox from '@material-ui/core/Checkbox';
15 import Input from '@material-ui/core/Input';
16 import InputLabel from '@material-ui/core/InputLabel';
17 import LockIcon from '@material-ui/icons/LockOutlined';
18 import Paper from '@material-ui/core/Paper';
19 import Typography from '@material-ui/core/Typography';
20 import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
22 import connect, { Connect } from '../flux/connect';
23 import authenticationService from '../services/authenticationService';
25 import { UpdateAuthentication } from '../actions/authentication';
27 const styles = (theme: Theme) => createStyles({
30 display: 'block', // Fix IE11 issue.
31 marginLeft: theme.spacing.unit * 3,
32 marginRight: theme.spacing.unit * 3,
33 [theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
40 marginTop: theme.spacing.unit * 8,
42 flexDirection: 'column',
44 padding: `${ theme.spacing.unit * 2 }px ${ theme.spacing.unit * 3 }px ${ theme.spacing.unit * 3 }px`,
47 margin: theme.spacing.unit,
48 backgroundColor: theme.palette.secondary.main,
51 width: '100%', // Fix IE11 issue.
52 marginTop: theme.spacing.unit,
55 marginTop: theme.spacing.unit * 3,
59 type LoginProps = RouteComponentProps<{}> & WithStyles<typeof styles> & Connect ;
61 interface ILoginState {
70 // todo: ggf. redirect to einbauen
71 class LoginComponent extends React.Component<LoginProps, ILoginState> {
73 constructor(props: LoginProps) {
85 render(): JSX.Element {
86 const { classes } = this.props;
90 <main className={ classes.layout }>
91 <Paper className={ classes.paper }>
92 <Avatar className={ classes.avatar }>
95 <Typography variant="caption">Sign in</Typography>
96 <form className={ classes.form }>
97 <FormControl margin="normal" required fullWidth>
98 <InputLabel htmlFor="email">Email Address</InputLabel>
99 <Input id="email" name="email" autoComplete="email" autoFocus
100 disabled={ this.state.busy }
101 value = {this.state.email }
102 onChange={ event => { this.setState({ email: event.target.value }) } }/>
104 <FormControl margin="normal" required fullWidth>
105 <InputLabel htmlFor="password">Password</InputLabel>
110 autoComplete="current-password"
111 disabled={ this.state.busy }
112 value={ this.state.password }
113 onChange={ event => { this.setState({ password: event.target.value }) } }
116 <FormControl margin="normal" required fullWidth>
117 <InputLabel htmlFor="password">Scope</InputLabel>
122 disabled={this.state.busy}
123 value={this.state.scope}
124 onChange={event => { this.setState({ scope: event.target.value }) }}
128 control={ <Checkbox value="remember" color="primary" /> }
136 disabled = { this.state.busy }
137 className={ classes.submit }
138 onClick = { this.onSignIn }
146 open={!!this.state.message}
147 onClose={() => { this.setState({message: ''})}}
148 aria-labelledby="alert-dialog-title"
149 aria-describedby="alert-dialog-description"
151 <DialogTitle id="alert-dialog-title">{"Error"}</DialogTitle>
153 <DialogContentText id="alert-dialog-description">
154 { this.state.message }
158 <Button onClick={() => { this.setState({ message: '' }) }} color="secondary" autoFocus>
167 private onSignIn = async (event: React.MouseEvent<HTMLButtonElement>) => {
168 event.preventDefault();
170 this.setState({ busy: true });
171 const token = await authenticationService.authenticateUser(this.state.email, this.state.password, this.state.scope);
172 this.props.dispatch(new UpdateAuthentication(token));
173 this.setState({ busy: false });
177 this.props.state.framework.navigationState.search &&
178 this.props.state.framework.navigationState.search.replace(/^\?/, "")
179 .split('&').map(e => e.split("="));
180 const returnTo = query && query.find(e => e[0] === "returnTo");
181 this.props.history.replace(returnTo && returnTo[1] || "/");
185 message: "Could not log in. Please check your credentials or ask your administrator for assistence.",
192 export const Login = withStyles(styles)(withRouter(connect()(LoginComponent)));
193 export default Login;