241 lines
7.5 KiB
JavaScript
241 lines
7.5 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.getModifiedFieldValues()
|
|
|
|
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(window.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.getFieldValue("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 active={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>
|
|
)
|
|
}
|
|
}
|