DocSpace-buildtools/web/ASC.Web.Common/src/pages/login/index.js

433 lines
10 KiB
JavaScript
Raw Normal View History

2019-11-27 11:14:51 +00:00
import React, { Component } from "react";
2019-11-22 11:48:54 +00:00
import PropTypes from "prop-types";
import { withRouter } from "react-router";
import {
2020-07-02 08:44:17 +00:00
Box,
2019-11-22 11:48:54 +00:00
Button,
TextInput,
Text,
Heading,
2019-11-22 11:48:54 +00:00
Link,
toastr,
Checkbox,
HelpButton,
PasswordInput
2019-11-22 11:48:54 +00:00
} from "asc-web-components";
import PageLayout from "../../components/PageLayout";
2019-11-22 11:48:54 +00:00
import { connect } from "react-redux";
import styled from "styled-components";
import { withTranslation } from "react-i18next";
2019-11-22 11:48:54 +00:00
import i18n from "./i18n";
import SubModalDialog from "./sub-components/modal-dialog";
import { login, setIsLoaded } from "../../store/auth/actions";
import { sendInstructionsToChangePassword } from "../../api/people";
2019-11-22 11:48:54 +00:00
const FormContainer = styled.form`
2020-07-06 13:06:37 +00:00
margin: 32px auto 0 auto;
2020-07-02 08:44:17 +00:00
max-width: 311px;
2019-11-22 11:48:54 +00:00
2020-07-06 16:19:55 +00:00
/* .login-header {
min-height: 79px;
margin-bottom: 24px;
.login-logo {
max-width: 216px;
max-height: 35px;
2020-07-06 16:19:55 +00:00
} */
2020-07-06 16:19:55 +00:00
.login-title {
margin: 8px 0;
2020-07-06 16:19:55 +00:00
text-align:center;
}
2019-11-22 11:48:54 +00:00
}
.login-input {
2020-07-02 08:44:17 +00:00
margin-bottom: 16px;
2019-11-22 11:48:54 +00:00
}
.login-forgot-wrapper {
height: 36px;
.login-checkbox-wrapper {
position: absolute;
display: inline-flex;
.login-checkbox {
float: left;
span {
font-size: 12px;
}
}
.login-tooltip {
display: inline-flex;
2019-12-26 14:08:24 +00:00
@media(min-width: 1025px) {
margin-left: 8px;
margin-top: 4px;
}
@media(max-width: 1024px) {
padding: 4px 8px 8px 8px;
}
}
}
.login-link {
float: right;
line-height: 16px;
2019-11-22 11:48:54 +00:00
}
}
.login-button {
margin-bottom: 16px;
2019-11-22 11:48:54 +00:00
}
.login-button-dialog {
margin-right: 8px;
2019-11-22 11:48:54 +00:00
}
2020-07-02 08:44:17 +00:00
.login-bottom-border {
2020-07-07 11:17:26 +00:00
width: 100%;
2020-07-02 08:44:17 +00:00
height: 1px;
background: #ECEEF1;
}
.login-bottom-text {
margin: 0 8px;
}
2019-11-22 11:48:54 +00:00
`;
2020-07-06 13:06:37 +00:00
const RegisterContainer = styled(Box)`
position: absolute;
2020-07-06 13:12:19 +00:00
z-index: 184;
2020-07-06 13:06:37 +00:00
width: 100%;
height: 66px;
bottom: 0;
right: 0;
background-color: #F8F9F9;
cursor: pointer;
2020-07-06 13:06:37 +00:00
`;
2019-11-27 11:14:51 +00:00
class Form extends Component {
constructor(props) {
super(props);
this.state = {
identifierValid: true,
identifier: "",
isLoading: false,
isDisabled: false,
passwordValid: true,
password: "",
isChecked: false,
openDialog: false,
email: "",
errorText: ""
};
}
onChangeLogin = event => {
this.setState({ identifier: event.target.value });
!this.state.identifierValid && this.setState({ identifierValid: true });
this.state.errorText && this.setState({ errorText: "" });
};
onChangePassword = event => {
this.setState({ password: event.target.value });
!this.state.passwordValid && this.setState({ passwordValid: true });
this.state.errorText && this.setState({ errorText: "" });
2019-11-22 11:48:54 +00:00
};
2019-11-27 11:14:51 +00:00
onChangeEmail = event => {
this.setState({ email: event.target.value });
2019-11-22 11:48:54 +00:00
};
2019-11-27 11:14:51 +00:00
onChangeCheckbox = () => this.setState({ isChecked: !this.state.isChecked });
2019-11-22 11:48:54 +00:00
2019-11-27 11:14:51 +00:00
onClick = () => {
this.setState({
openDialog: true,
isDisabled: true,
email: this.state.identifier
});
};
onKeyPress = event => {
if (event.key === "Enter") {
!this.state.isDisabled
? this.onSubmit()
: this.onSendPasswordInstructions();
}
};
onSendPasswordInstructions = () => {
this.setState({ isLoading: true });
sendInstructionsToChangePassword(this.state.email)
.then(
res => toastr.success(res),
message => toastr.error(message)
)
.finally(this.onDialogClose());
};
onDialogClose = () => {
this.setState({
openDialog: false,
isDisabled: false,
isLoading: false,
email: ""
});
};
onSubmit = () => {
const { errorText, identifier, password } = this.state;
const { login, setIsLoaded, history } = this.props;
errorText && this.setState({ errorText: "" });
2019-11-22 11:48:54 +00:00
let hasError = false;
const userName = identifier.trim();
if (!userName) {
hasError = true;
2019-11-27 11:14:51 +00:00
this.setState({ identifierValid: !hasError });
2019-11-22 11:48:54 +00:00
}
const pass = password.trim();
if (!pass) {
hasError = true;
2019-11-27 11:14:51 +00:00
this.setState({ passwordValid: !hasError });
2019-11-22 11:48:54 +00:00
}
if (hasError) return false;
2019-11-27 11:14:51 +00:00
this.setState({ isLoading: true });
2019-11-22 11:48:54 +00:00
2019-11-28 12:08:08 +00:00
login(userName, pass)
.then(() => {
2019-11-22 11:48:54 +00:00
setIsLoaded(true);
history.push("/");
2019-11-28 12:08:08 +00:00
})
.catch(error => {
2019-11-27 11:14:51 +00:00
this.setState({ errorText: error, isLoading: false });
2019-11-28 12:08:08 +00:00
});
2019-11-22 11:48:54 +00:00
};
2019-11-27 11:14:51 +00:00
componentDidMount() {
const { match, t } = this.props;
const { error, confirmedEmail } = match.params;
document.title = `${t("Authorization")} ${t("OrganizationName")}`;
error && this.setState({ errorText: error });
confirmedEmail && this.setState({ identifier: confirmedEmail });
2019-11-27 11:14:51 +00:00
window.addEventListener("keyup", this.onKeyPress);
}
2019-11-22 11:48:54 +00:00
2019-11-27 11:14:51 +00:00
componentWillUnmount() {
window.removeEventListener("keyup", this.onKeyPress);
}
2019-11-22 11:48:54 +00:00
settings = {
minLength: 6,
upperCase: false,
digits: false,
specSymbols: false
}
2019-11-27 11:14:51 +00:00
render() {
const { greetingTitle, match, t } = this.props;
2019-11-27 11:14:51 +00:00
const {
identifierValid,
identifier,
isLoading,
passwordValid,
password,
isChecked,
openDialog,
email,
errorText
} = this.state;
const { params } = match;
//console.log("Login render");
return (
2020-07-06 13:06:37 +00:00
<>
<Box marginProp="120px 0 0 0" displayProp="flex" justifyContent="center" widthProp="100%">
2020-07-06 16:19:55 +00:00
<Box>
<Text fontSize="32px" fontWeight={600}>
{greetingTitle}
</Text>
</Box>
2020-07-06 13:06:37 +00:00
</Box>
<FormContainer>
<TextInput
id="login"
name="login"
hasError={!identifierValid}
value={identifier}
placeholder={t("RegistrationEmailWatermark")}
size="huge"
scale={true}
isAutoFocussed={true}
tabIndex={1}
isDisabled={isLoading}
autoComplete="username"
onChange={this.onChangeLogin}
onKeyDown={this.onKeyPress}
className="login-input"
/>
<PasswordInput
passwordSettings={this.settings}
NewPasswordButtonVisible={false}
className="login-input"
id="password"
inputName="password"
placeholder={t("Password")}
type="password"
hasError={!passwordValid}
inputValue={password}
size="huge"
scale={true}
tabIndex={2}
isDisabled={isLoading}
autoComplete="current-password"
onChange={this.onChangePassword}
onKeyDown={this.onKeyPress}
/>
<div className="login-forgot-wrapper">
<div className="login-checkbox-wrapper">
<Checkbox
className="login-checkbox"
isChecked={isChecked}
onChange={this.onChangeCheckbox}
label={<Text fontSize='13px'>{t("Remember")}</Text>}
/>
<HelpButton
className="login-tooltip"
helpButtonHeaderContent={t("CookieSettingsTitle")}
tooltipContent={
<Text fontSize='12px'>{t("RememberHelper")}</Text>
}
/>
</div>
<Link
fontSize='13px'
color="#316DAA"
className="login-link"
type="page"
isHovered={false}
onClick={this.onClick}
>
{t("ForgotPassword")}
</Link>
</div>
2020-07-06 13:06:37 +00:00
{openDialog ? (
<SubModalDialog
openDialog={openDialog}
isLoading={isLoading}
email={email}
onChangeEmail={this.onChangeEmail}
onSendPasswordInstructions={this.onSendPasswordInstructions}
onDialogClose={this.onDialogClose}
t={t}
/>
) : null}
<Button
id="button"
className="login-button"
primary
size="big"
scale={true}
label={isLoading ? t("LoadingProcessing") : t("LoginButton")}
tabIndex={3}
isDisabled={isLoading}
2019-11-27 11:14:51 +00:00
isLoading={isLoading}
2020-07-06 13:06:37 +00:00
onClick={this.onSubmit}
2019-11-27 11:14:51 +00:00
/>
2020-07-06 13:06:37 +00:00
{params.confirmedEmail && (
<Text isBold={true} fontSize='16px'>
{t("MessageEmailConfirmed")} {t("MessageAuthorize")}
</Text>
)}
<Text fontSize='14px' color="#c30">
{errorText}
</Text>
2020-07-06 13:06:37 +00:00
<Box displayProp="flex" alignItems="center">
<div className="login-bottom-border"></div>
2020-07-07 11:17:26 +00:00
<Text className="login-bottom-text" color="#A3A9AE">{t("Or")}</Text>
2020-07-06 13:06:37 +00:00
<div className="login-bottom-border"></div>
</Box>
</FormContainer>
</>
2019-11-27 11:14:51 +00:00
);
}
}
Form.propTypes = {
2019-11-22 11:48:54 +00:00
login: PropTypes.func.isRequired,
match: PropTypes.object.isRequired,
2019-11-27 11:14:51 +00:00
history: PropTypes.object.isRequired,
setIsLoaded: PropTypes.func.isRequired,
greetingTitle: PropTypes.string.isRequired,
t: PropTypes.func.isRequired,
i18n: PropTypes.object.isRequired,
2019-11-27 11:14:51 +00:00
language: PropTypes.string.isRequired
2019-11-22 11:48:54 +00:00
};
2019-11-27 11:14:51 +00:00
Form.defaultProps = {
2019-11-22 11:48:54 +00:00
identifier: "",
password: "",
email: ""
};
const FormWrapper = withTranslation()(Form);
const LoginForm = props => {
const { language, isLoaded } = props;
i18n.changeLanguage(language);
2020-07-06 13:06:37 +00:00
const onRegisterClick = () => {
alert("Register clicked");
}
return (
<>
2020-07-06 13:06:37 +00:00
{isLoaded && <>
(
<PageLayout sectionBodyContent={<FormWrapper i18n={i18n} {...props} />} />
<RegisterContainer paddingProp="24px 50%" onClick={onRegisterClick}>
<Text color="#316DAA">
Register
</Text>
</RegisterContainer>
)
</>
}
</>
);
};
2019-11-27 11:14:51 +00:00
LoginForm.propTypes = {
language: PropTypes.string.isRequired,
isLoaded: PropTypes.bool
2019-11-27 11:14:51 +00:00
};
2019-11-22 11:48:54 +00:00
function mapStateToProps(state) {
return {
isLoaded: state.auth.isLoaded,
2019-11-22 11:48:54 +00:00
language: state.auth.user.cultureName || state.auth.settings.culture,
greetingTitle: state.auth.settings.greetingSettings
};
}
2019-11-27 11:14:51 +00:00
export default connect(mapStateToProps, { login, setIsLoaded })(
withRouter(LoginForm)
);