feat: certificates section in profile

This commit is contained in:
Jannat Patel
2022-09-13 12:47:01 +05:30
parent d959cacd15
commit 7d18215bc9
12 changed files with 158 additions and 115 deletions

View File

@@ -194,7 +194,8 @@ jinja = {
"lms.lms.utils.first_lesson_exists",
"lms.lms.utils.get_courses_under_review",
"lms.lms.utils.has_course_instructor_role",
"lms.lms.utils.has_course_moderator_role"
"lms.lms.utils.has_course_moderator_role",
"lms.lms.utils.get_certificates"
],
"filters": []
}

View File

@@ -455,3 +455,8 @@ def get_courses_under_review():
}, ["name", "upcoming", "title", "image", "enable_certification", "status", "published"]
)
def get_certificates(member=None):
return frappe.get_all("LMS Certificate", {
"member": member or frappe.session.user
}, ["course", "member", "issue_date", "expiry_date", "name"])

View File

@@ -2,28 +2,28 @@
{% if enrolled | length %}
<div class="cards-parent">
{% for course in enrolled %}
{{ widgets.CourseCard(course=course) }}
{% endfor %}
{% for course in enrolled %}
{{ widgets.CourseCard(course=course) }}
{% endfor %}
</div>
{% else %}
{% set site_name = frappe.db.get_single_value("System Settings", "app_name") %}
<div class="empty-state">
<div class="empty-state-text text-left">
<div class="text-center">
<div class="empty-state-heading">{{ _("You haven't enrolled for any courses") }}</div>
<div class="course-meta mb-6">{{ _("Here are a few courses we recommend for you to get started with {0}").format(site_name) }}</div>
{% set site_name = frappe.db.get_single_value("System Settings", "app_name") %}
<div class="empty-state">
<div class="empty-state-text text-left">
<div class="text-center">
<div class="empty-state-heading">{{ _("You haven't enrolled for any courses") }}</div>
<div class="course-meta mb-6">{{ _("Here are a few courses we recommend for you to get started with {0}").format(site_name) }}</div>
</div>
{% set recommended_courses = get_popular_courses() %}
<div class="cards-parent">
{% for course in recommended_courses %}
{% if course %}
{% set course_details = frappe.get_doc("LMS Course", course.course) %}
{{ widgets.CourseCard(course=course_details) }}
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% set recommended_courses = get_popular_courses() %}
<div class="cards-parent">
{% for course in recommended_courses %}
{% if course %}
{% set course_details = frappe.get_doc("LMS Course", course.course) %}
{{ widgets.CourseCard(course=course_details) }}
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endif %}

View File

@@ -894,9 +894,9 @@ pre {
}
}
.profile-card {
flex-direction: column;
padding: 1rem 1.25rem;
.column-card {
flex-direction: column;
padding: 1.25rem;
}
.empty-state {
@@ -1398,19 +1398,19 @@ pre {
overflow: inherit;
}
.dashboard .nav-link {
.lms-nav .nav-link {
color: var(--text-muted);
padding: 0 0 var(--padding-md);
margin-right: var(--margin-xl);
}
.dashboard .nav-link.active {
.lms-nav .nav-link.active {
font-weight: 600;
border-bottom: 1px solid var(--primary);
color: var(--text-color);
}
.dashboard .nav-link:hover {
.lma.nav .nav-link:hover {
color: inherit;
}

View File

@@ -1,18 +1,25 @@
<div id="certificate-card" style="background: #FFFFFF; border-radius: 0.5rem; position: relative;
box-shadow: 0px 1px 2px rgba(25, 39, 52, 0.05), 0px 0px 4px rgba(25, 39, 52, 0.1); padding: 1rem;">
<div style="border: 10px solid var(--primary-color); display: flex; flex-direction: column; align-items: center; padding: 4rem;
justify-content: center; background-color: #FFFFFF;">
<img src="{{ logo }}" style="height: 1.5rem;">
<div style="margin-top: 4rem;">
{{ _("This certifies that") }}
</div>
<div style="font-size: 2rem; font-weight: 500; color: #192734;"> {{ member.full_name }} </div>
<div style="margin-top: 0.5rem;"> {{ _("has successfully completed the course on") }}
<b> {{ course.title }} </b> on {{ frappe.utils.format_date(certificate.issue_date, "medium") }}. </div>
<div style="font-size: 2rem; font-weight: 500; color: #192734;">
{{ member.full_name }}
</div>
<div style="margin-top: 0.5rem;">
{{ _("has successfully completed the course on") }}
<b> {{ course.title }} </b>
on {{ frappe.utils.format_date(certificate.issue_date, "medium") }}.
</div>
<div style="display: flex; justify-content: center; margin: 4rem auto 0; width: fit-content;">
{% if instructors %}
<div>
<div style="color: #192734; font-weight: bold; font-family: cursive; font-size: 1.25rem;">
@@ -25,14 +32,13 @@
{% if certificate.expiry_date %}
<div style="margin-left: 2rem;">
<div style="color: #192734; font-weight: bold; font-family: cursive; font-size: 1.25rem;">
{{ frappe.utils.format_date(certificate.expiry_date, "medium") }}
</div>
<hr style="margin: 0.5rem 0;">
<div> {{ _("Expiry date") }} </div>
<div style="color: #192734; font-weight: bold; font-family: cursive; font-size: 1.25rem;">
{{ frappe.utils.format_date(certificate.expiry_date, "medium") }}
</div>
<hr style="margin: 0.5rem 0;">
<div> {{ _("Expiry date") }} </div>
</div>
{% endif %}
</div>
</div>
</div>

View File

@@ -0,0 +1,30 @@
{% set certificates = get_certificates(user) %}
{% if certificates | length %}
<div class="cards-parent">
{% for certificate in certificates %}
{% set course = frappe.db.get_value("LMS Course", certificate.course, ["title", "name", "image"], as_dict=True) %}
<div class="common-card-style column-card">
<div class="font-weight-bold">
{{ course.title }}
</div>
<div>
{{ _("Issued on") }} : {{ frappe.utils.format_date(certificate.issue_date, "medium") }}
</div>
<a class="stretched-link" href="/courses/{{ course.name }}/{{ certificate.name }}"></a>
</div>
{% endfor %}
</div>
{% else %}
{% set course_list_link = "<a href='/courses'> course list </a>" %}
<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 certificates") }}</div>
<div class="course-meta">{{ _("Check out the {0} to know more about certification.").format(course_list_link) }}</div>
</div>
</div>
{% endif %}

View File

@@ -1,4 +1,4 @@
{% set courses = get_authored_courses(None, only_published=False) %}
{% set courses = get_authored_courses(user or None, only_published=False) %}
{% if courses | length %}
<div class="cards-parent">

View File

@@ -16,9 +16,9 @@
<a class="dark-links" href="/courses/{{ course.name }}">{{ course.title }}</a>
</div>
{% if custom_template %}
{{ custom_template }}
{{ custom_template }}
{% else %}
{% include "lms/templates/certificate.html" %}
{% include "lms/templates/certificate.html" %}
{% endif %}
<script src="/assets/lms/js/html2canvas.js"></script>

View File

@@ -19,8 +19,7 @@ def get_context(context):
context.course = frappe.db.get_value("LMS Course", course_name, ["title", "name", "image"], as_dict=True)
context.instructors = (", ").join([x.full_name for x in get_instructors(course_name)])
context.member = frappe.db.get_value("User", context.certificate.member,
["full_name"], as_dict=True)
context.member = frappe.db.get_value("User", context.certificate.member, ["full_name"], as_dict=True)
context.logo = frappe.db.get_single_value("Website Settings", "banner_image")
template_name = frappe.db.get_single_value("LMS Settings", "custom_certificate_template")

View File

@@ -14,7 +14,7 @@
</a>
{% endif %}
<ul class="nav" id="courses-tab">
<ul class="nav lms-nav" id="courses-tab">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#courses-enrolled">
{{ _("Courses Enrolled") }}

View File

@@ -5,28 +5,72 @@
{% block content %}
{% set read_only = member.name != frappe.session.user %}
{% set user = member.name %}
<div class="common-page-style profile-page">
{{ ProfileBanner(member) }}
<div class="profile-page-body">
<div class="container">
{% set read_only = member.name != frappe.session.user %}
{{ RoleSettings(member) }}
{{ About(member) }}
{{ EducationDetails(member) }}
{{ WorkDetails(member) }}
{{ Certification(member) }}
{{ Contact(member) }}
{{ Skills(member) }}
{{ CareerPreference(member) }}
<ul class="nav lms-nav" id="courses-tab">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#profile">
{{ _("Profile") }}
</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#courses-created">
{{ _("Courses Created") }}
</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#certificates">
{{ _("Certificates") }}
</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#settings">
{{ _("Settings") }}
</a>
</li>
</ul>
<div class="border-bottom mb-4"></div>
<div class="tab-content">
<div class="tab-pane active" id="profile" role="tabpanel" aria-labelledby="profile">
{{ About(member) }}
{{ EducationDetails(member) }}
{{ WorkDetails(member) }}
{{ ExternalCertification(member) }}
{{ Contact(member) }}
{{ Skills(member) }}
{{ CareerPreference(member) }}
{{ ProfileTabs(profile_tabs) }}
</div>
<div class="tab-pane fade" id="courses-created" role="tabpanel" aria-labelledby="courses-created">
{% include "lms/templates/courses_created.html" %}
</div>
<div class="tab-pane fade" id="certificates" role="tabpanel" aria-labelledby="certificates">
{% include "lms/templates/certificates_section.html" %}
</div>
<div class="tab-pane fade" id="settings" role="tabpanel" aria-labelledby="settings">
{{ RoleSettings(member) }}
</div>
</div>
</div>
</div>
<div class="container">
{{ CoursesCreated(member, read_only) }}
{{ CoursesMentored(member, read_only) }}
{{ ProfileTabs(profile_tabs) }}
</div>
</div>
{% endblock %}
@@ -81,23 +125,6 @@
{% endmacro %}
<!-- Courses Created -->
{% macro CoursesCreated(member, read_only) %}
{% set authored_courses = get_authored_courses(member.name) %}
{% if authored_courses | length %}
<div class="profile-courses">
<div class="course-home-headings"> {{ _("Courses Created") }} </div>
<div class="cards-parent">
{% for course in authored_courses %}
{{ widgets.CourseCard(course=course, read_only=read_only) }}
{% endfor %}
</div>
</div>
{% endif %}
{% endmacro %}
<!-- Courses Mentored -->
{% macro CoursesMentored(member, read_only) %}
{% if member.get_mentored_courses() | length %}
@@ -113,34 +140,6 @@
{% endmacro %}
<!-- Courses Enrolled -->
{% macro CoursesEnrolled(member, read_only) %}
{% set enrolled = get_enrolled_courses() %}
{% if enrolled.completed | length %}
<div class="profile-courses">
<div class="course-home-headings"> {{ _("Courses Completed") }} </div>
<div class="cards-parent">
{% for course in enrolled.completed %}
{{ widgets.CourseCard(course=course, read_only=read_only) }}
{% endfor %}
</div>
</div>
{% endif %}
{% if enrolled.in_progress | length %}
<div class="profile-courses">
<div class="course-home-headings"> {{ _("Courses In Progress") }} </div>
<div class="cards-parent">
{% for course in enrolled.in_progress %}
{{ widgets.CourseCard(course=course, read_only=read_only) }}
{% endfor %}
</div>
</div>
{% endif %}
{% endmacro %}
<!-- Profile Tabs Extension -->
{% macro ProfileTabs(profile_tabs) %}
<div>
@@ -160,7 +159,7 @@
{% macro RoleSettings(member) %}
{% if has_course_moderator_role() %}
<div class="">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("Role Settings") }} </div>
<div>
<label class="role">
@@ -184,7 +183,7 @@
{% macro About(member) %}
{% if member.bio %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("About") }} </div>
<div class="description">{{ member.bio }}</div>
</div>
@@ -196,7 +195,7 @@
<!-- Work Preference -->
{% macro WorkPreference(member) %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("Work Preference") }} </div>
<div> {{ member.attire }} </div>
<div> {{ member.collaboration }} </div>
@@ -213,7 +212,7 @@
{% macro CareerPreference(member) %}
{% if member.preferred_functions or member.preferred_industries or member.preferred_location or member.dream_companies %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("Career Preference") }} </div>
<div class="profile-column-grid">
@@ -261,7 +260,7 @@
{% macro Contact(member) %}
{% if member.linkedin or member.medium or member.github %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("Contact") }} </div>
<div class="profile-column-grid">
{% if member.linkedin %}
@@ -294,7 +293,7 @@
{% macro Skills(member) %}
{% if member.skill | length %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("Skills")}} </div>
<div class="profile-column-grid">
{% for skill in member.skill %}
@@ -311,12 +310,12 @@
{% macro EducationDetails(member) %}
{% if member.education %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("Education") }} </div>
<div class="profile-grid-card">
{% for edu in member.education %}
<div class="profile-card-row">
<div class="column-card-row">
<div class="bold-title"> {{ edu.institution_name }} </div>
<div class="profile-item"> {{ edu.degree_type }} <span></span> {{ edu.major }}
{% if not member.hide_private %}
@@ -347,7 +346,7 @@
{% if work_details | length %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("Work Experience") }} </div>
<div class="profile-grid-card">
@@ -379,11 +378,11 @@
<!-- Certifications -->
{% macro Certification(member) %}
{% macro ExternalCertification(member) %}
{% if member.certification %}
<div class="education-details">
<div class="common-card-style profile-card">
<div class="course-home-headings"> {{ _("Certification") }} </div>
<div class="common-card-style column-card">
<div class="course-home-headings"> {{ _("External Certification") }} </div>
<div class="profile-grid-card">
{% for cert in member.certification %}
<div class="">

View File

@@ -1,5 +1,6 @@
import frappe
from lms.page_renderers import get_profile_url_prefix
from frappe.utils.jinja import render_template
def get_context(context):
@@ -20,6 +21,8 @@ def get_context(context):
return
context.profile_tabs = get_profile_tabs(context.member)
template_name = frappe.db.get_single_value("LMS Settings", "custom_certificate_template")
context.custom_certificate_template = frappe.db.get_value("Web Template", template_name, "template")
def get_profile_tabs(user):