Files
deighton-ar/website/src/Auth/Login.js
2018-05-25 10:16:28 -07:00

243 lines
7.6 KiB
JavaScript

import React, { Component, Fragment } from "react"
import PropTypes from "prop-types"
import { regExpPattern } from "regexp-pattern"
import { api } from "src/API"
import { WaitModal, MessageModal } from "../Modal"
import {
Box,
Image,
Link,
Text,
Row,
Column,
BoundInput,
BoundCheckbox,
BoundButton,
} from "ui"
import headerLogo from "images/logo.png"
import { versionInfo } from "../version"
import { FormBinder } from "react-form-binder"
import autobind from "autobind-decorator"
import { sizeInfo, colorInfo } from "ui/style"
export class Login extends Component {
static propTypes = {
history: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
}
static bindings = {
email: {
alwaysGet: true,
isValid: (r, v) => regExpPattern.email.test(v),
},
password: {
alwaysGet: true,
isValid: (r, v) => v !== "",
},
rememberMe: {
alwaysGet: true,
initValue: true,
},
submit: {
noValue: true,
isDisabled: (r) => !r.anyModified || !r.allValid,
},
}
constructor(props) {
super(props)
this.state = {
waitModal: false,
messageModal: null,
binder: new FormBinder({}, Login.bindings),
}
}
@autobind
handleSubmit(e) {
e.preventDefault()
e.stopPropagation()
if (this.state.messageModal) {
this.setState({ messageModal: null })
return
} else if (this.state.waitModal) {
return
}
let obj = this.state.binder.getModifiedBindingValues()
if (obj) {
this.setState({ waitModal: true })
api
.login(obj.email.trim(), obj.password, obj.rememberMe)
.then((user) => {
this.setState({ waitModal: false })
if (this.props.history) {
let url =
new URLSearchParams(this.props.history.location.search).get(
"redirect"
) || "/"
try {
this.props.history.replace(url)
} catch (error) {
this.props.history.replace("/")
}
}
})
.catch((error) => {
this.setState({
waitModal: false,
messageModal: {
icon: "hand",
message: `Unable to login`,
detail: error.message,
},
})
})
}
}
@autobind
handleMessageModalDismiss() {
this.setState({
messageModal: null,
binder: new FormBinder(
{ email: this.state.binder.getBindingValue("email") },
Login.bindings
),
})
const elems = document.getElementsByName("password")
if (elems) {
elems[0].focus()
}
}
render() {
const { messageModal, waitModal } = this.state
return (
<Fragment>
<Column.Item grow />
<Column.Item>
<Row>
<Row.Item grow />
<Row.Item width={sizeInfo.modalWidth}>
<form onSubmit={this.handleSubmit} id="loginForm">
<Box
border={{
width: sizeInfo.headerBorderWidth,
color: colorInfo.headerBorder,
}}
radius={sizeInfo.formBoxRadius}>
<Row>
<Row.Item width={sizeInfo.formRowSpacing} />
<Row.Item>
<Column>
<Column.Item height={sizeInfo.formColumnSpacing} />
<Column.Item>
<Row>
<Row.Item grow />
<Row.Item>
<Image
source={headerLogo}
width={sizeInfo.loginLogoWidth}
/>
</Row.Item>
<Row.Item grow />
</Row>
</Column.Item>
<Column.Item height={sizeInfo.formColumnSpacing} />
<Column.Item>
<Text size="large">Login</Text>
</Column.Item>
<Column.Item height={sizeInfo.formColumnSpacing} />
<Column.Item>
<BoundInput
label="Email"
name="email"
placeholder="example@xyz.com"
binder={this.state.binder}
message="Enter the email address associated with your account."
/>
</Column.Item>
<Column.Item>
<BoundInput
password
label="Password"
name="password"
binder={this.state.binder}
message="Enter your password."
/>
</Column.Item>
<Column.Item>
<Row>
<Row.Item>
<Link to="/forgot-password">
Forgot your password?
</Link>
</Row.Item>
<Row.Item grow />
<Row.Item>
<BoundCheckbox
label="Remember Me"
name="rememberMe"
binder={this.state.binder}
/>
</Row.Item>
</Row>
</Column.Item>
<Column.Item height={sizeInfo.formColumnSpacing} />
<Column.Item height={sizeInfo.buttonHeight}>
<Row>
<Row.Item grow />
<Row.Item>
<BoundButton
name="submit"
text="Login"
submit="loginForm"
binder={this.state.binder}
/>
</Row.Item>
</Row>
</Column.Item>
<Column.Item height={sizeInfo.formColumnSpacing} />
<Column.Item>
<Text>
Please contact{" "}
<Link to={`mailto:${versionInfo.supportEmail}`}>
{versionInfo.supportEmail}
</Link>{" "}
to request login credentials.
</Text>
</Column.Item>
<Column.Item height={sizeInfo.formColumnSpacing} />
</Column>
</Row.Item>
<Row.Item width={sizeInfo.formRowSpacing} />
</Row>
</Box>
</form>
</Row.Item>
<Row.Item grow />
</Row>
</Column.Item>
<Column.Item grow>
<WaitModal open={waitModal} message="Logging in..." />
<MessageModal
error
open={!!messageModal}
icon={messageModal ? messageModal.icon : ""}
message={messageModal ? messageModal.message : ""}
detail={messageModal ? messageModal.detail : ""}
onDismiss={this.handleMessageModalDismiss}
/>
</Column.Item>
</Fragment>
)
}
}