diff --git a/src/courseware/CourseContainer.jsx b/src/courseware/CourseContainer.jsx
index a3c70693..c4e63272 100644
--- a/src/courseware/CourseContainer.jsx
+++ b/src/courseware/CourseContainer.jsx
@@ -66,6 +66,7 @@ function CourseContainer(props) {
unitId={unitId}
models={models}
tabs={props.metadata.tabs}
+ verifiedMode={props.metadata.verifiedMode}
/>
);
}
@@ -89,6 +90,13 @@ CourseContainer.propTypes = {
type: PropTypes.string,
url: PropTypes.string,
})),
+ verifiedMode: PropTypes.shape({
+ price: PropTypes.number.isRequired,
+ currency: PropTypes.string.isRequired,
+ currencySymbol: PropTypes.string.isRequired,
+ sku: PropTypes.string.isRequired,
+ upgradeUrl: PropTypes.string.isRequired,
+ }),
}),
fetchCourseMetadata: PropTypes.func.isRequired,
fetchCourseBlocks: PropTypes.func.isRequired,
diff --git a/src/courseware/course/Course.jsx b/src/courseware/course/Course.jsx
index 5fd4f8b6..01b0b7a3 100644
--- a/src/courseware/course/Course.jsx
+++ b/src/courseware/course/Course.jsx
@@ -7,11 +7,12 @@ import SequenceContainer from './SequenceContainer';
import { createSequenceIdList } from '../utils';
import AlertList from '../../user-messages/AlertList';
import CourseHeader from './CourseHeader';
+import CourseSock from './course-sock';
import CourseTabsNavigation from './CourseTabsNavigation';
import InstructorToolbar from '../InstructorToolbar';
export default function Course({
- courseOrg, courseNumber, courseName, courseUsageKey, courseId, sequenceId, unitId, models, tabs,
+ courseOrg, courseNumber, courseName, courseUsageKey, courseId, sequenceId, unitId, models, tabs, verifiedMode,
}) {
const nextSequenceHandler = useCallback(() => {
const sequenceIds = createSequenceIdList(models, courseId);
@@ -70,6 +71,7 @@ export default function Course({
onNext={nextSequenceHandler}
onPrevious={previousSequenceHandler}
/>
+ {verifiedMode && }
>
);
@@ -96,8 +98,16 @@ Course.propTypes = {
type: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
})).isRequired,
+ verifiedMode: PropTypes.shape({
+ price: PropTypes.number.isRequired,
+ currency: PropTypes.string.isRequired,
+ currencySymbol: PropTypes.string,
+ sku: PropTypes.string.isRequired,
+ upgradeUrl: PropTypes.string.isRequired,
+ }),
};
Course.defaultProps = {
unitId: undefined,
+ verifiedMode: null,
};
diff --git a/src/courseware/course/course-sock/assets/learner-quote.png b/src/courseware/course/course-sock/assets/learner-quote.png
new file mode 100644
index 00000000..46918fa9
Binary files /dev/null and b/src/courseware/course/course-sock/assets/learner-quote.png differ
diff --git a/src/courseware/course/course-sock/assets/learner-quote2.png b/src/courseware/course/course-sock/assets/learner-quote2.png
new file mode 100644
index 00000000..b73d71a7
Binary files /dev/null and b/src/courseware/course/course-sock/assets/learner-quote2.png differ
diff --git a/src/courseware/course/course-sock/assets/verified-cert.png b/src/courseware/course/course-sock/assets/verified-cert.png
new file mode 100644
index 00000000..1b2be6cb
Binary files /dev/null and b/src/courseware/course/course-sock/assets/verified-cert.png differ
diff --git a/src/courseware/course/course-sock/index.jsx b/src/courseware/course/course-sock/index.jsx
new file mode 100644
index 00000000..1e364a13
--- /dev/null
+++ b/src/courseware/course/course-sock/index.jsx
@@ -0,0 +1,175 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { FormattedMessage } from '@edx/frontend-platform/i18n';
+import LearnerQuote1 from './assets/learner-quote.png';
+import LearnerQuote2 from './assets/learner-quote2.png';
+import VerifiedCert from './assets/verified-cert.png';
+
+export default class CourseSock extends Component {
+ constructor(props) {
+ super(props);
+ this.verifiedMode = props.verifiedMode;
+ this.state = { showUpsell: false };
+ }
+
+ handleClick = () => {
+ this.setState(state => ({
+ showUpsell: !state.showUpsell,
+ }));
+ }
+
+ render() {
+ const buttonClass = this.state.showUpsell ? 'btn-success' : 'btn-outline-success';
+ return (
+
+
+
+
+ {this.state.showUpsell && (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+ —
+
+
+
+
+

+
+
+
+ —
+
+
+
+
+
+
+ )}
+
+ );
+ }
+}
+
+CourseSock.propTypes = {
+ verifiedMode: PropTypes.shape({
+ price: PropTypes.number,
+ currency: PropTypes.string,
+ currencySymbol: PropTypes.string,
+ sku: PropTypes.string,
+ upgradeUrl: PropTypes.string,
+ }),
+};
+
+CourseSock.defaultProps = {
+ verifiedMode: null,
+};
diff --git a/src/data/course-meta/slice.js b/src/data/course-meta/slice.js
index 43213b1a..319ee5d7 100644
--- a/src/data/course-meta/slice.js
+++ b/src/data/course-meta/slice.js
@@ -17,6 +17,7 @@ const courseMetaSlice = createSlice({
org: payload.org,
tabs: payload.tabs,
userHasAccess: payload.userHasAccess,
+ verifiedMode: payload.verifiedMode,
}),
fetchCourseMetadataFailure: (draftState) => {
draftState.fetchState = 'failed';