Compare commits
1 Commits
teak-desig
...
schen/upse
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdb0f48f08 |
2
.env
2
.env
@@ -41,4 +41,4 @@ ACCOUNT_PROFILE_URL=''
|
||||
ENABLE_NOTICES=''
|
||||
CAREER_LINK_URL=''
|
||||
OPTIMIZELY_FULL_STACK_SDK_KEY=''
|
||||
EXPERIMENT_08_23_VAN_PAINTED_DOOR=true
|
||||
EXPERIMENT_08_23_VAN_PAINTED_DOOR='true'
|
||||
|
||||
@@ -48,3 +48,4 @@ ACCOUNT_PROFILE_URL='http://localhost:1995'
|
||||
ENABLE_NOTICES=''
|
||||
CAREER_LINK_URL=''
|
||||
OPTIMIZELY_FULL_STACK_SDK_KEY=''
|
||||
EXPERIMENT_08_23_VAN_PAINTED_DOOR=true
|
||||
|
||||
29
src/containers/CertificatePreviewModal/hooks.js
Normal file
29
src/containers/CertificatePreviewModal/hooks.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { reduxHooks } from 'hooks';
|
||||
import messages from './messages';
|
||||
|
||||
export const useCertificatePreviewData = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const selectedCardId = reduxHooks.useCertificatePreviewData().cardId;
|
||||
|
||||
const { courseId } = reduxHooks.useCardCourseRunData(selectedCardId) || {};
|
||||
|
||||
const courseTitle = courseId;
|
||||
const header = formatMessage(messages.previewTitle, { courseTitle });
|
||||
|
||||
const closePreviewModal = reduxHooks.useUpdateCertificatePreviewModalCallback(null);
|
||||
|
||||
const getCertificatePreviewUrl = () => `${getConfig().LMS_BASE_URL}/certificates/upsell/course/${courseId}`;
|
||||
|
||||
return {
|
||||
showModal: selectedCardId != null,
|
||||
header,
|
||||
closePreviewModal,
|
||||
getCertificatePreviewUrl,
|
||||
};
|
||||
};
|
||||
|
||||
export default useCertificatePreviewData;
|
||||
48
src/containers/CertificatePreviewModal/index.jsx
Normal file
48
src/containers/CertificatePreviewModal/index.jsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
ModalDialog,
|
||||
} from '@edx/paragon';
|
||||
import { UpgradeButton } from '../CourseCard/components/CourseCardActions/UpgradeButton';
|
||||
import useCertificatePreviewData from './hooks';
|
||||
|
||||
export const CertificatePreviewModal = ({
|
||||
cardId,
|
||||
}) => {
|
||||
const {
|
||||
showModal,
|
||||
header,
|
||||
closePreviewModal,
|
||||
getCertificatePreviewUrl,
|
||||
} = useCertificatePreviewData();
|
||||
|
||||
return (
|
||||
<ModalDialog
|
||||
isOpen={showModal}
|
||||
onClose={closePreviewModal}
|
||||
hasCloseButton
|
||||
isFullscreenOnMobile
|
||||
size="lg"
|
||||
className="p-4 px-4.5"
|
||||
title={header}
|
||||
>
|
||||
<h3>{header}</h3>
|
||||
<div>
|
||||
<iframe
|
||||
title={header}
|
||||
src={getCertificatePreviewUrl()}
|
||||
width={725}
|
||||
height={400}
|
||||
/>
|
||||
</div>
|
||||
<UpgradeButton
|
||||
cardId={cardId}
|
||||
/>
|
||||
</ModalDialog>
|
||||
);
|
||||
};
|
||||
CertificatePreviewModal.propTypes = {
|
||||
cardId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default CertificatePreviewModal;
|
||||
12
src/containers/CertificatePreviewModal/messages.js
Normal file
12
src/containers/CertificatePreviewModal/messages.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/* eslint-disable quotes */
|
||||
import { StrictDict } from 'utils';
|
||||
|
||||
export const messages = StrictDict({
|
||||
previewTitle: {
|
||||
id: 'learner-dash.certificatePreview.title',
|
||||
description: 'The title of the email settings modal',
|
||||
defaultMessage: 'Your certificate preview for {courseTitle} ',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -47,6 +47,7 @@ export const useCardDetailsData = ({ cardId }) => {
|
||||
} = reduxHooks.useCardEntitlementData(cardId);
|
||||
|
||||
const openSessionModal = reduxHooks.useUpdateSelectSessionModalCallback(cardId);
|
||||
const openCertificatePreview = reduxHooks.useUpdateCertificatePreviewModalCallback(cardId);
|
||||
|
||||
return {
|
||||
providerName: providerName || formatMessage(messages.unknownProviderName),
|
||||
@@ -57,6 +58,7 @@ export const useCardDetailsData = ({ cardId }) => {
|
||||
openSessionModal,
|
||||
courseNumber,
|
||||
changeOrLeaveSessionMessage: formatMessage(messages.changeOrLeaveSessionButton),
|
||||
openCertificatePreview,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -16,23 +16,35 @@ export const CourseCardDetails = ({ cardId }) => {
|
||||
openSessionModal,
|
||||
courseNumber,
|
||||
changeOrLeaveSessionMessage,
|
||||
openCertificatePreview,
|
||||
} = useCardDetailsData({ cardId });
|
||||
|
||||
return (
|
||||
<span className="small" data-testid="CourseCardDetails">
|
||||
{providerName} • {courseNumber}
|
||||
{!(isEntitlement && !isFulfilled) && accessMessage && (
|
||||
` • ${accessMessage}`
|
||||
)}
|
||||
{isEntitlement && isFulfilled && canChange ? (
|
||||
<>
|
||||
{' • '}
|
||||
<Button variant="link" size="inline" className="m-0 p-0" onClick={openSessionModal}>
|
||||
{changeOrLeaveSessionMessage}
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</span>
|
||||
<div>
|
||||
<span className="small" data-testid="CourseCardDetails">
|
||||
{providerName} • {courseNumber}
|
||||
{!(isEntitlement && !isFulfilled) && accessMessage && (
|
||||
` • ${accessMessage}`
|
||||
)}
|
||||
{isEntitlement && isFulfilled && canChange ? (
|
||||
<>
|
||||
{' • '}
|
||||
<Button variant="link" size="inline" className="m-0 p-0" onClick={openSessionModal}>
|
||||
{changeOrLeaveSessionMessage}
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</span>
|
||||
<Button
|
||||
variant="link"
|
||||
size="inline"
|
||||
className="float-right"
|
||||
data-testid="certificate-preview"
|
||||
onClick={openCertificatePreview}
|
||||
>
|
||||
Preview Your Certificate
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import { MoreVert } from '@edx/paragon/icons';
|
||||
import { StrictDict } from '@edx/react-unit-test-utils';
|
||||
|
||||
import EmailSettingsModal from 'containers/EmailSettingsModal';
|
||||
import CertificatePreviewModal from 'containers/CertificatePreviewModal';
|
||||
import UnenrollConfirmModal from 'containers/UnenrollConfirmModal';
|
||||
import { reduxHooks } from 'hooks';
|
||||
import SocialShareMenu from './SocialShareMenu';
|
||||
@@ -32,6 +33,7 @@ export const CourseCardMenu = ({ cardId }) => {
|
||||
const { shouldShowUnenrollItem, shouldShowDropdown } = useOptionVisibility(cardId);
|
||||
const { isMasquerading } = reduxHooks.useMasqueradeData();
|
||||
const { isEmailEnabled } = reduxHooks.useCardEnrollmentData(cardId);
|
||||
const showCertificatePreviewModal = reduxHooks.useShowCertificatePreviewModal(cardId);
|
||||
|
||||
if (!shouldShowDropdown) {
|
||||
return null;
|
||||
@@ -73,6 +75,11 @@ export const CourseCardMenu = ({ cardId }) => {
|
||||
cardId={cardId}
|
||||
/>
|
||||
)}
|
||||
{showCertificatePreviewModal && (
|
||||
<CertificatePreviewModal
|
||||
cardId={cardId}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,14 +6,12 @@ import PaintedDoorExperimentProvider from 'widgets/RecommendationsPaintedDoorBtn
|
||||
export const AppWrapper = ({
|
||||
children,
|
||||
}) => {
|
||||
if (process.env.EXPERIMENT_08_23_VAN_PAINTED_DOOR) {
|
||||
return (
|
||||
<PaintedDoorExperimentProvider>
|
||||
{children}
|
||||
</PaintedDoorExperimentProvider>
|
||||
);
|
||||
}
|
||||
return children;
|
||||
console.log(`process.env.EXPERIMENT_08_23_VAN_PAINTED_DOOR = ${Boolean(process.env.EXPERIMENT_08_23_VAN_PAINTED_DOOR)}`);
|
||||
return (
|
||||
<PaintedDoorExperimentProvider>
|
||||
{children}
|
||||
</PaintedDoorExperimentProvider>
|
||||
);
|
||||
};
|
||||
AppWrapper.propTypes = {
|
||||
children: PropTypes.oneOfType([
|
||||
|
||||
@@ -12,6 +12,7 @@ const initialState = {
|
||||
suggestedCourses: [],
|
||||
filterState: {},
|
||||
selectSessionModal: {},
|
||||
certificatePreviewModal: {},
|
||||
};
|
||||
|
||||
export const cardId = (val) => `card-${val}`;
|
||||
@@ -48,6 +49,10 @@ const app = createSlice({
|
||||
...state,
|
||||
selectSessionModal: { cardId: payload },
|
||||
}),
|
||||
updateCertificatePreviewModal: (state, { payload }) => ({
|
||||
...state,
|
||||
certificatePreviewModal: { cardId: payload },
|
||||
}),
|
||||
setPageNumber: (state, { payload }) => ({ ...state, pageNumber: payload }),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,9 +19,15 @@ export const showSelectSessionModal = createSelector(
|
||||
(data) => data.cardId != null,
|
||||
);
|
||||
|
||||
export const showCertificatePreviewModal = createSelector(
|
||||
[simpleSelectors.certificatePreviewModal],
|
||||
(data) => data.cardId != null,
|
||||
);
|
||||
|
||||
export default StrictDict({
|
||||
numCourses,
|
||||
hasCourses,
|
||||
hasAvailableDashboards,
|
||||
showSelectSessionModal,
|
||||
showCertificatePreviewModal,
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@ export const simpleSelectors = StrictDict({
|
||||
emailConfirmation: mkSimpleSelector(app => app.emailConfirmation),
|
||||
enterpriseDashboard: mkSimpleSelector(app => app.enterpriseDashboard || {}),
|
||||
selectSessionModal: mkSimpleSelector(app => app.selectSessionModal),
|
||||
certificatePreviewModal: mkSimpleSelector(app => app.certificatePreviewModal),
|
||||
pageNumber: mkSimpleSelector(app => app.pageNumber),
|
||||
socialShareSettings: mkSimpleSelector(app => app.socialShareSettings),
|
||||
});
|
||||
|
||||
@@ -13,6 +13,8 @@ export const useEmailConfirmationData = () => useSelector(selectors.emailConfirm
|
||||
export const useEnterpriseDashboardData = () => useSelector(selectors.enterpriseDashboard);
|
||||
export const usePlatformSettingsData = () => useSelector(selectors.platformSettings);
|
||||
export const useSelectSessionModalData = () => useSelector(selectors.selectSessionModal);
|
||||
export const useCertificatePreviewData = () => useSelector(selectors.certificatePreviewModal);
|
||||
|
||||
export const useSocialShareSettings = () => useSelector(selectors.socialShareSettings);
|
||||
|
||||
/** global-level meta-selectors **/
|
||||
@@ -22,6 +24,7 @@ export const useCurrentCourseList = (opts) => useSelector(
|
||||
state => selectors.currentList(state, opts),
|
||||
);
|
||||
export const useShowSelectSessionModal = () => useSelector(selectors.showSelectSessionModal);
|
||||
export const useShowCertificatePreviewModal = () => useSelector(selectors.showCertificatePreviewModal);
|
||||
|
||||
// eslint-disable-next-line
|
||||
export const useCourseCardData = (selector) => (cardId) => useSelector(
|
||||
@@ -67,6 +70,11 @@ export const useUpdateSelectSessionModalCallback = (cardId) => {
|
||||
return () => dispatch(actions.updateSelectSessionModal(cardId));
|
||||
};
|
||||
|
||||
export const useUpdateCertificatePreviewModalCallback = (cardId) => {
|
||||
const dispatch = useDispatch();
|
||||
return () => dispatch(actions.updateCertificatePreviewModal(cardId));
|
||||
};
|
||||
|
||||
export const useTrackCourseEvent = (tracker, cardId, ...args) => {
|
||||
const { courseId } = module.useCardCourseRunData(cardId);
|
||||
return (e) => tracker(courseId, ...args)(e);
|
||||
|
||||
Reference in New Issue
Block a user