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 && ( +
+
+

+ +

+

+ +

+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+

+

+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+

+

+
+ Christina Fong +
+ +
+ + +
+
+
+ Chery Troell +
+ +
+ + +
+
+
+
+ Example Certificate + + + +
+
+ )} +
+ ); + } +} + +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';