@@ -298,7 +298,7 @@ import {
import { useRouter } from 'vue-router'
import { Trash2 } from 'lucide-vue-next'
import { useOnboarding, useTelemetry } from 'frappe-ui/frappe'
-import { sessionStore } from '../stores/session'
+import { sessionStore } from '@/stores/session'
import Uploader from '@/components/Controls/Uploader.vue'
import MultiSelect from '@/components/Controls/MultiSelect.vue'
import Link from '@/components/Controls/Link.vue'
@@ -313,8 +313,8 @@ const { capture } = useTelemetry()
const { $dialog } = app.appContext.config.globalProperties
const props = defineProps({
- batchName: {
- type: String,
+ batch: {
+ type: Object,
required: true,
},
})
@@ -361,7 +361,7 @@ onMounted(() => {
const fetchBatchInfo = () => {
batchDetail.reload()
- getMetaInfo('batches', props.batchName, meta)
+ getMetaInfo('batches', props.batch?.data?.name, meta)
}
const keyboardShortcut = (e) => {
diff --git a/frontend/src/pages/Batches/BatchOverview.vue b/frontend/src/pages/Batches/BatchOverview.vue
new file mode 100644
index 00000000..cacba3bf
--- /dev/null
+++ b/frontend/src/pages/Batches/BatchOverview.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+ {{ batch.data.title }}
+
+
+ {{ batch.data.description }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Courses') }}
+
+
+
+
+
+
+
+
diff --git a/frontend/src/pages/Batches.vue b/frontend/src/pages/Batches/Batches.vue
similarity index 99%
rename from frontend/src/pages/Batches.vue
rename to frontend/src/pages/Batches/Batches.vue
index 43cc71de..a01c6ecd 100644
--- a/frontend/src/pages/Batches.vue
+++ b/frontend/src/pages/Batches/Batches.vue
@@ -141,7 +141,7 @@ import { computed, inject, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { ChevronDown, Plus } from 'lucide-vue-next'
import { sessionStore } from '@/stores/session'
-import BatchCard from '@/components/BatchCard.vue'
+import BatchCard from '@/pages/Batches/components/BatchCard.vue'
import EmptyState from '@/components/EmptyState.vue'
const user = inject('$user')
diff --git a/frontend/src/pages/Batches/components/AdminBatchDashboard.vue b/frontend/src/pages/Batches/components/AdminBatchDashboard.vue
new file mode 100644
index 00000000..45091163
--- /dev/null
+++ b/frontend/src/pages/Batches/components/AdminBatchDashboard.vue
@@ -0,0 +1,281 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Students') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ /* showProgressModal = true
+ currentStudent = row */
+ }
+ "
+ class="cursor-pointer"
+ >
+
+
+
+
+
+
+
+ {{ dayjs(row[column.key]).format('DD MMM YYYY') }}
+
+
+ {{ Math.ceil(row[column.key]) }}%
+
+
+ {{ row[column.key].toString() }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/pages/Batches/components/Annoucements.vue b/frontend/src/pages/Batches/components/Annoucements.vue
new file mode 100644
index 00000000..41238f22
--- /dev/null
+++ b/frontend/src/pages/Batches/components/Annoucements.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+ {{ comm.sender_full_name }}
+
+
+
+ {{ timeAgo(comm.communication_date) }}
+
+
+
+
+
+
+
+ {{ __('No announcements have been made yet for this batch') }}
+
+
+
+
+
diff --git a/frontend/src/components/Assessments.vue b/frontend/src/pages/Batches/components/Assessments.vue
similarity index 100%
rename from frontend/src/components/Assessments.vue
rename to frontend/src/pages/Batches/components/Assessments.vue
diff --git a/frontend/src/components/BatchCard.vue b/frontend/src/pages/Batches/components/BatchCard.vue
similarity index 100%
rename from frontend/src/components/BatchCard.vue
rename to frontend/src/pages/Batches/components/BatchCard.vue
diff --git a/frontend/src/components/BatchDashboard.vue b/frontend/src/pages/Batches/components/BatchDashboard.vue
similarity index 87%
rename from frontend/src/components/BatchDashboard.vue
rename to frontend/src/pages/Batches/components/BatchDashboard.vue
index d7639490..71e9fa61 100644
--- a/frontend/src/components/BatchDashboard.vue
+++ b/frontend/src/pages/Batches/components/BatchDashboard.vue
@@ -11,7 +11,7 @@
+
diff --git a/frontend/src/pages/Courses/CourseDashboard.vue b/frontend/src/pages/Courses/CourseDashboard.vue
index 186c29f1..1c9fa8c5 100644
--- a/frontend/src/pages/Courses/CourseDashboard.vue
+++ b/frontend/src/pages/Courses/CourseDashboard.vue
@@ -349,14 +349,12 @@ const updateLessonProgress = (value: string) => {
}
watch([searchFilter], () => {
- let filterApplied = false
let filters: Filters = {
course: props.course.data?.name,
}
if (searchFilter.value) {
filters.member_name = ['like', `%${searchFilter.value}%`]
- filterApplied = true
}
progressList.update({
@@ -392,7 +390,7 @@ const progressColumns = computed(() => {
width: '30%',
},
{
- label: __('Start Date'),
+ label: __('Enrolled On'),
key: 'creation',
align: 'right',
},
diff --git a/frontend/src/pages/Home/AdminHome.vue b/frontend/src/pages/Home/AdminHome.vue
index 669dd305..8bb3af34 100644
--- a/frontend/src/pages/Home/AdminHome.vue
+++ b/frontend/src/pages/Home/AdminHome.vue
@@ -210,7 +210,7 @@ import {
} from 'lucide-vue-next'
import { formatTime } from '@/utils'
import CourseCard from '@/components/CourseCard.vue'
-import BatchCard from '@/components/BatchCard.vue'
+import BatchCard from '@/pages/Batches/components/BatchCard.vue'
const user = inject
('$user')
const dayjs = inject('$dayjs')
diff --git a/frontend/src/pages/Home/StudentHome.vue b/frontend/src/pages/Home/StudentHome.vue
index 1c45e331..10e9f1f4 100644
--- a/frontend/src/pages/Home/StudentHome.vue
+++ b/frontend/src/pages/Home/StudentHome.vue
@@ -150,7 +150,7 @@ import {
Video,
} from 'lucide-vue-next'
import CourseCard from '@/components/CourseCard.vue'
-import BatchCard from '@/components/BatchCard.vue'
+import BatchCard from '@/pages/Batches/components/BatchCard.vue'
import UpcomingEvaluations from '@/components/UpcomingEvaluations.vue'
const dayjs = inject('$dayjs')
diff --git a/frontend/src/router.js b/frontend/src/router.js
index ce46a656..1d57a76f 100644
--- a/frontend/src/router.js
+++ b/frontend/src/router.js
@@ -42,18 +42,12 @@ const routes = [
{
path: '/batches',
name: 'Batches',
- component: () => import('@/pages/Batches.vue'),
- },
- {
- path: '/batches/details/:batchName',
- name: 'BatchDetail',
- component: () => import('@/pages/BatchDetail.vue'),
- props: true,
+ component: () => import('@/pages/Batches/Batches.vue'),
},
{
path: '/batches/:batchName',
- name: 'Batch',
- component: () => import('@/pages/Batch.vue'),
+ name: 'BatchDetail',
+ component: () => import('@/pages/Batches/BatchDetail.vue'),
props: true,
},
{
@@ -125,12 +119,6 @@ const routes = [
component: () => import('@/pages/LessonForm.vue'),
props: true,
},
- {
- path: '/batches/:batchName/edit',
- name: 'BatchForm',
- component: () => import('@/pages/BatchForm.vue'),
- props: true,
- },
{
path: '/job-opening/:jobName/edit',
name: 'JobForm',
diff --git a/lms/lms/doctype/lms_batch_enrollment/lms_batch_enrollment.json b/lms/lms/doctype/lms_batch_enrollment/lms_batch_enrollment.json
index 179867fb..adbdc3e7 100644
--- a/lms/lms/doctype/lms_batch_enrollment/lms_batch_enrollment.json
+++ b/lms/lms/doctype/lms_batch_enrollment/lms_batch_enrollment.json
@@ -9,6 +9,7 @@
"member",
"member_name",
"member_username",
+ "member_image",
"column_break_sjzm",
"batch",
"payment",
@@ -70,11 +71,17 @@
"label": "Batch",
"options": "LMS Batch",
"reqd": 1
+ },
+ {
+ "fetch_from": "member.user_image",
+ "fieldname": "member_image",
+ "fieldtype": "Attach Image",
+ "label": "Member Image"
}
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2026-02-03 10:51:28.475356",
+ "modified": "2026-02-10 16:07:28.315982",
"modified_by": "sayali@frappe.io",
"module": "LMS",
"name": "LMS Batch Enrollment",
diff --git a/lms/lms/utils.py b/lms/lms/utils.py
index 5631aa1c..acdacdc5 100644
--- a/lms/lms/utils.py
+++ b/lms/lms/utils.py
@@ -1110,7 +1110,7 @@ def get_batch_details(batch: str):
is_student_enrolled = frappe.session.user in batch_students
if not (is_batch_published or is_batch_admin or is_student_enrolled):
- return
+ return {}
batch_details = frappe.db.get_value(
"LMS Batch",