AA-51: Adds in 'Up next' banner to course home
This commit is contained in:
@@ -75,6 +75,7 @@
|
|||||||
@import 'features/course-duration-limits';
|
@import 'features/course-duration-limits';
|
||||||
@import 'features/enterprise-learner-portal-banner';
|
@import 'features/enterprise-learner-portal-banner';
|
||||||
@import 'features/first-purchase-banner';
|
@import 'features/first-purchase-banner';
|
||||||
|
@import 'features/next-up-banner';
|
||||||
|
|
||||||
// search
|
// search
|
||||||
@import 'search/search';
|
@import 'search/search';
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ $static-path: '../..';
|
|||||||
@import 'features/course-duration-limits';
|
@import 'features/course-duration-limits';
|
||||||
@import 'features/enterprise-learner-portal-banner';
|
@import 'features/enterprise-learner-portal-banner';
|
||||||
@import 'features/first-purchase-banner';
|
@import 'features/first-purchase-banner';
|
||||||
|
@import 'features/next-up-banner';
|
||||||
|
|
||||||
// Individual Pages
|
// Individual Pages
|
||||||
@import "views/program-marketing-page";
|
@import "views/program-marketing-page";
|
||||||
|
|||||||
29
lms/static/sass/features/_next-up-banner.scss
Normal file
29
lms/static/sass/features/_next-up-banner.scss
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Up next banner
|
||||||
|
.next-up-banner {
|
||||||
|
display: none; // Required to be none for Optimizely experiment in AA-29
|
||||||
|
background-color: #d8edf8;
|
||||||
|
color: #393f43;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 1px solid #bbdff2;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin: $baseline auto;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
a:not(.btn) {
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: underline;
|
||||||
|
color: #006ea9;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: darken(#006ea9, 15%);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& + .page-content {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,6 +63,9 @@ from openedx.features.course_experience.course_tools import HttpMethod
|
|||||||
</header>
|
</header>
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<div class="page-content-main">
|
<div class="page-content-main">
|
||||||
|
% if next_up_banner_fragment:
|
||||||
|
${HTML(next_up_banner_fragment.body_html())}
|
||||||
|
% endif
|
||||||
% if offer_banner_fragment:
|
% if offer_banner_fragment:
|
||||||
${HTML(offer_banner_fragment.content)}
|
${HTML(offer_banner_fragment.content)}
|
||||||
% endif
|
% endif
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
## mako
|
||||||
|
|
||||||
|
<%page expression_filter="h"/>
|
||||||
|
|
||||||
|
<%!
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="next-up-banner">
|
||||||
|
<b>${_("Get started on what's next: ")}</b>
|
||||||
|
<a href="${resume_course_url}">${assignment_title}</a>
|
||||||
|
(${assignment_duration})
|
||||||
|
</div>
|
||||||
@@ -48,6 +48,7 @@ from .course_home_messages import CourseHomeMessageFragmentView
|
|||||||
from .course_outline import CourseOutlineFragmentView
|
from .course_outline import CourseOutlineFragmentView
|
||||||
from .course_sock import CourseSockFragmentView
|
from .course_sock import CourseSockFragmentView
|
||||||
from .latest_update import LatestUpdateFragmentView
|
from .latest_update import LatestUpdateFragmentView
|
||||||
|
from .next_up_banner import NextUpBannerFragmentView
|
||||||
from .welcome_message import WelcomeMessageFragmentView
|
from .welcome_message import WelcomeMessageFragmentView
|
||||||
|
|
||||||
EMPTY_HANDOUTS_HTML = u'<ol></ol>'
|
EMPTY_HANDOUTS_HTML = u'<ol></ol>'
|
||||||
@@ -88,10 +89,11 @@ class CourseHomeFragmentView(EdxFragmentView):
|
|||||||
"""
|
"""
|
||||||
Returns information relevant to resume course functionality.
|
Returns information relevant to resume course functionality.
|
||||||
|
|
||||||
Returns a tuple: (has_visited_course, resume_course_url)
|
Returns a tuple: (has_visited_course, resume_course_url, resume_course_title)
|
||||||
has_visited_course: True if the user has ever visted the course, False otherwise.
|
has_visited_course: True if the user has ever visited the course, False otherwise.
|
||||||
resume_course_url: The URL of the 'resume course' block if the user has visited the course,
|
resume_course_url: The URL of the 'resume course' block if the user has visited the course,
|
||||||
otherwise the URL of the course root.
|
otherwise the URL of the course root.
|
||||||
|
resume_course_title: The display_name of the resume course block, otherwise the display_name of course root
|
||||||
|
|
||||||
"""
|
"""
|
||||||
course_outline_root_block = get_course_outline_block_tree(request, course_id, request.user)
|
course_outline_root_block = get_course_outline_block_tree(request, course_id, request.user)
|
||||||
@@ -99,10 +101,12 @@ class CourseHomeFragmentView(EdxFragmentView):
|
|||||||
has_visited_course = bool(resume_block)
|
has_visited_course = bool(resume_block)
|
||||||
if resume_block:
|
if resume_block:
|
||||||
resume_course_url = resume_block['lms_web_url']
|
resume_course_url = resume_block['lms_web_url']
|
||||||
|
resume_course_title = resume_block['display_name']
|
||||||
else:
|
else:
|
||||||
resume_course_url = course_outline_root_block['lms_web_url'] if course_outline_root_block else None
|
resume_course_url = course_outline_root_block['lms_web_url'] if course_outline_root_block else None
|
||||||
|
resume_course_title = course_outline_root_block['display_name'] if course_outline_root_block else None
|
||||||
|
|
||||||
return has_visited_course, resume_course_url
|
return has_visited_course, resume_course_url, resume_course_title
|
||||||
|
|
||||||
def _get_course_handouts(self, request, course):
|
def _get_course_handouts(self, request, course):
|
||||||
"""
|
"""
|
||||||
@@ -141,6 +145,7 @@ class CourseHomeFragmentView(EdxFragmentView):
|
|||||||
update_message_fragment = None
|
update_message_fragment = None
|
||||||
course_sock_fragment = None
|
course_sock_fragment = None
|
||||||
offer_banner_fragment = None
|
offer_banner_fragment = None
|
||||||
|
next_up_banner_fragment = None
|
||||||
course_expiration_fragment = None
|
course_expiration_fragment = None
|
||||||
has_visited_course = None
|
has_visited_course = None
|
||||||
resume_course_url = None
|
resume_course_url = None
|
||||||
@@ -162,8 +167,11 @@ class CourseHomeFragmentView(EdxFragmentView):
|
|||||||
course_sock_fragment = CourseSockFragmentView().render_to_fragment(
|
course_sock_fragment = CourseSockFragmentView().render_to_fragment(
|
||||||
request, course=course_overview, **kwargs
|
request, course=course_overview, **kwargs
|
||||||
)
|
)
|
||||||
has_visited_course, resume_course_url = self._get_resume_course_info(request, course_id)
|
has_visited_course, resume_course_url, resume_course_title = self._get_resume_course_info(
|
||||||
|
request, course_id
|
||||||
|
)
|
||||||
handouts_html = self._get_course_handouts(request, course)
|
handouts_html = self._get_course_handouts(request, course)
|
||||||
|
|
||||||
offer_banner_fragment = get_first_purchase_offer_banner_fragment(
|
offer_banner_fragment = get_first_purchase_offer_banner_fragment(
|
||||||
request.user,
|
request.user,
|
||||||
course_overview
|
course_overview
|
||||||
@@ -172,6 +180,11 @@ class CourseHomeFragmentView(EdxFragmentView):
|
|||||||
request.user,
|
request.user,
|
||||||
course_overview
|
course_overview
|
||||||
)
|
)
|
||||||
|
|
||||||
|
next_up_banner_fragment = NextUpBannerFragmentView().render_to_fragment(
|
||||||
|
assignment_title=resume_course_title, resume_course_url=resume_course_url, assignment_duration='10 min'
|
||||||
|
)
|
||||||
|
|
||||||
elif allow_public_outline or allow_public:
|
elif allow_public_outline or allow_public:
|
||||||
outline_fragment = CourseOutlineFragmentView().render_to_fragment(
|
outline_fragment = CourseOutlineFragmentView().render_to_fragment(
|
||||||
request, course_id=course_id, user_is_enrolled=False, **kwargs
|
request, course_id=course_id, user_is_enrolled=False, **kwargs
|
||||||
@@ -228,6 +241,7 @@ class CourseHomeFragmentView(EdxFragmentView):
|
|||||||
'course_home_message_fragment': course_home_message_fragment,
|
'course_home_message_fragment': course_home_message_fragment,
|
||||||
'offer_banner_fragment': offer_banner_fragment,
|
'offer_banner_fragment': offer_banner_fragment,
|
||||||
'course_expiration_fragment': course_expiration_fragment,
|
'course_expiration_fragment': course_expiration_fragment,
|
||||||
|
'next_up_banner_fragment': next_up_banner_fragment,
|
||||||
'has_visited_course': has_visited_course,
|
'has_visited_course': has_visited_course,
|
||||||
'resume_course_url': resume_course_url,
|
'resume_course_url': resume_course_url,
|
||||||
'course_tools': course_tools,
|
'course_tools': course_tools,
|
||||||
|
|||||||
27
openedx/features/course_experience/views/next_up_banner.py
Normal file
27
openedx/features/course_experience/views/next_up_banner.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
"""
|
||||||
|
View logic for handling course messages.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from web_fragments.fragment import Fragment
|
||||||
|
|
||||||
|
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
|
||||||
|
|
||||||
|
|
||||||
|
class NextUpBannerFragmentView(EdxFragmentView):
|
||||||
|
"""
|
||||||
|
A fragment that displays an up next banner with a call to action to resume the course.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# pylint: disable=arguments-differ
|
||||||
|
def render_to_fragment(self, assignment_title, resume_course_url, assignment_duration='10 mins'):
|
||||||
|
"""
|
||||||
|
Renders an up next banner fragment with the provided assignment title, duration, and a link to the URL.
|
||||||
|
"""
|
||||||
|
context = {
|
||||||
|
'assignment_title': assignment_title,
|
||||||
|
'resume_course_url': resume_course_url,
|
||||||
|
'assignment_duration': assignment_duration,
|
||||||
|
}
|
||||||
|
html = render_to_string('course_experience/next-up-banner-fragment.html', context)
|
||||||
|
return Fragment(html)
|
||||||
Reference in New Issue
Block a user