feat: certified participants page
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
"course",
|
"course",
|
||||||
"member",
|
"member",
|
||||||
"member_name",
|
"member_name",
|
||||||
|
"published",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"issue_date",
|
"issue_date",
|
||||||
"expiry_date",
|
"expiry_date",
|
||||||
@@ -60,11 +61,17 @@
|
|||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Batch",
|
"label": "Batch",
|
||||||
"options": "LMS Batch"
|
"options": "LMS Batch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "published",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Publish on Participant Page"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-08-29 15:23:08.637215",
|
"modified": "2023-09-13 11:03:23.479255",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Certificate",
|
"name": "LMS Certificate",
|
||||||
|
|||||||
@@ -68,3 +68,4 @@ lms.patches.v1_0.rename_lms_batch_membership_doctype
|
|||||||
lms.patches.v1_0.rename_lms_class_to_lms_batch
|
lms.patches.v1_0.rename_lms_class_to_lms_batch
|
||||||
lms.patches.v1_0.rename_classes_in_navbar
|
lms.patches.v1_0.rename_classes_in_navbar
|
||||||
lms.patches.v1_0.publish_batches
|
lms.patches.v1_0.publish_batches
|
||||||
|
lms.patches.v1_0.publish_certificates
|
||||||
8
lms/patches/v1_0/publish_certificates.py
Normal file
8
lms/patches/v1_0/publish_certificates.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
certificates = frappe.get_all("LMS Certificate", pluck="name")
|
||||||
|
|
||||||
|
for certificate in certificates:
|
||||||
|
frappe.db.set_value("LMS Certificate", certificate, "published", 1)
|
||||||
@@ -174,7 +174,7 @@
|
|||||||
<img class="icon icon-xl" src="/assets/lms/icons/comment.svg">
|
<img class="icon icon-xl" src="/assets/lms/icons/comment.svg">
|
||||||
<div class="empty-state-text">
|
<div class="empty-state-text">
|
||||||
<div class="empty-state-heading">{{ _("No Batches") }}</div>
|
<div class="empty-state-heading">{{ _("No Batches") }}</div>
|
||||||
<div class="course-meta">{{ _("Nothing to see here.") }}</div>
|
<div class="course-meta">{{ _("Please contact the Administrator for more information.") }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|||||||
@@ -7,11 +7,28 @@
|
|||||||
<main class="common-page-style">
|
<main class="common-page-style">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<header>
|
<header>
|
||||||
<div class="page-title">
|
{% if course_filter | length %}
|
||||||
|
<select class="lms-menu pull-right" id="certificate-filter">
|
||||||
|
<option selected value="">
|
||||||
|
{{ _("Filter by Certificate") }}
|
||||||
|
</option>
|
||||||
|
{% for course in course_filter %}
|
||||||
|
<option value="{{ course }}">
|
||||||
|
{{ course }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
{% endif %}
|
||||||
|
<div class="page-title mb-5">
|
||||||
{{ _("Certified Participants") }}
|
{{ _("Certified Participants") }}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
{{ ParticipantsList() }}
|
{% if participants | length %}
|
||||||
|
{{ ParticipantsList() }}
|
||||||
|
{% else %}
|
||||||
|
{{ EmptyState() }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -21,11 +38,11 @@
|
|||||||
{% for participant in participants %}
|
{% for participant in participants %}
|
||||||
<div class="common-card-style column-card align-center">
|
<div class="common-card-style column-card align-center">
|
||||||
{{ widgets.Avatar(member=participant, avatar_class="avatar-large") }}
|
{{ widgets.Avatar(member=participant, avatar_class="avatar-large") }}
|
||||||
<div class="bold-heading">
|
<div class="bold-heading text-center">
|
||||||
{{ participant.full_name }}
|
{{ participant.full_name }}
|
||||||
</div>
|
</div>
|
||||||
{% for course in participant.courses %}
|
{% for course in participant.courses %}
|
||||||
<div>
|
<div class="course-name text-center mb-1" data-course="{{ course }}">
|
||||||
{{ course }}
|
{{ course }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -33,3 +50,13 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</article>
|
</article>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro EmptyState() %}
|
||||||
|
<div class="empty-state">
|
||||||
|
<img class="icon icon-xl" src="/assets/lms/icons/comment.svg">
|
||||||
|
<div class="empty-state-text">
|
||||||
|
<div class="empty-state-heading">{{ _("No Certified Participants") }}</div>
|
||||||
|
<div class="course-meta">{{ _("Enroll in a batch to get certified.") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
18
lms/www/certified_participants/certified_participants.js
Normal file
18
lms/www/certified_participants/certified_participants.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
frappe.ready(() => {
|
||||||
|
$("#certificate-filter").change((e) => {
|
||||||
|
filter_certified_participants();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const filter_certified_participants = () => {
|
||||||
|
const certificate = $("#certificate-filter").val();
|
||||||
|
$(".common-card-style").removeClass("hide");
|
||||||
|
|
||||||
|
if (certificate) {
|
||||||
|
$(".common-card-style").addClass("hide");
|
||||||
|
$(`[data-course='${certificate}']`)
|
||||||
|
.closest(".common-card-style")
|
||||||
|
.removeClass("hide");
|
||||||
|
console.log(certificate);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3,20 +3,40 @@ import frappe
|
|||||||
|
|
||||||
def get_context(context):
|
def get_context(context):
|
||||||
context.no_cache = 1
|
context.no_cache = 1
|
||||||
context.members = frappe.get_all(
|
members = frappe.get_all(
|
||||||
"LMS Certificate", pluck="member", order_by="creation desc", distinct=1
|
"LMS Certificate",
|
||||||
|
filters={"published": 1},
|
||||||
|
pluck="member",
|
||||||
|
order_by="issue_date desc",
|
||||||
|
distinct=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
participants = []
|
participants = []
|
||||||
for member in context.members:
|
course_filter = []
|
||||||
|
for member in members:
|
||||||
details = frappe.db.get_value(
|
details = frappe.db.get_value(
|
||||||
"User", member, ["name", "full_name", "user_image", "username", "enabled"], as_dict=1
|
"User", member, ["name", "full_name", "user_image", "username", "enabled"], as_dict=1
|
||||||
)
|
)
|
||||||
courses = frappe.get_all("LMS Certificate", {"member": member}, pluck="course")
|
courses = frappe.get_all(
|
||||||
|
"LMS Certificate",
|
||||||
|
filters={"member": member, "published": 1},
|
||||||
|
fields=["course", "issue_date"],
|
||||||
|
)
|
||||||
details.courses = []
|
details.courses = []
|
||||||
for course in courses:
|
for course in courses:
|
||||||
details.courses.append(frappe.db.get_value("LMS Course", course, "title"))
|
|
||||||
|
if not details.issue_date:
|
||||||
|
details.issue_date = course.issue_date
|
||||||
|
|
||||||
|
title = frappe.db.get_value("LMS Course", course.course, "title")
|
||||||
|
details.courses.append(title)
|
||||||
|
|
||||||
|
if title not in course_filter:
|
||||||
|
course_filter.append(title)
|
||||||
|
|
||||||
if details.enabled:
|
if details.enabled:
|
||||||
participants.append(details)
|
participants.append(details)
|
||||||
|
|
||||||
|
participants = sorted(participants, key=lambda d: d.issue_date, reverse=True)
|
||||||
context.participants = participants
|
context.participants = participants
|
||||||
|
context.course_filter = course_filter
|
||||||
|
|||||||
Reference in New Issue
Block a user