fix: delete batch and pass fields prop to brand settings

This commit is contained in:
Jannat Patel
2025-07-10 22:21:26 +05:30
parent b8ae0db0bd
commit 6f9f27c030
6 changed files with 152 additions and 27 deletions

View File

@@ -65,6 +65,10 @@
}"
>
<Button variant="solid" class="w-full mt-4">
<template #prefix>
<Settings v-if="isModerator" class="size-4 stroke-1.5" />
<LogIn v-else class="size-4 stroke-1.5" />
</template>
<span>
{{ isModerator ? __('Manage Batch') : __('Visit Batch') }}
</span>
@@ -85,6 +89,9 @@
"
>
<Button v-if="!isStudent" class="w-full mt-4" variant="solid">
<template #prefix>
<CreditCard class="size-4 stroke-1.5" />
</template>
<span>
{{ __('Register Now') }}
</span>
@@ -100,6 +107,9 @@
"
@click="enrollInBatch()"
>
<template #prefix>
<GraduationCap class="size-4 stroke-1.5" />
</template>
{{ __('Enroll Now') }}
</Button>
<router-link
@@ -112,6 +122,9 @@
}"
>
<Button class="w-full mt-2">
<template #prefix>
<Pencil class="size-4 stroke-1.5" />
</template>
<span>
{{ __('Edit') }}
</span>
@@ -122,8 +135,17 @@
</template>
<script setup>
import { inject, computed } from 'vue'
import { Badge, Button, createResource, toast } from 'frappe-ui'
import { BookOpen, Clock, Globe } from 'lucide-vue-next'
import { Button, createResource, toast } from 'frappe-ui'
import {
BookOpen,
Clock,
CreditCard,
Globe,
GraduationCap,
LogIn,
Pencil,
Settings,
} from 'lucide-vue-next'
import { formatNumberIntoCurrency, formatTime } from '@/utils'
import DateRange from '@/components/Common/DateRange.vue'
import { useRouter } from 'vue-router'

View File

@@ -7,17 +7,17 @@
}"
>
<template #body-content>
<div class="flex justify-between space-x-10 text-base">
<div class="flex justify-between space-x-10 text-base mt-10">
<div class="w-full">
<div class="flex items-center justify-between space-x-5 mb-4">
<div class="text-xl font-semibold text-ink-gray-6">
<!-- <div class="text-xl font-semibold text-ink-gray-6">
{{ __('{0} Members').format(memberCount) }}
</div>
</div> -->
<FormControl
v-model="searchFilter"
:label="__('Search by Member Name')"
:placeholder="__('Search by Member Name')"
type="text"
class="w-1/2"
class="w-full"
/>
</div>
<div class="max-h-[70vh] overflow-y-auto">
@@ -90,13 +90,22 @@
</div>
</div>
<div class="mb-4 self-start w-full space-y-5">
<NumberChart
class="border rounded-md"
:config="{
title: __('Average Progress %'),
value: chartDetails.data?.average_progress || 0,
}"
/>
<div class="flex items-center space-x-4">
<NumberChart
class="border rounded-md w-full"
:config="{
title: __('Enrollments'),
value: memberCount || 0,
}"
/>
<NumberChart
class="border rounded-md w-full"
:config="{
title: __('Average Progress %'),
value: chartDetails.data?.average_progress || 0,
}"
/>
</div>
<DonutChart
:config="{
data: chartDetails.data?.progress_distribution || [],

View File

@@ -88,9 +88,31 @@ const update = () => {
)
}
watch(branding, (newData) => {
if (newData && !isDirty.value) {
isDirty.value = true
}
watch(branding, (updatedDoc) => {
let textFields = []
let imageFields = []
props.fields.forEach((f) => {
if (f.type === 'Upload') {
imageFields.push(f.name)
} else {
textFields.push(f.name)
}
})
textFields.forEach((field) => {
if (updatedDoc.data[field] != updatedDoc.previousData[field]) {
isDirty.value = true
}
})
imageFields.forEach((field) => {
if (
updatedDoc.data[field] &&
updatedDoc.data[field].file_url != updatedDoc.previousData[field].file_url
) {
isDirty.value = true
}
})
})
</script>

View File

@@ -37,8 +37,13 @@
<component
v-if="activeTab.template"
:is="activeTab.template"
:label="activeTab.label"
:description="activeTab.description"
v-bind="{
label: activeTab.label,
description: activeTab.description,
...(activeTab.label === 'Branding'
? { fields: activeTab.fields }
: {}),
}"
/>
<PaymentSettings
v-else-if="activeTab.label === 'Payment Gateway'"

View File

@@ -4,9 +4,16 @@
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" />
<Button variant="solid" @click="saveBatch()">
{{ __('Save') }}
</Button>
<div class="flex items-center space-x-2">
<Button v-if="batchDetail.data?.name" @click="deleteBatch">
<template #icon>
<Trash2 class="size-4 stroke-1.5" />
</template>
</Button>
<Button variant="solid" @click="saveBatch()">
{{ __('Save') }}
</Button>
</div>
</header>
<div class="py-5">
<div class="px-20 pb-5 space-y-5 border-b mb-5">
@@ -303,10 +310,11 @@
<script setup>
import {
computed,
onMounted,
getCurrentInstance,
inject,
reactive,
onMounted,
onBeforeUnmount,
reactive,
ref,
} from 'vue'
import {
@@ -318,9 +326,11 @@ import {
createResource,
usePageMeta,
toast,
call,
Toast,
} from 'frappe-ui'
import { useRouter } from 'vue-router'
import { Image } from 'lucide-vue-next'
import { Image, Trash2 } from 'lucide-vue-next'
import { capture } from '@/telemetry'
import { useOnboarding } from 'frappe-ui/frappe'
import { sessionStore } from '../stores/session'
@@ -338,6 +348,8 @@ const user = inject('$user')
const { brand } = sessionStore()
const { updateOnboardingStep } = useOnboarding('learning')
const instructors = ref([])
const app = getCurrentInstance()
const { $dialog } = app.appContext.config.globalProperties
const props = defineProps({
batchName: {
@@ -539,6 +551,38 @@ const editBatchDetails = () => {
)
}
const deleteBatch = () => {
$dialog({
title: __('Confirm your action to delete'),
message: __(
'Deleting this batch will also delete all its data including enrolled students, linked courses, assessments, feedback and discussions. Are you sure you want to continue?'
),
actions: [
{
label: __('Delete'),
theme: 'red',
variant: 'solid',
onClick({ close }) {
trashBatch(close)
close()
},
},
],
})
}
const trashBatch = (close) => {
call('lms.lms.api.delete_batch', {
batch: props.batchName,
}).then(() => {
toast.success(__('Batch deleted successfully'))
close()
router.push({
name: 'Batches',
})
})
}
const saveImage = (file) => {
batch.image = file
}