fix: course home, course cards and course outline cleanup
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import re
|
||||
import frappe
|
||||
from frappe.utils import flt, cint, cstr
|
||||
from school.lms.md import markdown_to_html
|
||||
from school.lms.md import markdown_to_html, find_macros
|
||||
import string
|
||||
from frappe import _
|
||||
|
||||
@@ -85,6 +85,13 @@ def get_lesson_details(chapter):
|
||||
lesson_details = frappe.db.get_value("Course Lesson", row.lesson,
|
||||
["name", "title", "include_in_preview", "body", "creation"], as_dict=True)
|
||||
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
|
||||
lesson_details.icon = "icon-list"
|
||||
macros = find_macros(lesson_details.body)
|
||||
for macro in macros:
|
||||
if macro[0] == "YouTubeVideo":
|
||||
lesson_details.icon = "icon-video"
|
||||
elif macro[0] == "Quiz":
|
||||
lesson_details.icon = "icon-quiz"
|
||||
lessons.append(lesson_details)
|
||||
return lessons
|
||||
|
||||
|
||||
@@ -17,10 +17,33 @@
|
||||
<div class="course-card-content">
|
||||
<div class="course-card-meta">
|
||||
{% if get_lessons(course.name) | length %}
|
||||
<span>
|
||||
<div class="vertically-center">
|
||||
<svg class="icon icon-md">
|
||||
<use href="#icon-education"></use>
|
||||
</svg>
|
||||
{{ get_lessons(course.name) | length }} {{ _("Lessons") }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% set student_count = get_students(course.name) | length %}
|
||||
{% if student_count %}
|
||||
<div class="vertically-center">
|
||||
<svg class="icon icon-md">
|
||||
<use class="" href="#icon-users">
|
||||
</svg>
|
||||
{{ student_count }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% set avg_rating = get_average_rating(course.name) %}
|
||||
{% if avg_rating %}
|
||||
<div class="vertically-center">
|
||||
<svg class="icon icon-md">
|
||||
<use href="#icon-star"></use>
|
||||
</svg>
|
||||
{{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="course-card-title">{{ course.title }}</div>
|
||||
|
||||
@@ -59,22 +82,6 @@
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
{% set student_count = get_students(course.name) | length %}
|
||||
<span class="course-student-count">
|
||||
{% if student_count %}
|
||||
<span class="vertically-center mr-3">
|
||||
<img class="icon-background" src="/assets/school/icons/user.svg" />
|
||||
{{ student_count }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% set avg_rating = get_average_rating(course.name) %}
|
||||
{% if avg_rating %}
|
||||
<span class="vertically-center">
|
||||
<img class="icon-background" src="/assets/school/icons/rating.svg" />
|
||||
{{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{% if read_only %}
|
||||
|
||||
@@ -23,12 +23,15 @@
|
||||
<div class="lessons">
|
||||
|
||||
{% for lesson in get_lessons(course.name, chapter) %}
|
||||
|
||||
<div class="lesson-info {% if membership.current_lesson == lesson.name %} active-lesson {% endif %}">
|
||||
{% set active = membership.current_lesson == lesson.name %}
|
||||
<div class="lesson-info {% if active %} active-lesson {% endif %}">
|
||||
|
||||
{% if membership or lesson.include_in_preview %}
|
||||
<a class="lesson-links" href="{{ get_lesson_url(course.name, lesson.number) }}{{course.query_parameter}}"
|
||||
data-course="{{ course.name }}">
|
||||
<svg class="icon icon-md">
|
||||
<use class="" href="#{{ lesson.icon }}{% if active %}-blue{% endif %}">
|
||||
</svg>
|
||||
{{ lesson.title }}
|
||||
|
||||
{% if membership %}
|
||||
@@ -43,14 +46,18 @@
|
||||
title="This lesson is not available for preview. As you are the Instructor of the course only you can see it."
|
||||
href="{{ get_lesson_url(course.name, lesson.number) }}{{course.query_parameter}}"
|
||||
data-course="{{ course.name }}">
|
||||
<img class="mr-3" src="/assets/school/icons/lock.svg">
|
||||
<svg class="icon icon-md">
|
||||
<use class="" href="#icon-lock">
|
||||
</svg>
|
||||
<div>{{ lesson.title }}</div>
|
||||
</a>
|
||||
|
||||
{% else %}
|
||||
<div class="no-preview" title="This lesson is not available for preview" data-course="{{ course.name }}">
|
||||
<div class="lesson-links">
|
||||
<img class="mr-3" src="/assets/school/icons/lock.svg">
|
||||
<svg class="icon icon-md">
|
||||
<use class="" href="#icon-lock">
|
||||
</svg>
|
||||
<div>{{ lesson.title }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -83,7 +90,7 @@ frappe.ready(() => {
|
||||
});
|
||||
|
||||
const expand_the_first_chapter = () => {
|
||||
var elements = $(".course-outline .collapse");
|
||||
let elements = $(".course-outline .collapse");
|
||||
elements.each((i, element) => {
|
||||
if (i < 1) {
|
||||
show_section(element);
|
||||
@@ -95,13 +102,21 @@ const expand_the_first_chapter = () => {
|
||||
const expand_the_active_chapter = () => {
|
||||
|
||||
/* Find anchor matching the URL for course details page */
|
||||
var selector = $(`a[href="${decodeURIComponent(window.location.pathname)}"]`).parent();
|
||||
let selector = $(`a[href="${decodeURIComponent(window.location.pathname)}"]`).parent();
|
||||
if (!selector.length) {
|
||||
selector = $(`a[href^="${decodeURIComponent(window.location.pathname)}"]`).parent();
|
||||
}
|
||||
if (selector.length && $(".course-details-page").length) {
|
||||
$(".lesson-info").removeClass("active-lesson")
|
||||
$(".lesson-info").removeClass("active-lesson");
|
||||
$(".lesson-info").each((i, elem) => {
|
||||
let href = $(elem).find("use").attr("href");
|
||||
href.endsWith("blue") && $(elem).find("use").attr("href", href.substring(0, href.length - 5));
|
||||
})
|
||||
|
||||
selector.addClass("active-lesson");
|
||||
let href = selector.find("use").attr("href");
|
||||
!href.endsWith("blue") && selector.find("use").attr("href", `${href}-blue`);
|
||||
|
||||
show_section(selector.parent().parent());
|
||||
}
|
||||
|
||||
@@ -124,7 +139,7 @@ const show_section = (element) => {
|
||||
};
|
||||
|
||||
const rotate_chapter_icon = (e) => {
|
||||
var icon = $(e.currentTarget).children(".chapter-icon");
|
||||
let icon = $(e.currentTarget).children(".chapter-icon");
|
||||
if (icon.css("transform") == "none") {
|
||||
icon.css("transform", "rotate(90deg)");
|
||||
} else {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="avg-rating-stars">
|
||||
<div class="rating">
|
||||
{% for i in [1, 2, 3, 4, 5] %}
|
||||
<svg class="icon icon-md {% if i <= avg_rating %} star-click {% endif %}" data-rating="{{ i }}">
|
||||
<svg class="icon icon-md {% if i <= frappe.utils.ceil(avg_rating) %} star-click {% endif %}" data-rating="{{ i }}">
|
||||
<use href="#icon-star"></use>
|
||||
</svg>
|
||||
{% endfor %}
|
||||
@@ -49,14 +49,16 @@
|
||||
{% if reviews | length %}
|
||||
<div class="mt-12">
|
||||
{% for review in reviews %}
|
||||
<div class="">
|
||||
<div class="review-card-footer">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="mr-5">
|
||||
{{ widgets.Avatar(member=review.owner_details, avatar_class="avatar-medium") }}
|
||||
</div>
|
||||
<div>
|
||||
<a class="button-links" href="{{get_profile_url(review.owner_details.username) }}">
|
||||
<div class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
|
||||
<div class="mr-3">
|
||||
{{ widgets.Avatar(member=review.owner_details, avatar_class="avatar-medium") }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="d-flex align-items-center">
|
||||
<a class="button-links mr-2" href="{{get_profile_url(review.owner_details.username) }}">
|
||||
<span class="bold-heading">
|
||||
{{ review.owner_details.full_name }}
|
||||
</span>
|
||||
@@ -69,12 +71,12 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-16 mt-4">
|
||||
<div> {{ review.review }} </div>
|
||||
<div class="frappe-timestamp mt-2 mb-6 course-meta" data-timestamp="{{ review.creation }}"> frappe.utils.pretty_date(review.creation) </div>
|
||||
|
||||
<div class="frappe-timestamp course-meta" data-timestamp="{{ review.creation }}"> frappe.utils.pretty_date(review.creation) </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="review-content"> {{ review.review }} </div>
|
||||
</div>
|
||||
{% if loop.index != reviews | length %}
|
||||
<div class="card-divider"></div>
|
||||
|
||||
Reference in New Issue
Block a user