%page expression_filter="h"/>
<%inherit file="main.html" />
<%def name="online_help_token()"><% return "learnerdashboard" %>%def>
<%namespace name='static' file='static_content.html'/>
<%!
import pytz
from courseware.context_processor import user_timezone_locale_prefs
from datetime import datetime, timedelta
from django.utils import timezone
from django.utils.translation import ugettext as _
from django.template import RequestContext
from third_party_auth import pipeline
from django.core.urlresolvers import reverse
from util.date_utils import strftime_localized
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.theming import helpers as theming_helpers
from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string
from openedx.core.djangolib.markup import HTML, Text
from entitlements.models import CourseEntitlement
from student.models import CourseEnrollment
%>
<%
cert_name_short = settings.CERT_NAME_SHORT
cert_name_long = settings.CERT_NAME_LONG
%>
<%block name="pagetitle">${_("Dashboard")}%block>
<%block name="bodyclass">view-dashboard is-authenticated%block>
<%block name="header_extras">
% for template_name in ["donation"]:
% endfor
%block>
<%block name="js_extra">
<%static:js group='dashboard'/>
<%static:require_module module_name="js/learner_dashboard/unenrollment_factory" class_name="UnenrollmentFactory">
UnenrollmentFactory({
urls: {
dashboard: "${reverse('dashboard') | n, js_escaped_string}",
signInUser: "${reverse('signin_user') | n, js_escaped_string}",
changeEmailSettings: "${reverse('change_email_settings') | n, js_escaped_string}",
browseCourses: "${marketing_link('COURSES') | n, js_escaped_string}"
},
isEdx: true
});
%static:require_module>
<%static:require_module module_name="js/learner_dashboard/entitlement_unenrollment_factory" class_name="EntitlementUnenrollmentFactory">
## Wait until the document is fully loaded before initializing the EntitlementUnenrollmentView
## to ensure events are setup correctly.
$(document).ready(function() {
EntitlementUnenrollmentFactory({
dashboardPath: "${reverse('dashboard') | n, js_escaped_string}",
signInPath: "${reverse('signin_user') | n, js_escaped_string}"
});
});
%static:require_module>
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
<%static:require_module module_name="course_search/js/dashboard_search_factory" class_name="DashboardSearchFactory">
DashboardSearchFactory();
%static:require_module>
% endif
% if redirect_message:
<%static:require_module module_name="js/views/message_banner" class_name="MessageBannerView">
var banner = new MessageBannerView({urgency: 'low', type: 'warning'});
$('#content').prepend(banner.$el);
banner.showMessage(${redirect_message | n, dump_js_escaped_json})
%static:require_module>
% endif
%block>
%if banner_account_activation_message:
${banner_account_activation_message | n, decode.utf8}
%endif
%if enrollment_message:
${enrollment_message | n, decode.utf8}
%endif
%if enterprise_message:
${ enterprise_message | n, decode.utf8 }
%endif
%if account_activation_messages:
% for account_activation_message in account_activation_messages:
${ account_activation_message | n, decode.utf8 }
% endfor
%endif
${_("My Courses")}
% if len(course_entitlements + course_enrollments) > 0:
<% share_settings = getattr(settings, 'SOCIAL_SHARING_SETTINGS', {}) %>
% for dashboard_index, enrollment in enumerate(course_entitlements + course_enrollments):
<%
# Check if the course run is an entitlement and if it has an associated session
entitlement = enrollment if isinstance(enrollment, CourseEntitlement) else None
entitlement_session = entitlement.enrollment_course_run if entitlement else None
entitlement_days_until_expiration = entitlement.get_days_until_expiration() if entitlement else None
entitlement_expiration = datetime.now(tz=pytz.UTC) + timedelta(days=entitlement_days_until_expiration) if (entitlement and entitlement_days_until_expiration < settings.ENTITLEMENT_EXPIRED_ALERT_PERIOD) else None
entitlement_expiration_date = strftime_localized(entitlement_expiration, 'SHORT_DATE') if entitlement and entitlement_expiration else None
entitlement_expired_at = strftime_localized(entitlement.expired_at_datetime, 'SHORT_DATE') if entitlement and entitlement.expired_at_datetime else None
is_fulfilled_entitlement = True if entitlement and entitlement_session else False
is_unfulfilled_entitlement = True if entitlement and not entitlement_session else False
entitlement_available_sessions = []
if entitlement:
# Grab the available, enrollable sessions for a given entitlement and scrape them for relevant attributes
entitlement_available_sessions = [{
'session_id': course['key'],
'enrollment_end': course['enrollment_end'],
'pacing_type': course['pacing_type'],
'advertised_start': CourseOverview.get_from_id(CourseKey.from_string(course['key'])).advertised_start,
'start': CourseOverview.get_from_id(CourseKey.from_string(course['key'])).start,
'end': CourseOverview.get_from_id(CourseKey.from_string(course['key'])).end,
} for course in course_entitlement_available_sessions[str(entitlement.uuid)]]
if is_fulfilled_entitlement:
# If the user has a fulfilled entitlement, pass through the entitlements CourseEnrollment object
enrollment = entitlement_session
else:
# If the user has an unfulfilled entitlement, pass through a bare CourseEnrollment object built off of the next available session
upcoming_sessions = course_entitlement_available_sessions[str(entitlement.uuid)]
next_session = upcoming_sessions[0] if upcoming_sessions else None
if not next_session:
continue
enrollment = CourseEnrollment(user=user, course_id=next_session['key'], mode=next_session['type'])
# We only show email settings for entitlement cards if the entitlement has an associated enrollment
show_email_settings = is_fulfilled_entitlement and (entitlement_session.course_id in show_email_settings_for)
else:
show_email_settings = (enrollment.course_id in show_email_settings_for)
session_id = enrollment.course_id
show_courseware_link = (session_id in show_courseware_links_for)
cert_status = cert_statuses.get(session_id)
can_refund_entitlement = entitlement and entitlement.is_entitlement_refundable()
can_unenroll = (not cert_status) or cert_status.get('can_unenroll') if not unfulfilled_entitlement else False
credit_status = credit_statuses.get(session_id)
course_mode_info = all_course_modes.get(session_id)
is_paid_course = True if entitlement else (session_id in enrolled_courses_either_paid)
is_course_blocked = (session_id in block_courses)
course_verification_status = verification_status_by_course.get(session_id, {})
course_requirements = courses_requirements_not_met.get(session_id)
related_programs = inverted_programs.get(unicode(entitlement.course_uuid if is_unfulfilled_entitlement else session_id))
show_consent_link = (session_id in consent_required_courses)
course_overview = enrollment.course_overview
%>
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=course_overview, course_card_index=dashboard_index, enrollment=enrollment, is_unfulfilled_entitlement=is_unfulfilled_entitlement, is_fulfilled_entitlement=is_fulfilled_entitlement, entitlement=entitlement, entitlement_session=entitlement_session, entitlement_available_sessions=entitlement_available_sessions, entitlement_expiration_date=entitlement_expiration_date, entitlement_expired_at=entitlement_expired_at, show_courseware_link=show_courseware_link, cert_status=cert_status, can_refund_entitlement=can_refund_entitlement, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_blocked=is_course_blocked, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard, show_consent_link=show_consent_link, enterprise_customer_name=enterprise_customer_name' />
% endfor
% else:
${_("You are not enrolled in any courses yet.")}
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE'):
${_("Explore courses")}
%endif
% endif
% if staff_access and len(errored_courses) > 0:
${_("Course-loading errors")}
% for course_dir, errors in errored_courses.items():
${course_dir}
% for (msg, err) in errors:
${msg}
${err}
% endfor
% endfor
% endif
%if sidebar_account_activation_message:
${sidebar_account_activation_message | n, decode.utf8}
%endif
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
% endif
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE'):
${_("Browse recently launched courses and see what's new in your favorite subjects.")}
${Text(_("Email Settings for {course_number}")).format(course_number=HTML(''))}
,
## Translators: this text gives status on if the modal interface (a menu or piece of UI that takes the full focus of the screen) is open or not
${_("window open")}
,
## Translators: this text gives status on if the modal interface (a menu or piece of UI that takes the full focus of the screen) is open or not
${_("window open")}