Merge pull request #303 from pateljannat/course-page-redesign
This commit is contained in:
@@ -183,7 +183,8 @@ jinja = {
|
|||||||
"school.lms.utils.get_reviews",
|
"school.lms.utils.get_reviews",
|
||||||
"school.lms.utils.is_eligible_to_review",
|
"school.lms.utils.is_eligible_to_review",
|
||||||
"school.lms.utils.get_initial_members",
|
"school.lms.utils.get_initial_members",
|
||||||
"school.lms.utils.get_sorted_reviews"
|
"school.lms.utils.get_sorted_reviews",
|
||||||
|
"school.lms.utils.is_instructor"
|
||||||
],
|
],
|
||||||
"filters": []
|
"filters": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ def get_lesson_details(chapter):
|
|||||||
|
|
||||||
for row in lesson_list:
|
for row in lesson_list:
|
||||||
lesson_details = frappe.db.get_value("Course Lesson", row.lesson,
|
lesson_details = frappe.db.get_value("Course Lesson", row.lesson,
|
||||||
["name", "title", "include_in_preview", "body"], as_dict=True)
|
["name", "title", "include_in_preview", "body", "creation"], as_dict=True)
|
||||||
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
|
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
|
||||||
lessons.append(lesson_details)
|
lessons.append(lesson_details)
|
||||||
return lessons
|
return lessons
|
||||||
@@ -289,3 +289,6 @@ def get_initial_members(course):
|
|||||||
member.member, ["name", "username", "full_name", "user_image"], as_dict=True))
|
member.member, ["name", "username", "full_name", "user_image"], as_dict=True))
|
||||||
|
|
||||||
return member_details
|
return member_details
|
||||||
|
|
||||||
|
def is_instructor(course):
|
||||||
|
return len(list(filter(lambda x: x.name == frappe.session.user, get_instructors(course)))) > 0
|
||||||
|
|||||||
@@ -41,14 +41,14 @@
|
|||||||
{% elif is_instructor and not lesson.include_in_preview %}
|
{% elif is_instructor and not lesson.include_in_preview %}
|
||||||
<a class="lesson-links"
|
<a class="lesson-links"
|
||||||
title="This lesson is not available for preview. As you are the Instructor of the course only you can see it."
|
title="This lesson is not available for preview. As you are the Instructor of the course only you can see it."
|
||||||
href="{{ course.get_lesson_url(lesson.number) }}{{course.query_parameter}}"
|
href="{{ get_lesson_url(lesson.number) }}{{course.query_parameter}}"
|
||||||
data-course="{{ course.name }}">
|
data-course="{{ course.name }}">
|
||||||
<img class="mr-3" src="/assets/school/icons/lock.svg">
|
<img class="mr-3" src="/assets/school/icons/lock.svg">
|
||||||
<div>{{ lesson.title }}</div>
|
<div>{{ lesson.title }}</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="no-preview" title="This lesson is not available for preview">
|
<div class="no-preview" title="This lesson is not available for preview" data-course="{{ course.name }}">
|
||||||
<div class="lesson-links">
|
<div class="lesson-links">
|
||||||
<img class="mr-3" src="/assets/school/icons/lock.svg">
|
<img class="mr-3" src="/assets/school/icons/lock.svg">
|
||||||
<div>{{ lesson.title }}</div>
|
<div>{{ lesson.title }}</div>
|
||||||
@@ -76,9 +76,13 @@ frappe.ready(() => {
|
|||||||
rotate_chapter_icon(e);
|
rotate_chapter_icon(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
$(".no-preview").click((e) => {
|
||||||
|
show_no_preview_dialog(e);
|
||||||
|
});
|
||||||
|
|
||||||
var expand_the_first_chapter = () => {
|
});
|
||||||
|
|
||||||
|
const expand_the_first_chapter = () => {
|
||||||
var elements = $(".course-outline .collapse");
|
var elements = $(".course-outline .collapse");
|
||||||
elements.each((i, element) => {
|
elements.each((i, element) => {
|
||||||
if (i < 1) {
|
if (i < 1) {
|
||||||
@@ -86,9 +90,9 @@ var expand_the_first_chapter = () => {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
var expand_the_active_chapter = () => {
|
const expand_the_active_chapter = () => {
|
||||||
|
|
||||||
/* Find anchor matching the URL for course details page */
|
/* Find anchor matching the URL for course details page */
|
||||||
var selector = $(`a[href="${decodeURIComponent(window.location.pathname)}"]`).parent();
|
var selector = $(`a[href="${decodeURIComponent(window.location.pathname)}"]`).parent();
|
||||||
@@ -111,21 +115,30 @@ var expand_the_active_chapter = () => {
|
|||||||
else {
|
else {
|
||||||
expand_the_first_chapter();
|
expand_the_first_chapter();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
var show_section = (element) => {
|
const show_section = (element) => {
|
||||||
$(element).addClass("show");
|
$(element).addClass("show");
|
||||||
$(element).siblings(".chapter-title").children(".chapter-icon").css("transform", "rotate(90deg)");
|
$(element).siblings(".chapter-title").children(".chapter-icon").css("transform", "rotate(90deg)");
|
||||||
$(element).siblings(".chapter-title").attr("aria-expanded", true);
|
$(element).siblings(".chapter-title").attr("aria-expanded", true);
|
||||||
}
|
};
|
||||||
|
|
||||||
var rotate_chapter_icon = (e) => {
|
const rotate_chapter_icon = (e) => {
|
||||||
var icon = $(e.currentTarget).children(".chapter-icon");
|
var icon = $(e.currentTarget).children(".chapter-icon");
|
||||||
if (icon.css("transform") == "none") {
|
if (icon.css("transform") == "none") {
|
||||||
icon.css("transform", "rotate(90deg)");
|
icon.css("transform", "rotate(90deg)");
|
||||||
} else {
|
} else {
|
||||||
icon.css("transform", "none");
|
icon.css("transform", "none");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const show_no_preview_dialog = (e) => {
|
||||||
|
frappe.warn(__("Not available for preview"),
|
||||||
|
__("This lesson is not available for preview. Please join the course to access it."),
|
||||||
|
() => {
|
||||||
|
window.location.href = `/courses/${ $(e.currentTarget).data("course") }`
|
||||||
|
},
|
||||||
|
__("Start Learning"), false);
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -114,10 +114,11 @@ def exercise_renderer(argument):
|
|||||||
|
|
||||||
def youtube_video_renderer(video_id):
|
def youtube_video_renderer(video_id):
|
||||||
return f"""
|
return f"""
|
||||||
<iframe width="100%" height="315"
|
<iframe width="100%" height="400"
|
||||||
src="https://www.youtube.com/embed/{video_id}"
|
src="https://www.youtube.com/embed/{video_id}"
|
||||||
title="YouTube video player"
|
title="YouTube video player"
|
||||||
frameborder="0"
|
frameborder="0"
|
||||||
|
style="border-radius: var(--border-radius-lg)"
|
||||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||||
allowfullscreen>
|
allowfullscreen>
|
||||||
</iframe>
|
</iframe>
|
||||||
|
|||||||
@@ -403,6 +403,8 @@ input[type=checkbox] {
|
|||||||
font-size: var(--text-md);
|
font-size: var(--text-md);
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
box-shadow: var(--btn-shadow);
|
box-shadow: var(--btn-shadow);
|
||||||
|
border: none;
|
||||||
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:disabled {
|
.button:disabled {
|
||||||
@@ -412,6 +414,7 @@ input[type=checkbox] {
|
|||||||
.wide-button {
|
.wide-button {
|
||||||
padding: 0.5rem 6rem;
|
padding: 0.5rem 6rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
width: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
@@ -435,10 +438,8 @@ input[type=checkbox] {
|
|||||||
color: var(--gray-700);
|
color: var(--gray-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
.is-default:disabled {
|
||||||
.video-preview {
|
color: var(--gray-500);
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-primary {
|
.is-primary {
|
||||||
@@ -561,7 +562,7 @@ input[type=checkbox] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.course-content-parent .lesson-links {
|
.course-content-parent .lesson-links {
|
||||||
padding: 0 0 0 1rem;
|
padding: 0.5rem 1rem;
|
||||||
margin-bottom: 0.75rem;
|
margin-bottom: 0.75rem;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
line-height: 200%;
|
line-height: 200%;
|
||||||
@@ -669,7 +670,7 @@ input[type=checkbox] {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: var(--text-3-5xl);
|
font-size: var(--text-3-5xl);
|
||||||
letter-spacing: -0.0175em;
|
letter-spacing: -0.0175em;
|
||||||
color: var(--gray-800);
|
color: var(--gray-900);
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,8 +860,7 @@ input[type=checkbox] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lesson-content-card {
|
.lesson-content-card {
|
||||||
padding: 24px;
|
margin-top: 2rem;
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.lesson-content-card .alert-dismissible .close {
|
.lesson-content-card .alert-dismissible .close {
|
||||||
@@ -905,8 +905,15 @@ input[type=checkbox] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.active-lesson {
|
.active-lesson {
|
||||||
background-color: var(--gray-100);
|
background-color: var(--blue-100);
|
||||||
border-radius: var(--border-radius-md);
|
border-radius: var(--border-radius-md);
|
||||||
|
color: var(--blue-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lesson-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lesson-progress {
|
.lesson-progress {
|
||||||
@@ -914,7 +921,7 @@ input[type=checkbox] {
|
|||||||
padding: 4px 8px 4px;
|
padding: 4px 8px 4px;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
line-height: 120%;
|
line-height: 120%;
|
||||||
margin: 0px 10px 20px;
|
margin-left: 1rem;
|
||||||
border-radius: var(--border-radius-md);
|
border-radius: var(--border-radius-md);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,9 +47,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="quiz-footer">
|
<div class="quiz-footer">
|
||||||
<span class="font-weight-bold"> <span class="current-question">1</span> of {{ quiz.questions | length }}</span>
|
<span class="font-weight-bold"> <span class="current-question">1</span> of {{ quiz.questions | length }}</span>
|
||||||
<button class="button pull-right" id="check" disabled>Check</button>
|
<button class="button pull-right is-default" id="check" disabled>Check</button>
|
||||||
<button class="button hide" id="next">Next Question</button>
|
<div class="button is-secondary hide" id="next">Next Question</div>
|
||||||
<button class="button is-default hide" id="summary">Summary</button>
|
<div class="button is-secondary is-default hide" id="summary">Summary</div>
|
||||||
<small id="submission-message" class="font-weight-bold hide"> Please join the course to submit the Quiz.</small>
|
<small id="submission-message" class="font-weight-bold hide"> Please join the course to submit the Quiz.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="button is-secondary pull-right hide" id="try-again">Try Again</div>
|
<div class="button is-secondary pull-right hide" id="try-again">Try Again</div>
|
||||||
|
|||||||
@@ -33,34 +33,60 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% macro LessonContent(lesson) %}
|
{% macro LessonContent(lesson) %}
|
||||||
{% set is_instructor = frappe.session.user == course.instructor %}
|
{% set instructors = get_instructors(course.name) %}
|
||||||
|
{% set is_instructor = is_instructor(course.name) %}
|
||||||
<div class="lesson-content">
|
<div class="lesson-content">
|
||||||
<div class="course-home-headings title
|
<div class="lesson-title">
|
||||||
{% if membership %} is-member {% endif %}
|
<div class="course-home-headings title mb-0
|
||||||
{% if membership or is_instructor %} eligible-for-submission {% endif %}" data-lesson="{{ lesson.name }}"
|
{% if membership %} is-member {% endif %}
|
||||||
data-course="{{ course.name }}">
|
{% if membership or is_instructor %} eligible-for-submission {% endif %}" data-lesson="{{ lesson.name }}"
|
||||||
{{ lesson.title }}
|
data-course="{{ course.name }}">{{ lesson.title }}</div>
|
||||||
<span class="lesson-progress {{hide if get_progress(course.name, lesson.name) != 'Complete' else ''}}">COMPLETED</span>
|
<span class="lesson-progress {{hide if get_progress(course.name, lesson.name) != 'Complete' else ''}}">COMPLETED</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
{% set instructors = instructors %}
|
||||||
|
{% set ins_len = instructors | length %}
|
||||||
|
{% for instructor in instructors %}
|
||||||
|
{% if ins_len > 1 and loop.index == 1 %}
|
||||||
|
<div class="avatar-group overlap">
|
||||||
|
{% endif %}
|
||||||
|
{{ widgets.Avatar(member=instructor, avatar_class="avatar-small") }}
|
||||||
|
|
||||||
|
{% if ins_len > 1 and loop.index == ins_len %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<a class="button-links ml-2" href="{{ get_profile_url(instructors[0].username) }}">
|
||||||
|
<span class="course-creator-name">
|
||||||
|
{% if ins_len == 1 %}
|
||||||
|
{{ instructors[0].full_name }}
|
||||||
|
{% else %}
|
||||||
|
{% set suffix = "other" if ins_len - 1 == 1 else "others" %}
|
||||||
|
{{ instructors[0].full_name.split(" ")[0] }} and {{ ins_len - 1 }} {{ suffix }}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<div class="ml-3 course-meta"> {{ frappe.utils.format_date(lesson.creation, "medium") }} </div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="markdown-source lesson-content-card">
|
||||||
{% if membership or lesson.include_in_preview or is_instructor %}
|
{% if membership or lesson.include_in_preview or is_instructor %}
|
||||||
<div class="common-card-style lesson-content-card markdown-source">
|
{% if is_instructor and not lesson.include_in_preview %}
|
||||||
{% if is_instructor and not lesson.include_in_preview %}
|
<div class="small alert alert-secondary alert-dismissible mt-4 mb-4">
|
||||||
<small class="alert alert-secondary alert-dismissible">
|
|
||||||
This lesson is not available for preview. As you are the Instructor of the course only you can see it.
|
This lesson is not available for preview. As you are the Instructor of the course only you can see it.
|
||||||
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
|
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
|
||||||
</small>
|
|
||||||
{% endif %}
|
|
||||||
{{ render_html(lesson.body) }}</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="common-card-style lesson-content-card">
|
|
||||||
<div class="w-25 text-center" style="margin: 0 auto;">
|
|
||||||
<small>This lesson is not available for preview. Please join the course to access it.</small>
|
|
||||||
<a class="button is-primary ml-auto mr-auto mt-3" href="/courses/{{ course.name }}"> Start Learning </a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{{ render_html(lesson.body) }}
|
||||||
|
{% else %}
|
||||||
|
<div class="">
|
||||||
|
<a class="button is-primary pull-right" href="/courses/{{ course.name }}"> Start Learning </a>
|
||||||
|
<div class="">This lesson is not available for preview. Please join the course to access it.</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ frappe.ready(() => {
|
|||||||
view_all_mentors(e);
|
view_all_mentors(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".video-preview").click((e) => {
|
|
||||||
show_video_dialog(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".review-link").click((e) => {
|
$(".review-link").click((e) => {
|
||||||
show_review_dialog(e);
|
show_review_dialog(e);
|
||||||
});
|
});
|
||||||
@@ -158,11 +154,6 @@ var view_all_mentors = (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var show_video_dialog = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
$("#video-modal").modal("show");
|
|
||||||
}
|
|
||||||
|
|
||||||
var show_review_dialog = (e) => {
|
var show_review_dialog = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$("#review-modal").modal("show");
|
$("#review-modal").modal("show");
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from school.lms.utils import slugify, get_membership, get_lessons, get_batch
|
from school.lms.utils import slugify, get_membership, get_lessons, get_batch, get_lesson_url
|
||||||
|
|
||||||
def get_common_context(context):
|
def get_common_context(context):
|
||||||
context.no_cache = 1
|
context.no_cache = 1
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user