Compare commits
2 Commits
web-form-c
...
certificat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff1363b437 | ||
|
|
952e3a9906 |
@@ -134,7 +134,7 @@ fixtures = ["Custom Field"]
|
||||
website_route_rules = [
|
||||
{"from_route": "/sketches/<sketch>", "to_route": "sketches/sketch"},
|
||||
{"from_route": "/courses/<course>", "to_route": "courses/course"},
|
||||
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"},
|
||||
{"from_route": "/courses/<course>/<certificate>", "to_route": "courses/certificate"},
|
||||
{"from_route": "/hackathons/<hackathon>", "to_route": "hackathons/hackathon"},
|
||||
{"from_route": "/hackathons/<hackathon>/<project>", "to_route": "hackathons/project"},
|
||||
{"from_route": "/add-a-new-batch", "to_route": "add-a-new-batch"},
|
||||
@@ -175,4 +175,5 @@ community_markdown_macro_renderers = {
|
||||
"Exercise": "community.plugins.exercise_renderer",
|
||||
"Quiz": "community.plugins.quiz_renderer",
|
||||
"YouTubeVideo": "community.plugins.youtube_video_renderer",
|
||||
"Video": "community.plugins.video_renderer"
|
||||
}
|
||||
|
||||
@@ -17,6 +17,15 @@ frappe.ui.form.on('Lesson', {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4">
|
||||
Video
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
{{ Video("url_of_source") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4">
|
||||
YouTube Video
|
||||
|
||||
@@ -29,13 +29,17 @@ def create_certificate(course):
|
||||
return certificate
|
||||
|
||||
else:
|
||||
expires_after_yrs = course_details.expiry
|
||||
expires_after_yrs = int(course_details.expiry)
|
||||
expiry_date = None
|
||||
if expires_after_yrs:
|
||||
expiry_date = add_years(nowdate(), expires_after_yrs)
|
||||
|
||||
certificate = frappe.get_doc({
|
||||
"doctype": "LMS Certification",
|
||||
"student": frappe.session.user,
|
||||
"course": course,
|
||||
"issue_date": nowdate(),
|
||||
"expiry_date": add_years(nowdate(), int(expires_after_yrs))
|
||||
"expiry_date": expiry_date
|
||||
})
|
||||
certificate.save(ignore_permissions=True)
|
||||
return certificate.name
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
"section_break_5",
|
||||
"short_introduction",
|
||||
"description",
|
||||
"chapters"
|
||||
"chapters",
|
||||
"certification_section",
|
||||
"enable_certification",
|
||||
"expiry"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -119,6 +122,25 @@
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "certification_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Certification"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "enable_certification",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Certification"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "enable_certification",
|
||||
"fieldname": "expiry",
|
||||
"fieldtype": "Select",
|
||||
"label": "Certification Expires After Years",
|
||||
"options": "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
@@ -140,7 +162,7 @@
|
||||
"link_fieldname": "course"
|
||||
}
|
||||
],
|
||||
"modified": "2021-08-20 11:01:15.795219",
|
||||
"modified": "2021-08-25 11:04:57.211898",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Course",
|
||||
|
||||
@@ -20,6 +20,7 @@ import markdown
|
||||
from markdown import Extension
|
||||
from markdown.inlinepatterns import InlineProcessor
|
||||
import xml.etree.ElementTree as etree
|
||||
import html as HTML
|
||||
|
||||
def markdown_to_html(text):
|
||||
"""Renders markdown text into html.
|
||||
@@ -109,4 +110,5 @@ def sanitize_html(html, macro):
|
||||
classname = ""
|
||||
if macro == "YouTubeVideo":
|
||||
classname = "lesson-video"
|
||||
|
||||
return "<div class='" + classname + "'>" + "\n".join(str(node) for node in nodes) + "</div>"
|
||||
|
||||
@@ -106,3 +106,6 @@ def youtube_video_renderer(video_id):
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
"""
|
||||
|
||||
def video_renderer(src):
|
||||
return "<video controls width='100%'><source src={0} type='video/mp4'></video>".format(src)
|
||||
|
||||
@@ -1414,17 +1414,24 @@ textarea.form-control {
|
||||
}
|
||||
|
||||
.certificate-page .common-card-style {
|
||||
flex-direction: column;
|
||||
font-family: Inter;
|
||||
color: black;
|
||||
font-size: 2rem;
|
||||
text-align: center;
|
||||
width: 40%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.certificate-content {
|
||||
padding: 5rem;
|
||||
background-image: url(/assets/community/images/certificate-background.png);
|
||||
}
|
||||
|
||||
.certificate-ribbon {
|
||||
background-color: var(--primary-color);
|
||||
margin-right: 2rem;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.certificate-heading {
|
||||
font-size: 4rem;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 3rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -1433,18 +1440,47 @@ textarea.form-control {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.certificate-logo {
|
||||
height: 20px;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.certificate-content {
|
||||
padding: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.certificate-page .common-card-style {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.certificate-content {
|
||||
padding: 2rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.certificate-heading {
|
||||
font-size: 3rem;
|
||||
}
|
||||
.certificate-ribbon {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.certificate-heading {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 550px) {
|
||||
.certificate-page .common-card-style {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.certificate-page .common-card-style {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.certificate-heading {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<div class="common-card-style">
|
||||
<div class="certificate-content">
|
||||
<div class="certificate-heading">
|
||||
Certificate of Completion
|
||||
</div>
|
||||
@@ -7,26 +8,28 @@
|
||||
<span class="font-weight-bold">{{ course.title }}</span> online course on
|
||||
<span class="font-weight-bold">{{ frappe.utils.format_date(certificate.issue_date, "medium") }}</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between;" class="certificate-footer">
|
||||
<div class="certificate-footer">
|
||||
<div>
|
||||
<div class="font-weight-bold">
|
||||
<span>
|
||||
Instructor:
|
||||
</div>
|
||||
<div>
|
||||
</span>
|
||||
<span class="font-weight-bold">
|
||||
{{ instructor.full_name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% if certificate.expiry_date %}
|
||||
<div>
|
||||
<div class="font-weight-bold">
|
||||
<span>
|
||||
Expiry Date:
|
||||
</div>
|
||||
<div>
|
||||
</span>
|
||||
<span class="font-weight-bold">
|
||||
{{ frappe.utils.format_date(certificate.expiry_date, "medium") }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<img src="{{ logo }}" class="certificate-logo">
|
||||
</div>
|
||||
<div>
|
||||
<img src="{{ logo }}" style="height: 50px;">
|
||||
</div>
|
||||
<div class="certificate-ribbon"></div>
|
||||
</div>
|
||||
<script src="/assets/community/js/html2canvas.js"></script>
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
<div class="custom-checkbox">
|
||||
<label class="quiz-label">
|
||||
<input class="option" value="{{ option | urlencode }}"
|
||||
data-correct="{{ question['is_correct_' + loop.index | string] }}"
|
||||
{% if question.multiple %} type="checkbox"
|
||||
{% else %} type="radio" name="{{ question.question | urlencode }}" {% endif %}>
|
||||
data-correct="{{ question['is_correct_' + loop.index | string] }}" {% if question.multiple %}
|
||||
type="checkbox" {% else %} type="radio" name="{{ question.question | urlencode }}" {% endif %}>
|
||||
<img class="empty-checkbox mr-3" />
|
||||
</label>
|
||||
<span class="label-area">{{ frappe.utils.md_to_html(option) }}</span>
|
||||
@@ -51,6 +50,7 @@
|
||||
<button class="btn btn-primary pull-right" id="check" disabled>Check</button>
|
||||
<button class="btn btn-primary hide" id="next">Next</button>
|
||||
<button class="btn btn-primary hide" id="summary">Summary</button>
|
||||
<small id="submission-message" class="font-weight-bold hide"> Please join the course to submit the Quiz.</small>
|
||||
</div>
|
||||
<div class="button is-secondary pull-right hide" id="try-again">Try Again</div>
|
||||
<h4 class="success-message"></h4>
|
||||
|
||||
@@ -40,14 +40,16 @@
|
||||
{% endblock %}
|
||||
|
||||
{% macro LessonContent(lesson) %}
|
||||
{% set is_instructor = frappe.session.user == course.instructor %}
|
||||
<div class="lesson-content">
|
||||
<div class="course-home-headings title {% if membership %} is-member {% endif %}" data-lesson="{{ lesson.name }}"
|
||||
<div class="course-home-headings title
|
||||
{% if membership %} is-member {% endif %}
|
||||
{% if membership or is_instructor %} eligible-for-submission {% endif %}" data-lesson="{{ lesson.name }}"
|
||||
data-course="{{ course.name }}">
|
||||
{{ lesson.title }}
|
||||
<span class="lesson-progress {{hide if course.get_progress(lesson.name) != 'Complete' else ''}}">COMPLETED</span>
|
||||
</div>
|
||||
|
||||
{% set is_instructor = frappe.session.user == course.instructor %}
|
||||
|
||||
{% if membership or lesson.include_in_preview or is_instructor %}
|
||||
<div class="common-card-style lesson-content-card markdown-source">{{ lesson.render_html() }}</div>
|
||||
|
||||
@@ -133,7 +133,18 @@ var check_answer = (e) => {
|
||||
|
||||
$(".explanation").removeClass("hide");
|
||||
$("#check").addClass("hide");
|
||||
current_index == total_questions ? $("#summary").removeClass("hide") : $("#next").removeClass("hide");
|
||||
|
||||
if (current_index == total_questions) {
|
||||
if ($(".eligible-for-submission").length) {
|
||||
$("#summary").removeClass("hide")
|
||||
}
|
||||
else {
|
||||
$("#submission-message").removeClass("hide");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$("#next").removeClass("hide")
|
||||
}
|
||||
|
||||
var [answer, is_correct] = parse_options();
|
||||
add_to_local_storage(quiz_name, current_index, answer, is_correct)
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
frappe.ready(() => {
|
||||
|
||||
if ($(document).width() <= 550) {
|
||||
$(".certificate-footer").css("flex-direction", "column");
|
||||
$(".certificate-footer").children().addClass("mb-5");
|
||||
}
|
||||
|
||||
$("#export-as-pdf").click((e) => {
|
||||
export_as_pdf(e);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
var export_as_pdf = (e) => {
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
{% endmacro %}
|
||||
|
||||
{% macro AboutOverviewSection(member) %}
|
||||
{% set enrollment = member.get_course_membership("Student") | length %}
|
||||
{% set mentorship = member.get_course_membership("Mentor") | length %}
|
||||
{% set reviews = member.get_user_reviews() | length %}
|
||||
<div class="profile-parent-section">
|
||||
{% if member.bio %}
|
||||
<div class="profile-about-section">
|
||||
@@ -70,31 +73,35 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if enrollment or reviews or mentorship %}
|
||||
<div class="course-overview-section">
|
||||
<div class="course-home-headings">
|
||||
Overview
|
||||
</div>
|
||||
<div class="common-card-style overview-card small-title">
|
||||
{% if member.get_course_membership("Student") | length %}
|
||||
{% if enrollment %}
|
||||
<div class="overtime-item">
|
||||
<img class="icon-background mr-1" src="/assets/community/icons/user.svg" />
|
||||
{{ member.get_course_membership("Student") | length }} Enrolled
|
||||
{{ enrollment }} Enrolled
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if member.get_user_reviews() | length %}
|
||||
{% if reviews %}
|
||||
<div class="overtime-item">
|
||||
<img class="icon-background mr-1" src="/assets/community/icons/rating.svg" />
|
||||
{{ member.get_user_reviews() | length }} Created
|
||||
{{ reviews }} Created
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if member.get_course_membership("Mentor") | length%}
|
||||
{% if mentorship %}
|
||||
<div class="overtime-item">
|
||||
<img class="icon-background mr-1" src="/assets/community/icons/calendar.svg" />
|
||||
{{ member.get_course_membership("Mentor") | length }} Mentored
|
||||
{{ mentorship }} Mentored
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user