Files
edx-platform/lms/static/js/student_account/components/PasswordResetConfirmation.jsx
Zainab Amir 2d3c6c05e1 Update page title to H1 (#25783)
Rebrand related work for:
- VAN-160
- VAN-186
2020-12-07 18:41:55 +05:00

147 lines
4.5 KiB
JavaScript

/* globals gettext */
import 'whatwg-fetch';
import PropTypes from 'prop-types';
import React from 'react';
import { Button, StatusAlert } from '@edx/paragon/static';
import PasswordResetInput from './PasswordResetInput';
// NOTE: Use static paragon with this because some internal classes (StatusAlert at least)
// conflict with some standard LMS ones ('alert' at least). This means that you need to do
// something like the following on any templates that use this class:
//
// <link type='text/css' rel='stylesheet' href='${STATIC_URL}paragon/static/paragon.min.css'>
//
class PasswordResetConfirmation extends React.Component {
constructor(props) {
super(props);
this.state = {
password: '',
passwordConfirmation: '',
showMatchError: false,
isValid: true,
validationMessage: '',
};
this.onBlurPassword1 = this.onBlurPassword1.bind(this);
this.onBlurPassword2 = this.onBlurPassword2.bind(this);
}
onBlurPassword1(password) {
this.updatePasswordState(password, this.state.passwordConfirmation);
this.validatePassword(password);
}
onBlurPassword2(passwordConfirmation) {
this.updatePasswordState(this.state.password, passwordConfirmation);
}
updatePasswordState(password, passwordConfirmation) {
this.setState({
password,
passwordConfirmation,
showMatchError: !!password && !!passwordConfirmation && (password !== passwordConfirmation),
});
}
validatePassword(password) {
fetch('/api/user/v1/validation/registration', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
password,
}),
})
.then(res => res.json())
.then((response) => {
let validationMessage = '';
// Be careful about grabbing this message, since we could have received an HTTP error or the
// endpoint didn't give us what we expect. We only care if we get a clear error message.
if (response.validation_decisions && response.validation_decisions.password) {
validationMessage = response.validation_decisions.password;
}
this.setState({
isValid: !validationMessage,
validationMessage,
});
});
}
render() {
return (
<section id="password-reset-confirm-anchor" className="form-type">
<div id="password-reset-confirm-form" className="form-wrapper" aria-live="polite">
<StatusAlert
alertType="danger"
dismissible={false}
open={!!this.props.errorMessage}
dialog={this.props.errorMessage}
/>
<form id="passwordreset-form" method="post" action="">
<h1 className="section-title">
<span className="text">
{this.props.formTitle}
</span>
</h1>
<p className="action-label" id="new_password_help_text">
{gettext('Enter and confirm your new password.')}
</p>
<PasswordResetInput
name="new_password1"
describedBy="new_password_help_text"
label={gettext('New Password')}
onBlur={this.onBlurPassword1}
isValid={this.state.isValid}
validationMessage={this.state.validationMessage}
/>
<PasswordResetInput
name="new_password2"
describedBy="new_password_help_text"
label={gettext('Confirm Password')}
onBlur={this.onBlurPassword2}
isValid={!this.state.showMatchError}
validationMessage={gettext('Passwords do not match.')}
/>
<input
type="hidden"
id="csrf_token"
name="csrfmiddlewaretoken"
value={this.props.csrfToken}
/>
<Button
type="submit"
className={['action', 'action-primary', 'action-update', 'js-reset']}
label={this.props.primaryActionButtonLabel}
/>
</form>
</div>
</section>
);
}
}
PasswordResetConfirmation.propTypes = {
csrfToken: PropTypes.string.isRequired,
errorMessage: PropTypes.string,
primaryActionButtonLabel: PropTypes.string,
formTitle: PropTypes.string,
};
PasswordResetConfirmation.defaultProps = {
errorMessage: '',
primaryActionButtonLabel: gettext('Reset My Password'),
formTitle: gettext('Reset Your Password'),
};
export { PasswordResetConfirmation }; // eslint-disable-line import/prefer-default-export