@@ -25,7 +25,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { createListResource, Avatar } from 'frappe-ui'
|
||||
import { createResource, Avatar } from 'frappe-ui'
|
||||
import { timeAgo } from '@/utils'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -35,24 +35,15 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const communications = createListResource({
|
||||
doctype: 'Communication',
|
||||
fields: [
|
||||
'subject',
|
||||
'content',
|
||||
'recipients',
|
||||
'cc',
|
||||
'communication_date',
|
||||
'sender',
|
||||
'sender_full_name',
|
||||
],
|
||||
filters: {
|
||||
reference_doctype: 'LMS Batch',
|
||||
reference_name: props.batch,
|
||||
const communications = createResource({
|
||||
url: 'lms.lms.api.get_announcements',
|
||||
makeParams(value) {
|
||||
return {
|
||||
batch: props.batch,
|
||||
}
|
||||
},
|
||||
orderBy: 'communication_date desc',
|
||||
auto: true,
|
||||
cache: ['batch', props.batch],
|
||||
cache: ['announcement', props.batch],
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<a
|
||||
:href="cls.join_url"
|
||||
target="_blank"
|
||||
class="w-1/2 cursor-pointer inline-flex items-center justify-center gap-2 transition-colors focus:outline-none text-gray-800 bg-gray-100 hover:bg-gray-200 active:bg-gray-300 focus-visible:ring focus-visible:ring-gray-400 h-7 text-base px-2 rounded"
|
||||
class="w-full cursor-pointer inline-flex items-center justify-center gap-2 transition-colors focus:outline-none text-gray-800 bg-gray-100 hover:bg-gray-200 active:bg-gray-300 focus-visible:ring focus-visible:ring-gray-400 h-7 text-base px-2 rounded"
|
||||
>
|
||||
<Video class="h-4 w-4 stroke-1.5" />
|
||||
{{ __('Join') }}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<script setup>
|
||||
import { Dialog, Input, TextEditor, createResource } from 'frappe-ui'
|
||||
import { reactive } from 'vue'
|
||||
import { createToast } from '@/utils/'
|
||||
import { showToast } from '@/utils/'
|
||||
|
||||
const show = defineModel()
|
||||
|
||||
@@ -94,22 +94,14 @@ const makeAnnouncement = (close) => {
|
||||
},
|
||||
onSuccess() {
|
||||
close()
|
||||
createToast({
|
||||
title: 'Success',
|
||||
text: 'Announcement has been sent successfully',
|
||||
icon: 'Check',
|
||||
iconClasses: 'bg-green-600 text-white rounded-md p-px',
|
||||
})
|
||||
showToast(
|
||||
__('Success'),
|
||||
__('Announcement has been sent successfully'),
|
||||
'check'
|
||||
)
|
||||
},
|
||||
onError(err) {
|
||||
createToast({
|
||||
title: 'Error',
|
||||
text: err.messages?.[0] || err,
|
||||
icon: 'x',
|
||||
iconClasses: 'bg-red-600 text-white rounded-md p-px',
|
||||
position: 'top-center',
|
||||
timeout: 10,
|
||||
})
|
||||
showToast(__('Error'), __(err.messages?.[0] || err), 'check')
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -236,7 +236,7 @@ const breadcrumbs = computed(() => {
|
||||
const isStudent = computed(() => {
|
||||
return (
|
||||
user?.data &&
|
||||
batch.data?.students.length &&
|
||||
batch.data?.students?.length &&
|
||||
batch.data?.students.includes(user.data.name)
|
||||
)
|
||||
})
|
||||
|
||||
@@ -248,12 +248,7 @@ import {
|
||||
reactive,
|
||||
watch,
|
||||
} from 'vue'
|
||||
import {
|
||||
convertToTitleCase,
|
||||
showToast,
|
||||
getFileSize,
|
||||
updateDocumentTitle,
|
||||
} from '@/utils'
|
||||
import { convertToTitleCase, showToast, updateDocumentTitle } from '@/utils'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import { FileText, Image, X } from 'lucide-vue-next'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
@@ -17,14 +17,9 @@
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
<router-link
|
||||
v-if="user.data"
|
||||
:to="{ name: 'CourseDetail', params: { courseName: courseName } }"
|
||||
>
|
||||
<Button variant="solid">
|
||||
{{ __('Start Learning') }}
|
||||
</Button>
|
||||
</router-link>
|
||||
<Button v-if="user.data" @click="enrollStudent()" variant="solid">
|
||||
{{ __('Start Learning') }}
|
||||
</Button>
|
||||
<Button v-else @click="redirectToLogin()">
|
||||
{{ __('Login') }}
|
||||
</Button>
|
||||
@@ -194,7 +189,7 @@ import { createResource, Breadcrumbs, Button } from 'frappe-ui'
|
||||
import { computed, watch, inject, ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
import CourseOutline from '@/components/CourseOutline.vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-vue-next'
|
||||
import Discussions from '@/components/Discussions.vue'
|
||||
import { getEditorTools, updateDocumentTitle } from '../utils'
|
||||
@@ -204,6 +199,7 @@ import CourseInstructors from '@/components/CourseInstructors.vue'
|
||||
import ProgressBar from '@/components/ProgressBar.vue'
|
||||
|
||||
const user = inject('$user')
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const allowDiscussions = ref(false)
|
||||
const editor = ref(null)
|
||||
@@ -379,6 +375,30 @@ const allowInstructorContent = () => {
|
||||
return false
|
||||
}
|
||||
|
||||
const enrollment = createResource({
|
||||
url: 'frappe.client.insert',
|
||||
makeParams() {
|
||||
return {
|
||||
doc: {
|
||||
doctype: 'LMS Enrollment',
|
||||
course: props.courseName,
|
||||
member: user.data?.name,
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const enrollStudent = () => {
|
||||
enrollment.submit(
|
||||
{},
|
||||
{
|
||||
onSuccess() {
|
||||
window.location.reload()
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const redirectToLogin = () => {
|
||||
window.location.href = `/login?redirect-to=/lms/courses/${props.courseName}`
|
||||
}
|
||||
|
||||
@@ -781,3 +781,24 @@ def update_course_statistics():
|
||||
course.name,
|
||||
{"lessons": lessons, "enrollments": enrollments, "rating": avg_rating},
|
||||
)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_announcements(batch):
|
||||
return frappe.get_all(
|
||||
"Communication",
|
||||
filters={
|
||||
"reference_doctype": "LMS Batch",
|
||||
"reference_name": batch,
|
||||
},
|
||||
fields=[
|
||||
"subject",
|
||||
"content",
|
||||
"recipients",
|
||||
"cc",
|
||||
"communication_date",
|
||||
"sender",
|
||||
"sender_full_name",
|
||||
],
|
||||
order_by="communication_date desc",
|
||||
)
|
||||
|
||||
@@ -7,17 +7,3 @@ from frappe.model.document import Document
|
||||
|
||||
class BatchStudent(Document):
|
||||
pass
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def enroll_batch(batch_name):
|
||||
if frappe.db.exists(
|
||||
"Batch Student", {"student": frappe.session.user, "parent": batch_name}
|
||||
):
|
||||
frappe.throw("You are already enrolled in this batch")
|
||||
enrollment = frappe.new_doc("Batch Student")
|
||||
enrollment.student = frappe.session.user
|
||||
enrollment.parent = batch_name
|
||||
enrollment.parentfield = "students"
|
||||
enrollment.parenttype = "LMS Batch"
|
||||
enrollment.save(ignore_permissions=True)
|
||||
|
||||
@@ -33,6 +33,7 @@ class LMSBatch(Document):
|
||||
self.validate_timetable()
|
||||
self.send_confirmation_mail()
|
||||
self.validate_evaluation_end_date()
|
||||
self.add_students_to_live_class()
|
||||
|
||||
def validate_batch_end_date(self):
|
||||
if self.end_date < self.start_date:
|
||||
@@ -139,6 +140,27 @@ class LMSBatch(Document):
|
||||
if cint(self.seat_count) < len(self.students):
|
||||
frappe.throw(_("There are no seats available in this batch."))
|
||||
|
||||
def add_students_to_live_class(self):
|
||||
for student in self.students:
|
||||
if student.is_new():
|
||||
live_classes = frappe.get_all(
|
||||
"LMS Live Class", {"batch_name": self.name}, ["name", "event"]
|
||||
)
|
||||
|
||||
for live_class in live_classes:
|
||||
if live_class.event:
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Event Participants",
|
||||
"reference_doctype": "User",
|
||||
"reference_docname": student.student,
|
||||
"email": student.student,
|
||||
"parent": live_class.event,
|
||||
"parenttype": "Event",
|
||||
"parentfield": "event_participants",
|
||||
}
|
||||
).save()
|
||||
|
||||
def validate_timetable(self):
|
||||
for schedule in self.timetable:
|
||||
if schedule.start_time and schedule.end_time:
|
||||
|
||||
@@ -10,19 +10,20 @@
|
||||
"title",
|
||||
"host",
|
||||
"batch_name",
|
||||
"event",
|
||||
"column_break_astv",
|
||||
"date",
|
||||
"time",
|
||||
"duration",
|
||||
"section_break_glxh",
|
||||
"description",
|
||||
"section_break_glxh",
|
||||
"date",
|
||||
"duration",
|
||||
"column_break_spvt",
|
||||
"time",
|
||||
"timezone",
|
||||
"password",
|
||||
"auto_recording",
|
||||
"section_break_yrpq",
|
||||
"password",
|
||||
"start_url",
|
||||
"column_break_yokr",
|
||||
"auto_recording",
|
||||
"join_url"
|
||||
],
|
||||
"fields": [
|
||||
@@ -122,11 +123,18 @@
|
||||
"fieldtype": "Select",
|
||||
"label": "Auto Recording",
|
||||
"options": "No Recording\nLocal\nCloud"
|
||||
},
|
||||
{
|
||||
"fieldname": "event",
|
||||
"fieldtype": "Link",
|
||||
"label": "Event",
|
||||
"options": "Event",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2024-01-09 11:22:33.272341",
|
||||
"modified": "2024-10-31 15:41:35.540856",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Live Class",
|
||||
|
||||
@@ -16,6 +16,7 @@ class LMSLiveClass(Document):
|
||||
if calendar:
|
||||
event = self.create_event()
|
||||
self.add_event_participants(event, calendar)
|
||||
frappe.db.set_value(self.doctype, self.name, "event", event.name)
|
||||
|
||||
def create_event(self):
|
||||
start = f"{self.date} {self.time}"
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
"default": "0",
|
||||
"fieldname": "payment_received",
|
||||
"fieldtype": "Check",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Payment Received"
|
||||
},
|
||||
{
|
||||
@@ -140,7 +141,7 @@
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-10-26 16:54:12.408274",
|
||||
"modified": "2024-10-31 15:33:39.420366",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Payment",
|
||||
|
||||
Reference in New Issue
Block a user