feat: update logistration pages (#591)
- removed few unused classes - updated login page to rely on error messages generated from the frontend only. VAN-138
This commit is contained in:
@@ -591,11 +591,6 @@ select.form-control {
|
||||
border: 2px solid #F0CC00;
|
||||
}
|
||||
|
||||
.one-rem-font {
|
||||
font-size: 0.99rem;
|
||||
color: #707070;
|
||||
}
|
||||
|
||||
.institute-heading {
|
||||
color: $primary-700;
|
||||
}
|
||||
@@ -668,16 +663,13 @@ select.form-control {
|
||||
}
|
||||
}
|
||||
|
||||
.arrow-back-icon {
|
||||
margin-top:2px;
|
||||
}
|
||||
|
||||
.icon-size {
|
||||
width: 2.3rem;
|
||||
}
|
||||
.has-floating-label {
|
||||
color: $gray-500;
|
||||
}
|
||||
|
||||
.pgn__form-control-floating-label .pgn__form-control-floating-label-content {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
// Utility functions
|
||||
|
||||
import * as QueryString from 'query-string';
|
||||
|
||||
import { AUTH_PARAMS } from '../constants';
|
||||
|
||||
export default function processLink(link) {
|
||||
let matches;
|
||||
link.replace(/(.*?)<a href=["']([^"']*).*?>([^<]+)<\/a>(.*)/g, function () { // eslint-disable-line func-names
|
||||
matches = Array.prototype.slice.call(arguments, 1, 5); // eslint-disable-line prefer-rest-params
|
||||
});
|
||||
return matches;
|
||||
}
|
||||
|
||||
export const getTpaProvider = (tpaHintProvider, primaryProviders, secondaryProviders) => {
|
||||
let tpaProvider = null;
|
||||
let skipHintedLogin = false;
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
import { LOGIN_PAGE } from '../constants';
|
||||
import processLink, { updatePathWithQueryParams } from './dataUtils';
|
||||
|
||||
describe('processLink', () => {
|
||||
it('should use the provided processLink function to', () => {
|
||||
const expectedHref = 'http://test.server.com/';
|
||||
const expectedText = 'test link';
|
||||
const link = `<a href="${expectedHref}">${expectedText}</a>`;
|
||||
|
||||
const matches = processLink(link);
|
||||
|
||||
expect(matches[1]).toEqual(expectedHref);
|
||||
expect(matches[2]).toEqual(expectedText);
|
||||
});
|
||||
});
|
||||
import { updatePathWithQueryParams } from './dataUtils';
|
||||
|
||||
describe('updatePathWithQueryParams', () => {
|
||||
it('should append query params into the path', () => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export {
|
||||
default,
|
||||
getTpaProvider,
|
||||
getTpaHint,
|
||||
updatePathWithQueryParams,
|
||||
|
||||
@@ -31,10 +31,11 @@ const ForgotPasswordPage = (props) => {
|
||||
const { intl, status, submitState } = props;
|
||||
|
||||
const platformName = getConfig().SITE_NAME;
|
||||
const supportUrl = getConfig().LOGIN_ISSUE_SUPPORT_LINK;
|
||||
const regex = new RegExp(VALID_EMAIL_REGEX, 'i');
|
||||
|
||||
const [validationError, setValidationError] = useState('');
|
||||
const [key, setKey] = useState('');
|
||||
const supportUrl = getConfig().LOGIN_ISSUE_SUPPORT_LINK;
|
||||
|
||||
useEffect(() => {
|
||||
sendPageEvent('login_and_registration', 'reset');
|
||||
@@ -55,8 +56,8 @@ const ForgotPasswordPage = (props) => {
|
||||
};
|
||||
|
||||
const tabTitle = (
|
||||
<div className="d-flex">
|
||||
<Icon src={ChevronLeft} className="arrow-back-icon" />
|
||||
<div className="d-inline-flex flex-wrap align-items-center">
|
||||
<Icon src={ChevronLeft} />
|
||||
<span className="ml-2">{intl.formatMessage(messages['sign.in.text'])}</span>
|
||||
</div>
|
||||
);
|
||||
@@ -64,7 +65,7 @@ const ForgotPasswordPage = (props) => {
|
||||
return (
|
||||
<BaseComponent>
|
||||
<div>
|
||||
<Tabs activeKey="" id="controlled-tab-example" onSelect={(k) => setKey(k)}>
|
||||
<Tabs activeKey="" id="controlled-tab" onSelect={(k) => setKey(k)}>
|
||||
<Tab title={tabTitle} eventKey={LOGIN_PAGE} />
|
||||
</Tabs>
|
||||
{ key && (
|
||||
@@ -132,14 +133,16 @@ const ForgotPasswordPage = (props) => {
|
||||
name="forgot-password"
|
||||
className="ml-4 font-weight-500 text-body"
|
||||
destination={supportUrl}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
window.open(supportUrl, '_blank');
|
||||
}}
|
||||
>{intl.formatMessage(messages['need.help.sign.in.text'])}
|
||||
target="_blank"
|
||||
showLaunchIcon={false}
|
||||
>
|
||||
{intl.formatMessage(messages['need.help.sign.in.text'])}
|
||||
</Hyperlink>
|
||||
<p className="mt-5 one-rem-font">{intl.formatMessage(messages['additional.help.text'])}
|
||||
<span><Hyperlink isInline destination={`mailto:${getConfig().INFO_EMAIL}`}>{getConfig().INFO_EMAIL}</Hyperlink></span>
|
||||
<p className="mt-5 small text-gray-700">
|
||||
{intl.formatMessage(messages['additional.help.text'], { platformName })}
|
||||
<span>
|
||||
<Hyperlink isInline destination={`mailto:${getConfig().INFO_EMAIL}`}>{getConfig().INFO_EMAIL}</Hyperlink>
|
||||
</span>
|
||||
</p>
|
||||
</Form>
|
||||
</>
|
||||
|
||||
@@ -84,7 +84,7 @@ const messages = defineMessages({
|
||||
},
|
||||
'additional.help.text': {
|
||||
id: 'additional.help.text',
|
||||
defaultMessage: 'For additional help, contact edX support at ',
|
||||
defaultMessage: 'For additional help, contact {platformName} support at ',
|
||||
description: 'additional help text on forgot password page',
|
||||
},
|
||||
'sign.in.text': {
|
||||
|
||||
@@ -6,7 +6,6 @@ import { Alert, Hyperlink } from '@edx/paragon';
|
||||
import { Error } from '@edx/paragon/icons';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import processLink from '../data/utils';
|
||||
import ChangePasswordPrompt from './ChangePasswordPrompt';
|
||||
import {
|
||||
ACCOUNT_LOCKED_OUT,
|
||||
@@ -24,10 +23,9 @@ import messages from './messages';
|
||||
|
||||
const LoginFailureMessage = (props) => {
|
||||
const { intl } = props;
|
||||
const { context, errorCode, value } = props.loginError;
|
||||
const { context, errorCode } = props.loginError;
|
||||
const authService = getAuthService();
|
||||
let errorList;
|
||||
let link;
|
||||
let resetLink = (
|
||||
<Hyperlink destination="/reset" isInline>
|
||||
{intl.formatMessage(messages['login.incorrect.credentials.error.reset.link.text'])}
|
||||
@@ -70,9 +68,6 @@ const LoginFailureMessage = (props) => {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case INTERNAL_SERVER_ERROR:
|
||||
errorList = <p>{intl.formatMessage(messages['internal.server.error.message'])}</p>;
|
||||
break;
|
||||
case INVALID_FORM:
|
||||
errorList = <p>{intl.formatMessage(messages['login.form.invalid.error.message'])}</p>;
|
||||
break;
|
||||
@@ -149,28 +144,10 @@ const LoginFailureMessage = (props) => {
|
||||
);
|
||||
case REQUIRE_PASSWORD_CHANGE:
|
||||
return <ChangePasswordPrompt />;
|
||||
case INTERNAL_SERVER_ERROR:
|
||||
default:
|
||||
// TODO: use errorCode instead of processing error messages on frontend
|
||||
errorList = value.trim().split('\n');
|
||||
errorList = errorList.map((error) => {
|
||||
let matches;
|
||||
if (error.includes('a href')) {
|
||||
matches = processLink(error);
|
||||
const [beforeLink, href, linkText, afterLink] = matches;
|
||||
link = href;
|
||||
if (href.indexOf('/dashboard?tpa_hint') === 0) {
|
||||
link = `/login?next=${href}`;
|
||||
}
|
||||
return (
|
||||
<p key={error}>
|
||||
{beforeLink}
|
||||
<a href={link}>{linkText}</a>
|
||||
{afterLink}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
return <p key={error}>{error}</p>;
|
||||
});
|
||||
errorList = <p>{intl.formatMessage(messages['internal.server.error.message'])}</p>;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -185,7 +162,6 @@ LoginFailureMessage.defaultProps = {
|
||||
loginError: {
|
||||
redirectUrl: null,
|
||||
errorCode: null,
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -194,7 +170,6 @@ LoginFailureMessage.propTypes = {
|
||||
context: PropTypes.object,
|
||||
email: PropTypes.string,
|
||||
errorCode: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
redirectUrl: PropTypes.string,
|
||||
}),
|
||||
intl: intlShape.isRequired,
|
||||
|
||||
@@ -201,11 +201,10 @@ describe('LoginFailureMessage', () => {
|
||||
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
|
||||
});
|
||||
|
||||
it('should match direct render of error message', () => {
|
||||
const errorMessage = 'Email or password is incorrect.';
|
||||
it('should match internal server of error message', () => {
|
||||
props = {
|
||||
loginError: {
|
||||
value: errorMessage,
|
||||
errorCode: 'invalid-error-code',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -215,29 +214,10 @@ describe('LoginFailureMessage', () => {
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
const expectedMessage = 'We couldn\'t sign you in.'.concat(errorMessage);
|
||||
const expectedMessage = 'We couldn\'t sign you in.An error has occurred. Try refreshing the page, or check your internet connection.';
|
||||
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
|
||||
});
|
||||
|
||||
it('should match error message containing link snapshot', () => {
|
||||
props = {
|
||||
loginError: {
|
||||
value: 'To be on the safe side, you can reset your password <a href="/reset">here</a> before you try again.\n',
|
||||
},
|
||||
};
|
||||
|
||||
const loginFailureMessage = mount(
|
||||
<IntlProvider locale="en">
|
||||
<IntlLoginFailureMessage {...props} />
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
const expectedMessage = 'We couldn\'t sign you in.To be on the safe side, you can reset your password here before you try again.';
|
||||
|
||||
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
|
||||
expect(loginFailureMessage.find('#login-failure-alert').find('a').props().href).toEqual('/reset');
|
||||
});
|
||||
|
||||
it('should show modal that nudges users to change password', () => {
|
||||
props = {
|
||||
loginError: {
|
||||
|
||||
@@ -13,6 +13,7 @@ import configureStore from 'redux-mock-store';
|
||||
|
||||
import { COMPLETE_STATE, PENDING_STATE } from '../../data/constants';
|
||||
import { loginRequest, loginRequestFailure, loginRequestReset } from '../data/actions';
|
||||
import { INTERNAL_SERVER_ERROR } from '../data/constants';
|
||||
import LoginFailureMessage from '../LoginFailure';
|
||||
import LoginPage from '../LoginPage';
|
||||
|
||||
@@ -201,12 +202,12 @@ describe('LoginPage', () => {
|
||||
// ******** test alert messages ********
|
||||
|
||||
it('should match login error message', () => {
|
||||
const errorMessage = 'Email or password is incorrect.';
|
||||
const errorMessage = 'An error has occurred. Try refreshing the page, or check your internet connection.';
|
||||
store = mockStore({
|
||||
...initialState,
|
||||
login: {
|
||||
...initialState.login,
|
||||
loginError: { value: errorMessage },
|
||||
loginError: { errorCode: INTERNAL_SERVER_ERROR },
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ const ResetPasswordPage = (props) => {
|
||||
};
|
||||
|
||||
const tabTitle = (
|
||||
<div className="d-flex">
|
||||
<Icon src={ChevronLeft} className="arrow-back-icon" />
|
||||
<div className="d-inline-flex flex-wrap align-items-center">
|
||||
<Icon src={ChevronLeft} />
|
||||
<span className="ml-2">{intl.formatMessage(messages['sign.in'])}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user