diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index dec0f6a3a6..9fc071c837 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -83,10 +83,14 @@ from openedx.core.djangoapps.external_auth.login_and_register import register as from openedx.core.djangoapps.external_auth.models import ExternalAuthMap from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY from openedx.core.djangoapps.programs.models import ProgramsApiConfig -from openedx.core.djangoapps.programs.utils import ProgramProgressMeter +from openedx.core.djangoapps.programs.utils import ( + ProgramDataExtender, + ProgramProgressMeter +) from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.theming import helpers as theming_helpers from openedx.core.djangoapps.user_api.preferences import api as preferences_api +from openedx.core.djangoapps.waffle_utils import WaffleFlagNamespace, WaffleFlag from openedx.core.djangolib.markup import HTML from openedx.features.course_experience import course_home_url_name from openedx.features.enterprise_support.api import get_dashboard_consent_notification @@ -780,8 +784,28 @@ def dashboard(request): # is passed in the template context to allow rendering of program-related # information on the dashboard. meter = ProgramProgressMeter(request.site, user, enrollments=course_enrollments) + ecommerce_service = EcommerceService() inverted_programs = meter.invert_programs() + urls, program_data = {}, {} + bundles_on_dashboard_flag = WaffleFlag(WaffleFlagNamespace(name=u'student.experiments'), u'bundles_on_dashboard') + + if (bundles_on_dashboard_flag.is_enabled()): + programs_data = meter.programs + if programs_data: + program_data = meter.programs[0] + program_data = ProgramDataExtender(program_data, request.user).extend() + course_data = meter.progress(programs=[program_data], count_only=False)[0] + + program_data.pop('courses') + skus = program_data.get('skus') + + urls = { + 'commerce_api_url': reverse('commerce_api:v0:baskets:create'), + 'buy_button_url': ecommerce_service.get_checkout_page_url(*skus) + } + urls['completeProgramURL'] = urls['buy_button_url'] + '&bundle=' + program_data.get('uuid') + # Construct a dictionary of course mode information # used to render the course list. We re-use the course modes dict # we loaded earlier to avoid hitting the database. @@ -879,6 +903,8 @@ def dashboard(request): course_enrollments = [enr for enr in course_enrollments if entitlement.enrollment_course_run.course_id != enr.course_id] # pylint: disable=line-too-long context = { + 'urls': urls, + 'program_data': program_data, 'enterprise_message': enterprise_message, 'consent_required_courses': consent_required_courses, 'enterprise_customer_name': enterprise_customer_name, @@ -921,7 +947,6 @@ def dashboard(request): 'display_sidebar_on_dashboard': display_sidebar_on_dashboard, } - ecommerce_service = EcommerceService() if ecommerce_service.is_enabled(request.user): context.update({ 'use_ecommerce_payment_flow': True, diff --git a/lms/static/sass/_experiments.scss b/lms/static/sass/_experiments.scss index e63167ded8..22127b3f9c 100644 --- a/lms/static/sass/_experiments.scss +++ b/lms/static/sass/_experiments.scss @@ -4,396 +4,38 @@ // Please list the ticket number of the experiment // -------------------- -// LEARNER-1726 Track Selection V3 +// LEARNER-3072 Program Purchase on dashboard -/* This css was added as part of the LEARNER-1726 experiment */ -.v2.register-choice { - margin: 0 2% 20px 0 !important -} +/* This css was added as part of the LEARNER-3072 experiment */ -.v2.register-choice-certificate .list-actions { - text-align: left !important; -} - -.v2.register-choice-continue .list-actions { - margin-bottom: 0 !important; -} - -.v2.register-choice-continue .action-select { - display: inline-block !important; - list-style-type: none !important; - width: 100% !important; -} - -.v2.register-choice-continue .continue-link { - display: inline-block !important; - padding: 10px 15px !important; - border-radius: 3px !important; - border: 1px solid #d7548e !important; - box-shadow: 0 2px 1px 0 #982c62 !important; - background: white !important; - text-align: center !important; - color: #d7548e !important; - float: left !important; - font-size: 15px; - font-weight: 500 !important; -} - -.v2.register-choice-v2-donate { - height: 300px; - background: none !important; - border-top-color: grey !important; - border-top-width: 1px !important; -} - -@media screen and (min-width: 375px) { - .v2.register-choice-v2-donate { - height: 250px; - } -} - -.v2.register-choice-v2-donate .list-actions { - margin-bottom: 0 !important; -} - -.v2.register-choice-v2-donate .list-actions a { - background: transparent !important; - color: #0075b4 !important; - box-shadow: none !important; - text-decoration: underline !important; - border: none !important; - white-space: normal; -} - -.v2.register-choice-v2-donate .wrapper-copy-inline { - height: 70px !important; - width: 100% !important; - display: flex !important; -} - -.v2.register-choice-v2-donate .wrapper-copy { - width: 70% !important; - height: auto !important; -} - -.v2.page-header { - padding: 0; -} - -.v2 img { - margin-top: 20px; - margin-left: 5px; -} - -.v2 .continue-link { - font-weight: bold !important; -} - -.v2.register-choice-certificate, -.v2.register-choice-continue, -.v2.register-choice-view { - width: 100%; -} - -.v2.register-choice-continue { - border-color: #d7548e !important; -} - -.v2 .wrapper-copy-inline { - max-height: 115px; -} - -.v2.register-choice-v2-donate .wrapper-copy-inline { - display: block !important; -} - -.v2.register-choice-v2-donate .copy-inline { - width: 100% !important; -} - -.v2.register-choice-v2-donate .list-actions { - width: 100% !important; - margin-top: 20px !important; - text-align: center !important; -} - -.v2 .wrapper-copy-inline .wrapper-copy { - width: 100% !important; -} - -.v2 input, .v2 a { - font-size: 15px !important; -} - -.v2 button { - background-color: rgb(0, 103, 0); - border-color: rgb(0, 103, 0); - border-radius: 2px; - box-shadow: rgb(0, 77, 0) 0 2px 1px 0; +.complete-program-dashboard-button { + float: right; + display: block; + box-sizing: border-box; + color: rgb(242, 248, 251) !important; cursor: pointer; - font-family: $font-family-sans-serif; - height: auto; - margin-right: 4px; - margin-top: 0; - padding: 10px 15px; - width: initial; - background-image: none !important; - font-size: 14px !important; - font-weight: 500 !important; - - &:hover, - &:focus { - background-color: #009b00 !important; - border-color: #009b00; - box-shadow: #004d00 0 2px 1px 0; - } + background: rgb(0, 129, 0) none repeat scroll 0% 0% / auto padding-box border-box !important; + font: normal normal 600 normal 15px / normal "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + padding: 7px; + transition: color 0.25s ease-in-out 0s, background 0.25s ease-in-out 0s, box-shadow 0.25s ease-in-out 0s; + text-decoration: none !important; + border: none !important; + margin-top: 5px; } -.savings-message { - margin-top: 10px; - font-size: 11px; +.complete-program-dashboard-button:hover { + background: #009b00 !important; } -@media screen and (min-width: 375px) { - .savings-message { - font-size: 13px; - margin-left: 16px; - } +.complete-program-dashboard-span { + display: block; + float: right; } -.v2 .continue-link, .v2 input, .v2 button, .v2 a { - width: 100%; -} - -.v2 img { +.complete-program-dashboard-div { display: none; -} - -.v2 .deco-divider { - display: none; -} - -.v2 .visual-reference { - width: 38%; -} - -@media (min-width: 420px) { - .v2 button { - height: 45px; - font-size: 16px !important; - } -} - -@media (min-width: 768px) { - .v2.register-choice-certificate, - .v2.register-choice-continue, - .v2.deco-divider { - width: 46.5% !important; - display: inline-block; - min-height: 270px; - } - - .v2.register-choice-v2-donate .wrapper-copy-inline { - display: flex !important; - } - - .v2.register-choice-v2-donate .copy-inline { - width: 40% !important; - } - - .v2.register-choice-v2-donate .list-actions { - margin-top: 0 !important; - text-align: right !important; - } - - .v2 .wrapper-copy-inline .wrapper-copy { - width: 100% !important; - } - - .v2 input, .v2 a { - font-size: 15px !important; - } - - .v2 .continue-link, .v2.register-choice-certificate button, .v2.register-choice-certificate input { - margin-top: 20px; - width: initial; - } - - .v2.register-choice-v2-donate a { - width: 100% !important; - } - - .v2.register-choice-view { - height: 250px; - } - - .v2 img { - display: initial; - } - - .v2.register-choice { - margin: 0 2% 20px 0; - } - - .v2.register-choice-continue .wrapper-copy-inline .wrapper-copy, .v2.register-choice-certificate .wrapper-copy-inline .wrapper-copy { - width: 60%; - } - - .v2.register-choice-view .wrapper-copy-inline .wrapper-copy { - width: 100%; - } - - .v2.register-choice { - padding: 15px !important; - } - - .v2.register-choice-continue .wrapper-copy-inline .wrapper-copy, .v2.register-choice-certificate .wrapper-copy-inline .wrapper-copy { - width: 60%; - } - - .v2.register-choice { - padding: 20px !important; - } - - .v2.register-choice.register-choice-view { - margin-right: 0; - } - - .v2.register-choice .list-actions:last-child { - float: left; - width: 100%; - margin-top: 0; - } - - .v2.register-choice .action-select { - width: 100% !important; - } - - .v2 .continue-link:hover, - .v2 .continue-link:focus { - background-color: #d7548e !important; - color: white !important; - text-decoration: none; - } - - .v2 .continue-link:hover { - cursor: pointer; - } - - .v2 .copy li { - margin-bottom: 5px; - } - - .v2.register-choice .copy-inline { - width: 100%; - } - - .v2 .register-choice-view { - border-color: #2991c3 !important; - } - - .v2 .visual-reference { - vertical-align: top; - } - - .v2 .wrapper-copy-inline .wrapper-copy ul { - margin-top: 0; - padding-left: 30px; - } - - .v2 .img-certificate { - border: 2px solid #009b00 !important; - float: right; - height: 120px; - width: auto; - margin-top: 0 !important; - display: none; - } - - .v2 .img-donate { - margin-top: 0; - float: right; - border: 2px solid #d7548e !important; - display: none; - } - - .v2 .img-view { - border: 2px solid #2991c3 !important; - } - - .v2.register-choice .title { - width: 100%; - margin-bottom: 20px; - } - - .v2.register-choice.register-choice-view .action-select { - border: 1px solid transparent !important; - border-radius: 3px; - } - - .v2.register-choice.register-choice-view .action-select button { - border: 1px solid transparent !important; - } - - .v2.register-choice.register-choice-view .action-select:hover { - border: 1px solid #0075b4 !important; - } - - .v2.deco-divider { - width: 3% !important; - box-sizing: border-box; - float: left; - display: inline-block; - height: 250px; - margin: 0 0 40px 0 !important; - border-left: 4px solid #f5f5f5 !important; border-top:none !important; - - .copy { - position: absolute; - top: 110px !important; - left: calc(50% - 40px) !important; - margin-left: 20px; - background: white; - text-align: center; - color: #474747; - width: 10px; - padding: 0 !important; - } - } -} - -@media (min-width: 835px) { - .v2.register-choice-certificate, - .v2.register-choice-continue, - .v2.deco-divider { - min-height: 250px; - } -} - -@media (min-width: 1024px) { - .v2 .continue-link { - width: 55%; - } - - .v2.deco-divider .copy { - margin-left: 15px; - } -} - -@media (min-width: 1096px) { - .v2.register-choice-certificate, - .v2.register-choice-continue, - .v2.deco-divider { - min-height: 260px; - } - - .v2 .img-certificate, .v2 .img-donate { - margin-top: 10px; - display: initial; - } - - .v2 .continue-link, .v2.register-choice-certificate button, - .v2.register-choice-certificate input { - margin-top: -22px !important; - } + float: right; + width: auto; + max-width: 420px; + margin: 0 0 10px 0; } diff --git a/lms/templates/dashboard/_dashboard_course_listing.html b/lms/templates/dashboard/_dashboard_course_listing.html index 9d5f52fae5..939294c758 100644 --- a/lms/templates/dashboard/_dashboard_course_listing.html +++ b/lms/templates/dashboard/_dashboard_course_listing.html @@ -326,17 +326,31 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ %endif % if related_programs: - + % endif % if cert_status: