diff --git a/package-lock.json b/package-lock.json
index b857455a..7d7bc6b0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/browserslist-config": "^1.1.0",
+ "@edx/frontend-component-header": "^5.3.1",
"@edx/frontend-enterprise-hotjar": "3.0.0",
"@edx/frontend-platform": "8.1.0",
"@edx/openedx-atlas": "^0.6.0",
@@ -2255,9 +2256,9 @@
}
},
"node_modules/@edx/frontend-component-footer": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-14.0.0.tgz",
- "integrity": "sha512-3Riz6ippBnPz1oq6gZgFBx27bJkNL+rwwKrv0uCuHV/5MscS1aYeKx1ZAMuUsxkKcGX6uhyU6PwM6agvnhKfNQ==",
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-13.1.0.tgz",
+ "integrity": "sha512-Rtv8dfQmL75El8kF8dG9nYF1Cqj2AbWPLVLE4b0XTvipfx2RMeDKpgAO5XLAzTt0h+5fmiMCGhVEv3Y70Xu5pQ==",
"peer": true,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "6.5.2",
@@ -2339,6 +2340,82 @@
"react": ">=16.3"
}
},
+ "node_modules/@edx/frontend-component-header": {
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-5.3.4.tgz",
+ "integrity": "sha512-niuaXu0+qWPHud9Bs1pqmNXvZc9jpf8WS270/2YEH5owokd+BiDwQ6MWkvS9qbuQIVGPGTSZFFTttUKmQO5O0A==",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "6.6.0",
+ "@fortawesome/free-brands-svg-icons": "6.6.0",
+ "@fortawesome/free-regular-svg-icons": "6.6.0",
+ "@fortawesome/free-solid-svg-icons": "6.6.0",
+ "@fortawesome/react-fontawesome": "^0.2.0",
+ "axios-mock-adapter": "1.22.0",
+ "babel-polyfill": "6.26.0",
+ "jest-environment-jsdom": "^29.7.0",
+ "react-responsive": "8.2.0",
+ "react-transition-group": "4.4.5"
+ },
+ "peerDependencies": {
+ "@edx/frontend-platform": "^7.0.0 || ^8.0.0",
+ "@openedx/paragon": ">= 21.5.7 < 23.0.0",
+ "prop-types": "^15.5.10",
+ "react": "^16.9.0 || ^17.0.0",
+ "react-dom": "^16.9.0 || ^17.0.0"
+ }
+ },
+ "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-common-types": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz",
+ "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-svg-core": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz",
+ "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-brands-svg-icons": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz",
+ "integrity": "sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-regular-svg-icons": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz",
+ "integrity": "sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ==",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-solid-svg-icons": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz",
+ "integrity": "sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@edx/frontend-enterprise-hotjar": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-hotjar/-/frontend-enterprise-hotjar-3.0.0.tgz",
@@ -7114,7 +7191,6 @@
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.22.0.tgz",
"integrity": "sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==",
- "dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"is-buffer": "^2.0.5"
@@ -13420,7 +13496,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
- "dev": true,
"funding": [
{
"type": "github",
diff --git a/package.json b/package.json
index 92f23b94..c6e72f40 100755
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/browserslist-config": "^1.1.0",
+ "@edx/frontend-component-header": "^5.3.1",
"@edx/frontend-enterprise-hotjar": "3.0.0",
"@edx/frontend-platform": "8.1.0",
"@edx/openedx-atlas": "^0.6.0",
diff --git a/src/App.scss b/src/App.scss
index eed6b145..2292f72e 100755
--- a/src/App.scss
+++ b/src/App.scss
@@ -9,6 +9,7 @@ $fa-font-path: "~font-awesome/fonts";
$input-focus-box-shadow: $input-box-shadow; // hack to get upgrade to paragon 4.0.0 to work
+@import "~@edx/frontend-component-header/dist/index";
@import "~@edx/frontend-component-footer/dist/_footer";
.text-ellipsis {
diff --git a/src/containers/LearnerDashboardHeader/CollapsedHeader/CollapseMenuBody.jsx b/src/containers/LearnerDashboardHeader/CollapsedHeader/CollapseMenuBody.jsx
deleted file mode 100644
index 82de5aaf..00000000
--- a/src/containers/LearnerDashboardHeader/CollapsedHeader/CollapseMenuBody.jsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import { getConfig } from '@edx/frontend-platform';
-import { useIntl } from '@edx/frontend-platform/i18n';
-import { AppContext } from '@edx/frontend-platform/react';
-import { Button, Badge } from '@openedx/paragon';
-
-import urls from 'data/services/lms/urls';
-import { reduxHooks } from 'hooks';
-
-import { findCoursesNavDropdownClicked } from '../hooks';
-import messages from '../messages';
-
-export const CollapseMenuBody = ({ isOpen }) => {
- const { formatMessage } = useIntl();
- const { authenticatedUser } = React.useContext(AppContext);
-
- const dashboard = reduxHooks.useEnterpriseDashboardData();
- const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
-
- const exploreCoursesClick = findCoursesNavDropdownClicked(
- urls.baseAppUrl(courseSearchUrl),
- );
-
- if (!isOpen) {
- return null;
- }
-
- return (
-
-
-
-
-
- {authenticatedUser && (
- <>
- {!!dashboard && (
-
- )}
- {!dashboard && getConfig().CAREER_LINK_URL && (
-
- )}
-
-
- {getConfig().ORDER_HISTORY_URL && (
-
- )}
-
- >
- )}
-
- );
-};
-
-CollapseMenuBody.propTypes = {
- isOpen: PropTypes.bool.isRequired,
-};
-
-export default CollapseMenuBody;
diff --git a/src/containers/LearnerDashboardHeader/CollapsedHeader/CollapseMenuBody.test.jsx b/src/containers/LearnerDashboardHeader/CollapsedHeader/CollapseMenuBody.test.jsx
deleted file mode 100644
index 2af8ae7e..00000000
--- a/src/containers/LearnerDashboardHeader/CollapsedHeader/CollapseMenuBody.test.jsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { shallow } from '@edx/react-unit-test-utils';
-import { AppContext } from '@edx/frontend-platform/react';
-
-import CollapseMenuBody from './CollapseMenuBody';
-
-jest.mock('@edx/frontend-platform/react', () => ({
- AppContext: {
- authenticatedUser: {
- username: 'username',
- },
- },
-}));
-
-jest.mock('hooks', () => ({
- reduxHooks: {
- useEnterpriseDashboardData: () => ({
- url: 'url',
- }),
- usePlatformSettingsData: () => ({
- courseSearchUrl: '/courseSearchUrl',
- }),
- },
-}));
-
-jest.mock('../hooks', () => ({
- findCoursesNavDropdownClicked: (url) => jest.fn().mockName(`findCoursesNavDropdownClicked("${url}")`),
-}));
-
-describe('CollapseMenuBody', () => {
- test('render', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
-
- test('render empty if not open', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- expect(wrapper.isEmptyRender()).toBe(true);
- });
-
- test('render unauthenticated', () => {
- const { authenticatedUser } = AppContext;
- AppContext.authenticatedUser = null;
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- AppContext.authenticatedUser = authenticatedUser;
- });
-});
diff --git a/src/containers/LearnerDashboardHeader/CollapsedHeader/__snapshots__/CollapseMenuBody.test.jsx.snap b/src/containers/LearnerDashboardHeader/CollapsedHeader/__snapshots__/CollapseMenuBody.test.jsx.snap
deleted file mode 100644
index c8cc4de8..00000000
--- a/src/containers/LearnerDashboardHeader/CollapsedHeader/__snapshots__/CollapseMenuBody.test.jsx.snap
+++ /dev/null
@@ -1,105 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`CollapseMenuBody render 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
-exports[`CollapseMenuBody render empty if not open 1`] = `null`;
-
-exports[`CollapseMenuBody render unauthenticated 1`] = `
-
-
-
-
-
-
-`;
diff --git a/src/containers/LearnerDashboardHeader/CollapsedHeader/__snapshots__/index.test.jsx.snap b/src/containers/LearnerDashboardHeader/CollapsedHeader/__snapshots__/index.test.jsx.snap
deleted file mode 100644
index 2a1dc7bc..00000000
--- a/src/containers/LearnerDashboardHeader/CollapsedHeader/__snapshots__/index.test.jsx.snap
+++ /dev/null
@@ -1,48 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`CollapsedHeader render nothing if not collapsed 1`] = `false`;
-
-exports[`CollapsedHeader renders 1`] = `
-
-
-
-
-`;
-
-exports[`CollapsedHeader renders with isOpen true 1`] = `
-
-
-
-
-`;
diff --git a/src/containers/LearnerDashboardHeader/CollapsedHeader/index.jsx b/src/containers/LearnerDashboardHeader/CollapsedHeader/index.jsx
deleted file mode 100644
index 5cf9762b..00000000
--- a/src/containers/LearnerDashboardHeader/CollapsedHeader/index.jsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react';
-
-import { useIntl } from '@edx/frontend-platform/i18n';
-import { MenuIcon, Close } from '@openedx/paragon/icons';
-import { IconButton, Icon } from '@openedx/paragon';
-
-import { useLearnerDashboardHeaderData, useIsCollapsed } from '../hooks';
-
-import CollapseMenuBody from './CollapseMenuBody';
-import BrandLogo from '../BrandLogo';
-
-import messages from '../messages';
-
-export const CollapsedHeader = () => {
- const { formatMessage } = useIntl();
- const isCollapsed = useIsCollapsed();
- const { isOpen, toggleIsOpen } = useLearnerDashboardHeaderData();
-
- return (
- isCollapsed && (
- <>
-
-
- >
- )
- );
-};
-
-CollapsedHeader.propTypes = {};
-
-export default CollapsedHeader;
diff --git a/src/containers/LearnerDashboardHeader/CollapsedHeader/index.test.jsx b/src/containers/LearnerDashboardHeader/CollapsedHeader/index.test.jsx
deleted file mode 100644
index c21e98cc..00000000
--- a/src/containers/LearnerDashboardHeader/CollapsedHeader/index.test.jsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { shallow } from '@edx/react-unit-test-utils';
-
-import CollapsedHeader from '.';
-
-import { useLearnerDashboardHeaderData, useIsCollapsed } from '../hooks';
-
-jest.mock('../BrandLogo', () => jest.fn(() => 'BrandLogo'));
-jest.mock('./CollapseMenuBody', () => jest.fn(() => 'CollapseMenuBody'));
-
-jest.mock('../hooks', () => ({
- useIsCollapsed: jest.fn(() => true),
- useLearnerDashboardHeaderData: jest.fn(() => ({
- isOpen: false,
- toggleIsOpen: jest.fn().mockName('toggleIsOpen'),
- })),
-}));
-
-describe('CollapsedHeader', () => {
- it('renders', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
-
- it('render nothing if not collapsed', () => {
- useIsCollapsed.mockReturnValueOnce(false);
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
-
- it('renders with isOpen true', () => {
- useLearnerDashboardHeaderData.mockReturnValueOnce({
- isOpen: true,
- toggleIsOpen: jest.fn().mockName('toggleIsOpen'),
- });
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
-});
diff --git a/src/containers/LearnerDashboardHeader/ExpandedHeader/AuthenticatedUserDropdown.jsx b/src/containers/LearnerDashboardHeader/ExpandedHeader/AuthenticatedUserDropdown.jsx
deleted file mode 100644
index e0751bb3..00000000
--- a/src/containers/LearnerDashboardHeader/ExpandedHeader/AuthenticatedUserDropdown.jsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import React from 'react';
-
-import { getConfig } from '@edx/frontend-platform';
-import { useIntl } from '@edx/frontend-platform/i18n';
-import { AppContext } from '@edx/frontend-platform/react';
-import { AvatarButton, Dropdown, Badge } from '@openedx/paragon';
-
-import { reduxHooks } from 'hooks';
-
-import messages from '../messages';
-
-export const AuthenticatedUserDropdown = () => {
- const { formatMessage } = useIntl();
- const { authenticatedUser } = React.useContext(AppContext);
- const dashboard = reduxHooks.useEnterpriseDashboardData();
-
- return (
- authenticatedUser && (
-
-
-
- {authenticatedUser.username}
-
-
-
- { getConfig().ENABLE_EDX_PERSONAL_DASHBOARD && (
- <>
- {formatMessage(messages.dashboardSwitch)}
-
- {formatMessage(messages.dashboardPersonal)}
-
- {!!dashboard && (
-
- {dashboard.label} {formatMessage(messages.dashboard)}
-
- )}
-
- >
- )}
-
- {!dashboard && getConfig().CAREER_LINK_URL && (
-
- {formatMessage(messages.career)}
-
- {formatMessage(messages.newAlert)}
-
-
- )}
-
- {formatMessage(messages.profile)}
-
-
- {formatMessage(messages.account)}
-
- {getConfig().ORDER_HISTORY_URL && (
-
- {formatMessage(messages.orderHistory)}
-
- )}
-
-
- {formatMessage(messages.signOut)}
-
-
-
- )
- );
-};
-
-AuthenticatedUserDropdown.propTypes = {};
-
-export default AuthenticatedUserDropdown;
diff --git a/src/containers/LearnerDashboardHeader/ExpandedHeader/AuthenticatedUserDropdown.test.jsx b/src/containers/LearnerDashboardHeader/ExpandedHeader/AuthenticatedUserDropdown.test.jsx
deleted file mode 100644
index e7452d35..00000000
--- a/src/containers/LearnerDashboardHeader/ExpandedHeader/AuthenticatedUserDropdown.test.jsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import { shallow } from '@edx/react-unit-test-utils';
-
-import { reduxHooks } from 'hooks';
-import { getConfig } from '@edx/frontend-platform';
-import { AppContext } from '@edx/frontend-platform/react';
-import { AuthenticatedUserDropdown } from './AuthenticatedUserDropdown';
-import { useIsCollapsed } from '../hooks';
-
-jest.mock('@edx/frontend-platform', () => ({
- getConfig: jest.fn(),
-}));
-
-jest.mock('@edx/frontend-platform/react', () => ({
- AppContext: {
- authenticatedUser: {
- profileImage: 'profileImage',
- username: 'username',
- },
- },
-}));
-const COURSE_SEARCH_URL = 'test-course-search-url';
-
-jest.mock('hooks', () => ({
- reduxHooks: {
- useEnterpriseDashboardData: jest.fn(),
- usePlatformSettingsData: jest.fn(() => ({
- courseSearchUrl: COURSE_SEARCH_URL,
- })),
- },
-}));
-jest.mock('../hooks', () => ({
- useIsCollapsed: jest.fn(),
- findCoursesNavDropdownClicked: (href) => jest.fn().mockName(`findCoursesNavDropdownClicked('${href}')`),
-}));
-
-jest.mock('data/services/lms/urls', () => ({
- baseAppUrl: (url) => (url),
- programsUrl: 'http://localhost:18000/dashboard/programs',
-}));
-
-const config = {
- ACCOUNT_PROFILE_URL: 'http://account-profile-url.test',
- ACCOUNT_SETTINGS_URL: 'http://account-settings-url.test',
- LOGOUT_URL: 'http://logout-url.test',
- ORDER_HISTORY_URL: 'http://order-history-url.test',
- SUPPORT_URL: 'http://localhost:18000/support',
- CAREER_LINK_URL: 'http://localhost:18000/career',
- LMS_BASE_URL: 'http:/localhost:18000',
- ENABLE_EDX_PERSONAL_DASHBOARD: true,
-};
-getConfig.mockReturnValue(config);
-
-describe('AuthenticatedUserDropdown', () => {
- const defaultDashboardData = {
- label: 'label',
- url: 'url',
- };
-
- describe('snapshots', () => {
- test('no auth render empty', () => {
- const { authenticatedUser } = AppContext;
- AppContext.authenticatedUser = null;
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- expect(wrapper.isEmptyRender()).toBe(true);
- AppContext.authenticatedUser = authenticatedUser;
- });
- test('with enterprise dashboard', () => {
- reduxHooks.useEnterpriseDashboardData.mockReturnValueOnce(defaultDashboardData);
- useIsCollapsed.mockReturnValueOnce(true);
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
- test('without enterprise dashboard and expanded', () => {
- reduxHooks.useEnterpriseDashboardData.mockReturnValueOnce(null);
- useIsCollapsed.mockReturnValueOnce(false);
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
- });
-});
diff --git a/src/containers/LearnerDashboardHeader/ExpandedHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap b/src/containers/LearnerDashboardHeader/ExpandedHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap
deleted file mode 100644
index eafdef3c..00000000
--- a/src/containers/LearnerDashboardHeader/ExpandedHeader/__snapshots__/AuthenticatedUserDropdown.test.jsx.snap
+++ /dev/null
@@ -1,139 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`AuthenticatedUserDropdown snapshots no auth render empty 1`] = `null`;
-
-exports[`AuthenticatedUserDropdown snapshots with enterprise dashboard 1`] = `
-
-
-
- username
-
-
-
-
-
- SWITCH DASHBOARD
-
-
- Personal
-
-
- label
-
- Dashboard
-
-
-
-
- Profile
-
-
- Account
-
-
- Order History
-
-
-
- Sign Out
-
-
-
-`;
-
-exports[`AuthenticatedUserDropdown snapshots without enterprise dashboard and expanded 1`] = `
-
-
-
- username
-
-
-
-
-
- SWITCH DASHBOARD
-
-
- Personal
-
-
-
-
- Career
-
- New
-
-
-
- Profile
-
-
- Account
-
-
- Order History
-
-
-
- Sign Out
-
-
-
-`;
diff --git a/src/containers/LearnerDashboardHeader/ExpandedHeader/__snapshots__/index.test.jsx.snap b/src/containers/LearnerDashboardHeader/ExpandedHeader/__snapshots__/index.test.jsx.snap
deleted file mode 100644
index 44e08f16..00000000
--- a/src/containers/LearnerDashboardHeader/ExpandedHeader/__snapshots__/index.test.jsx.snap
+++ /dev/null
@@ -1,52 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ExpandedHeader render 1`] = `
-
-`;
-
-exports[`ExpandedHeader render empty if collapsed 1`] = `null`;
diff --git a/src/containers/LearnerDashboardHeader/ExpandedHeader/index.jsx b/src/containers/LearnerDashboardHeader/ExpandedHeader/index.jsx
deleted file mode 100644
index f257cbc5..00000000
--- a/src/containers/LearnerDashboardHeader/ExpandedHeader/index.jsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React from 'react';
-
-import { getConfig } from '@edx/frontend-platform';
-import { useIntl } from '@edx/frontend-platform/i18n';
-import { Button } from '@openedx/paragon';
-
-import urls from 'data/services/lms/urls';
-import { reduxHooks } from 'hooks';
-
-import AuthenticatedUserDropdown from './AuthenticatedUserDropdown';
-import { useIsCollapsed, findCoursesNavClicked } from '../hooks';
-import messages from '../messages';
-import BrandLogo from '../BrandLogo';
-
-export const ExpandedHeader = () => {
- const { formatMessage } = useIntl();
- const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
- const isCollapsed = useIsCollapsed();
-
- const exploreCoursesClick = findCoursesNavClicked(
- urls.baseAppUrl(courseSearchUrl),
- );
-
- if (isCollapsed) {
- return null;
- }
-
- return (
-
- );
-};
-
-ExpandedHeader.propTypes = {};
-
-export default ExpandedHeader;
diff --git a/src/containers/LearnerDashboardHeader/ExpandedHeader/index.test.jsx b/src/containers/LearnerDashboardHeader/ExpandedHeader/index.test.jsx
deleted file mode 100644
index 3b96a1db..00000000
--- a/src/containers/LearnerDashboardHeader/ExpandedHeader/index.test.jsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { shallow } from '@edx/react-unit-test-utils';
-
-import ExpandedHeader from '.';
-
-import { useIsCollapsed } from '../hooks';
-
-jest.mock('data/services/lms/urls', () => ({
- programsUrl: () => 'programsUrl',
- baseAppUrl: url => (`http://localhost:18000${url}`),
-}));
-
-jest.mock('hooks', () => ({
- reduxHooks: {
- usePlatformSettingsData: () => ({
- courseSearchUrl: '/courseSearchUrl',
- }),
- },
-}));
-
-jest.mock('../hooks', () => ({
- useIsCollapsed: jest.fn(),
- findCoursesNavClicked: (url) => jest.fn().mockName(`findCoursesNavClicked("${url}")`),
-}));
-
-jest.mock('./AuthenticatedUserDropdown', () => 'AuthenticatedUserDropdown');
-jest.mock('../BrandLogo', () => 'BrandLogo');
-
-describe('ExpandedHeader', () => {
- test('render', () => {
- useIsCollapsed.mockReturnValueOnce(false);
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
-
- test('render empty if collapsed', () => {
- useIsCollapsed.mockReturnValueOnce(true);
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- expect(wrapper.isEmptyRender()).toBe(true);
- });
-});
diff --git a/src/containers/LearnerDashboardHeader/LearnerDashboardMenu.jsx b/src/containers/LearnerDashboardHeader/LearnerDashboardMenu.jsx
new file mode 100644
index 00000000..9dcecc3a
--- /dev/null
+++ b/src/containers/LearnerDashboardHeader/LearnerDashboardMenu.jsx
@@ -0,0 +1,75 @@
+import { getConfig } from '@edx/frontend-platform';
+
+import urls from 'data/services/lms/urls';
+
+import messages from './messages';
+
+const getLearnerHeaderMenu = (
+ formatMessage,
+ courseSearchUrl,
+ authenticatedUser,
+ exploreCoursesClick,
+) => ({
+ mainMenu: [
+ {
+ type: 'item',
+ href: '/',
+ content: formatMessage(messages.course),
+ isActive: true,
+ },
+ {
+ type: 'item',
+ href: `${urls.programsUrl()}`,
+ content: formatMessage(messages.program),
+ },
+ {
+ type: 'item',
+ href: `${urls.baseAppUrl(courseSearchUrl)}`,
+ content: formatMessage(messages.discoverNew),
+ onClick: (e) => {
+ exploreCoursesClick(e);
+ },
+ },
+ ],
+ secondaryMenu: [
+ {
+ type: 'item',
+ href: `${getConfig().SUPPORT_URL}`,
+ content: formatMessage(messages.help),
+ },
+ ],
+ userMenu: [
+ {
+ heading: '',
+ items: [
+ {
+ type: 'item',
+ href: `${getConfig().ACCOUNT_PROFILE_URL}/u/${authenticatedUser?.username}`,
+ content: formatMessage(messages.profile),
+ },
+ {
+ type: 'item',
+ href: `${getConfig().ACCOUNT_SETTINGS_URL}`,
+ content: formatMessage(messages.account),
+ },
+ ...(getConfig().ORDER_HISTORY_URL ? [{
+ type: 'item',
+ href: getConfig().ORDER_HISTORY_URL,
+ content: formatMessage(messages.orderHistory),
+ }] : []),
+ ],
+ },
+ {
+ heading: '',
+ items: [
+ {
+ type: 'item',
+ href: `${getConfig().LOGOUT_URL}`,
+ content: formatMessage(messages.signOut),
+ },
+ ],
+ },
+ ],
+});
+
+export default getLearnerHeaderMenu;
diff --git a/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap b/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap
index 87ec64c7..a1f0a9e7 100644
--- a/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap
+++ b/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap
@@ -3,8 +3,72 @@
exports[`LearnerDashboardHeader render 1`] = `
-
-
+
`;
diff --git a/src/containers/LearnerDashboardHeader/hooks.js b/src/containers/LearnerDashboardHeader/hooks.js
index 7eee8437..115322c1 100644
--- a/src/containers/LearnerDashboardHeader/hooks.js
+++ b/src/containers/LearnerDashboardHeader/hooks.js
@@ -1,9 +1,12 @@
import React from 'react';
import { useWindowSize, breakpoints } from '@openedx/paragon';
+import { useIntl } from '@edx/frontend-platform/i18n';
import track from 'tracking';
import { StrictDict } from 'utils';
import { linkNames } from 'tracking/constants';
+import getLearnerHeaderMenu from './LearnerDashboardMenu';
+
import * as module from './hooks';
export const state = StrictDict({
@@ -24,6 +27,13 @@ export const findCoursesNavDropdownClicked = (href) => track.findCourses.findCou
linkName: linkNames.learnerHomeNavDropdownExplore,
});
+export const useLearnerDashboardHeaderMenu = ({
+ courseSearchUrl, authenticatedUser, exploreCoursesClick,
+}) => {
+ const { formatMessage } = useIntl();
+ return getLearnerHeaderMenu(formatMessage, courseSearchUrl, authenticatedUser, exploreCoursesClick);
+};
+
export const useLearnerDashboardHeaderData = () => {
const [isOpen, setIsOpen] = module.state.isOpen(false);
const toggleIsOpen = () => setIsOpen(!isOpen);
@@ -39,4 +49,5 @@ export default {
findCoursesNavClicked,
findCoursesNavDropdownClicked,
useLearnerDashboardHeaderData,
+ useLearnerDashboardHeaderMenu,
};
diff --git a/src/containers/LearnerDashboardHeader/hooks.test.js b/src/containers/LearnerDashboardHeader/hooks.test.js
index 72349f6e..c9bac080 100644
--- a/src/containers/LearnerDashboardHeader/hooks.test.js
+++ b/src/containers/LearnerDashboardHeader/hooks.test.js
@@ -13,6 +13,7 @@ const {
findCoursesNavClicked,
findCoursesNavDropdownClicked,
useLearnerDashboardHeaderData,
+ useLearnerDashboardHeaderMenu,
} = hooks;
jest.mock('tracking', () => ({
@@ -48,6 +49,17 @@ describe('LearnerDashboardHeader hooks', () => {
});
});
+ describe('getLearnerDashboardHeaderMenu', () => {
+ test('calls header menu data hook', () => {
+ const courseSearchUrl = '/courses';
+ const authenticatedUser = {
+ username: 'test',
+ };
+ const learnerHomeHeaderMenu = useLearnerDashboardHeaderMenu({ courseSearchUrl, authenticatedUser });
+ expect(learnerHomeHeaderMenu.mainMenu.length).toBe(3);
+ });
+ });
+
describe('findCoursesNavDropdownClicked', () => {
test('calls tracking with dropdown link name', () => {
findCoursesNavDropdownClicked(url);
diff --git a/src/containers/LearnerDashboardHeader/index.jsx b/src/containers/LearnerDashboardHeader/index.jsx
index dfa8dbfb..833a14d7 100644
--- a/src/containers/LearnerDashboardHeader/index.jsx
+++ b/src/containers/LearnerDashboardHeader/index.jsx
@@ -1,21 +1,45 @@
import React from 'react';
import MasqueradeBar from 'containers/MasqueradeBar';
+import { AppContext } from '@edx/frontend-platform/react';
+import Header from '@edx/frontend-component-header';
+import { reduxHooks } from 'hooks';
+import urls from 'data/services/lms/urls';
+
import ConfirmEmailBanner from './ConfirmEmailBanner';
-import CollapsedHeader from './CollapsedHeader';
-import ExpandedHeader from './ExpandedHeader';
+import { useLearnerDashboardHeaderMenu, findCoursesNavClicked } from './hooks';
import './index.scss';
-export const LearnerDashboardHeader = () => (
- <>
-
-
-
-
- >
-);
+export const LearnerDashboardHeader = () => {
+ const { authenticatedUser } = React.useContext(AppContext);
+ const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
+
+ const exploreCoursesClick = () => {
+ findCoursesNavClicked(
+ urls.baseAppUrl(courseSearchUrl),
+ );
+ };
+
+ const learnerHomeHeaderMenu = useLearnerDashboardHeaderMenu({
+ courseSearchUrl,
+ authenticatedUser,
+ exploreCoursesClick,
+ });
+
+ return (
+ <>
+
+
+
+ >
+ );
+};
LearnerDashboardHeader.propTypes = {};
diff --git a/src/containers/LearnerDashboardHeader/index.test.jsx b/src/containers/LearnerDashboardHeader/index.test.jsx
index a7335565..e07fbda4 100644
--- a/src/containers/LearnerDashboardHeader/index.test.jsx
+++ b/src/containers/LearnerDashboardHeader/index.test.jsx
@@ -1,18 +1,35 @@
+import { mergeConfig } from '@edx/frontend-platform';
import { shallow } from '@edx/react-unit-test-utils';
+import Header from '@edx/frontend-component-header';
+
+import urls from 'data/services/lms/urls';
import LearnerDashboardHeader from '.';
+import { findCoursesNavClicked } from './hooks';
+jest.mock('hooks', () => ({
+ reduxHooks: {
+ usePlatformSettingsData: jest.fn(() => ({
+ courseSearchUrl: '/course-search-url',
+ })),
+ },
+}));
+jest.mock('./hooks', () => ({
+ ...jest.requireActual('./hooks'),
+ findCoursesNavClicked: jest.fn(),
+}));
jest.mock('containers/MasqueradeBar', () => 'MasqueradeBar');
-jest.mock('./CollapsedHeader', () => 'CollapsedHeader');
jest.mock('./ConfirmEmailBanner', () => 'ConfirmEmailBanner');
-jest.mock('./ExpandedHeader', () => 'ExpandedHeader');
+jest.mock('@edx/frontend-component-header', () => 'Header');
describe('LearnerDashboardHeader', () => {
test('render', () => {
+ mergeConfig({ ORDER_HISTORY_URL: 'test-url' });
const wrapper = shallow();
expect(wrapper.snapshot).toMatchSnapshot();
expect(wrapper.instance.findByType('ConfirmEmailBanner')).toHaveLength(1);
expect(wrapper.instance.findByType('MasqueradeBar')).toHaveLength(1);
- expect(wrapper.instance.findByType('CollapsedHeader')).toHaveLength(1);
- expect(wrapper.instance.findByType('ExpandedHeader')).toHaveLength(1);
+ expect(wrapper.instance.findByType(Header)).toHaveLength(1);
+ wrapper.instance.findByType(Header)[0].props.mainMenuItems[2].onClick();
+ expect(findCoursesNavClicked).toHaveBeenCalledWith(urls.baseAppUrl('/course-search-url'));
});
});