Fork of the excellent esp8266-react - https://github.com/rjwats/esp8266-react
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.0 KiB

  1. import React, { Component } from 'react';
  2. import { withStyles } from '@material-ui/core/styles';
  3. import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
  4. import Paper from '@material-ui/core/Paper';
  5. import Typography from '@material-ui/core/Typography';
  6. import Fab from '@material-ui/core/Fab';
  7. import { APP_NAME } from '../constants/App';
  8. import ForwardIcon from '@material-ui/icons/Forward';
  9. import { withSnackbar } from 'notistack';
  10. import { SIGN_IN_ENDPOINT } from '../constants/Endpoints';
  11. import { withAuthenticationContext } from '../authentication/Context';
  12. import PasswordValidator from '../components/PasswordValidator';
  13. const styles = theme => {
  14. return {
  15. loginPage: {
  16. display: "flex",
  17. height: "100vh",
  18. margin: "auto",
  19. padding: theme.spacing(2),
  20. justifyContent: "center",
  21. flexDirection: "column",
  22. maxWidth: theme.breakpoints.values.sm
  23. },
  24. loginPanel: {
  25. textAlign: "center",
  26. padding: theme.spacing(2),
  27. paddingTop: "200px",
  28. backgroundImage: 'url("/app/icon.png")',
  29. backgroundRepeat: "no-repeat",
  30. backgroundPosition: "50% " + theme.spacing(2) + "px",
  31. backgroundSize: "auto 150px",
  32. width: "100%"
  33. },
  34. extendedIcon: {
  35. marginRight: theme.spacing(0.5),
  36. },
  37. textField: {
  38. width: "100%"
  39. },
  40. button: {
  41. marginRight: theme.spacing(2),
  42. marginTop: theme.spacing(2),
  43. }
  44. }
  45. }
  46. class SignInPage extends Component {
  47. constructor(props) {
  48. super(props);
  49. this.state = {
  50. username: '',
  51. password: '',
  52. processing: false
  53. };
  54. }
  55. handleValueChange = name => event => {
  56. this.setState({ [name]: event.target.value });
  57. };
  58. onSubmit = () => {
  59. const { username, password } = this.state;
  60. const { authenticationContext } = this.props;
  61. this.setState({ processing: true });
  62. fetch(SIGN_IN_ENDPOINT, {
  63. method: 'POST',
  64. body: JSON.stringify({ username, password }),
  65. headers: new Headers({
  66. 'Content-Type': 'application/json'
  67. })
  68. })
  69. .then(response => {
  70. if (response.status === 200) {
  71. return response.json();
  72. } else if (response.status === 401) {
  73. throw Error("Invalid login details.");
  74. } else {
  75. throw Error("Invalid status code: " + response.status);
  76. }
  77. }).then(json => {
  78. authenticationContext.signIn(json.access_token);
  79. })
  80. .catch(error => {
  81. this.props.enqueueSnackbar(error.message, {
  82. variant: 'warning',
  83. });
  84. this.setState({ processing: false });
  85. });
  86. };
  87. render() {
  88. const { username, password, processing } = this.state;
  89. const { classes } = this.props;
  90. return (
  91. <div className={classes.loginPage}>
  92. <Paper className={classes.loginPanel}>
  93. <Typography variant="h4">{APP_NAME}</Typography>
  94. <ValidatorForm onSubmit={this.onSubmit}>
  95. <TextValidator
  96. disabled={processing}
  97. validators={['required']}
  98. errorMessages={['Username is required']}
  99. name="username"
  100. label="Username"
  101. className={classes.textField}
  102. value={username}
  103. onChange={this.handleValueChange('username')}
  104. margin="normal"
  105. />
  106. <PasswordValidator
  107. disabled={processing}
  108. validators={['required']}
  109. errorMessages={['Password is required']}
  110. name="password"
  111. label="Password"
  112. className={classes.textField}
  113. value={password}
  114. onChange={this.handleValueChange('password')}
  115. margin="normal"
  116. />
  117. <Fab variant="extended" color="primary" className={classes.button} type="submit" disabled={processing}>
  118. <ForwardIcon className={classes.extendedIcon} />
  119. Sign In
  120. </Fab>
  121. </ValidatorForm>
  122. </Paper>
  123. </div>
  124. );
  125. }
  126. }
  127. export default withAuthenticationContext(
  128. withSnackbar(withStyles(styles)(SignInPage))
  129. );