Merge pull request #781 from pateljannat/certified-users

feat: certified participants
This commit is contained in:
Jannat Patel
2024-04-23 17:58:50 +05:30
committed by GitHub
5 changed files with 106 additions and 2 deletions

View File

@@ -0,0 +1,54 @@
<template>
<header
class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5"
>
<Breadcrumbs :items="breadcrumbs" />
</header>
<div class="grid grid-cols-3 gap-4 m-5">
<div v-for="participant in participants.data">
<router-link
:to="{
name: 'Profile',
params: { username: participant.username },
}"
>
<div class="flex shadow rounded-md h-full p-2">
<UserAvatar :user="participant" size="3xl" class="mr-2" />
<div>
<router-link
:to="{
name: 'Profile',
params: { username: participant.username },
}"
>
<div class="text-lg font-semibold mb-2">
{{ participant.full_name }}
</div>
</router-link>
<div class="font-medium text-gray-700 text-xs mb-1">
{{ __('is certified for') }}
</div>
<div class="leading-5" v-for="course in participant.courses">
{{ course }}
</div>
</div>
</div>
</router-link>
</div>
</div>
</template>
<script setup>
import { Breadcrumbs, createResource } from 'frappe-ui'
import { computed } from 'vue'
import UserAvatar from '@/components/UserAvatar.vue'
const participants = createResource({
url: 'lms.lms.api.get_certified_participants',
auto: true,
cache: ['certified-participants'],
})
const breadcrumbs = computed(() => {
return [{ label: 'Certified Participants', to: '/certified-participants' }]
})
</script>

View File

@@ -125,6 +125,11 @@ const routes = [
component: () => import('@/pages/AssignmentSubmission.vue'),
props: true,
},
{
path: '/certified-participants',
name: 'CertifiedParticipants',
component: () => import('@/pages/CertifiedParticipants.vue'),
},
]
let router = createRouter({

View File

@@ -1,6 +1,12 @@
import { toast } from 'frappe-ui'
import { useTimeAgo } from '@vueuse/core'
import { BookOpen, Users, TrendingUp, Briefcase } from 'lucide-vue-next'
import {
BookOpen,
Users,
TrendingUp,
Briefcase,
GraduationCap,
} from 'lucide-vue-next'
import { Quiz } from '@/utils/quiz'
import { Upload } from '@/utils/upload'
import Header from '@editorjs/header'
@@ -325,6 +331,12 @@ export function getSidebarLinks() {
to: 'Batches',
activeFor: ['Batches', 'BatchDetail', 'Batch'],
},
{
label: 'Certified Participants',
icon: GraduationCap,
to: 'CertifiedParticipants',
activeFor: ['CertifiedParticipants'],
},
{
label: 'Jobs',
icon: Briefcase,

View File

@@ -4,6 +4,8 @@
import frappe
from frappe.translate import get_all_translations
from frappe import _
from frappe.query_builder import DocType
from frappe.query_builder.functions import Count
@frappe.whitelist()
@@ -325,3 +327,34 @@ def get_evaluator_details(evaluator):
"calendar": calendar.name,
"is_authorised": calendar.authorization_code,
}
@frappe.whitelist(allow_guest=True)
def get_certified_participants():
LMSCertificate = DocType("LMS Certificate")
participants = (
frappe.qb.from_(LMSCertificate)
.select("DISTINCT member")
.where(LMSCertificate.published == 1)
.order_by("creation desc")
.run()
)
participant_details = []
for participant in participants:
details = frappe.db.get_value(
"User",
participant.member,
["name", "full_name", "username", "user_image"],
as_dict=True,
)
course_names = frappe.get_all(
"LMS Certificate", {"member": participant.member}, pluck="course"
)
courses = []
for course in course_names:
courses.append(frappe.db.get_value("LMS Course", course, "title"))
details.courses = courses
participant_details.append(details)
return participant_details

View File

@@ -34,7 +34,7 @@ class LMSLiveClass(Document):
def add_event_participants(self, event, calendar):
participants = frappe.get_all(
"Batch Student", {"parent": self.class_name}, pluck="student"
"Batch Student", {"parent": self.batch_name}, pluck="student"
)
participants.append(frappe.session.user)