Revert "jaebradley/learner 3600 upsell modal"
This commit is contained in:
committed by
GitHub
parent
0d76e40e00
commit
fb387c9633
@@ -1,127 +0,0 @@
|
||||
import React from 'react';
|
||||
import Slider from 'react-slick';
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function NextArrow(props) {
|
||||
const {currentSlide, slideCount, onClick, displayedSlides} = props;
|
||||
const showArrow = slideCount - currentSlide > displayedSlides;
|
||||
const opts = {
|
||||
className: classNames('js-carousel-nav', 'carousel-arrow', 'next', 'btn btn-secondary', {'active': showArrow}),
|
||||
onClick
|
||||
};
|
||||
|
||||
if (!showArrow) {
|
||||
opts.disabled = 'disabled';
|
||||
}
|
||||
|
||||
return (
|
||||
<button {...opts}>
|
||||
<span>Next </span>
|
||||
<span className="icon fa fa-chevron-right" aria-hidden="true"></span>
|
||||
<span className="sr">{ 'Scroll carousel forwards' }</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function PrevArrow(props) {
|
||||
const {currentSlide, onClick} = props;
|
||||
const showArrow = currentSlide > 0;
|
||||
const opts = {
|
||||
className: classNames('js-carousel-nav', 'carousel-arrow', 'prev', 'btn btn-secondary', {'active': showArrow}),
|
||||
onClick
|
||||
};
|
||||
|
||||
if (!showArrow) {
|
||||
opts.disabled = 'disabled';
|
||||
}
|
||||
|
||||
return (
|
||||
<button {...opts} >
|
||||
<span className="icon fa fa-chevron-left" aria-hidden="true"></span>
|
||||
<span> Prev</span>
|
||||
<span className="sr">{ 'Scroll carousel backwards' }</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default class Carousel extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
// Default to undefined to not focus on page load
|
||||
activeIndex: undefined,
|
||||
};
|
||||
|
||||
this.carousels = [];
|
||||
|
||||
this.afterChange = this.afterChange.bind(this);
|
||||
this.getCarouselContent = this.getCarouselContent.bind(this);
|
||||
}
|
||||
|
||||
afterChange(activeIndex) {
|
||||
this.setState({ activeIndex });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { activeIndex } = this.state;
|
||||
|
||||
if (!isNaN(activeIndex)) {
|
||||
this.carousels[activeIndex].focus();
|
||||
}
|
||||
}
|
||||
|
||||
getCarouselContent() {
|
||||
return this.props.slides.map((slide, i) => {
|
||||
const firstIndex = this.state.activeIndex || 0;
|
||||
const lastIndex = firstIndex + this.props.slides.length;
|
||||
const tabIndex = (firstIndex <= i && i < lastIndex) ? undefined : '-1';
|
||||
const carouselLinkProps = {
|
||||
ref: (item) => {
|
||||
this.carousels[i] = item;
|
||||
},
|
||||
tabIndex: tabIndex,
|
||||
className: 'carousel-item'
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...carouselLinkProps}>
|
||||
{ slide }
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const carouselSettings = {
|
||||
accessibility: true,
|
||||
dots: true,
|
||||
infinite: false,
|
||||
speed: 500,
|
||||
className: 'carousel-wrapper',
|
||||
nextArrow: <NextArrow displayedSlides={1} />,
|
||||
prevArrow: <PrevArrow />,
|
||||
afterChange: this.afterChange,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
initialSlide: 0,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 540,
|
||||
settings: 'unslick'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return (
|
||||
<Slider {...carouselSettings} >
|
||||
{this.getCarouselContent()}
|
||||
</Slider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Carousel.propTypes = {
|
||||
slides: PropTypes.array.isRequired
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { UpsellExperimentModal } from './UpsellExperimentModal.jsx';
|
||||
|
||||
// https://openedx.atlassian.net/browse/LEARNER-3583
|
||||
|
||||
export class CourseHomeUpsellExperimentModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
// This content will be updated in the future
|
||||
return (
|
||||
<UpsellExperimentModal
|
||||
slides={[
|
||||
(<div>
|
||||
<span>My Stats introduces new personalized views that help you track your progress towards completing your course!</span>
|
||||
<p />
|
||||
<span>With My Stats you will see your:</span>
|
||||
<p />
|
||||
<ul className="upsell-modal-checkmark-group">
|
||||
<li className="upsell-modal-checkmark">Course Activity Streak (log in every week to keep your streak alive)</li>
|
||||
<li className="upsell-modal-checkmark">Grade Progress (see how you're tracking towards a passing grade)</li>
|
||||
<li className="upsell-modal-checkmark">Discussion Forum Engagements (top learners use the forums - how do you measure up?)</li>
|
||||
</ul>
|
||||
</div>),
|
||||
(<div>
|
||||
<div><b>Course Activity Streak</b></div>
|
||||
<p />
|
||||
<span>Did you know the learners most likely to complete a course log in every week? Let us help you track your weekly streak - log in every week and learn something new! You can also see how many of the other learners in your course logged in this week.</span>
|
||||
</div>),
|
||||
(<div>
|
||||
<div><b>Grade Progress</b></div>
|
||||
<p />
|
||||
<span>Wonder how you're doing in the course so far? We can not only show you all your grades, and how much each assignment is worth, but also upcoming graded assignments. This is a great way to track what you might need to work on for a final exam.</span>
|
||||
</div>),
|
||||
(<div>
|
||||
<div><b>Discussion engagements</b></div>
|
||||
<p />
|
||||
<span>A large percentage of successful learners are engaged on the discussion forums. Compare your forum stats to previous graduates!</span>
|
||||
</div>),
|
||||
]}
|
||||
modalTitle="My Stats"
|
||||
buttonLabel="Upgrade ($100 USD)"
|
||||
buttonDisplay="Upgrade ($100 USD)"
|
||||
buttonDestinationURL='https://edx.org'
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Modal, Button } from '@edx/paragon/static';
|
||||
|
||||
import Carousel from './Carousel.jsx';
|
||||
|
||||
// https://openedx.atlassian.net/browse/LEARNER-3583
|
||||
|
||||
export class UpsellExperimentModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isOpen: this.props.isOpen,
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
slides,
|
||||
modalTitle,
|
||||
buttonLabel,
|
||||
buttonDisplay,
|
||||
buttonDestinationURL,
|
||||
} = this.props;
|
||||
const body = (
|
||||
<div>
|
||||
<Carousel id="upsell-modal" slides={slides} />
|
||||
<img
|
||||
className="upsell-certificate"
|
||||
src="https://courses.edx.org/static/images/edx-verified-mini-cert.png"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<Modal
|
||||
open={this.state.isOpen}
|
||||
className="upsell-modal"
|
||||
title={modalTitle}
|
||||
onClose={() => {}}
|
||||
body={body}
|
||||
buttons={[
|
||||
(<Button
|
||||
label={buttonLabel}
|
||||
display={buttonDisplay}
|
||||
buttonType="success"
|
||||
// unfortunately, Button components don't have an href component
|
||||
onClick={() => window.location = buttonDestinationURL}
|
||||
/>),
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UpsellExperimentModal.defaultProps = {
|
||||
isOpen: true,
|
||||
};
|
||||
|
||||
UpsellExperimentModal.propTypes = {
|
||||
isOpen: PropTypes.bool,
|
||||
slides: PropTypes.arrayOf(PropTypes.node).isRequired,
|
||||
modalTitle: PropTypes.string.isRequired,
|
||||
buttonLabel: PropTypes.string.isRequired,
|
||||
buttonDisplay: PropTypes.string.isRequired,
|
||||
buttonDestinationURL: PropTypes.string.isRequired,
|
||||
};
|
||||
@@ -954,7 +954,6 @@ STATIC_ROOT = ENV_ROOT / "staticfiles"
|
||||
STATICFILES_DIRS = [
|
||||
COMMON_ROOT / "static",
|
||||
PROJECT_ROOT / "static",
|
||||
NODE_MODULES_ROOT / "@edx",
|
||||
]
|
||||
|
||||
FAVICON_PATH = 'images/favicon.ico'
|
||||
|
||||
@@ -39,6 +39,3 @@
|
||||
// Extra theme-specific rules
|
||||
@import 'lms/theme/extras';
|
||||
@import 'lms/theme/extras-v2';
|
||||
|
||||
// Experiments
|
||||
@import 'experiments';
|
||||
|
||||
@@ -39,403 +39,3 @@
|
||||
max-width: 420px;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
/* Part of LEARNER-3583 experiment (https://openedx.atlassian.net/browse/LEARNER-3583) */
|
||||
|
||||
/* modal-specific */
|
||||
|
||||
#upsell-modal {
|
||||
display: none;
|
||||
|
||||
/* slick modal from https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css */
|
||||
|
||||
.slick-list,
|
||||
.slick-slider,
|
||||
.slick-track {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.slick-loading {
|
||||
.slick-slide,
|
||||
.slick-track {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-slider {
|
||||
box-sizing: border-box;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-touch-action: pan-y;
|
||||
touch-action: pan-y;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.slick-list {
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&.dragging {
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-slider {
|
||||
.slick-list,
|
||||
.slick-track {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
-moz-transform: translate3d(0, 0, 0);
|
||||
-ms-transform: translate3d(0, 0, 0);
|
||||
-o-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.slick-track {
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
display: table;
|
||||
content: '';
|
||||
}
|
||||
|
||||
&::after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-slide {
|
||||
display: none;
|
||||
float: left;
|
||||
height: 100%;
|
||||
min-height: 1px;
|
||||
}
|
||||
|
||||
[dir=rtl] .slick-slide {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.slick-slide {
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.slick-loading img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.dragging img {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-initialized .slick-slide {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.slick-vertical .slick-slide {
|
||||
display: block;
|
||||
height: auto;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.slick-arrow.slick-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* slick theme from https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css */
|
||||
|
||||
.slick-dots,
|
||||
.slick-next,
|
||||
.slick-prev {
|
||||
position: absolute;
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.slick-dots li button::before,
|
||||
.slick-next::before,
|
||||
.slick-prev::before {
|
||||
font-family: slick;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
|
||||
.slick-next,
|
||||
.slick-prev {
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
top: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-transform: translate(0, -50%);
|
||||
-ms-transform: translate(0, -50%);
|
||||
transform: translate(0, -50%);
|
||||
cursor: pointer;
|
||||
color: transparent;
|
||||
border: none;
|
||||
outline: 0;
|
||||
background: 0 0;
|
||||
}
|
||||
|
||||
.slick-next {
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: transparent;
|
||||
outline: 0;
|
||||
background: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-prev {
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: transparent;
|
||||
outline: 0;
|
||||
background: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-next {
|
||||
&:focus::before,
|
||||
&:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-prev {
|
||||
&:focus::before,
|
||||
&:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-next.slick-disabled::before,
|
||||
.slick-prev.slick-disabled::before {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.slick-next::before {
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
opacity: 0.75;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.slick-prev {
|
||||
&::before {
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
opacity: 0.75;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
left: -25px;
|
||||
}
|
||||
|
||||
[dir=rtl] .slick-prev {
|
||||
right: -25px;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.slick-prev::before {
|
||||
content: '• ';
|
||||
}
|
||||
|
||||
.slick-next::before,
|
||||
[dir=rtl] .slick-prev::before {
|
||||
content: '•’';
|
||||
}
|
||||
|
||||
.slick-next {
|
||||
right: -25px;
|
||||
}
|
||||
|
||||
[dir=rtl] .slick-next {
|
||||
right: auto;
|
||||
left: -25px;
|
||||
|
||||
&::before {
|
||||
content: '•';
|
||||
}
|
||||
}
|
||||
|
||||
.slick-dotted.slick-slider {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.slick-dots {
|
||||
bottom: -25px;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
text-align: center;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 5px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
|
||||
button {
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
color: transparent;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
background: 0 0;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&:focus::before,
|
||||
&:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&::before {
|
||||
font-size: 6px;
|
||||
line-height: 20px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
content: '•';
|
||||
text-align: center;
|
||||
opacity: 0.25;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
&.slick-active button::before {
|
||||
opacity: 0.75;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.paragon__btn.paragon__btn-secondary {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.paragon__btn.paragon__btn-success {
|
||||
font-size: initial;
|
||||
float: left;
|
||||
background: green;
|
||||
}
|
||||
|
||||
.paragon__btn.paragon__btn-light {
|
||||
line-height: 0.25;
|
||||
font-weight: 600;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.paragon__modal-title {
|
||||
font-weight: 600;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.paragon__modal-title::before {
|
||||
content: "NEW";
|
||||
font-size: small;
|
||||
background-color: #ccdde6;
|
||||
color: #00507e;
|
||||
margin-right: 8px;
|
||||
box-shadow: 0 0 0 4px #ccdde6;
|
||||
font-weight: 500;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.paragon__modal-footer {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.carousel-arrow {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.carousel-arrow.prev {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 80%;
|
||||
box-shadow: initial;
|
||||
font-size: small;
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.carousel-arrow.next {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 80%;
|
||||
box-shadow: initial;
|
||||
font-size: small;
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.carousel-wrapper {
|
||||
display: flex;
|
||||
|
||||
.slick-dots {
|
||||
margin-bottom: 6%;
|
||||
margin-left: 33%;
|
||||
width: 33%;
|
||||
display: block;
|
||||
|
||||
li > button::before {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-list {
|
||||
margin-bottom: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-slide.carousel-item {
|
||||
padding: 0 10px;
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
.upsell-certificate {
|
||||
height: 43px;
|
||||
position: absolute;
|
||||
left: 40%;
|
||||
margin-top: 29px;
|
||||
}
|
||||
|
||||
.upsell-modal-checkmark-group {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.upsell-modal-checkmark::before {
|
||||
content: '✔️\00a0\00a0\00a0\00a0';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,19 +17,8 @@ from openedx.core.djangolib.markup import HTML
|
||||
from openedx.features.course_experience import UNIFIED_COURSE_TAB_FLAG, SHOW_REVIEWS_TOOL_FLAG
|
||||
%>
|
||||
|
||||
<%block name="header_extras">
|
||||
<link rel="stylesheet" type="text/css" href="${static.url('paragon/static/paragon.min.css')}" />
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
<div class="course-view page-content-container" id="course-container">
|
||||
|
||||
${static.renderReact(
|
||||
component="CourseHomeUpsellExperimentModal",
|
||||
id="upsell-modal",
|
||||
props={},
|
||||
)}
|
||||
|
||||
<header class="page-header has-secondary">
|
||||
<div class="page-header-main">
|
||||
<nav aria-label="${_('Course Outline')}" class="sr-is-focusable" tabindex="-1">
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"backbone": "~1.3.2",
|
||||
"backbone.paginator": "~2.0.3",
|
||||
"bootstrap": "v4.0.0-beta.2",
|
||||
"classnames": "^2.2.5",
|
||||
"coffee-loader": "^0.7.3",
|
||||
"coffee-script": "1.6.1",
|
||||
"css-loader": "^0.28.5",
|
||||
@@ -38,7 +37,6 @@
|
||||
"raw-loader": "^0.5.1",
|
||||
"react": "^15.5.4",
|
||||
"react-dom": "^15.5.4",
|
||||
"react-slick": "^0.16.0",
|
||||
"requirejs": "~2.3.2",
|
||||
"rtlcss": "^2.2.0",
|
||||
"sass-loader": "^6.0.6",
|
||||
|
||||
@@ -25,8 +25,6 @@ module.exports = {
|
||||
// LMS
|
||||
SingleSupportForm: './lms/static/support/jsx/single_support_form.jsx',
|
||||
AlertStatusBar: './lms/static/js/accessible_components/StatusBarAlert.jsx',
|
||||
UpsellExperimentModal: './lms/static/common/js/components/UpsellExperimentModal.jsx',
|
||||
CourseHomeUpsellExperimentModal: './lms/static/common/js/components/CourseHomeUpsellExperimentModal.jsx',
|
||||
|
||||
// Features
|
||||
CourseGoals: './openedx/features/course_experience/static/course_experience/js/CourseGoals.js',
|
||||
|
||||
Reference in New Issue
Block a user