feat: frontend changes for executive education courses on B2C dashboard (#181)

This commit is contained in:
Ejaz Ahmad
2023-08-10 12:24:17 +05:00
committed by GitHub
9 changed files with 49 additions and 5 deletions

View File

@@ -8,15 +8,20 @@ import { reduxHooks } from 'hooks';
import useActionDisabledState from '../hooks';
import ActionButton from './ActionButton';
import messages from './messages';
import { useEnterpriseDashboardData } from '../../../../data/redux/hooks/app';
export const BeginCourseButton = ({ cardId }) => {
const { formatMessage } = useIntl();
const { homeUrl } = reduxHooks.useCardCourseRunData(cardId);
const { disableBeginCourse } = useActionDisabledState(cardId);
const { authOrgId } = useEnterpriseDashboardData();
const { isExecutiveEd2uCourse } = useActionDisabledState(cardId);
const execEdURLParam = `?org_id=${authOrgId}`;
const handleClick = reduxHooks.useTrackCourseEvent(
track.course.enterCourseClicked,
cardId,
homeUrl,
homeUrl + ((isExecutiveEd2uCourse && authOrgId) ? execEdURLParam : ''),
);
return (
<ActionButton

View File

@@ -8,15 +8,20 @@ import { reduxHooks } from 'hooks';
import useActionDisabledState from '../hooks';
import ActionButton from './ActionButton';
import messages from './messages';
import { useEnterpriseDashboardData } from '../../../../data/redux/hooks/app';
export const ResumeButton = ({ cardId }) => {
const { formatMessage } = useIntl();
const { resumeUrl } = reduxHooks.useCardCourseRunData(cardId);
const { disableResumeCourse } = useActionDisabledState(cardId);
const { authOrgId } = useEnterpriseDashboardData();
const { isExecutiveEd2uCourse } = useActionDisabledState(cardId);
const execEdURLParam = `?org_id=${authOrgId}`;
const handleClick = reduxHooks.useTrackCourseEvent(
track.course.enterCourseClicked,
cardId,
resumeUrl,
resumeUrl + ((isExecutiveEd2uCourse && authOrgId) ? execEdURLParam : ''),
);
return (
<ActionButton

View File

@@ -10,11 +10,14 @@ import SelectSessionButton from './SelectSessionButton';
import BeginCourseButton from './BeginCourseButton';
import ResumeButton from './ResumeButton';
import ViewCourseButton from './ViewCourseButton';
import useActionDisabledState from '../hooks';
export const CourseCardActions = ({ cardId }) => {
const { isEntitlement, isFulfilled } = reduxHooks.useCardEntitlementData(cardId);
const { isVerified, hasStarted } = reduxHooks.useCardEnrollmentData(cardId);
const { isArchived } = reduxHooks.useCardCourseRunData(cardId);
const { isExecutiveEd2uCourse } = useActionDisabledState(cardId);
let PrimaryButton;
if (isEntitlement) {
PrimaryButton = isFulfilled ? ViewCourseButton : SelectSessionButton;
@@ -26,7 +29,7 @@ export const CourseCardActions = ({ cardId }) => {
return (
<ActionRow data-test-id="CourseCardActions">
{!(isEntitlement || isVerified) && <UpgradeButton cardId={cardId} />}
{(!(isEntitlement || isVerified) && !isExecutiveEd2uCourse) && <UpgradeButton cardId={cardId} />}
<PrimaryButton cardId={cardId} />
</ActionRow>
);

View File

@@ -9,9 +9,12 @@ jest.mock('hooks', () => ({
useCardCourseRunData: jest.fn(),
useCardEnrollmentData: jest.fn(),
useCardEntitlementData: jest.fn(),
useMasqueradeData: jest.fn(),
},
}));
jest.mock('../hooks', () => jest.fn(() => ({ isExecutiveEd2uCourse: false })));
jest.mock('./UpgradeButton', () => 'UpgradeButton');
jest.mock('./SelectSessionButton', () => 'SelectSessionButton');
jest.mock('./ViewCourseButton', () => 'ViewCourseButton');
@@ -23,11 +26,12 @@ describe('CourseCardActions', () => {
cardId: 'cardId',
};
const createWrapper = ({
isEntitlement, isFulfilled, isArchived, isVerified, hasStarted,
isEntitlement, isFulfilled, isArchived, isVerified, hasStarted, isMasquerading,
}) => {
reduxHooks.useCardEntitlementData.mockReturnValueOnce({ isEntitlement, isFulfilled });
reduxHooks.useCardCourseRunData.mockReturnValueOnce({ isArchived });
reduxHooks.useCardEnrollmentData.mockReturnValueOnce({ isVerified, hasStarted });
reduxHooks.useMasqueradeData.mockReturnValueOnce({ isMasquerading });
return shallow(<CourseCardActions {...props} />);
};
describe('snapshot', () => {

View File

@@ -8,6 +8,7 @@ exports[`CourseCardMenu default snapshot 1`] = `
<Dropdown.Toggle
alt="Course actions dropdown"
as="IconButton"
disabled={false}
iconAs="Icon"
id="course-actions-dropdown-test-card-id"
src={[MockFunction icons.MoreVert]}
@@ -69,6 +70,7 @@ exports[`CourseCardMenu masquerading snapshot 1`] = `
<Dropdown.Toggle
alt="Course actions dropdown"
as="IconButton"
disabled={false}
iconAs="Icon"
id="course-actions-dropdown-test-card-id"
src={[MockFunction icons.MoreVert]}

View File

@@ -16,6 +16,7 @@ import {
} from './hooks';
import messages from './messages';
import useActionDisabledState from '../hooks';
export const CourseCardMenu = ({ cardId }) => {
const { formatMessage } = useIntl();
@@ -23,6 +24,7 @@ export const CourseCardMenu = ({ cardId }) => {
const emailSettingsModal = useEmailSettings();
const unenrollModal = useUnenrollData();
const handleToggleDropdown = useHandleToggleDropdown(cardId);
const { isExecutiveEd2uCourse } = useActionDisabledState(cardId);
const {
courseName,
@@ -50,6 +52,7 @@ export const CourseCardMenu = ({ cardId }) => {
iconAs={Icon}
variant="primary"
alt={formatMessage(messages.dropdownAlt)}
disabled={isExecutiveEd2uCourse}
/>
<Dropdown.Menu>
{showUnenrollItem && (

View File

@@ -1,9 +1,10 @@
import { reduxHooks } from 'hooks';
import { EXECUTIVE_EDUCATION_COURSE_MODES } from '../../../data/constants/course';
export const useActionDisabledState = (cardId) => {
const { isMasquerading } = reduxHooks.useMasqueradeData();
const {
canUpgrade, hasAccess, isAudit, isAuditAccessExpired,
canUpgrade, hasAccess, isAudit, isAuditAccessExpired, mode,
} = reduxHooks.useCardEnrollmentData(cardId);
const {
isEntitlement, isFulfilled, canChange, hasSessions,
@@ -19,6 +20,8 @@ export const useActionDisabledState = (cardId) => {
const disableCourseTitle = (isEntitlement && !isFulfilled) || disableViewCourse;
const isExecutiveEd2uCourse = (EXECUTIVE_EDUCATION_COURSE_MODES.includes(mode));
return {
disableBeginCourse,
disableResumeCourse,
@@ -26,6 +29,7 @@ export const useActionDisabledState = (cardId) => {
disableUpgradeCourse,
disableSelectSession,
disableCourseTitle,
isExecutiveEd2uCourse,
};
};

View File

@@ -0,0 +1,17 @@
// Constants related to courses
export const COURSE_MODES = {
VERIFIED: 'verified',
PROFESSIONAL: 'professional',
NO_ID_PROFESSIONAL: 'no-id-professional',
AUDIT: 'audit',
HONOR: 'honor',
EXECUTIVE_EDUCATION: 'executive-education',
PAID_EXECUTIVE_EDUCATION: 'paid-executive-education',
UNPAID_EXECUTIVE_EDUCATION: 'unpaid-executive-education',
};
export const EXECUTIVE_EDUCATION_COURSE_MODES = [
COURSE_MODES.EXECUTIVE_EDUCATION,
COURSE_MODES.PAID_EXECUTIVE_EDUCATION,
COURSE_MODES.UNPAID_EXECUTIVE_EDUCATION,
];

View File

@@ -97,6 +97,7 @@ export const courseCard = StrictDict({
isEmailEnabled: enrollment.isEmailEnabled,
hasOptedOutOfEmail: enrollment.hasOptedOutOfEmail,
mode: enrollment.mode,
};
},
),