Skip to content

Commit

Permalink
feat: generate bulk certificates for batch students
Browse files Browse the repository at this point in the history
  • Loading branch information
pateljannat committed Dec 4, 2024
1 parent 0b7ff1d commit 6c3bb34
Show file tree
Hide file tree
Showing 7 changed files with 742 additions and 5,291 deletions.
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
"codemirror-editor-vue3": "^2.8.0",
"dayjs": "^1.11.6",
"feather-icons": "^4.28.0",
"frappe-ui": "^0.1.72",
"frappe-ui": "^0.1.89",
"lucide-vue-next": "^0.383.0",
"markdown-it": "^14.0.0",
"pinia": "^2.0.33",
"socket.io-client": "^4.7.2",
"tailwindcss": "^3.3.3",
"typescript": "^5.7.2",
"vue": "^3.4.23",
"vue-chartjs": "^5.3.0",
"vue-draggable-next": "^2.2.1",
Expand Down
132 changes: 132 additions & 0 deletions frontend/src/components/Modals/BulkCertificates.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<template>
<Dialog
v-model="show"
:options="{
title: __('Generate Certificates'),
size: 'lg',
actions: [
{
label: 'Create',
variant: 'solid',
onClick: ({ close }) => {
generateCertificates(close)
},
},
],
}"
>
<template #body-content>
<div class="space-y-4">
<FormControl
type="select"
v-model="details.course"
:label="__('Course')"
:options="getCourses()"
/>
<Link
v-model="details.evaluator"
:label="__('Evaluator')"
doctype="Course Evaluator"
/>
<FormControl
type="date"
v-model="details.issue_date"
:label="__('Issue Date')"
/>
<FormControl
type="date"
v-model="details.expiry_date"
:label="__('Expiry Date')"
/>
<Link
v-model="details.template"
:label="__('Template')"
doctype="Print Format"
:filters="{
doc_type: 'LMS Certificate',
}"
/>
<Switch
size="sm"
:label="__('Published')"
:description="
__(
'Enabling this will publish the certificate on the certified participants page.'
)
"
v-model="details.published"
/>
</div>
</template>
</Dialog>
</template>
<script setup>
import { inject, reactive } from 'vue'
import { createResource, Dialog, FormControl, Switch } from 'frappe-ui'
import Link from '@/components/Controls/Link.vue'
import { showToast } from '@/utils'
const show = defineModel()
const dayjs = inject('$dayjs')
const details = reactive({
issue_date: dayjs().format('YYYY-MM-DD'),
expiry_date: null,
template: null,
evaluator: null,
published: true,
})
const props = defineProps({
batch: {
type: [Object, null],
required: true,
},
})
const createCertificate = createResource({
url: 'frappe.client.insert',
makeParams(values) {
return {
doc: {
doctype: 'LMS Certificate',
issue_date: details.issue_date,
expiry_date: details.expiry_date,
template: details.template,
published: details.published,
course: values.course,
batch: values.batch,
member: values.member,
evaluator: details.evaluator,
},
}
},
})
const generateCertificates = (close) => {
props.batch?.students.forEach((student) => {
createCertificate.submit(
{
course: details.course,
batch: props.batch.name,
member: student,
},
{
onError(err) {
showToast(__('Error'), err.messages?.[0] || err, 'x')
},
}
)
})
close()
showToast(__('Success'), __('Certificates generated successfully'), 'check')
}
const getCourses = () => {
return props.batch?.courses.map((course) => {
return {
label: course.course,
value: course.course,
}
})
}
</script>
2 changes: 1 addition & 1 deletion frontend/src/components/SettingDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const update = () => {
{},
{
onError(err) {
showToast('Error', err.messages?.[0] || err, 'x')
showToast(__('Error'), err.messages?.[0] || err, 'x')
},
}
)
Expand Down
29 changes: 20 additions & 9 deletions frontend/src/pages/Batch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,29 @@
class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5"
>
<Breadcrumbs class="h-7" :items="breadcrumbs" />
<Button v-if="user.data?.is_moderator" @click="openAnnouncementModal()">
<span>
{{ __('Make an Announcement') }}
</span>
<template #suffix>
<SendIcon class="h-4 stroke-1.5" />
</template>
</Button>
<div class="flex items-center space-x-2">
<Button
v-if="user.data?.is_moderator"
@click="openCertificateDialog = true"
>
{{ __('Generate Certificates') }}
</Button>
<Button v-if="user.data?.is_moderator" @click="openAnnouncementModal()">
<span>
{{ __('Make an Announcement') }}
</span>
<template #suffix>
<SendIcon class="h-4 stroke-1.5" />
</template>
</Button>
</div>
</header>
<div v-if="batch.data" class="grid grid-cols-[70%,30%] h-screen">
<div class="border-r-2">
<Tabs
v-model="tabIndex"
:tabs="tabs"
tablistClass="overflow-y-hidden sticky top-11 bg-white z-10"
tablistClass="overflow-y-hidden bg-white"
>
<template #tab="{ tab, selected }" class="overflow-x-hidden">
<div>
Expand Down Expand Up @@ -169,6 +177,7 @@
</div>
</div>
</div>
<BulkCertificates v-model="openCertificateDialog" :batch="batch.data" />
</template>
<script setup>
import { Breadcrumbs, Button, createResource, Tabs, Badge } from 'frappe-ui'
Expand Down Expand Up @@ -197,9 +206,11 @@ import Announcements from '@/components/Annoucements.vue'
import AnnouncementModal from '@/components/Modals/AnnouncementModal.vue'
import Discussions from '@/components/Discussions.vue'
import DateRange from '@/components/Common/DateRange.vue'
import BulkCertificates from '@/components/Modals/BulkCertificates.vue'
const user = inject('$user')
const showAnnouncementModal = ref(false)
const openCertificateDialog = ref(false)
const props = defineProps({
batchName: {
Expand Down
Loading

0 comments on commit 6c3bb34

Please sign in to comment.