feat: eval and certification flow with purchased certificate
This commit is contained in:
@@ -1,2 +1,116 @@
|
||||
<template>Course Certificate</template>
|
||||
<script setup></script>
|
||||
<template>
|
||||
<header
|
||||
class="sticky top-0 z-10 flex items-center justify-between border-b bg-surface-white px-3 py-2.5 sm:px-5"
|
||||
>
|
||||
<Breadcrumbs class="h-7" :items="breadcrumbs" />
|
||||
</header>
|
||||
<div class="p-5">
|
||||
<div v-if="certificate.data">
|
||||
<div class="text-lg text-ink-gray-9 font-semibold mb-1">
|
||||
{{ __('Certification') }}
|
||||
</div>
|
||||
<div class="text-ink-gray-9 text-sm">
|
||||
{{
|
||||
__(
|
||||
'You are already certified for this course. Click on the card below to open your certificate.'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
<div
|
||||
class="border p-2 w-fit rounded-md space-y-2 hover:bg-surface-gray-1 cursor-pointer mt-5"
|
||||
@click="openCertificate(certificate.data)"
|
||||
>
|
||||
<div class="text-ink-gray-9 font-semibold">
|
||||
{{ courseTitle }}
|
||||
</div>
|
||||
<div class="text-sm text-ink-gray-7 font-medium">
|
||||
{{ __('Issued On') }}:
|
||||
{{ dayjs(certificate.data.issue_date).format('DD MMM YYYY') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<UpcomingEvaluations v-if="courses.length" :courses="courses" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, inject, onMounted, ref } from 'vue'
|
||||
import { Breadcrumbs, call, createResource } from 'frappe-ui'
|
||||
import UpcomingEvaluations from '@/components/UpcomingEvaluations.vue'
|
||||
|
||||
const courseTitle = ref(null)
|
||||
const evaluator = ref(null)
|
||||
const courses = ref([])
|
||||
const user = inject('$user')
|
||||
const dayjs = inject('$dayjs')
|
||||
|
||||
const props = defineProps({
|
||||
courseName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
fetchCourseDetails()
|
||||
})
|
||||
|
||||
const certificate = createResource({
|
||||
url: 'frappe.client.get_value',
|
||||
params: {
|
||||
doctype: 'LMS Certificate',
|
||||
filters: {
|
||||
member: user.data?.name,
|
||||
course: props.courseName,
|
||||
},
|
||||
fieldname: ['name', 'template', 'issue_date'],
|
||||
},
|
||||
auto: true,
|
||||
})
|
||||
|
||||
const fetchCourseDetails = () => {
|
||||
call('frappe.client.get_value', {
|
||||
doctype: 'LMS Course',
|
||||
filters: { name: props.courseName },
|
||||
fieldname: ['title', 'evaluator'],
|
||||
}).then((data) => {
|
||||
courseTitle.value = data.title
|
||||
evaluator.value = data.evaluator
|
||||
populateCourses()
|
||||
})
|
||||
}
|
||||
|
||||
const populateCourses = () => {
|
||||
courses.value = [
|
||||
{
|
||||
course: props.courseName,
|
||||
title: courseTitle.value,
|
||||
evaluator: evaluator.value,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
const openCertificate = (certificate) => {
|
||||
window.open(
|
||||
`/api/method/frappe.utils.print_format.download_pdf?doctype=LMS+Certificate&name=${
|
||||
certificate.name
|
||||
}&format=${encodeURIComponent(certificate.template)}`,
|
||||
'_blank'
|
||||
)
|
||||
}
|
||||
|
||||
const breadcrumbs = computed(() => [
|
||||
{
|
||||
label: __('Courses'),
|
||||
route: { name: 'Courses' },
|
||||
},
|
||||
{
|
||||
label: courseTitle.value,
|
||||
route: { name: 'CourseDetail', params: { courseName: props.courseName } },
|
||||
},
|
||||
{
|
||||
label: __('Certification'),
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
@@ -196,11 +196,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container border-t">
|
||||
<div class="text-lg font-semibold mt-5 mb-4">
|
||||
<div class="container border-t space-y-4">
|
||||
<div class="text-lg font-semibold mt-5">
|
||||
{{ __('Pricing and Certification') }}
|
||||
</div>
|
||||
<div class="grid grid-cols-3 mb-4">
|
||||
<div class="grid grid-cols-3">
|
||||
<FormControl
|
||||
type="checkbox"
|
||||
v-model="course.paid_course"
|
||||
@@ -217,17 +217,19 @@
|
||||
:label="__('Paid Certificate')"
|
||||
/>
|
||||
</div>
|
||||
<FormControl
|
||||
v-model="course.course_price"
|
||||
:label="__('Amount')"
|
||||
class="mb-4"
|
||||
/>
|
||||
<FormControl v-model="course.course_price" :label="__('Amount')" />
|
||||
<Link
|
||||
doctype="Currency"
|
||||
v-model="course.currency"
|
||||
:filters="{ enabled: 1 }"
|
||||
:label="__('Currency')"
|
||||
/>
|
||||
<Link
|
||||
v-if="course.paid_certificate"
|
||||
doctype="Course Evaluator"
|
||||
v-model="course.evaluator"
|
||||
:label="__('Evaluator')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -299,6 +301,7 @@ const course = reactive({
|
||||
disable_self_learning: false,
|
||||
enable_certification: false,
|
||||
paid_course: false,
|
||||
paid_certificate: false,
|
||||
course_price: '',
|
||||
currency: '',
|
||||
})
|
||||
@@ -394,6 +397,7 @@ const courseResource = createResource({
|
||||
'paid_course',
|
||||
'featured',
|
||||
'enable_certification',
|
||||
'paid_certifiate',
|
||||
]
|
||||
for (let idx in checkboxes) {
|
||||
let key = checkboxes[idx]
|
||||
|
||||
@@ -4,45 +4,7 @@
|
||||
class="sticky top-0 z-10 flex items-center justify-between border-b bg-surface-white px-3 py-2.5 sm:px-5"
|
||||
>
|
||||
<Breadcrumbs class="h-7" :items="breadcrumbs" />
|
||||
<div
|
||||
v-if="
|
||||
lesson.data && lesson.data.membership && lesson.data.paid_certificate
|
||||
"
|
||||
>
|
||||
<router-link
|
||||
v-if="!lesson.data.membership.purchased_certificate"
|
||||
:to="{
|
||||
name: 'Billing',
|
||||
params: {
|
||||
type: 'certificate',
|
||||
name: courseName,
|
||||
},
|
||||
}"
|
||||
>
|
||||
<Button>
|
||||
<template #prefix>
|
||||
<GraduationCap class="size-4 stroke-1.5" />
|
||||
</template>
|
||||
{{ __('Get Certified') }}
|
||||
</Button>
|
||||
</router-link>
|
||||
<router-link
|
||||
v-else-if="!lesson.data.membership.certficate"
|
||||
:to="{
|
||||
name: 'CourseCertification',
|
||||
params: {
|
||||
courseName: courseName,
|
||||
},
|
||||
}"
|
||||
>
|
||||
<Button>
|
||||
<template #prefix>
|
||||
<GraduationCap class="size-4 stroke-1.5" />
|
||||
</template>
|
||||
{{ __('Get Certified') }}
|
||||
</Button>
|
||||
</router-link>
|
||||
</div>
|
||||
<CertificationLinks :courseName="courseName" />
|
||||
</header>
|
||||
<div class="grid md:grid-cols-[70%,30%] h-screen">
|
||||
<div
|
||||
@@ -243,6 +205,7 @@ import EditorJS from '@editorjs/editorjs'
|
||||
import LessonContent from '@/components/LessonContent.vue'
|
||||
import CourseInstructors from '@/components/CourseInstructors.vue'
|
||||
import ProgressBar from '@/components/ProgressBar.vue'
|
||||
import CertificationLinks from '@/components/CertificationLinks.vue'
|
||||
|
||||
const user = inject('$user')
|
||||
const router = useRouter()
|
||||
|
||||
Reference in New Issue
Block a user