Merge pull request #301 from pateljannat/course-list-page

This commit is contained in:
Jannat Patel
2022-02-17 15:04:48 +05:30
committed by GitHub
9 changed files with 77 additions and 30 deletions

View File

@@ -23,13 +23,13 @@ class LMSCertification(Document):
@frappe.whitelist()
def create_certificate(course):
certificate = is_certified()
certificate = is_certified(course)
if certificate:
return certificate
else:
expires_after_yrs = int(course_details.expiry)
expires_after_yrs = int(frappe.db.get_value("LMS Course", course, "expiry"))
expiry_date = None
if expires_after_yrs:
expiry_date = add_years(nowdate(), expires_after_yrs)
@@ -42,4 +42,4 @@ def create_certificate(course):
"expiry_date": expiry_date
})
certificate.save(ignore_permissions=True)
return certificate.name
return certificate

View File

@@ -1,8 +1,22 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import frappe
import unittest
from school.lms.doctype.lms_course.test_lms_course import new_course
from school.lms.doctype.lms_certification.lms_certification import create_certificate
from frappe.utils import nowdate, add_years, cint
class TestLMSCertification(unittest.TestCase):
pass
def test_certificate_creation(self):
course = new_course("Test Certificate", 1, 2)
certificate = create_certificate(course.name)
self.assertEqual(certificate.student, "Administrator")
self.assertEqual(certificate.course, course.name)
self.assertEqual(certificate.issue_date, nowdate())
self.assertEqual(certificate.expiry_date, add_years(nowdate(), cint(course.expiry)))
frappe.db.delete("LMS Certification", certificate.name)
frappe.db.delete("LMS Course", course.name)

View File

@@ -12,18 +12,10 @@ class TestLMSCourse(unittest.TestCase):
frappe.db.sql('delete from `tabLMS Course Mentor Mapping`')
frappe.db.sql('delete from `tabLMS Course`')
def new_course(self, title):
doc = frappe.get_doc({
"doctype": "LMS Course",
"title": title,
"short_introduction": title,
"description": title
})
doc.insert(ignore_permissions=True)
return doc
def test_new_course(self):
course = self.new_course("Test Course")
course = new_course("Test Course")
assert course.title == "Test Course"
assert course.name == "test-course"
@@ -32,7 +24,7 @@ class TestLMSCourse(unittest.TestCase):
assert courses == []
# new couse, but not published
course = self.new_course("Test Course")
course = new_course("Test Course")
assert courses == []
# publish the course
@@ -45,7 +37,7 @@ class TestLMSCourse(unittest.TestCase):
# disabled this test as it is failing
def _test_add_mentors(self):
course = self.new_course("Test Course")
course = new_course("Test Course")
assert course.get_mentors() == []
user = new_user("Tester", "tester@example.com")
@@ -66,3 +58,15 @@ def new_user(name, email):
first_name=name))
doc.insert()
return doc
def new_course(title, certificate=0, expiry=0):
doc = frappe.get_doc({
"doctype": "LMS Course",
"title": title,
"short_introduction": title,
"description": title,
"enable_certificate": certificate,
"expiry": expiry
})
doc.insert(ignore_permissions=True)
return doc

View File

@@ -92,8 +92,7 @@ input[type=checkbox] {
background: #FFFFFF;
border-radius: var(--border-radius-md);
position: relative;
border: 1px solid #EEF0F2;
box-shadow: var(--shadow-base);
box-shadow: var(--shadow-sm);
}
.course-card {
@@ -400,7 +399,6 @@ input[type=checkbox] {
display: flex;
align-items: center;
justify-content: center;
width: fit-content;
padding: 0.25rem 1.25rem;
font-size: var(--text-md);
line-height: 20px;
@@ -424,6 +422,7 @@ input[type=checkbox] {
.is-secondary {
background: #FFFFFF;
color: inherit;
}
.is-secondary:hover {
@@ -1274,17 +1273,17 @@ pre {
}
.search {
background-image: url(/assets/frappe/icons/timeless/search.svg);
border: 1px solid #C8CFD5;
box-sizing: border-box;
border-radius: var(--border-radius);
font-size: 0.75rem;
border: none;
border-radius: var(--border-radius-md);
font-size: var(--text-sm);
padding: 0.625rem 0.75rem;
height: 36px;
background-repeat: no-repeat;
text-indent: 1.5rem;
background-position: 1rem 0.65rem;
background-position: 1rem 0.6rem;
float: right;
width: 25%;
background-color: var(--gray-100);
}
.section-heading {

View File

@@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 7.44462C3.5 5.26607 5.26607 3.5 7.44462 3.5C9.62318 3.5 11.3892 5.26607 11.3892 7.44462C11.3892 8.50829 10.9683 9.47362 10.2838 10.1831C10.265 10.1972 10.247 10.2128 10.2299 10.2299C10.2128 10.247 10.1972 10.265 10.1831 10.2838C9.47362 10.9683 8.50829 11.3892 7.44462 11.3892C5.26607 11.3892 3.5 9.62318 3.5 7.44462ZM10.5696 11.2767C9.71788 11.9722 8.62996 12.3892 7.44462 12.3892C4.71378 12.3892 2.5 10.1755 2.5 7.44462C2.5 4.71378 4.71378 2.5 7.44462 2.5C10.1755 2.5 12.3892 4.71378 12.3892 7.44462C12.3892 8.62996 11.9722 9.71788 11.2767 10.5696L13.3538 12.6467C13.549 12.8419 13.549 13.1585 13.3538 13.3538C13.1585 13.549 12.8419 13.549 12.6467 13.3538L10.5696 11.2767Z" fill="#4C5A67"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 7.44462C3.5 5.26607 5.26607 3.5 7.44462 3.5C9.62318 3.5 11.3892 5.26607 11.3892 7.44462C11.3892 8.50829 10.9683 9.47362 10.2838 10.1831C10.265 10.1972 10.247 10.2128 10.2299 10.2299C10.2128 10.247 10.1972 10.265 10.1831 10.2838C9.47362 10.9683 8.50829 11.3892 7.44462 11.3892C5.26607 11.3892 3.5 9.62318 3.5 7.44462ZM10.5696 11.2767C9.71788 11.9722 8.62996 12.3892 7.44462 12.3892C4.71378 12.3892 2.5 10.1755 2.5 7.44462C2.5 4.71378 4.71378 2.5 7.44462 2.5C10.1755 2.5 12.3892 4.71378 12.3892 7.44462C12.3892 8.62996 11.9722 9.71788 11.2767 10.5696L13.3538 12.6467C13.549 12.8419 13.549 13.1585 13.3538 13.3538C13.1585 13.549 12.8419 13.549 12.6467 13.3538L10.5696 11.2767Z" fill="#687178"/>
</svg>

Before

Width:  |  Height:  |  Size: 849 B

After

Width:  |  Height:  |  Size: 849 B

View File

@@ -246,7 +246,7 @@ const create_certificate = (e) => {
"course": course
},
callback: (data) => {
window.location.href = `/courses/${course}/${data.message}`;
window.location.href = `/courses/${course}/${data.message.name}`;
}
})
};

View File

@@ -176,6 +176,18 @@
</a>
{% endif %}
{% set certificate = is_certified(course.name) %}
{% set progress = frappe.utils.cint(membership.progress) %}
{% if certificate %}
<a class="button wide-button is-secondary mt-2" href="/courses/{{ course.name }}/{{ certificate }}">
{{ _("Get Certificate") }}
</a>
{% elif course.enable_certification and progress == 100 %}
<div class="button wide-button is-secondary mt-4" id="certification" data-course="{{ course.name }}">
{{ _("Get Certificate") }}
</div>
{% endif %}
<div class="overlay-heading"> {{ _("Course Include:") }} </div>
{% if get_lessons(course.name) | length %}
<div class="mt-3">

View File

@@ -41,6 +41,10 @@ frappe.ready(() => {
notify_user(e);
})
$("#certification").click((e) => {
create_certificate(e);
});
})
var check_mentor_request = () => {
@@ -196,7 +200,7 @@ var submit_review = (e) => {
}
}
})
}
};
var notify_user = (e) => {
e.preventDefault();
@@ -216,4 +220,18 @@ var notify_user = (e) => {
$("#notify-me").addClass("hide");
}
})
}
};
const create_certificate = (e) => {
e.preventDefault();
course = $(e.currentTarget).attr("data-course");
frappe.call({
method: "school.lms.doctype.lms_certification.lms_certification.create_certificate",
args: {
"course": course
},
callback: (data) => {
window.location.href = `/courses/${course}/${data.message.name}`;
}
})
};

View File

@@ -13,7 +13,7 @@ def get_context(context):
course = frappe.db.get_value("LMS Course", course_name,
["name", "title", "image", "short_introduction", "description", "is_published", "upcoming",
"disable_self_learning", "video_link"],
"disable_self_learning", "video_link", "enable_certification"],
as_dict=True)
related_courses = frappe.get_all("Related Courses", {"parent": course.name}, ["course"])