feat: generate certificate from course page

This commit is contained in:
Jannat Patel
2024-07-12 15:56:50 +05:30
parent 6e1d62340f
commit 23b2e8d682
11 changed files with 146 additions and 228 deletions

View File

@@ -63,7 +63,13 @@
{{ __('Start Learning') }}
</span>
</Button>
<Button v-if="canGetCertificate">
<Button
v-if="canGetCertificate"
@click="fetchCertificate()"
variant="subtle"
class="w-full mt-2"
size="md"
>
{{ __('Get Certificate') }}
</Button>
<router-link
@@ -139,7 +145,7 @@ function enrollStudent() {
})
setTimeout(() => {
window.location.href = `/login?redirect-to=${window.location.pathname}`
}, 3000)
}, 2000)
} else {
const enrollStudentResource = createResource({
url: 'lms.lms.doctype.lms_enrollment.lms_enrollment.create_membership',
@@ -179,6 +185,37 @@ const is_instructor = () => {
}
const canGetCertificate = computed(() => {
console.log(props.course)
if (
props.course.data?.enable_certification &&
props.course.data?.membership?.progress == 100
) {
return true
}
return false
})
const certificate = createResource({
url: 'lms.lms.doctype.lms_certificate.lms_certificate.create_certificate',
makeParams(values) {
return {
course: values.course,
}
},
onSuccess(data) {
console.log(data)
window.open(
`/api/method/frappe.utils.print_format.download_pdf?doctype=LMS+Certificate&name=${
data.name
}&format=${encodeURIComponent(data.template)}`,
'_blank'
)
},
})
const fetchCertificate = () => {
certificate.submit({
course: props.course.data?.name,
member: user.data?.name,
})
}
</script>

View File

@@ -1,10 +1,14 @@
<template>
<div ref="videoContainer" class="video-block group relative">
<video @timeupdate="updateTime" @ended="videoEnded" class="rounded-lg">
<video
@timeupdate="updateTime"
@ended="videoEnded"
class="rounded-lg border border-gray-100"
>
<source :src="fileURL" :type="type" />
</video>
<div
class="flex items-center space-x-2 bg-gray-200 rounded-lg p-0.5 absolute bottom-3 w-[98%] left-0 right-0 mx-auto"
class="flex items-center space-x-2 bg-gray-200 rounded-md p-0.5 absolute bottom-3 w-[98%] left-0 right-0 mx-auto"
>
<Button variant="ghost">
<template #icon>

View File

@@ -171,7 +171,7 @@
{{ lesson.data.course_title }}
</div>
<div v-if="user && lesson.data.membership" class="text-sm mt-3">
{{ Math.ceil(lessonProgress) }}% completed
{{ Math.ceil(lessonProgress) }}% {{ __('completed') }}
</div>
<ProgressBar
@@ -190,7 +190,7 @@
</template>
<script setup>
import { createResource, Breadcrumbs, Button } from 'frappe-ui'
import { computed, watch, inject, ref } from 'vue'
import { computed, watch, inject, ref, onMounted, onBeforeUnmount } from 'vue'
import CourseOutline from '@/components/CourseOutline.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import { useRoute } from 'vue-router'
@@ -208,6 +208,8 @@ const allowDiscussions = ref(false)
const editor = ref(null)
const instructorEditor = ref(null)
const lessonProgress = ref(0)
const timer = ref(0)
let timerInterval
const props = defineProps({
courseName: {
@@ -224,6 +226,10 @@ const props = defineProps({
},
})
onMounted(() => {
startTimer()
})
const lesson = createResource({
url: 'lms.lms.utils.get_lesson',
cache: ['lesson', props.courseName, props.chapterNumber, props.lessonNumber],
@@ -237,7 +243,6 @@ const lesson = createResource({
auto: true,
onSuccess(data) {
lessonProgress.value = data.membership?.progress
markProgress(data)
if (data.content) editor.value = renderEditor('editor', data.content)
if (data.instructor_content?.blocks?.length)
instructorEditor.value = renderEditor(
@@ -269,11 +274,9 @@ const renderEditor = (holder, content) => {
})
}
const markProgress = (data) => {
if (user.data && !data.progress) {
setTimeout(() => {
progress.submit()
}, 30000)
const markProgress = () => {
if (user.data && !lesson.data?.progress) {
progress.submit()
}
}
@@ -325,10 +328,32 @@ watch(
chapter: newChapterNumber,
lesson: newLessonNumber,
})
clearInterval(timerInterval)
timer.value = 0
startTimer()
}
}
)
const startTimer = () => {
console.log('starting timer')
timerInterval = setInterval(() => {
timer.value++
console.log(timer.value)
if (timer.value == 30) {
console.log('30 seconds passed')
console.log(lesson.data?.title)
clearInterval(timerInterval)
markProgress()
}
}, 1000)
}
onBeforeUnmount(() => {
console.log('clearing interval')
clearInterval(timerInterval)
})
const checkIfDiscussionsAllowed = () => {
let quizPresent = false
JSON.parse(lesson.data?.content)?.blocks?.forEach((block) => {