diff --git a/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx b/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx
index 03837ee1c9..0d157184d7 100644
--- a/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx
+++ b/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx
@@ -1,10 +1,8 @@
-import React, { useEffect } from 'react';
+import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
-import {
- FormattedDate, FormattedMessage, injectIntl, intlShape,
-} from '@edx/frontend-platform/i18n';
+import { FormattedDate, FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Button, Card } from '@openedx/paragon';
import { getConfig } from '@edx/frontend-platform';
@@ -13,8 +11,10 @@ import { COURSE_EXIT_MODES, getCourseExitMode } from '../../../courseware/course
import { DashboardLink, IdVerificationSupportLink, ProfileLink } from '../../../shared/links';
import { requestCert } from '../../data/thunks';
import messages from './messages';
+import ProgressCertificateStatusSlot from '../../../plugin-slots/ProgressCertificateStatusSlot';
-const CertificateStatus = ({ intl }) => {
+const CertificateStatus = () => {
+ const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -215,7 +215,6 @@ const CertificateStatus = ({ intl }) => {
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
-
if (!certCase) {
return null;
}
@@ -243,32 +242,32 @@ const CertificateStatus = ({ intl }) => {
return (
-
-
- {body}
-
-
- {buttonText && (buttonLocation || buttonAction) && (
- {
- logCertificateStatusButtonClicked(certStatus);
- if (buttonAction) { buttonAction(); }
- }}
- href={buttonLocation}
- block
- >
- {buttonText}
-
- )}
-
+
+
+
+
+ {body}
+
+
+ {buttonText && (buttonLocation || buttonAction) && (
+ {
+ logCertificateStatusButtonClicked(certStatus);
+ if (buttonAction) { buttonAction(); }
+ }}
+ href={buttonLocation}
+ block
+ >
+ {buttonText}
+
+ )}
+
+
+
);
};
-CertificateStatus.propTypes = {
- intl: intlShape.isRequired,
-};
-
-export default injectIntl(CertificateStatus);
+export default CertificateStatus;
diff --git a/src/plugin-slots/ProgressCertificateStatusSlot/README.md b/src/plugin-slots/ProgressCertificateStatusSlot/README.md
new file mode 100644
index 0000000000..a9aff2a768
--- /dev/null
+++ b/src/plugin-slots/ProgressCertificateStatusSlot/README.md
@@ -0,0 +1,53 @@
+# Unit Title Slot
+
+### Slot ID: `progress_certificate_status_slot`
+### Props:
+* `courseId`
+
+## Description
+
+This slot is used for modify the content in the CertificateStatus in the progress page for specific enrollment tracks.
+
+## Example
+
+The following `env.config.jsx` will render the `RenderWidget.props.id` of the course as `
` element.
+
+### Default content
+![Certificate Status slot with default content](./screenshot_default.png)
+
+### Replaced with custom component
+![Default content id showing in trigger slot](./screenshot_custom.png)
+
+```js
+import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
+
+const modifyWidget = (widget) => {
+ const { RenderWidget } = widget;
+ if (RenderWidget.props.id.includes('upgrade')) {
+ widget.RenderWidget = (
+
+
Upgrade certificate
+
{RenderWidget.props.id}
+
+ )
+ }
+
+ return widget;
+}
+
+const config = {
+ pluginSlots: {
+ progress_certificate_status_slot: {
+ keepDefault: true,
+ plugins: [{
+ op: PLUGIN_OPERATIONS.Modify,
+ widgetId: 'default_contents',
+ // Insert custom content top modify certificate status
+ fn: modifyWidget,
+ }],
+ }
+ },
+}
+
+export default config;
+```
diff --git a/src/plugin-slots/ProgressCertificateStatusSlot/index.jsx b/src/plugin-slots/ProgressCertificateStatusSlot/index.jsx
new file mode 100644
index 0000000000..6f7e554cb1
--- /dev/null
+++ b/src/plugin-slots/ProgressCertificateStatusSlot/index.jsx
@@ -0,0 +1,18 @@
+import PropTypes from 'prop-types';
+import { PluginSlot } from '@openedx/frontend-plugin-framework';
+
+const ProgressCertificateStatusSlot = ({ courseId, children }) => (
+
+ {children}
+
+);
+
+ProgressCertificateStatusSlot.propTypes = {
+ courseId: PropTypes.string.isRequired,
+ children: PropTypes.node.isRequired,
+};
+
+export default ProgressCertificateStatusSlot;
diff --git a/src/plugin-slots/ProgressCertificateStatusSlot/screenshot_custom.png b/src/plugin-slots/ProgressCertificateStatusSlot/screenshot_custom.png
new file mode 100644
index 0000000000..cbf7270c15
Binary files /dev/null and b/src/plugin-slots/ProgressCertificateStatusSlot/screenshot_custom.png differ
diff --git a/src/plugin-slots/ProgressCertificateStatusSlot/screenshot_default.png b/src/plugin-slots/ProgressCertificateStatusSlot/screenshot_default.png
new file mode 100644
index 0000000000..0ab8d50622
Binary files /dev/null and b/src/plugin-slots/ProgressCertificateStatusSlot/screenshot_default.png differ