-
- {{ evl.course_title }}
+
+
+ {{ evl.course_title }}
+
+
@@ -50,16 +93,6 @@
{{ __('Join Call') }}
-
@@ -84,11 +117,13 @@ import {
Clock,
GraduationCap,
HeadsetIcon,
+ EllipsisVertical,
} from 'lucide-vue-next'
import { inject, ref, getCurrentInstance } from 'vue'
import { formatTime } from '../utils'
import { Button, createResource, call } from 'frappe-ui'
import EvaluationModal from '@/components/Modals/EvaluationModal.vue'
+import { Menu, MenuButton, MenuItems, MenuItem } from '@headlessui/vue'
const dayjs = inject('$dayjs')
const user = inject('$user')
diff --git a/frontend/src/components/UserDropdown.vue b/frontend/src/components/UserDropdown.vue
index 18d81dc8..7bceecc4 100644
--- a/frontend/src/components/UserDropdown.vue
+++ b/frontend/src/components/UserDropdown.vue
@@ -82,6 +82,7 @@ import {
User,
Settings,
Sun,
+ Zap,
} from 'lucide-vue-next'
const router = useRouter()
@@ -125,89 +126,109 @@ const toggleTheme = () => {
const userDropdownOptions = computed(() => {
return [
{
- icon: User,
- label: 'My Profile',
- onClick: () => {
- router.push(`/user/${userResource.data?.username}`)
- },
- condition: () => {
- return isLoggedIn
- },
+ group: '',
+ items: [
+ {
+ icon: User,
+ label: 'My Profile',
+ onClick: () => {
+ router.push(`/user/${userResource.data?.username}`)
+ },
+ condition: () => {
+ return isLoggedIn
+ },
+ },
+ {
+ icon: theme.value === 'light' ? Moon : Sun,
+ label: 'Toggle Theme',
+ onClick: () => {
+ toggleTheme()
+ },
+ },
+ {
+ component: markRaw(Apps),
+ condition: () => {
+ let cookies = new URLSearchParams(
+ document.cookie.split('; ').join('&')
+ )
+ let system_user = cookies.get('system_user')
+ if (system_user === 'yes') return true
+ else return false
+ },
+ },
+ {
+ icon: Settings,
+ label: 'Settings',
+ onClick: () => {
+ settingsStore.isSettingsOpen = true
+ },
+ condition: () => {
+ return userResource.data?.is_moderator
+ },
+ },
+ {
+ icon: FrappeCloudIcon,
+ label: 'Login to Frappe Cloud',
+ onClick: () => {
+ $dialog({
+ title: __('Login to Frappe Cloud?'),
+ message: __(
+ 'Are you sure you want to login to your Frappe Cloud dashboard?'
+ ),
+ actions: [
+ {
+ label: __('Confirm'),
+ variant: 'solid',
+ onClick(close) {
+ loginToFrappeCloud()
+ close()
+ },
+ },
+ ],
+ })
+ },
+ condition: () => {
+ return (
+ userResource.data?.is_system_manager &&
+ userResource.data?.is_fc_site
+ )
+ },
+ },
+ ],
},
{
- icon: theme.value === 'light' ? Moon : Sun,
- label: 'Toggle Theme',
- onClick: () => {
- toggleTheme()
- },
- },
- {
- component: markRaw(Apps),
- condition: () => {
- let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
- let system_user = cookies.get('system_user')
- if (system_user === 'yes') return true
- else return false
- },
- },
- {
- icon: Settings,
- label: 'Settings',
- onClick: () => {
- settingsStore.isSettingsOpen = true
- },
- condition: () => {
- return userResource.data?.is_moderator
- },
- },
- {
- icon: FrappeCloudIcon,
- label: 'Login to Frappe Cloud',
- onClick: () => {
- $dialog({
- title: __('Login to Frappe Cloud?'),
- message: __(
- 'Are you sure you want to login to your Frappe Cloud dashboard?'
- ),
- actions: [
- {
- label: __('Confirm'),
- variant: 'solid',
- onClick(close) {
- loginToFrappeCloud()
- close()
- },
- },
- ],
- })
- },
- condition: () => {
- return (
- userResource.data?.is_system_manager && userResource.data?.is_fc_site
- )
- },
- },
- {
- icon: LogOut,
- label: 'Log out',
- onClick: () => {
- logout.submit().then(() => {
- isLoggedIn = false
- })
- },
- condition: () => {
- return isLoggedIn
- },
- },
- {
- icon: LogIn,
- label: 'Log in',
- onClick: () => {
- window.location.href = '/login'
- },
- condition: () => {
- return !isLoggedIn
- },
+ group: '',
+ items: [
+ {
+ icon: Zap,
+ label: 'Powered by Learning',
+ onClick: () => {
+ window.open('https://frappe.io/learning', '_blank')
+ },
+ },
+ {
+ icon: LogOut,
+ label: 'Log out',
+ onClick: () => {
+ logout.submit().then(() => {
+ isLoggedIn = false
+ })
+ },
+ condition: () => {
+ return isLoggedIn
+ },
+ },
+ {
+ icon: LogIn,
+ label: 'Log in',
+ onClick: () => {
+ window.location.href = '/login'
+ },
+ condition: () => {
+ return !isLoggedIn
+ },
+ },
+ ],
},
]
})
diff --git a/lms/lms/doctype/lms_course/lms_course.json b/lms/lms/doctype/lms_course/lms_course.json
index 90e900d0..6cf01f8e 100644
--- a/lms/lms/doctype/lms_course/lms_course.json
+++ b/lms/lms/doctype/lms_course/lms_course.json
@@ -277,28 +277,20 @@
"is_published_field": "published",
"links": [
{
- "group": "Chapters",
+ "link_doctype": "LMS Enrollment",
+ "link_fieldname": "course"
+ },
+ {
"link_doctype": "Course Chapter",
"link_fieldname": "course"
},
{
- "group": "Batches",
- "link_doctype": "LMS Batch Old",
- "link_fieldname": "course"
- },
- {
- "group": "Mentors",
- "link_doctype": "LMS Course Mentor Mapping",
- "link_fieldname": "course"
- },
- {
- "group": "Interests",
- "link_doctype": "LMS Course Interest",
+ "link_doctype": "Course Lesson",
"link_fieldname": "course"
}
],
"make_attachments_public": 1,
- "modified": "2025-03-04 15:43:25.151554",
+ "modified": "2025-03-13 16:01:19.105212",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Course",
diff --git a/lms/lms/doctype/lms_payment/lms_payment.json b/lms/lms/doctype/lms_payment/lms_payment.json
index cca8ae66..d66f0183 100644
--- a/lms/lms/doctype/lms_payment/lms_payment.json
+++ b/lms/lms/doctype/lms_payment/lms_payment.json
@@ -44,13 +44,15 @@
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
- "options": "currency"
+ "options": "currency",
+ "reqd": 1
},
{
"fieldname": "currency",
"fieldtype": "Link",
"label": "Currency",
- "options": "Currency"
+ "options": "Currency",
+ "reqd": 1
},
{
"fieldname": "column_break_rqkd",
@@ -70,7 +72,8 @@
"fieldname": "address",
"fieldtype": "Link",
"label": "Address",
- "options": "Address"
+ "options": "Address",
+ "reqd": 1
},
{
"default": "0",
@@ -124,13 +127,15 @@
"fieldname": "payment_for_document_type",
"fieldtype": "Select",
"label": "Payment for Document Type",
- "options": "\nLMS Course\nLMS Batch"
+ "options": "\nLMS Course\nLMS Batch",
+ "reqd": 1
},
{
"fieldname": "payment_for_document",
"fieldtype": "Dynamic Link",
"label": "Payment for Document",
- "options": "payment_for_document_type"
+ "options": "payment_for_document_type",
+ "reqd": 1
},
{
"fieldname": "source",
@@ -156,7 +161,7 @@
"link_fieldname": "payment"
}
],
- "modified": "2025-02-21 18:29:55.436611",
+ "modified": "2025-03-13 15:31:38.019002",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Payment",
diff --git a/lms/lms/utils.py b/lms/lms/utils.py
index b1a73e86..a0e7789a 100644
--- a/lms/lms/utils.py
+++ b/lms/lms/utils.py
@@ -1889,16 +1889,16 @@ def update_payment_record(doctype, docname):
try:
if payment_for_certificate:
- update_certificate_purchase(docname)
+ update_certificate_purchase(docname, data.payment)
elif doctype == "LMS Course":
- enroll_in_course(data.payment, docname)
+ enroll_in_course(docname, data.payment)
else:
enroll_in_batch(docname, data.payment)
except Exception as e:
frappe.log_error(frappe.get_traceback(), _("Enrollment Failed"))
-def enroll_in_course(payment_name, course):
+def enroll_in_course(course, payment_name):
if not frappe.db.exists(
"LMS Enrollment", {"member": frappe.session.user, "course": course}
):
@@ -1950,12 +1950,14 @@ def enroll_in_batch(batch, payment_name=None):
new_student.save()
-def update_certificate_purchase(course):
+def update_certificate_purchase(course, payment_name):
frappe.db.set_value(
"LMS Enrollment",
{"member": frappe.session.user, "course": course},
- "purchased_certificate",
- 1,
+ {
+ "purchased_certificate": 1,
+ "payment": payment_name,
+ },
)