diff --git a/package-lock.json b/package-lock.json
index a05b8b10..1c332ba1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4691,31 +4691,6 @@
}
}
},
- "@loadable/component": {
- "version": "5.14.1",
- "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.14.1.tgz",
- "integrity": "sha512-UQBZfZrp1FLTf8RNhljXNHFNY4QhAA1L2+GOEeABBFre9TD0aFyQh3Sai5QxcOfy+FTbjIfti5iHaNRR7yUzEQ==",
- "requires": {
- "@babel/runtime": "^7.7.7",
- "hoist-non-react-statics": "^3.3.1",
- "react-is": "^16.12.0"
- },
- "dependencies": {
- "@babel/runtime": {
- "version": "7.12.18",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.18.tgz",
- "integrity": "sha512-BogPQ7ciE6SYAUPtlm9tWbgI9+2AgqSam6QivMgXgAT+fKbgppaj4ZX15MHeLC1PVF5sNk70huBu20XxWOs8Cg==",
- "requires": {
- "regenerator-runtime": "^0.13.4"
- }
- },
- "regenerator-runtime": {
- "version": "0.13.7",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
- "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
- }
- }
- },
"@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
diff --git a/package.json b/package.json
index 8bdc7ec6..c6b456aa 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,6 @@
"@fortawesome/free-regular-svg-icons": "5.15.1",
"@fortawesome/free-solid-svg-icons": "5.15.1",
"@fortawesome/react-fontawesome": "0.1.13",
- "@loadable/component": "^5.14.1",
"babel-polyfill": "6.26.0",
"classnames": "^2.2.6",
"extract-react-intl-messages": "^4.1.1",
diff --git a/src/common-components/UnAuthOnlyRoute.jsx b/src/common-components/UnAuthOnlyRoute.jsx
new file mode 100644
index 00000000..f136f4f3
--- /dev/null
+++ b/src/common-components/UnAuthOnlyRoute.jsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import { Route } from 'react-router-dom';
+import { AppContext } from '@edx/frontend-platform/react';
+
+import { DEFAULT_REDIRECT_URL } from '../data/constants';
+
+/**
+ * This wrapper redirects the requester to our default redirect url if they are
+ * already authenticated.
+ */
+const UnAuthOnlyRoute = (props) => {
+ const { authenticatedUser, config } = React.useContext(AppContext);
+
+ if (authenticatedUser) {
+ global.location.href = config.LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
+ return null;
+ }
+
+ return ;
+};
+
+export default UnAuthOnlyRoute;
diff --git a/src/common-components/UnAuthenticatedRoute.jsx b/src/common-components/UnAuthenticatedRoute.jsx
deleted file mode 100644
index 2c9371f7..00000000
--- a/src/common-components/UnAuthenticatedRoute.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-/* eslint-disable react/prop-types */
-import React, { useEffect } from 'react';
-import { Route, useRouteMatch } from 'react-router-dom';
-import { AppContext } from '@edx/frontend-platform/react';
-import { sendPageEvent } from '@edx/frontend-platform/analytics';
-
-import { DEFAULT_REDIRECT_URL } from '../data/constants';
-
-/**
- * This wrapper redirects the requester to our default redirect url if they are
- * already authenticated.
- */
-const UnAuthenticatedRoute = (props) => {
- const { authenticatedUser, config } = React.useContext(AppContext);
- const match = useRouteMatch({
- path: props.path,
- exact: props.exact,
- strict: props.strict,
- sensitive: props.sensitive,
- });
-
- if (authenticatedUser) {
- global.location.href = config.LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
- return null;
- }
-
- useEffect(() => {
- if (match) {
- sendPageEvent('login_and_registration', props.path.replace('/', ''));
- }
- }, [match]);
-
- return ;
-};
-
-export default UnAuthenticatedRoute;
diff --git a/src/common-components/index.jsx b/src/common-components/index.jsx
index 65fc8d4b..20894220 100644
--- a/src/common-components/index.jsx
+++ b/src/common-components/index.jsx
@@ -1,7 +1,7 @@
export { default as HeaderLayout } from './HeaderLayout';
export { default as RedirectLogistration } from './RedirectLogistration';
export { default as registerIcons } from './RegisterFaIcons';
-export { default as UnAuthenticatedRoute } from './UnAuthenticatedRoute';
+export { default as UnAuthOnlyRoute } from './UnAuthOnlyRoute';
export { default as NotFoundPage } from './NotFoundPage';
export { default as SocialAuthProviders } from './SocialAuthProviders';
export { default as ThirdPartyAuthAlert } from './ThirdPartyAuthAlert';
@@ -12,4 +12,3 @@ export { default as APIFailureMessage } from './APIFailureMessage';
export { default as reducer } from './data/reducers';
export { default as saga } from './data/sagas';
export { storeName } from './data/selectors';
-export { default as Spinner } from './Spinner';
diff --git a/src/common-components/tests/UnAuthenticatedRoute.test.jsx b/src/common-components/tests/UnAuthOnlyRoute.test.jsx
similarity index 58%
rename from src/common-components/tests/UnAuthenticatedRoute.test.jsx
rename to src/common-components/tests/UnAuthOnlyRoute.test.jsx
index bfe34986..3b0ad0cb 100644
--- a/src/common-components/tests/UnAuthenticatedRoute.test.jsx
+++ b/src/common-components/tests/UnAuthOnlyRoute.test.jsx
@@ -1,36 +1,31 @@
-/* eslint-disable react/prop-types */
import React from 'react';
import { mount } from 'enzyme';
import { BrowserRouter as Router, MemoryRouter, Switch } from 'react-router-dom';
import { getConfig } from '@edx/frontend-platform';
-import * as analytics from '@edx/frontend-platform/analytics';
-import { UnAuthenticatedRoute } from '..';
-import { DEFAULT_REDIRECT_URL, LOGIN_PAGE, REGISTER_PAGE } from '../../data/constants';
+import { UnAuthOnlyRoute } from '..';
+import { DEFAULT_REDIRECT_URL, LOGIN_PAGE } from '../../data/constants';
const RRD = require('react-router-dom');
// Just render plain div with its children
+// eslint-disable-next-line react/prop-types
RRD.BrowserRouter = ({ children }) =>
{ children }
;
module.exports = RRD;
-jest.mock('@edx/frontend-platform/analytics');
-analytics.sendPageEvent = jest.fn();
-
const TestApp = () => (
- (Login Page)} />
- (Register Page)} />
+ (Login Page)} />
);
-describe('UnAuthenticatedRoute', () => {
- const routerWrapper = (initialEntry) => (
-
+describe('UnAuthOnlyRoute', () => {
+ const routerWrapper = () => (
+
);
@@ -65,14 +60,4 @@ describe('UnAuthenticatedRoute', () => {
expect(wrapper.find('span').text()).toBe('Login Page');
});
-
- it('send page event when login page is rendered', () => {
- mount(routerWrapper());
- expect(analytics.sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'login');
- });
-
- it('send page event when register page is rendered', () => {
- mount(routerWrapper(REGISTER_PAGE));
- expect(analytics.sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'register');
- });
});
diff --git a/src/forgot-password/ForgotPasswordPage.jsx b/src/forgot-password/ForgotPasswordPage.jsx
index 6142b76c..3e5446dd 100644
--- a/src/forgot-password/ForgotPasswordPage.jsx
+++ b/src/forgot-password/ForgotPasswordPage.jsx
@@ -6,6 +6,7 @@ import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { getConfig } from '@edx/frontend-platform';
+import { sendPageEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import {
Alert,
@@ -63,6 +64,8 @@ const ForgotPasswordPage = (props) => {
return error;
};
+ sendPageEvent('login_and_registration', 'reset');
+
return (
import('./ForgotPasswordPage.jsx'), {
- fallback: ,
-});
-
-const LoadableForgotPasswordPage = () => ;
-
-export default LoadableForgotPasswordPage;
diff --git a/src/forgot-password/index.js b/src/forgot-password/index.js
index 5e3f59c4..2d30ff06 100644
--- a/src/forgot-password/index.js
+++ b/src/forgot-password/index.js
@@ -1,4 +1,4 @@
-export { default } from './LoadableForgotPasswordPage';
+export { default } from './ForgotPasswordPage';
export { default as reducer } from './data/reducers';
export { FORGOT_PASSWORD } from './data/actions';
export { default as saga } from './data/sagas';
diff --git a/src/index.jsx b/src/index.jsx
index e88fb667..c3b345f5 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -7,19 +7,20 @@ import { AppProvider, ErrorPage } from '@edx/frontend-platform/react';
import React from 'react';
import ReactDOM from 'react-dom';
import { Redirect, Route, Switch } from 'react-router-dom';
+
import { messages as headerMessages } from '@edx/frontend-component-header';
import configureStore from './data/configureStore';
-import LoadableForgotPasswordPage from './forgot-password';
-import LoadableRegistrationPage from './register';
-import LoadableLoginPage from './login';
-import LoadableResetPasswordPage from './reset-password';
+import { RegistrationPage } from './register';
+import { LoginPage } from './login';
import {
LOGIN_PAGE, PAGE_NOT_FOUND, REGISTER_PAGE, RESET_PAGE, PASSWORD_RESET_CONFIRM,
} from './data/constants';
+import ForgotPasswordPage from './forgot-password';
import {
- HeaderLayout, UnAuthenticatedRoute, registerIcons, NotFoundPage,
+ HeaderLayout, UnAuthOnlyRoute, registerIcons, NotFoundPage,
} from './common-components';
+import ResetPasswordPage from './reset-password';
import appMessages from './i18n';
import './index.scss';
@@ -34,10 +35,10 @@ subscribe(APP_READY, () => {
-
-
-
-
+
+
+
+
diff --git a/src/login/LoadableLoginPage.jsx b/src/login/LoadableLoginPage.jsx
deleted file mode 100644
index 93782c61..00000000
--- a/src/login/LoadableLoginPage.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-import loadable from '@loadable/component';
-import Spinner from '../common-components/Spinner';
-
-const LoadableComponent = loadable(() => import('./LoginPage.jsx'), {
- fallback: ,
-});
-
-const LoadableLoginPage = () => ;
-
-export default LoadableLoginPage;
diff --git a/src/login/LoginHelpLinks.jsx b/src/login/LoginHelpLinks.jsx
index 46cbfff0..31f179bc 100644
--- a/src/login/LoginHelpLinks.jsx
+++ b/src/login/LoginHelpLinks.jsx
@@ -1,5 +1,4 @@
import React, { useState } from 'react';
-import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -30,17 +29,19 @@ const LoginHelpLinks = (props) => {
};
const forgotPasswordLink = () => (
-
{intl.formatMessage(messages['forgot.password.link'])}
-
+
);
const signUpLink = () => (
- {intl.formatMessage(messages['register.link'])}
-
+
+ {intl.formatMessage(messages['register.link'])}
+
);
const loginIssueSupportURL = (config) => (config.LOGIN_ISSUE_SUPPORT_LINK
diff --git a/src/login/LoginPage.jsx b/src/login/LoginPage.jsx
index eb0ea683..fddff73a 100644
--- a/src/login/LoginPage.jsx
+++ b/src/login/LoginPage.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import Skeleton from 'react-loading-skeleton';
-import { Link } from 'react-router-dom';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
@@ -38,6 +37,7 @@ class LoginPage extends React.Component {
constructor(props, context) {
super(props, context);
+ sendPageEvent('login_and_registration', 'login');
this.state = {
password: '',
email: '',
@@ -197,13 +197,9 @@ class LoginPage extends React.Component {
) : null}
{intl.formatMessage(messages['first.time.here'])}
-
- {intl.formatMessage(messages['create.an.account'])}
-
+
+ {intl.formatMessage(messages['create.an.account'])}.
+
diff --git a/src/login/index.js b/src/login/index.js
index 8591800b..769161d2 100644
--- a/src/login/index.js
+++ b/src/login/index.js
@@ -1,4 +1,4 @@
-export { default } from './LoadableLoginPage';
+export { default as LoginPage } from './LoginPage';
export { default as reducer } from './data/reducers';
export { default as saga } from './data/sagas';
export { storeName } from './data/selectors';
diff --git a/src/login/messages.jsx b/src/login/messages.jsx
index 9878fde8..d64a2dc7 100644
--- a/src/login/messages.jsx
+++ b/src/login/messages.jsx
@@ -48,7 +48,7 @@ const messages = defineMessages({
},
'create.an.account': {
id: 'create.an.account',
- defaultMessage: 'Create an account.',
+ defaultMessage: 'Create an account',
description: 'Message on button to return to register page',
},
'or.sign.in.with': {
diff --git a/src/login/tests/LoginHelpLinks.test.jsx b/src/login/tests/LoginHelpLinks.test.jsx
index 6adb7dab..e975aa1c 100644
--- a/src/login/tests/LoginHelpLinks.test.jsx
+++ b/src/login/tests/LoginHelpLinks.test.jsx
@@ -1,5 +1,4 @@
import React from 'react';
-import { BrowserRouter as Router } from 'react-router-dom';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import * as analytics from '@edx/frontend-platform/analytics';
import { mount } from 'enzyme';
@@ -21,9 +20,7 @@ describe('LoginHelpLinks', () => {
const reduxWrapper = children => (
-
- {children}
-
+ {children}
);
diff --git a/src/login/tests/LoginPage.test.jsx b/src/login/tests/LoginPage.test.jsx
index 525b2646..6a892a77 100644
--- a/src/login/tests/LoginPage.test.jsx
+++ b/src/login/tests/LoginPage.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import { Provider } from 'react-redux';
-import { BrowserRouter as Router } from 'react-router-dom';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import configureStore from 'redux-mock-store';
@@ -19,6 +18,7 @@ import { COMPLETE_STATE, PENDING_STATE } from '../../data/constants';
jest.mock('@edx/frontend-platform/analytics');
analytics.sendTrackEvent = jest.fn();
+analytics.sendPageEvent = jest.fn();
const IntlLoginFailureMessage = injectIntl(LoginFailureMessage);
const IntlLoginPage = injectIntl(LoginPage);
@@ -61,11 +61,7 @@ describe('LoginPage', () => {
const reduxWrapper = children => (
-
-
- {children}
-
-
+ {children}
);
@@ -381,6 +377,11 @@ describe('LoginPage', () => {
expect(analytics.sendTrackEvent).toHaveBeenCalledWith('edx.bi.register_form.toggled', { category: 'user-engagement' });
});
+ it('send page event when login page is rendered', () => {
+ mount(reduxWrapper());
+ expect(analytics.sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'login');
+ });
+
it('send tracking and page events when institutional button is clicked', () => {
store = mockStore({
...initialState,
diff --git a/src/login/tests/__snapshots__/LoginPage.test.jsx.snap b/src/login/tests/__snapshots__/LoginPage.test.jsx.snap
index 7abff277..44fd63e5 100644
--- a/src/login/tests/__snapshots__/LoginPage.test.jsx.snap
+++ b/src/login/tests/__snapshots__/LoginPage.test.jsx.snap
@@ -13,11 +13,13 @@ exports[`LoginPage should match TPA provider snapshot 1`] = `
First time here?
- Create an account.
+ Create an account
+ .
First time here?
- Create an account.
+ Create an account
+ .
First time here?
- Create an account.
+ Create an account
+ .
First time here?
- Create an account.
+ Create an account
+ .
First time here?
- Create an account.
+ Create an account
+ .
import('./RegistrationPage.jsx'), {
- fallback: ,
-});
-
-const LoadableRegistrationPage = () => ;
-
-export default LoadableRegistrationPage;
diff --git a/src/register/RegistrationPage.jsx b/src/register/RegistrationPage.jsx
index 0794ad7e..3fc92875 100644
--- a/src/register/RegistrationPage.jsx
+++ b/src/register/RegistrationPage.jsx
@@ -1,5 +1,4 @@
import React from 'react';
-import { Link } from 'react-router-dom';
import camelCase from 'lodash.camelcase';
import { connect } from 'react-redux';
@@ -7,7 +6,7 @@ import Skeleton from 'react-loading-skeleton';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
-import { sendTrackEvent } from '@edx/frontend-platform/analytics';
+import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
import {
injectIntl, intlShape, getCountryList, getLocale, FormattedMessage,
} from '@edx/frontend-platform/i18n';
@@ -37,7 +36,9 @@ class RegistrationPage extends React.Component {
constructor(props, context) {
super(props, context);
+ sendPageEvent('login_and_registration', 'register');
this.intl = props.intl;
+
this.state = {
email: '',
name: '',
@@ -435,13 +436,9 @@ class RegistrationPage extends React.Component {
)}
{intl.formatMessage(messages['already.have.an.edx.account'])}
-
+
{intl.formatMessage(messages['sign.in.hyperlink'])}
-
+
{intl.formatMessage(messages['create.a.new.account'])}
diff --git a/src/register/index.js b/src/register/index.js
index 0703e15e..496c0f7b 100644
--- a/src/register/index.js
+++ b/src/register/index.js
@@ -1,4 +1,4 @@
-export { default } from './LoadableRegistrationPage';
+export { default as RegistrationPage } from './RegistrationPage';
export { default as reducer } from './data/reducers';
export { default as saga } from './data/sagas';
export { storeName } from './data/selectors';
diff --git a/src/register/tests/RegistrationPage.test.jsx b/src/register/tests/RegistrationPage.test.jsx
index 0c2995f1..ae4fcc98 100644
--- a/src/register/tests/RegistrationPage.test.jsx
+++ b/src/register/tests/RegistrationPage.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import { Provider } from 'react-redux';
-import { BrowserRouter as Router } from 'react-router-dom';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import configureStore from 'redux-mock-store';
@@ -19,6 +18,7 @@ import { fetchRealtimeValidations, registerNewUser } from '../data/actions';
jest.mock('@edx/frontend-platform/analytics');
analytics.sendTrackEvent = jest.fn();
+analytics.sendPageEvent = jest.fn();
const IntlRegistrationPage = injectIntl(RegistrationPage);
const IntlRegistrationFailure = injectIntl(RegistrationFailureMessage);
@@ -76,11 +76,7 @@ describe('RegistrationPageTests', () => {
const reduxWrapper = children => (
-
-
- {children}
-
-
+ {children}
);
@@ -133,6 +129,11 @@ describe('RegistrationPageTests', () => {
expect(analytics.sendTrackEvent).toHaveBeenCalledWith('edx.bi.login_form.toggled', { category: 'user-engagement' });
});
+ it('send page event when register page is rendered', () => {
+ mount(reduxWrapper());
+ expect(analytics.sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'register');
+ });
+
it('should show optional fields section on optional check enabled', () => {
const registrationPage = mount(reduxWrapper());
registrationPage.find('input#optional').simulate('change', { target: { checked: true } });
diff --git a/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap b/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap
index a24177be..fbf4fe93 100644
--- a/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap
+++ b/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap
@@ -13,9 +13,10 @@ exports[`RegistrationPageTests should match TPA provider snapshot 1`] = `
Already have an edX account?
Sign in.
@@ -1561,9 +1562,10 @@ exports[`RegistrationPageTests should match default section snapshot 1`] = `
Already have an edX account?
Sign in.
@@ -3070,9 +3072,10 @@ exports[`RegistrationPageTests should match pending button state snapshot 1`] =
Already have an edX account?
Sign in.
diff --git a/src/reset-password/LoadableResetPasswordPage.jsx b/src/reset-password/LoadableResetPasswordPage.jsx
deleted file mode 100644
index 4f6b7831..00000000
--- a/src/reset-password/LoadableResetPasswordPage.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-import loadable from '@loadable/component';
-import Spinner from '../common-components/Spinner';
-
-const LoadableComponent = loadable(() => import('./ResetPasswordPage.jsx'), {
- fallback: ,
-});
-
-const LoadableResetPasswordPage = () => ;
-
-export default LoadableResetPasswordPage;
diff --git a/src/reset-password/ResetPasswordPage.jsx b/src/reset-password/ResetPasswordPage.jsx
index 5687cf4c..1b46aeaa 100644
--- a/src/reset-password/ResetPasswordPage.jsx
+++ b/src/reset-password/ResetPasswordPage.jsx
@@ -18,8 +18,8 @@ import ResetSuccessMessage from './ResetSuccess';
import {
AuthnValidationFormGroup,
APIFailureMessage,
- Spinner,
} from '../common-components';
+import Spinner from './Spinner';
import { API_RATELIMIT_ERROR, INTERNAL_SERVER_ERROR } from '../data/constants';
const ResetPasswordPage = (props) => {
diff --git a/src/common-components/Spinner.jsx b/src/reset-password/Spinner.jsx
similarity index 100%
rename from src/common-components/Spinner.jsx
rename to src/reset-password/Spinner.jsx
diff --git a/src/reset-password/index.js b/src/reset-password/index.js
index 335d1d21..2116170a 100644
--- a/src/reset-password/index.js
+++ b/src/reset-password/index.js
@@ -1,4 +1,4 @@
-export { default } from './LoadableResetPasswordPage';
+export { default } from './ResetPasswordPage';
export { default as reducer } from './data/reducers';
export { RESET_PASSWORD } from './data/actions';
export { default as saga } from './data/sagas';