VAN-322: UX-Review: Update Forgot Password Pages (#92)

This commit is contained in:
Zainab Amir
2021-01-25 19:29:18 +05:00
committed by GitHub
parent fed057c330
commit 35adc8eaf3
12 changed files with 143 additions and 118 deletions

View File

@@ -58,9 +58,9 @@ const ForgotPasswordPage = (props) => {
<div className="d-flex flex-column">
<Form className="mw-500">
{status === 'forbidden' ? <RequestInProgressAlert /> : null}
<h1 className="mt-3">
<h3 className="mt-3">
{intl.formatMessage(messages['logisration.forgot.password.page.heading'])}
</h1>
</h3>
<p className="mb-4">
{intl.formatMessage(messages['logisration.forgot.password.page.instructions'])}
</p>

View File

@@ -10,11 +10,11 @@ exports[`ForgotPasswordPage should match default section snapshot 1`] = `
<form
className="mw-500"
>
<h1
<h3
className="mt-3"
>
Password assistance
</h1>
</h3>
<p
className="mb-4"
>
@@ -46,7 +46,7 @@ exports[`ForgotPasswordPage should match default section snapshot 1`] = `
</p>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>
@@ -139,11 +139,11 @@ exports[`ForgotPasswordPage should match forbidden section snapshot 1`] = `
Your previous request is still in progress, please try again in a few moments.
</span>
</div>
<h1
<h3
className="mt-3"
>
Password assistance
</h1>
</h3>
<p
className="mb-4"
>
@@ -175,7 +175,7 @@ exports[`ForgotPasswordPage should match forbidden section snapshot 1`] = `
</p>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>
@@ -243,11 +243,11 @@ exports[`ForgotPasswordPage should match pending section snapshot 1`] = `
<form
className="mw-500"
>
<h1
<h3
className="mt-3"
>
Password assistance
</h1>
</h3>
<p
className="mb-4"
>
@@ -279,7 +279,7 @@ exports[`ForgotPasswordPage should match pending section snapshot 1`] = `
</p>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>

View File

@@ -59,6 +59,7 @@ initialize({
mergeConfig({
LOGIN_ISSUE_SUPPORT_LINK: process.env.LOGIN_ISSUE_SUPPORT_LINK || null,
ACTIVATION_EMAIL_SUPPORT_LINK: process.env.ACTIVATION_EMAIL_SUPPORT_LINK || null,
PASSWORD_RESET_SUPPORT_LINK: process.env.PASSWORD_RESET_SUPPORT_LINK || null,
});
},
},

View File

@@ -1,53 +1,49 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { Alert, Hyperlink } from '@edx/paragon';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import messages from './messages';
const ConfirmationAlert = (props) => {
const { email } = props;
const technicalSupportLink = (
<Hyperlink
destination="https://support.edx.org/hc/en-us/articles/206212088-What-if-I-did-not-receive-a-password-reset-message-"
>
<FormattedMessage
id="logistration.forgot.password.confirmation.support.link"
defaultMessage="contact technical support"
description="link text used in message: logistration.forgot.password.confirmation.support.link 'contact technical support.'"
/>
</Hyperlink>
);
const strongEmail = (<strong>{email}</strong>);
const lineBreak = (<br />);
const { email, intl } = props;
return (
<Alert
variant="success"
>
<Alert.Heading className="text-success">
<Alert id="confirmation-alert" variant="success">
<Alert.Heading>{intl.formatMessage(messages['authn.forgot.password.confirmation.title'])}</Alert.Heading>
<p>
<FormattedMessage
id="logistration.forgot.password.confirmation.title"
defaultMessage="Check Your Email"
description="Forgot password confirmation title"
id="logistration.forgot.password.confirmation.message"
defaultMessage="You entered {strongEmail}. If this email address is associated with your
edX account, we will send a message with password recovery instructions to this email address."
description="Forgot password confirmation message"
values={{ strongEmail: <strong>{email}</strong> }}
/>
</Alert.Heading>
<FormattedMessage
id="logistration.forgot.password.confirmation.message"
defaultMessage="You entered {strongEmail}. If this email address is associated with your edX account, we will send a message with password recovery instructions to this email address. {lineBreak}If you do not receive a password reset message after 1 minute, verify that you entered the correct email address, or check your spam folder.{lineBreak} If you need further assistance, {technicalSupportLink}."
description="Forgot password confirmation message"
values={{
strongEmail,
technicalSupportLink,
lineBreak,
}}
/>
</p>
<p>{intl.formatMessage(messages['authn.forgot.password.confirmation.info'])}</p>
<p>
<FormattedMessage
id="authn.forgot.password.technical.support.help.message"
defaultMessage="If you need further assistance, {technicalSupportLink}."
description="Message to help user contact technical support"
values={{
technicalSupportLink: (
<Alert.Link href={getConfig().PASSWORD_RESET_SUPPORT_LINK}>
{intl.formatMessage(messages['authn.forgot.password.confirmation.support.link'])}
</Alert.Link>
),
}}
/>
</p>
</Alert>
);
};
ConfirmationAlert.propTypes = {
email: PropTypes.string.isRequired,
intl: intlShape.isRequired,
};
export default ConfirmationAlert;
export default injectIntl(ConfirmationAlert);

View File

@@ -52,7 +52,7 @@ const LoginHelpLinks = (props) => {
};
const renderLoginHelp = () => (
<div className="login-help">
<div className="login-help small">
{ page === LOGIN_PAGE ? forgotPasswordLink() : signUpLink() }
{ loginIssueSupportURL(getConfig()) }
</div>
@@ -60,10 +60,9 @@ const LoginHelpLinks = (props) => {
return (
<>
<button type="button" className="mt-1 field-link" onClick={toggleLoginHelp}>
<button type="button" className="mt-1 field-link small" onClick={toggleLoginHelp}>
<FontAwesomeIcon className="mr-1" icon={showLoginHelp ? faCaretDown : faCaretRight} />
{getHelpButtonMessage()}
</button>
<SwitchContent
expression={showLoginHelp ? 'showHelp' : 'default'}

View File

@@ -242,6 +242,23 @@ const messages = defineMessages({
defaultMessage: 'contact support',
description: 'Link text used in account activation error message to go to learner help center',
},
// Confirmation Alert Message
'authn.forgot.password.confirmation.title': {
id: 'authn.forgot.password.confirmation.title',
defaultMessage: 'Check Your Email',
description: 'Forgot password confirmation message title',
},
'authn.forgot.password.confirmation.support.link': {
id: 'authn.forgot.password.confirmation.support.link',
defaultMessage: 'contact technical support',
description: 'Technical support link text',
},
'authn.forgot.password.confirmation.info': {
id: 'authn.forgot.password.confirmation.info',
defaultMessage: 'If you do not receive a password reset message after 1 minute, verify that you entered the correct '
+ 'email address, or check your spam folder.',
description: 'Part of message that appears after user requests password change',
},
});
export default messages;

View File

@@ -1,24 +1,34 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { mount } from 'enzyme';
import { mergeConfig } from '@edx/frontend-platform';
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
import ConfirmationAlert from '../ConfirmationAlert';
describe('ConfirmationAlert', () => {
let props = {};
const IntlConfirmationAlertMessage = injectIntl(ConfirmationAlert);
beforeEach(() => {
props = {
email: 'test@example.com',
};
describe('ConfirmationAlert', () => {
const supportLink = 'https://support.test.com/What-if-I-did-not-receive-a-password-reset-message';
mergeConfig({
PASSWORD_RESET_SUPPORT_LINK: supportLink,
});
it('should match default confirmation message snapshot', () => {
const tree = renderer.create(
it('should match default confirmation message', () => {
const confirmationAlertMessage = mount(
<IntlProvider locale="en">
<ConfirmationAlert {...props} />
<IntlConfirmationAlertMessage email="test@example.com" />
</IntlProvider>,
).toJSON();
expect(tree).toMatchSnapshot();
);
const expectedMessage = 'Check Your Email'
+ 'You entered test@example.com. If this email address is associated with your edX account, '
+ 'we will send a message with password recovery instructions to this email address.'
+ 'If you do not receive a password reset message after 1 minute, verify that you entered '
+ 'the correct email address, or check your spam folder.'
+ 'If you need further assistance, contact technical support.';
expect(confirmationAlertMessage.find('#confirmation-alert').first().text()).toEqual(expectedMessage);
expect(confirmationAlertMessage.find('#confirmation-alert').find('a').props().href).toEqual(supportLink);
});
});

View File

@@ -15,8 +15,8 @@ const mockStore = configureStore();
describe('LoginPage', () => {
const initialState = {
forgotPassword: { status: null },
logistration: {
forgotPassword: { status: null },
loginResult: { success: false, redirectUrl: '' },
response_error: null,
thirdPartyAuthContext: {
@@ -80,10 +80,11 @@ describe('LoginPage', () => {
});
it('should match forget password alert message snapshot', () => {
props = {
...props,
store = mockStore({
...initialState,
forgotPassword: { status: 'complete', email: 'test@example.com' },
};
});
const tree = renderer.create(reduxWrapper(<IntlLoginPage {...props} />)).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@@ -1,37 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ConfirmationAlert should match default confirmation message snapshot 1`] = `
<div
className="fade alert alert-success show"
role="alert"
>
<div
className="text-success alert-heading h4"
>
<span>
Check Your Email
</span>
</div>
<span>
You entered
<strong>
test@example.com
</strong>
. If this email address is associated with your edX account, we will send a message with password recovery instructions to this email address.
<br />
If you do not receive a password reset message after 1 minute, verify that you entered the correct email address, or check your spam folder.
<br />
If you need further assistance,
<a
href="https://support.edx.org/hc/en-us/articles/206212088-What-if-I-did-not-receive-a-password-reset-message-"
onClick={[Function]}
target="_self"
>
<span>
contact technical support
</span>
</a>
.
</span>
</div>
`;

View File

@@ -91,7 +91,7 @@ exports[`LoginPage should match TPA provider snapshot 1`] = `
</strong>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>
@@ -283,7 +283,7 @@ exports[`LoginPage should match default section snapshot 1`] = `
</strong>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>
@@ -379,6 +379,44 @@ exports[`LoginPage should match forget password alert message snapshot 1`] = `
<div
className="mw-500"
>
<div
className="fade alert alert-success show"
id="confirmation-alert"
role="alert"
>
<div
className="alert-heading h4"
>
Check Your Email
</div>
<p>
<span>
You entered
<strong>
test@example.com
</strong>
. If this email address is associated with your edX account, we will send a message with password recovery instructions to this email address.
</span>
</p>
<p>
If you do not receive a password reset message after 1 minute, verify that you entered the correct email address, or check your spam folder.
</p>
<p>
<span>
If you need further assistance,
<a
className="alert-link"
href="#"
onClick={[Function]}
onKeyDown={[Function]}
role="button"
>
contact technical support
</a>
.
</span>
</p>
</div>
<div
className="d-flex flex-row"
>
@@ -460,7 +498,7 @@ exports[`LoginPage should match forget password alert message snapshot 1`] = `
</strong>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>
@@ -637,7 +675,7 @@ exports[`LoginPage should match pending button state snapshot 1`] = `
</strong>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>
@@ -840,7 +878,7 @@ exports[`LoginPage should show error message 1`] = `
</strong>
</div>
<button
className="mt-1 field-link"
className="mt-1 field-link small"
onClick={[Function]}
type="button"
>

View File

@@ -80,9 +80,9 @@ const ResetPasswordPage = (props) => {
<div className="d-flex flex-column mw-500">
<Form>
<div className="reset-password-container">
<h1 className="mt-3">
<h3 className="mt-3">
{intl.formatMessage(messages['logistration.reset.password.page.heading'])}
</h1>
</h3>
<p className="mb-4">
{intl.formatMessage(messages['logistration.reset.password.page.instructions'])}
</p>

View File

@@ -58,11 +58,11 @@ exports[`ResetPasswordPage should match pending reset message section snapshot 1
<div
className="reset-password-container"
>
<h1
<h3
className="mt-3"
>
Reset Your Password
</h1>
</h3>
<p
className="mb-4"
>
@@ -159,11 +159,11 @@ exports[`ResetPasswordPage should match reset password default section snapshot
<div
className="reset-password-container"
>
<h1
<h3
className="mt-3"
>
Reset Your Password
</h1>
</h3>
<p
className="mb-4"
>
@@ -312,11 +312,11 @@ Array [
<div
className="reset-password-container"
>
<h1
<h3
className="mt-3"
>
Reset Your Password
</h1>
</h3>
<p
className="mb-4"
>