feat: upcoming evals
This commit is contained in:
@@ -12,7 +12,6 @@
|
|||||||
"frappe-ui": "^0.1.16",
|
"frappe-ui": "^0.1.16",
|
||||||
"lucide-vue-next": "^0.259.0",
|
"lucide-vue-next": "^0.259.0",
|
||||||
"pinia": "^2.0.33",
|
"pinia": "^2.0.33",
|
||||||
"qalendar": "^3.6.1",
|
|
||||||
"tailwindcss": "^3.2.7",
|
"tailwindcss": "^3.2.7",
|
||||||
"vue": "^3.2.25",
|
"vue": "^3.2.25",
|
||||||
"dayjs": "^1.11.6",
|
"dayjs": "^1.11.6",
|
||||||
|
|||||||
47
frontend/src/components/Assessments.vue
Normal file
47
frontend/src/components/Assessments.vue
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="text-lg font-semibold mb-4">
|
||||||
|
{{ __('Assessments') }}
|
||||||
|
</div>
|
||||||
|
<div v-if="assessments?.length">
|
||||||
|
<ListView
|
||||||
|
:columns="getAssessmentColumns()"
|
||||||
|
:rows="attempts?.data"
|
||||||
|
row-key="name"
|
||||||
|
:options="{ selectable: false, showTooltip: false }"
|
||||||
|
>
|
||||||
|
</ListView>
|
||||||
|
</div>
|
||||||
|
<div v-else class="text-sm italic text-gray-600">
|
||||||
|
{{ __('No Assessments') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ListView } from 'frappe-ui'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
assessments: {
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const getSubmissionColumns = () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'Assessment',
|
||||||
|
key: 'title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Type',
|
||||||
|
key: 'type',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Status/Score',
|
||||||
|
key: 'status',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-3">
|
<div class="flex items-center mb-3">
|
||||||
<BookOpen class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
<BookOpen class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||||
<span> {{ batch.courses }} {{ __('Courses') }} </span>
|
<span> {{ batch.courses.length }} {{ __('Courses') }} </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-3">
|
<div class="flex items-center mb-3">
|
||||||
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||||
|
|||||||
17
frontend/src/components/BatchDashboard.vue
Normal file
17
frontend/src/components/BatchDashboard.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<UpcomingEvaluations :upcoming_evals="batch.data.upcoming_evals" />
|
||||||
|
<Assessments :assessments="batch.data.assessments" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import UpcomingEvaluations from './UpcomingEvaluations.vue'
|
||||||
|
import Assessments from './Assessments.vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
batch: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -1,38 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="shadow rounded-md p-5" style="width: 300px">
|
<div v-if="batch.data" class="shadow rounded-md p-5" style="width: 300px">
|
||||||
<Badge
|
<Badge
|
||||||
v-if="batch.doc.seat_count && seats_left > 0"
|
v-if="batch.data.seat_count && seats_left > 0"
|
||||||
theme="green"
|
theme="green"
|
||||||
class="self-start mb-2 float-right"
|
class="self-start mb-2 float-right"
|
||||||
>
|
>
|
||||||
{{ seats_left }} {{ __('Seat Left') }}
|
{{ seats_left }} {{ __('Seat Left') }}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge
|
<Badge
|
||||||
v-else-if="batch.doc.seat_count && seats_left <= 0"
|
v-else-if="batch.data.seat_count && seats_left <= 0"
|
||||||
theme="red"
|
theme="red"
|
||||||
class="self-start mb-2 float-right"
|
class="self-start mb-2 float-right"
|
||||||
>
|
>
|
||||||
{{ __('Sold Out') }}
|
{{ __('Sold Out') }}
|
||||||
</Badge>
|
</Badge>
|
||||||
<div v-if="batch.doc.amount" class="text-lg font-semibold mb-3">
|
<div v-if="batch.data.amount" class="text-lg font-semibold mb-3">
|
||||||
{{ formatNumberIntoCurrency(batch.doc.amount, batch.doc.currency) }}
|
{{ formatNumberIntoCurrency(batch.data.amount, batch.data.currency) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-3">
|
<div class="flex items-center mb-3">
|
||||||
<BookOpen class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
<BookOpen class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||||
<span> {{ batch.doc.courses.length }} {{ __('Courses') }} </span>
|
<span> {{ batch.data.courses.length }} {{ __('Courses') }} </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-3">
|
<div class="flex items-center mb-3">
|
||||||
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||||
<span>
|
<span>
|
||||||
{{ dayjs(batch.doc.start_date).format('DD MMM YYYY') }} -
|
{{ dayjs(batch.data.start_date).format('DD MMM YYYY') }} -
|
||||||
{{ dayjs(batch.doc.end_date).format('DD MMM YYYY') }}
|
{{ dayjs(batch.data.end_date).format('DD MMM YYYY') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<Clock class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
<Clock class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||||
<span>
|
<span>
|
||||||
{{ formatTime(batch.doc.start_time) }} -
|
{{ formatTime(batch.data.start_time) }} -
|
||||||
{{ formatTime(batch.doc.end_time) }}
|
{{ formatTime(batch.data.end_time) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<Button v-if="user?.data?.is_moderator" class="w-full mt-4">
|
<Button v-if="user?.data?.is_moderator" class="w-full mt-4">
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-else-if="batch.doc.paid_batch"
|
v-else-if="batch.data.paid_batch"
|
||||||
class="w-full mt-4"
|
class="w-full mt-4"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
>
|
>
|
||||||
@@ -73,8 +73,8 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const seats_left = computed(() => {
|
const seats_left = computed(() => {
|
||||||
if (props.batch.doc.seat_count) {
|
if (props.batch.data?.seat_count) {
|
||||||
return props.batch.doc.seat_count - props.batch.doc.students.length
|
return props.batch.data?.seat_count - props.batch.data?.students?.length
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -114,35 +114,13 @@ import { Badge, createResource } from 'frappe-ui'
|
|||||||
import { ref, watchEffect } from 'vue'
|
import { ref, watchEffect } from 'vue'
|
||||||
|
|
||||||
const { user } = sessionStore()
|
const { user } = sessionStore()
|
||||||
let course = ref({})
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
course: {
|
course: {
|
||||||
type: [Object, String],
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const courseDetails = createResource({
|
|
||||||
url: 'lms.lms.utils.get_course_details',
|
|
||||||
cache: ['course', props.courseName],
|
|
||||||
makeParams() {
|
|
||||||
return {
|
|
||||||
course: props.course,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
transform(data) {
|
|
||||||
course.value = data
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
/* watchEffect(() => {
|
|
||||||
if (props.course && typeof props.course === "object") {
|
|
||||||
course.value = props.course;
|
|
||||||
} else {
|
|
||||||
courseDetails.reload();
|
|
||||||
}
|
|
||||||
}); */
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.course-image {
|
.course-image {
|
||||||
|
|||||||
53
frontend/src/components/UpcomingEvaluations.vue
Normal file
53
frontend/src/components/UpcomingEvaluations.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mb-10">
|
||||||
|
<div class="text-lg font-semibold mb-4">
|
||||||
|
{{ __('Upcoming Evaluations') }}
|
||||||
|
</div>
|
||||||
|
<div v-if="upcoming_evals.length">
|
||||||
|
<div class="grid grid-cols-2">
|
||||||
|
<div v-for="evl in upcoming_evals">
|
||||||
|
<div class="border rounded-md p-3">
|
||||||
|
<div class="font-medium mb-3">
|
||||||
|
{{ evl.course_title }}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mb-2">
|
||||||
|
<Calendar class="w-4 h-4 stroke-1.5" />
|
||||||
|
<span class="ml-2">
|
||||||
|
{{ dayjs(evl.date).format('DD MMMM YYYY') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mb-2">
|
||||||
|
<Clock class="w-4 h-4 stroke-1.5" />
|
||||||
|
<span class="ml-2">
|
||||||
|
{{ formatTime(evl.start_time) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<UserCog2 class="w-4 h-4 stroke-1.5" />
|
||||||
|
<span class="ml-2">
|
||||||
|
{{ evl.evaluator_name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="text-sm italic text-gray-600">
|
||||||
|
{{ __('No upcoming evaluations.') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { Calendar, Clock, UserCog2 } from 'lucide-vue-next'
|
||||||
|
import { inject } from 'vue'
|
||||||
|
import { formatTime } from '../utils'
|
||||||
|
|
||||||
|
const dayjs = inject('$dayjs')
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
upcoming_evals: {
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -1,44 +1,135 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-screen text-base">
|
<div v-if="user.data?.is_moderator || is_student" class="h-screen text-base">
|
||||||
<header
|
<header
|
||||||
class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5"
|
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" />
|
<Breadcrumbs class="h-7" :items="breadcrumbs" />
|
||||||
</header>
|
</header>
|
||||||
<div v-if="batch.doc">
|
<div v-if="batch.data">
|
||||||
<div class="grid grid-cols-[70%,30%] h-full">
|
<div class="grid grid-cols-[70%,30%] h-full">
|
||||||
<div class="border-r-2"></div>
|
<div class="border-r-2">
|
||||||
|
<Tabs class="overflow-hidden" v-model="tabIndex" :tabs="tabs">
|
||||||
|
<template #tab="{ tab, selected }">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="group -mb-px flex items-center gap-1 border-b border-transparent py-2.5 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900"
|
||||||
|
:class="{ 'text-gray-900': selected }"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
v-if="tab.icon"
|
||||||
|
:is="tab.icon"
|
||||||
|
class="h-4 stroke-1.5"
|
||||||
|
/>
|
||||||
|
{{ __(tab.label) }}
|
||||||
|
<Badge
|
||||||
|
v-if="tab.count"
|
||||||
|
:class="{
|
||||||
|
'text-gray-900 border border-gray-900': selected,
|
||||||
|
}"
|
||||||
|
variant="subtle"
|
||||||
|
theme="gray"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
{{ tab.count }}
|
||||||
|
</Badge>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #default="{ tab }">
|
||||||
|
<div class="p-10">
|
||||||
|
<div v-if="tab.label == 'Courses'">
|
||||||
|
<div class="text-xl font-semibold">
|
||||||
|
{{ __('Courses') }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 gap-8 mt-5"
|
||||||
|
>
|
||||||
|
<div v-for="course in courses.data">
|
||||||
|
<router-link
|
||||||
|
:to="{
|
||||||
|
name: 'CourseDetail',
|
||||||
|
params: {
|
||||||
|
courseName: course.name,
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<CourseCard :key="course.name" :course="course" />
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="tab.label == 'Dashboard'">
|
||||||
|
<BatchDashboard :batch="batch" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<div class="text-2xl font-semibold mb-3">
|
<div class="text-2xl font-semibold mb-3">
|
||||||
{{ batch.doc.title }}
|
{{ batch.data.title }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-2">
|
<div class="flex items-center mb-3">
|
||||||
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||||
<span>
|
<span>
|
||||||
{{ dayjs(batch.doc.start_date).format('DD MMM YYYY') }} -
|
{{ dayjs(batch.data.start_date).format('DD MMM YYYY') }} -
|
||||||
{{ dayjs(batch.doc.end_date).format('DD MMM YYYY') }}
|
{{ dayjs(batch.data.end_date).format('DD MMM YYYY') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<Clock class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
<Clock class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||||
<span>
|
<span>
|
||||||
{{ formatTime(batch.doc.start_time) }} -
|
{{ formatTime(batch.data.start_time) }} -
|
||||||
{{ formatTime(batch.doc.end_time) }}
|
{{ formatTime(batch.data.end_time) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-html="batch.doc.description"></div>
|
<div v-html="batch.data.description"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="h-screen">
|
||||||
|
<div class="text-base border rounded-md w-1/3 mx-auto my-32">
|
||||||
|
<div class="border-b px-5 py-3 font-medium">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center before:bg-red-600 before:w-2 before:h-2 before:rounded-md before:mr-2"
|
||||||
|
></span>
|
||||||
|
{{ __('Not Permitted') }}
|
||||||
|
</div>
|
||||||
|
<div class="px-5 py-3">
|
||||||
|
<div class="mb-4 leading-6">
|
||||||
|
{{
|
||||||
|
__(
|
||||||
|
'You are not a member of this batch. Please checkout our upcoming batches.'
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<router-link
|
||||||
|
:to="{
|
||||||
|
name: 'Batches',
|
||||||
|
params: {
|
||||||
|
batchName: batch.data?.name,
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Button variant="solid" class="w-full">
|
||||||
|
{{ __('Upcoming Batches') }}
|
||||||
|
</Button>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Breadcrumbs, createDocumentResource } from 'frappe-ui'
|
import { Breadcrumbs, Button, createResource, Tabs, Badge } from 'frappe-ui'
|
||||||
import { computed, inject } from 'vue'
|
import { computed, inject, ref } from 'vue'
|
||||||
import { Calendar, Clock } from 'lucide-vue-next'
|
import { Calendar, Clock, LayoutDashboard, BookOpen } from 'lucide-vue-next'
|
||||||
import { formatTime } from '@/utils'
|
import { formatTime } from '@/utils'
|
||||||
|
import CourseCard from '@/components/CourseCard.vue'
|
||||||
|
import BatchDashboard from '@/components/BatchDashboard.vue'
|
||||||
|
|
||||||
const dayjs = inject('$dayjs')
|
const dayjs = inject('$dayjs')
|
||||||
|
const user = inject('$user')
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
batchName: {
|
batchName: {
|
||||||
@@ -47,10 +138,12 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const batch = createDocumentResource({
|
const batch = createResource({
|
||||||
doctype: 'LMS Batch',
|
url: 'lms.lms.utils.get_batch_details',
|
||||||
name: props.batchName,
|
|
||||||
cache: ['batch', props.batchName],
|
cache: ['batch', props.batchName],
|
||||||
|
params: {
|
||||||
|
batch: props.batchName,
|
||||||
|
},
|
||||||
auto: true,
|
auto: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -62,9 +155,42 @@ const breadcrumbs = computed(() => {
|
|||||||
route: { name: 'BatchDetail', params: { batchName: props.batchName } },
|
route: { name: 'BatchDetail', params: { batchName: props.batchName } },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: batch?.doc?.title,
|
label: batch?.data?.title,
|
||||||
route: { name: 'Batch', params: { batchName: props.batchName } },
|
route: { name: 'Batch', params: { batchName: props.batchName } },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const is_student = computed(() => {
|
||||||
|
return (
|
||||||
|
user?.data &&
|
||||||
|
batch.data?.students.length &&
|
||||||
|
batch.data?.students.includes(user.data.name)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const tabIndex = ref(0)
|
||||||
|
const tabs = []
|
||||||
|
|
||||||
|
if (is_student) {
|
||||||
|
tabs.push({
|
||||||
|
label: 'Dashboard',
|
||||||
|
icon: LayoutDashboard,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tabs.push({
|
||||||
|
label: 'Courses',
|
||||||
|
count: computed(() => courses?.data?.length),
|
||||||
|
icon: BookOpen,
|
||||||
|
})
|
||||||
|
|
||||||
|
const courses = createResource({
|
||||||
|
url: 'lms.lms.utils.get_batch_courses',
|
||||||
|
params: {
|
||||||
|
batch: props.batchName,
|
||||||
|
},
|
||||||
|
cache: ['batchCourses', props.batchName],
|
||||||
|
auto: true,
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,42 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="batch.doc" class="h-screen text-base">
|
<div v-if="batch.data" class="h-screen text-base">
|
||||||
<header class="sticky top-0 z-10 border-b bg-white px-3 py-2.5 sm:px-5">
|
<header class="sticky top-0 z-10 border-b bg-white px-3 py-2.5 sm:px-5">
|
||||||
<Breadcrumbs :items="breadcrumbs" />
|
<Breadcrumbs :items="breadcrumbs" />
|
||||||
</header>
|
</header>
|
||||||
<div class="m-5 pb-10">
|
<div class="m-5 pb-10">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-3xl font-semibold">
|
<div class="text-3xl font-semibold">
|
||||||
{{ batch.doc.title }}
|
{{ batch.data.title }}
|
||||||
</div>
|
</div>
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
{{ batch.doc.description }}
|
{{ batch.data.description }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between w-1/2">
|
<div class="flex items-center justify-between w-1/2">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<BookOpen class="h-4 w-4 text-gray-700 mr-2" />
|
<BookOpen class="h-4 w-4 text-gray-700 mr-2" />
|
||||||
<span> {{ batch.doc.courses.length }} {{ __('Courses') }} </span>
|
<span> {{ batch.data.courses.length }} {{ __('Courses') }} </span>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="batch.doc.courses">·</span>
|
<span v-if="batch.data.courses">·</span>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<Calendar class="h-4 w-4 text-gray-700 mr-2" />
|
<Calendar class="h-4 w-4 text-gray-700 mr-2" />
|
||||||
<span>
|
<span>
|
||||||
{{ dayjs(batch.doc.start_date).format('DD MMM YYYY') }} -
|
{{ dayjs(batch.data.start_date).format('DD MMM YYYY') }} -
|
||||||
{{ dayjs(batch.doc.end_date).format('DD MMM YYYY') }}
|
{{ dayjs(batch.data.end_date).format('DD MMM YYYY') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="batch.doc.start_date">·</span>
|
<span v-if="batch.data.start_date">·</span>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<Clock class="h-4 w-4 text-gray-700 mr-2" />
|
<Clock class="h-4 w-4 text-gray-700 mr-2" />
|
||||||
<span>
|
<span>
|
||||||
{{ formatTime(batch.doc.start_time) }} -
|
{{ formatTime(batch.data.start_time) }} -
|
||||||
{{ formatTime(batch.doc.end_time) }}
|
{{ formatTime(batch.data.end_time) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-[60%,20%] gap-20 mt-10">
|
<div class="grid grid-cols-[60%,20%] gap-20 mt-10">
|
||||||
<div class="">
|
<div class="">
|
||||||
<div v-html="batch.doc.batch_details" class="batch-description"></div>
|
<div
|
||||||
|
v-html="batch.data.batch_details"
|
||||||
|
class="batch-description"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<BatchOverlay :batch="batch" />
|
<BatchOverlay :batch="batch" />
|
||||||
@@ -46,29 +49,41 @@
|
|||||||
<div class="text-2xl font-semibold">
|
<div class="text-2xl font-semibold">
|
||||||
{{ __('Courses') }}
|
{{ __('Courses') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5">
|
||||||
v-if="batch.doc.courses"
|
<div
|
||||||
v-for="course in batch.doc.courses"
|
v-if="batch.data.courses"
|
||||||
:key="course.course"
|
v-for="course in courses.data"
|
||||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5"
|
:key="course.course"
|
||||||
>
|
|
||||||
<router-link
|
|
||||||
:to="{
|
|
||||||
name: 'CourseDetail',
|
|
||||||
params: {
|
|
||||||
courseName: course.course,
|
|
||||||
},
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<CourseCard :course="course.course" :key="course.course" />
|
<router-link
|
||||||
</router-link>
|
:to="{
|
||||||
|
name: 'CourseDetail',
|
||||||
|
params: {
|
||||||
|
courseName: course.name,
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<CourseCard :course="course" :key="course.name" />
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="batch.data.batch_details_raw">
|
||||||
|
<div
|
||||||
|
v-html="batch.data.batch_details_raw"
|
||||||
|
class="batch-description"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Breadcrumbs, createDocumentResource } from 'frappe-ui'
|
import {
|
||||||
|
Breadcrumbs,
|
||||||
|
createDocumentResource,
|
||||||
|
createListResource,
|
||||||
|
createResource,
|
||||||
|
} from 'frappe-ui'
|
||||||
import { BookOpen, Calendar, Clock } from 'lucide-vue-next'
|
import { BookOpen, Calendar, Clock } from 'lucide-vue-next'
|
||||||
import { formatTime } from '../utils'
|
import { formatTime } from '../utils'
|
||||||
import { computed, inject } from 'vue'
|
import { computed, inject } from 'vue'
|
||||||
@@ -84,18 +99,29 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const batch = createDocumentResource({
|
const batch = createResource({
|
||||||
doctype: 'LMS Batch',
|
url: 'lms.lms.utils.get_batch_details',
|
||||||
name: props.batchName,
|
|
||||||
cache: ['batch', props.batchName],
|
cache: ['batch', props.batchName],
|
||||||
|
params: {
|
||||||
|
batch: props.batchName,
|
||||||
|
},
|
||||||
|
auto: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const courses = createResource({
|
||||||
|
url: 'lms.lms.utils.get_batch_courses',
|
||||||
|
params: {
|
||||||
|
batch: props.batchName,
|
||||||
|
},
|
||||||
|
cache: ['batchCourses', props.batchName],
|
||||||
auto: true,
|
auto: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const breadcrumbs = computed(() => {
|
const breadcrumbs = computed(() => {
|
||||||
let items = [{ label: 'All Batches', route: { name: 'Batches' } }]
|
let items = [{ label: 'All Batches', route: { name: 'Batches' } }]
|
||||||
items.push({
|
items.push({
|
||||||
label: batch?.doc?.title,
|
label: batch?.data?.title,
|
||||||
route: { name: 'BatchDetail', params: { batchName: batch?.doc?.name } },
|
route: { name: 'BatchDetail', params: { batchName: batch?.data?.name } },
|
||||||
})
|
})
|
||||||
return items
|
return items
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,119 +1,151 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-screen">
|
<div class="h-screen">
|
||||||
<div v-if="courses.data">
|
<div v-if="courses.data">
|
||||||
<header class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5">
|
<header
|
||||||
<Breadcrumbs class="h-7" :items="[{ label: __('All Courses'), route: { name: 'Courses' } }]" />
|
class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5"
|
||||||
<div class="flex">
|
>
|
||||||
<Button variant="solid">
|
<Breadcrumbs
|
||||||
<template #prefix>
|
class="h-7"
|
||||||
<Plus class="h-4 w-4" />
|
:items="[{ label: __('All Courses'), route: { name: 'Courses' } }]"
|
||||||
</template>
|
/>
|
||||||
{{ __("New Course") }}
|
<div class="flex">
|
||||||
</Button>
|
<Button variant="solid">
|
||||||
</div>
|
<template #prefix>
|
||||||
</header>
|
<Plus class="h-4 w-4" />
|
||||||
<div class="mx-5 py-5">
|
</template>
|
||||||
<Tabs class="overflow-hidden" v-model="tabIndex" :tabs="tabs">
|
{{ __('New Course') }}
|
||||||
<template #tab="{ tab, selected }">
|
</Button>
|
||||||
<div>
|
</div>
|
||||||
<button
|
</header>
|
||||||
class="group -mb-px flex items-center gap-2 border-b border-transparent py-2.5 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900"
|
<div class="mx-5 py-5">
|
||||||
:class="{ 'text-gray-900': selected }">
|
<Tabs class="overflow-hidden" v-model="tabIndex" :tabs="tabs">
|
||||||
<component v-if="tab.icon" :is="tab.icon" class="h-5" />
|
<template #tab="{ tab, selected }">
|
||||||
{{ __(tab.label) }}
|
<div>
|
||||||
<Badge :class="{ 'text-gray-900 border border-gray-900': selected }" variant="subtle" theme="gray"
|
<button
|
||||||
size="sm">
|
class="group -mb-px flex items-center gap-2 border-b border-transparent py-2.5 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900"
|
||||||
{{ tab.count }}
|
:class="{ 'text-gray-900': selected }"
|
||||||
</Badge>
|
>
|
||||||
</button>
|
<component v-if="tab.icon" :is="tab.icon" class="h-5" />
|
||||||
</div>
|
{{ __(tab.label) }}
|
||||||
</template>
|
<Badge
|
||||||
<template #default="{ tab }">
|
:class="{ 'text-gray-900 border border-gray-900': selected }"
|
||||||
<div v-if="tab.courses && tab.courses.value.length" class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5">
|
variant="subtle"
|
||||||
<router-link v-for="course in tab.courses.value"
|
theme="gray"
|
||||||
:to="course.membership && course.current_lesson
|
size="sm"
|
||||||
? {
|
>
|
||||||
name: 'Lesson', params: {
|
{{ tab.count }}
|
||||||
courseName: course.name,
|
</Badge>
|
||||||
chapterNumber: course.current_lesson.split('.')[0],
|
</button>
|
||||||
lessonNumber: course.current_lesson.split('.')[1]
|
</div>
|
||||||
}
|
</template>
|
||||||
}
|
<template #default="{ tab }">
|
||||||
: course.membership ? {
|
<div
|
||||||
name: 'Lesson', params: {
|
v-if="tab.courses && tab.courses.value.length"
|
||||||
courseName: course.name,
|
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5"
|
||||||
chapterNumber: 1,
|
>
|
||||||
lessonNumber: 1
|
<router-link
|
||||||
}
|
v-for="course in tab.courses.value"
|
||||||
} : { name: 'CourseDetail', params: { courseName: course.name } }">
|
:to="
|
||||||
<CourseCard :course="course" />
|
course.membership && course.current_lesson
|
||||||
</router-link>
|
? {
|
||||||
</div>
|
name: 'Lesson',
|
||||||
<div v-else class="grid flex-1 place-items-center text-xl font-medium text-gray-500">
|
params: {
|
||||||
<div class="flex flex-col items-center justify-center mt-4">
|
courseName: course.name,
|
||||||
<div>
|
chapterNumber: course.current_lesson.split('.')[0],
|
||||||
{{ __("No {0} courses found").format(tab.label.toLowerCase()) }}
|
lessonNumber: course.current_lesson.split('.')[1],
|
||||||
</div>
|
},
|
||||||
</div>
|
}
|
||||||
</div>
|
: course.membership
|
||||||
</template>
|
? {
|
||||||
</Tabs>
|
name: 'Lesson',
|
||||||
</div>
|
params: {
|
||||||
</div>
|
courseName: course.name,
|
||||||
</div>
|
chapterNumber: 1,
|
||||||
|
lessonNumber: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
name: 'CourseDetail',
|
||||||
|
params: { courseName: course.name },
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<CourseCard :course="course" />
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="grid flex-1 place-items-center text-xl font-medium text-gray-500"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col items-center justify-center mt-4">
|
||||||
|
<div>
|
||||||
|
{{
|
||||||
|
__('No {0} courses found').format(tab.label.toLowerCase())
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { sessionStore } from '@/stores/session'
|
import { createListResource, Breadcrumbs, Tabs, Badge, Button } from 'frappe-ui'
|
||||||
import { createListResource, Breadcrumbs, Tabs, Badge, Button } from 'frappe-ui';
|
import CourseCard from '@/components/CourseCard.vue'
|
||||||
import CourseCard from '@/components/CourseCard.vue';
|
|
||||||
import { Plus } from 'lucide-vue-next'
|
import { Plus } from 'lucide-vue-next'
|
||||||
import { ref, computed, inject } from 'vue'
|
import { ref, computed, inject } from 'vue'
|
||||||
|
|
||||||
const user = inject("$user")
|
const user = inject('$user')
|
||||||
const courses = createListResource({
|
const courses = createListResource({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
doctype: 'LMS Course',
|
doctype: 'LMS Course',
|
||||||
cache: ["courses", user?.data?.email],
|
cache: ['courses', user?.data?.email],
|
||||||
url: "lms.lms.utils.get_courses",
|
url: 'lms.lms.utils.get_courses',
|
||||||
auto: true,
|
auto: true,
|
||||||
});
|
})
|
||||||
|
|
||||||
const tabIndex = ref(0)
|
const tabIndex = ref(0)
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
label: 'Live',
|
label: 'Live',
|
||||||
courses: computed(() => courses.data?.live || []),
|
courses: computed(() => courses.data?.live || []),
|
||||||
count: computed(() => courses.data?.live?.length),
|
count: computed(() => courses.data?.live?.length),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Upcoming',
|
label: 'Upcoming',
|
||||||
courses: computed(() => courses.data?.upcoming),
|
courses: computed(() => courses.data?.upcoming),
|
||||||
count: computed(() => courses.data?.upcoming?.length),
|
count: computed(() => courses.data?.upcoming?.length),
|
||||||
}
|
},
|
||||||
];
|
]
|
||||||
|
|
||||||
if (user.data) {
|
if (user.data) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
label: 'Enrolled',
|
label: 'Enrolled',
|
||||||
courses: computed(() => courses.data?.enrolled),
|
courses: computed(() => courses.data?.enrolled),
|
||||||
count: computed(() => courses.data?.enrolled?.length),
|
count: computed(() => courses.data?.enrolled?.length),
|
||||||
});
|
})
|
||||||
|
|
||||||
if (user.data.is_moderator || user.data.is_instructor || courses.data?.created?.length) {
|
if (
|
||||||
tabs.push({
|
user.data.is_moderator ||
|
||||||
label: 'Created',
|
user.data.is_instructor ||
|
||||||
courses: computed(() => courses.data?.created),
|
courses.data?.created?.length
|
||||||
count: computed(() => courses.data?.created?.length),
|
) {
|
||||||
});
|
tabs.push({
|
||||||
};
|
label: 'Created',
|
||||||
|
courses: computed(() => courses.data?.created),
|
||||||
|
count: computed(() => courses.data?.created?.length),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (user.data.is_moderator) {
|
if (user.data.is_moderator) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
label: 'Under Review',
|
label: 'Under Review',
|
||||||
courses: computed(() => courses.data?.under_review),
|
courses: computed(() => courses.data?.under_review),
|
||||||
count: computed(() => courses.data?.under_review?.length),
|
count: computed(() => courses.data?.under_review?.length),
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -20,6 +20,15 @@ frappe.ui.form.on("LMS Batch", {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query("assessment_type", "assessment", function () {
|
||||||
|
let doctypes = ["LMS Quiz", "LMS Assignment"];
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
name: ["in", doctypes],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
frm.set_query("reference_doctype", "timetable_legends", function () {
|
frm.set_query("reference_doctype", "timetable_legends", function () {
|
||||||
let doctypes = ["Course Lesson", "LMS Quiz", "LMS Assignment"];
|
let doctypes = ["Course Lesson", "LMS Quiz", "LMS Assignment"];
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -297,7 +297,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-12-21 12:27:16.849362",
|
"modified": "2024-01-08 09:58:23.212334",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch",
|
"name": "LMS Batch",
|
||||||
|
|||||||
150
lms/lms/utils.py
150
lms/lms/utils.py
@@ -1348,12 +1348,27 @@ def get_neighbour_lesson(course, chapter, lesson):
|
|||||||
|
|
||||||
@frappe.whitelist(allow_guest=True)
|
@frappe.whitelist(allow_guest=True)
|
||||||
def get_batches():
|
def get_batches():
|
||||||
batches = frappe.get_all(
|
batches = []
|
||||||
|
batch_list = frappe.get_all("LMS Batch", pluck="name")
|
||||||
|
|
||||||
|
for batch in batch_list:
|
||||||
|
batches.append(get_batch_details(batch))
|
||||||
|
|
||||||
|
batches = categorize_batches(batches)
|
||||||
|
return batches
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
def get_batch_details(batch):
|
||||||
|
batch_details = frappe.db.get_value(
|
||||||
"LMS Batch",
|
"LMS Batch",
|
||||||
fields=[
|
batch,
|
||||||
|
[
|
||||||
"name",
|
"name",
|
||||||
"title",
|
"title",
|
||||||
"description",
|
"description",
|
||||||
|
"batch_details",
|
||||||
|
"batch_details_raw",
|
||||||
"start_date",
|
"start_date",
|
||||||
"end_date",
|
"end_date",
|
||||||
"start_time",
|
"start_time",
|
||||||
@@ -1362,19 +1377,36 @@ def get_batches():
|
|||||||
"published",
|
"published",
|
||||||
"amount",
|
"amount",
|
||||||
"currency",
|
"currency",
|
||||||
|
"paid_batch",
|
||||||
],
|
],
|
||||||
|
as_dict=True,
|
||||||
)
|
)
|
||||||
for batch in batches:
|
|
||||||
batch.courses = frappe.db.count("Batch Course", {"parent": batch.name})
|
batch_details.courses = frappe.get_all(
|
||||||
batch.price = fmt_money(batch.amount, 0, batch.currency)
|
"Batch Course", {"parent": batch}, pluck="course"
|
||||||
if batch.seat_count:
|
)
|
||||||
students_enrolled = frappe.db.count(
|
batch_details.students = frappe.get_all(
|
||||||
"Batch Student",
|
"Batch Student", {"parent": batch}, pluck="student"
|
||||||
{"parent": batch.name},
|
)
|
||||||
|
batch_details.price = fmt_money(batch_details.amount, 0, batch_details.currency)
|
||||||
|
|
||||||
|
is_student = frappe.session.user in batch_details.students
|
||||||
|
if frappe.session.user != "Guest":
|
||||||
|
if is_student:
|
||||||
|
batch_details.upcoming_evals = get_upcoming_evals(
|
||||||
|
frappe.session.user, batch_details.courses
|
||||||
)
|
)
|
||||||
batch.seats_left = batch.seat_count - students_enrolled
|
if is_student or has_course_moderator_role():
|
||||||
batches = categorize_batches(batches)
|
batch_details.assessments = get_assessments(batch, frappe.session.user)
|
||||||
return batches
|
|
||||||
|
if batch_details.seat_count:
|
||||||
|
students_enrolled = frappe.db.count(
|
||||||
|
"Batch Student",
|
||||||
|
{"parent": batch},
|
||||||
|
)
|
||||||
|
batch_details.seats_left = batch_details.seat_count - students_enrolled
|
||||||
|
|
||||||
|
return batch_details
|
||||||
|
|
||||||
|
|
||||||
def categorize_batches(batches):
|
def categorize_batches(batches):
|
||||||
@@ -1434,3 +1466,97 @@ def get_question_details(question):
|
|||||||
|
|
||||||
question_details = frappe.db.get_value("LMS Question", question, fields, as_dict=1)
|
question_details = frappe.db.get_value("LMS Question", question, fields, as_dict=1)
|
||||||
return question_details
|
return question_details
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
def get_batch_courses(batch):
|
||||||
|
courses = []
|
||||||
|
course_list = frappe.get_all("Batch Course", {"parent": batch}, pluck="course")
|
||||||
|
|
||||||
|
for course in course_list:
|
||||||
|
courses.append(get_course_details(course))
|
||||||
|
|
||||||
|
return courses
|
||||||
|
|
||||||
|
|
||||||
|
def get_assessments(batch, member=None):
|
||||||
|
if not member:
|
||||||
|
member = frappe.session.user
|
||||||
|
|
||||||
|
assessments = frappe.get_all(
|
||||||
|
"LMS Assessment",
|
||||||
|
{"parent": batch},
|
||||||
|
["name", "assessment_type", "assessment_name"],
|
||||||
|
)
|
||||||
|
|
||||||
|
for assessment in assessments:
|
||||||
|
if assessment.assessment_type == "LMS Assignment":
|
||||||
|
assessment = get_assignment_details(assessment, member)
|
||||||
|
|
||||||
|
elif assessment.assessment_type == "LMS Quiz":
|
||||||
|
assessment = get_quiz_details(assessment, member)
|
||||||
|
|
||||||
|
return assessments
|
||||||
|
|
||||||
|
|
||||||
|
def get_assignment_details(assessment, member):
|
||||||
|
assessment.title = frappe.db.get_value(
|
||||||
|
"LMS Assignment", assessment.assessment_name, "title"
|
||||||
|
)
|
||||||
|
|
||||||
|
existing_submission = frappe.db.exists(
|
||||||
|
{
|
||||||
|
"doctype": "LMS Assignment Submission",
|
||||||
|
"member": member,
|
||||||
|
"assignment": assessment.assessment_name,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assessment.completed = False
|
||||||
|
if existing_submission:
|
||||||
|
assessment.submission = frappe.db.get_value(
|
||||||
|
"LMS Assignment Submission",
|
||||||
|
existing_submission,
|
||||||
|
["name", "status", "comments"],
|
||||||
|
as_dict=True,
|
||||||
|
)
|
||||||
|
assessment.completed = True
|
||||||
|
|
||||||
|
assessment.edit_url = f"/assignments/{assessment.assessment_name}"
|
||||||
|
submission_name = existing_submission if existing_submission else "new-submission"
|
||||||
|
assessment.url = (
|
||||||
|
f"/assignment-submission/{assessment.assessment_name}/{submission_name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return assessment
|
||||||
|
|
||||||
|
|
||||||
|
def get_quiz_details(assessment, member):
|
||||||
|
assessment_details = frappe.db.get_value(
|
||||||
|
"LMS Quiz", assessment.assessment_name, ["title", "passing_percentage"], as_dict=1
|
||||||
|
)
|
||||||
|
assessment.title = assessment_details.title
|
||||||
|
|
||||||
|
existing_submission = frappe.get_all(
|
||||||
|
"LMS Quiz Submission",
|
||||||
|
{
|
||||||
|
"member": member,
|
||||||
|
"quiz": assessment.assessment_name,
|
||||||
|
},
|
||||||
|
["name", "score", "percentage"],
|
||||||
|
order_by="percentage desc",
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(existing_submission):
|
||||||
|
assessment.submission = existing_submission[0]
|
||||||
|
|
||||||
|
assessment.completed = False
|
||||||
|
if assessment.submission:
|
||||||
|
assessment.completed = True
|
||||||
|
|
||||||
|
assessment.edit_url = f"/quizzes/{assessment.assessment_name}"
|
||||||
|
submission_name = (
|
||||||
|
existing_submission[0].name if len(existing_submission) else "new-submission"
|
||||||
|
)
|
||||||
|
assessment.url = f"/quiz-submission/{assessment.assessment_name}/{submission_name}"
|
||||||
|
|
||||||
|
return assessment
|
||||||
|
|||||||
730
lms/public/frontend/assets/Batch.6cc6d79c.js
Normal file
730
lms/public/frontend/assets/Batch.6cc6d79c.js
Normal file
@@ -0,0 +1,730 @@
|
|||||||
|
import {
|
||||||
|
a as k,
|
||||||
|
s as o,
|
||||||
|
u as n,
|
||||||
|
A as e,
|
||||||
|
E as a,
|
||||||
|
K as j,
|
||||||
|
L as A,
|
||||||
|
C as r,
|
||||||
|
D as s,
|
||||||
|
af as T,
|
||||||
|
k as M,
|
||||||
|
j as g,
|
||||||
|
r as E,
|
||||||
|
P as I,
|
||||||
|
z as h,
|
||||||
|
B as Y,
|
||||||
|
y as x,
|
||||||
|
J as P,
|
||||||
|
F as y,
|
||||||
|
X as f,
|
||||||
|
Z as F,
|
||||||
|
a0 as H,
|
||||||
|
a1 as O,
|
||||||
|
$ as S,
|
||||||
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
|
import { f as $ } from "./index.05189aed.js";
|
||||||
|
import { _ as q } from "./CourseCard.6a41330a.js";
|
||||||
|
import { C as L, a as V } from "./clock.4d13ba48.js";
|
||||||
|
import { c as U, B as J } from "./index.43e529db.js";
|
||||||
|
import "./UserAvatar.b64a03ac.js";
|
||||||
|
import "./star.d3e8ecca.js";
|
||||||
|
const K = U("LayoutDashboardIcon", [
|
||||||
|
[
|
||||||
|
"rect",
|
||||||
|
{ width: "7", height: "9", x: "3", y: "3", rx: "1", key: "10lvy0" },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"rect",
|
||||||
|
{
|
||||||
|
width: "7",
|
||||||
|
height: "5",
|
||||||
|
x: "14",
|
||||||
|
y: "3",
|
||||||
|
rx: "1",
|
||||||
|
key: "16une8",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"rect",
|
||||||
|
{
|
||||||
|
width: "7",
|
||||||
|
height: "9",
|
||||||
|
x: "14",
|
||||||
|
y: "12",
|
||||||
|
rx: "1",
|
||||||
|
key: "1hutg5",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"rect",
|
||||||
|
{
|
||||||
|
width: "7",
|
||||||
|
height: "5",
|
||||||
|
x: "3",
|
||||||
|
y: "16",
|
||||||
|
rx: "1",
|
||||||
|
key: "ldoo1y",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
R = U("UserCog2Icon", [
|
||||||
|
["path", { d: "M14 19a6 6 0 0 0-12 0", key: "vej9p1" }],
|
||||||
|
["circle", { cx: "8", cy: "9", r: "4", key: "143rtg" }],
|
||||||
|
["circle", { cx: "19", cy: "11", r: "2", key: "1rxg02" }],
|
||||||
|
["path", { d: "M19 8v1", key: "1iffrw" }],
|
||||||
|
["path", { d: "M19 13v1", key: "z4xc62" }],
|
||||||
|
["path", { d: "m21.6 9.5-.87.5", key: "6lxupl" }],
|
||||||
|
["path", { d: "m17.27 12-.87.5", key: "1rwhxx" }],
|
||||||
|
["path", { d: "m21.6 12.5-.87-.5", key: "agvc9a" }],
|
||||||
|
["path", { d: "m17.27 10-.87-.5", key: "12d57s" }],
|
||||||
|
]),
|
||||||
|
X = { class: "mb-10" },
|
||||||
|
Z = { class: "text-lg font-semibold mb-4" },
|
||||||
|
G = { key: 0 },
|
||||||
|
Q = { class: "grid grid-cols-2" },
|
||||||
|
W = { class: "border rounded-md p-3" },
|
||||||
|
ee = { class: "font-medium mb-3" },
|
||||||
|
se = { class: "flex items-center mb-2" },
|
||||||
|
te = { class: "ml-2" },
|
||||||
|
ae = { class: "flex items-center mb-2" },
|
||||||
|
oe = { class: "ml-2" },
|
||||||
|
ne = { class: "flex items-center" },
|
||||||
|
ce = { class: "ml-2" },
|
||||||
|
re = { key: 1, class: "text-sm italic text-gray-600" },
|
||||||
|
le = {
|
||||||
|
__name: "UpcomingEvaluations",
|
||||||
|
props: { upcoming_evals: { type: Array, default: [] } },
|
||||||
|
setup(_) {
|
||||||
|
const l = k("$dayjs");
|
||||||
|
return (i, d) => (
|
||||||
|
o(),
|
||||||
|
n("div", X, [
|
||||||
|
e("div", Z, a(i.__("Upcoming Evaluations")), 1),
|
||||||
|
_.upcoming_evals.length
|
||||||
|
? (o(),
|
||||||
|
n("div", G, [
|
||||||
|
e("div", Q, [
|
||||||
|
(o(!0),
|
||||||
|
n(
|
||||||
|
j,
|
||||||
|
null,
|
||||||
|
A(
|
||||||
|
_.upcoming_evals,
|
||||||
|
(t) => (
|
||||||
|
o(),
|
||||||
|
n("div", null, [
|
||||||
|
e("div", W, [
|
||||||
|
e(
|
||||||
|
"div",
|
||||||
|
ee,
|
||||||
|
a(t.course_title),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
e("div", se, [
|
||||||
|
r(s(L), {
|
||||||
|
class: "w-4 h-4 stroke-1.5",
|
||||||
|
}),
|
||||||
|
e(
|
||||||
|
"span",
|
||||||
|
te,
|
||||||
|
a(
|
||||||
|
s(l)(
|
||||||
|
t.date
|
||||||
|
).format(
|
||||||
|
"DD MMMM YYYY"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
e("div", ae, [
|
||||||
|
r(s(V), {
|
||||||
|
class: "w-4 h-4 stroke-1.5",
|
||||||
|
}),
|
||||||
|
e(
|
||||||
|
"span",
|
||||||
|
oe,
|
||||||
|
a(
|
||||||
|
s($)(
|
||||||
|
t.start_time
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
e("div", ne, [
|
||||||
|
r(s(R), {
|
||||||
|
class: "w-4 h-4 stroke-1.5",
|
||||||
|
}),
|
||||||
|
e(
|
||||||
|
"span",
|
||||||
|
ce,
|
||||||
|
a(
|
||||||
|
t.evaluator_name
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
),
|
||||||
|
256
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
]))
|
||||||
|
: (o(),
|
||||||
|
n("div", re, a(i.__("No upcoming evaluations.")), 1)),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ie = { class: "text-lg font-semibold mb-4" },
|
||||||
|
de = { key: 0 },
|
||||||
|
me = { key: 1, class: "text-sm italic text-gray-600" },
|
||||||
|
_e = {
|
||||||
|
__name: "Assessments",
|
||||||
|
props: { assessments: { type: Array, default: [] } },
|
||||||
|
setup(_) {
|
||||||
|
return (l, i) => {
|
||||||
|
var d, t;
|
||||||
|
return (
|
||||||
|
o(),
|
||||||
|
n("div", null, [
|
||||||
|
e("div", ie, a(l.__("Assessments")), 1),
|
||||||
|
(d = _.assessments) != null && d.length
|
||||||
|
? (o(),
|
||||||
|
n("div", de, [
|
||||||
|
r(
|
||||||
|
s(T),
|
||||||
|
{
|
||||||
|
columns: l.getAssessmentColumns(),
|
||||||
|
rows:
|
||||||
|
(t = l.attempts) == null
|
||||||
|
? void 0
|
||||||
|
: t.data,
|
||||||
|
"row-key": "name",
|
||||||
|
options: {
|
||||||
|
selectable: !1,
|
||||||
|
showTooltip: !1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
["columns", "rows"]
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
: (o(), n("div", me, a(l.__("No Assessments")), 1)),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ue = {
|
||||||
|
__name: "BatchDashboard",
|
||||||
|
props: { batch: { type: Object, default: null } },
|
||||||
|
setup(_) {
|
||||||
|
return (l, i) => (
|
||||||
|
o(),
|
||||||
|
n("div", null, [
|
||||||
|
r(
|
||||||
|
le,
|
||||||
|
{ upcoming_evals: _.batch.data.upcoming_evals },
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
["upcoming_evals"]
|
||||||
|
),
|
||||||
|
r(_e, { assessments: _.batch.data.assessments }, null, 8, [
|
||||||
|
"assessments",
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
he = { key: 0, class: "h-screen text-base" },
|
||||||
|
pe = {
|
||||||
|
class: "sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5",
|
||||||
|
},
|
||||||
|
be = { key: 0 },
|
||||||
|
ye = { class: "grid grid-cols-[70%,30%] h-full" },
|
||||||
|
fe = { class: "border-r-2" },
|
||||||
|
ve = { class: "p-10" },
|
||||||
|
ge = { key: 0 },
|
||||||
|
xe = { class: "text-xl font-semibold" },
|
||||||
|
ke = { class: "grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 gap-8 mt-5" },
|
||||||
|
$e = { key: 1 },
|
||||||
|
we = { class: "p-5" },
|
||||||
|
Ne = { class: "text-2xl font-semibold mb-3" },
|
||||||
|
Ce = { class: "flex items-center mb-3" },
|
||||||
|
De = { class: "flex items-center mb-6" },
|
||||||
|
Be = ["innerHTML"],
|
||||||
|
Me = { key: 1, class: "h-screen" },
|
||||||
|
Ye = { class: "text-base border rounded-md w-1/3 mx-auto my-32" },
|
||||||
|
je = { class: "border-b px-5 py-3 font-medium" },
|
||||||
|
Ae = e(
|
||||||
|
"span",
|
||||||
|
{
|
||||||
|
class: "inline-flex items-center before:bg-red-600 before:w-2 before:h-2 before:rounded-md before:mr-2",
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
-1
|
||||||
|
),
|
||||||
|
Le = { class: "px-5 py-3" },
|
||||||
|
Ve = { class: "mb-4 leading-6" },
|
||||||
|
He = {
|
||||||
|
__name: "Batch",
|
||||||
|
props: { batchName: { type: String, required: !0 } },
|
||||||
|
setup(_) {
|
||||||
|
const l = k("$dayjs"),
|
||||||
|
i = k("$user"),
|
||||||
|
d = _,
|
||||||
|
t = M({
|
||||||
|
url: "lms.lms.utils.get_batch_details",
|
||||||
|
cache: ["batch", d.batchName],
|
||||||
|
params: { batch: d.batchName },
|
||||||
|
auto: !0,
|
||||||
|
}),
|
||||||
|
z = g(() => {
|
||||||
|
var c;
|
||||||
|
return [
|
||||||
|
{ label: "All Batches", route: { name: "Batches" } },
|
||||||
|
{
|
||||||
|
label: "Batch Details",
|
||||||
|
route: {
|
||||||
|
name: "BatchDetail",
|
||||||
|
params: { batchName: d.batchName },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label:
|
||||||
|
(c = t == null ? void 0 : t.data) == null
|
||||||
|
? void 0
|
||||||
|
: c.title,
|
||||||
|
route: {
|
||||||
|
name: "Batch",
|
||||||
|
params: { batchName: d.batchName },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
w = g(() => {
|
||||||
|
var c, p;
|
||||||
|
return (
|
||||||
|
(i == null ? void 0 : i.data) &&
|
||||||
|
((c = t.data) == null ? void 0 : c.students.length) &&
|
||||||
|
((p = t.data) == null
|
||||||
|
? void 0
|
||||||
|
: p.students.includes(i.data.name))
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
N = E(0),
|
||||||
|
v = [];
|
||||||
|
w && v.push({ label: "Dashboard", icon: K }),
|
||||||
|
v.push({
|
||||||
|
label: "Courses",
|
||||||
|
count: g(() => {
|
||||||
|
var c;
|
||||||
|
return (c = b == null ? void 0 : b.data) == null
|
||||||
|
? void 0
|
||||||
|
: c.length;
|
||||||
|
}),
|
||||||
|
icon: J,
|
||||||
|
});
|
||||||
|
const b = M({
|
||||||
|
url: "lms.lms.utils.get_batch_courses",
|
||||||
|
params: { batch: d.batchName },
|
||||||
|
cache: ["batchCourses", d.batchName],
|
||||||
|
auto: !0,
|
||||||
|
});
|
||||||
|
return (c, p) => {
|
||||||
|
var D, B;
|
||||||
|
const C = I("router-link");
|
||||||
|
return ((D = s(i).data) == null ? void 0 : D.is_moderator) ||
|
||||||
|
w.value
|
||||||
|
? (o(),
|
||||||
|
n("div", he, [
|
||||||
|
e("header", pe, [
|
||||||
|
r(
|
||||||
|
s(F),
|
||||||
|
{ class: "h-7", items: z.value },
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
["items"]
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
s(t).data
|
||||||
|
? (o(),
|
||||||
|
n("div", be, [
|
||||||
|
e("div", ye, [
|
||||||
|
e("div", fe, [
|
||||||
|
r(
|
||||||
|
s(O),
|
||||||
|
{
|
||||||
|
class: "overflow-hidden",
|
||||||
|
modelValue: N.value,
|
||||||
|
"onUpdate:modelValue":
|
||||||
|
p[0] ||
|
||||||
|
(p[0] = (m) =>
|
||||||
|
(N.value = m)),
|
||||||
|
tabs: v,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tab: h(
|
||||||
|
({
|
||||||
|
tab: m,
|
||||||
|
selected: u,
|
||||||
|
}) => [
|
||||||
|
e("div", null, [
|
||||||
|
e(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: Y(
|
||||||
|
[
|
||||||
|
"group -mb-px flex items-center gap-1 border-b border-transparent py-2.5 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900",
|
||||||
|
{
|
||||||
|
"text-gray-900":
|
||||||
|
u,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
},
|
||||||
|
[
|
||||||
|
m.icon
|
||||||
|
? (o(),
|
||||||
|
x(
|
||||||
|
P(
|
||||||
|
m.icon
|
||||||
|
),
|
||||||
|
{
|
||||||
|
key: 0,
|
||||||
|
class: "h-4 stroke-1.5",
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: y(
|
||||||
|
"",
|
||||||
|
!0
|
||||||
|
),
|
||||||
|
f(
|
||||||
|
" " +
|
||||||
|
a(
|
||||||
|
c.__(
|
||||||
|
m.label
|
||||||
|
)
|
||||||
|
) +
|
||||||
|
" ",
|
||||||
|
1
|
||||||
|
),
|
||||||
|
m.count
|
||||||
|
? (o(),
|
||||||
|
x(
|
||||||
|
s(
|
||||||
|
H
|
||||||
|
),
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
class: Y(
|
||||||
|
{
|
||||||
|
"text-gray-900 border border-gray-900":
|
||||||
|
u,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
variant:
|
||||||
|
"subtle",
|
||||||
|
theme: "gray",
|
||||||
|
size: "sm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
h(
|
||||||
|
() => [
|
||||||
|
f(
|
||||||
|
a(
|
||||||
|
m.count
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
[
|
||||||
|
"class",
|
||||||
|
]
|
||||||
|
))
|
||||||
|
: y(
|
||||||
|
"",
|
||||||
|
!0
|
||||||
|
),
|
||||||
|
],
|
||||||
|
2
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
default: h(
|
||||||
|
({ tab: m }) => [
|
||||||
|
e("div", ve, [
|
||||||
|
m.label ==
|
||||||
|
"Courses"
|
||||||
|
? (o(),
|
||||||
|
n(
|
||||||
|
"div",
|
||||||
|
ge,
|
||||||
|
[
|
||||||
|
e(
|
||||||
|
"div",
|
||||||
|
xe,
|
||||||
|
a(
|
||||||
|
c.__(
|
||||||
|
"Courses"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
e(
|
||||||
|
"div",
|
||||||
|
ke,
|
||||||
|
[
|
||||||
|
(o(
|
||||||
|
!0
|
||||||
|
),
|
||||||
|
n(
|
||||||
|
j,
|
||||||
|
null,
|
||||||
|
A(
|
||||||
|
s(
|
||||||
|
b
|
||||||
|
)
|
||||||
|
.data,
|
||||||
|
(
|
||||||
|
u
|
||||||
|
) => (
|
||||||
|
o(),
|
||||||
|
n(
|
||||||
|
"div",
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
r(
|
||||||
|
C,
|
||||||
|
{
|
||||||
|
to: {
|
||||||
|
name: "CourseDetail",
|
||||||
|
params: {
|
||||||
|
courseName:
|
||||||
|
u.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
h(
|
||||||
|
() => [
|
||||||
|
(o(),
|
||||||
|
x(
|
||||||
|
q,
|
||||||
|
{
|
||||||
|
key: u.name,
|
||||||
|
course: u,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
"course",
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
[
|
||||||
|
"to",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
256
|
||||||
|
)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
))
|
||||||
|
: m.label ==
|
||||||
|
"Dashboard"
|
||||||
|
? (o(),
|
||||||
|
n(
|
||||||
|
"div",
|
||||||
|
$e,
|
||||||
|
[
|
||||||
|
r(
|
||||||
|
ue,
|
||||||
|
{
|
||||||
|
batch: s(
|
||||||
|
t
|
||||||
|
),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
"batch",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
))
|
||||||
|
: y(
|
||||||
|
"",
|
||||||
|
!0
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 1,
|
||||||
|
},
|
||||||
|
8,
|
||||||
|
["modelValue"]
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
e("div", we, [
|
||||||
|
e(
|
||||||
|
"div",
|
||||||
|
Ne,
|
||||||
|
a(s(t).data.title),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
e("div", Ce, [
|
||||||
|
r(s(L), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
e(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
a(
|
||||||
|
s(l)(
|
||||||
|
s(t).data
|
||||||
|
.start_date
|
||||||
|
).format(
|
||||||
|
"DD MMM YYYY"
|
||||||
|
)
|
||||||
|
) +
|
||||||
|
" - " +
|
||||||
|
a(
|
||||||
|
s(l)(
|
||||||
|
s(t).data
|
||||||
|
.end_date
|
||||||
|
).format(
|
||||||
|
"DD MMM YYYY"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
e("div", De, [
|
||||||
|
r(s(V), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
e(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
a(
|
||||||
|
s($)(
|
||||||
|
s(t).data
|
||||||
|
.start_time
|
||||||
|
)
|
||||||
|
) +
|
||||||
|
" - " +
|
||||||
|
a(
|
||||||
|
s($)(
|
||||||
|
s(t).data
|
||||||
|
.end_time
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
e(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
innerHTML:
|
||||||
|
s(t).data
|
||||||
|
.description,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
Be
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]))
|
||||||
|
: y("", !0),
|
||||||
|
]))
|
||||||
|
: (o(),
|
||||||
|
n("div", Me, [
|
||||||
|
e("div", Ye, [
|
||||||
|
e("div", je, [
|
||||||
|
Ae,
|
||||||
|
f(" " + a(c.__("Not Permitted")), 1),
|
||||||
|
]),
|
||||||
|
e("div", Le, [
|
||||||
|
e(
|
||||||
|
"div",
|
||||||
|
Ve,
|
||||||
|
a(
|
||||||
|
c.__(
|
||||||
|
"You are not a member of this batch. Please checkout our upcoming batches."
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
r(
|
||||||
|
C,
|
||||||
|
{
|
||||||
|
to: {
|
||||||
|
name: "Batches",
|
||||||
|
params: {
|
||||||
|
batchName:
|
||||||
|
(B = s(t).data) == null
|
||||||
|
? void 0
|
||||||
|
: B.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: h(() => [
|
||||||
|
r(
|
||||||
|
s(S),
|
||||||
|
{
|
||||||
|
variant: "solid",
|
||||||
|
class: "w-full",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: h(() => [
|
||||||
|
f(
|
||||||
|
a(
|
||||||
|
c.__(
|
||||||
|
"Upcoming Batches"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
},
|
||||||
|
8,
|
||||||
|
["to"]
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export { He as default };
|
||||||
454
lms/public/frontend/assets/BatchDetail.c5dd0840.js
Normal file
454
lms/public/frontend/assets/BatchDetail.c5dd0840.js
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
import {
|
||||||
|
a as k,
|
||||||
|
j as D,
|
||||||
|
s as l,
|
||||||
|
u as m,
|
||||||
|
y as b,
|
||||||
|
z as f,
|
||||||
|
X as w,
|
||||||
|
E as s,
|
||||||
|
D as t,
|
||||||
|
a0 as M,
|
||||||
|
F as o,
|
||||||
|
A as a,
|
||||||
|
C as u,
|
||||||
|
$ as g,
|
||||||
|
k as Y,
|
||||||
|
P as N,
|
||||||
|
K as j,
|
||||||
|
L,
|
||||||
|
Z as T,
|
||||||
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
|
import { a as H, f as p } from "./index.05189aed.js";
|
||||||
|
import { B as $ } from "./index.43e529db.js";
|
||||||
|
import { C as B, a as C } from "./clock.4d13ba48.js";
|
||||||
|
import { _ as O } from "./CourseCard.6a41330a.js";
|
||||||
|
import "./UserAvatar.b64a03ac.js";
|
||||||
|
import "./star.d3e8ecca.js";
|
||||||
|
const S = { key: 0, class: "shadow rounded-md p-5", style: { width: "300px" } },
|
||||||
|
V = { key: 2, class: "text-lg font-semibold mb-3" },
|
||||||
|
E = { class: "flex items-center mb-3" },
|
||||||
|
z = { class: "flex items-center mb-3" },
|
||||||
|
A = { class: "flex items-center" },
|
||||||
|
F = {
|
||||||
|
__name: "BatchOverlay",
|
||||||
|
props: { batch: { type: Object, default: null } },
|
||||||
|
setup(c) {
|
||||||
|
const y = k("$dayjs"),
|
||||||
|
_ = k("$user"),
|
||||||
|
e = c,
|
||||||
|
v = D(() => {
|
||||||
|
var r, d, i, n;
|
||||||
|
return (r = e.batch.data) != null && r.seat_count
|
||||||
|
? ((d = e.batch.data) == null ? void 0 : d.seat_count) -
|
||||||
|
((n =
|
||||||
|
(i = e.batch.data) == null
|
||||||
|
? void 0
|
||||||
|
: i.students) == null
|
||||||
|
? void 0
|
||||||
|
: n.length)
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
return (r, d) => {
|
||||||
|
var i, n, h, x;
|
||||||
|
return c.batch.data
|
||||||
|
? (l(),
|
||||||
|
m("div", S, [
|
||||||
|
c.batch.data.seat_count && v.value > 0
|
||||||
|
? (l(),
|
||||||
|
b(
|
||||||
|
t(M),
|
||||||
|
{
|
||||||
|
key: 0,
|
||||||
|
theme: "green",
|
||||||
|
class: "self-start mb-2 float-right",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: f(() => [
|
||||||
|
w(
|
||||||
|
s(v.value) +
|
||||||
|
" " +
|
||||||
|
s(r.__("Seat Left")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: c.batch.data.seat_count && v.value <= 0
|
||||||
|
? (l(),
|
||||||
|
b(
|
||||||
|
t(M),
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
theme: "red",
|
||||||
|
class: "self-start mb-2 float-right",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: f(() => [
|
||||||
|
w(s(r.__("Sold Out")), 1),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: o("", !0),
|
||||||
|
c.batch.data.amount
|
||||||
|
? (l(),
|
||||||
|
m(
|
||||||
|
"div",
|
||||||
|
V,
|
||||||
|
s(
|
||||||
|
t(H)(
|
||||||
|
c.batch.data.amount,
|
||||||
|
c.batch.data.currency
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
))
|
||||||
|
: o("", !0),
|
||||||
|
a("div", E, [
|
||||||
|
u(t($), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(c.batch.data.courses.length) +
|
||||||
|
" " +
|
||||||
|
s(r.__("Courses")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
a("div", z, [
|
||||||
|
u(t(B), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(
|
||||||
|
t(y)(c.batch.data.start_date).format(
|
||||||
|
"DD MMM YYYY"
|
||||||
|
)
|
||||||
|
) +
|
||||||
|
" - " +
|
||||||
|
s(
|
||||||
|
t(y)(c.batch.data.end_date).format(
|
||||||
|
"DD MMM YYYY"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
a("div", A, [
|
||||||
|
u(t(C), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(t(p)(c.batch.data.start_time)) +
|
||||||
|
" - " +
|
||||||
|
s(t(p)(c.batch.data.end_time)),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
(n = (i = t(_)) == null ? void 0 : i.data) !=
|
||||||
|
null && n.is_moderator
|
||||||
|
? (l(),
|
||||||
|
b(
|
||||||
|
t(g),
|
||||||
|
{ key: 3, class: "w-full mt-4" },
|
||||||
|
{
|
||||||
|
default: f(() => [
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(r.__("Manage Batch")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: c.batch.data.paid_batch
|
||||||
|
? (l(),
|
||||||
|
b(
|
||||||
|
t(g),
|
||||||
|
{
|
||||||
|
key: 4,
|
||||||
|
class: "w-full mt-4",
|
||||||
|
variant: "solid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: f(() => [
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(r.__("Register Now")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: o("", !0),
|
||||||
|
(x = (h = t(_)) == null ? void 0 : h.data) !=
|
||||||
|
null && x.is_moderator
|
||||||
|
? (l(),
|
||||||
|
b(
|
||||||
|
t(g),
|
||||||
|
{ key: 5, class: "w-full mt-2" },
|
||||||
|
{
|
||||||
|
default: f(() => [
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(r.__("Edit")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: o("", !0),
|
||||||
|
]))
|
||||||
|
: o("", !0);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const R = { key: 0, class: "h-screen text-base" },
|
||||||
|
q = { class: "sticky top-0 z-10 border-b bg-white px-3 py-2.5 sm:px-5" },
|
||||||
|
I = { class: "m-5 pb-10" },
|
||||||
|
K = { class: "text-3xl font-semibold" },
|
||||||
|
P = { class: "my-3" },
|
||||||
|
X = { class: "flex items-center justify-between w-1/2" },
|
||||||
|
Z = { class: "flex items-center" },
|
||||||
|
G = { key: 0 },
|
||||||
|
J = { class: "flex items-center" },
|
||||||
|
Q = { key: 1 },
|
||||||
|
U = { class: "flex items-center" },
|
||||||
|
W = { class: "grid grid-cols-[60%,20%] gap-20 mt-10" },
|
||||||
|
tt = { class: "" },
|
||||||
|
at = ["innerHTML"],
|
||||||
|
et = { class: "text-2xl font-semibold" },
|
||||||
|
st = { class: "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5" },
|
||||||
|
ct = { key: 0 },
|
||||||
|
lt = ["innerHTML"],
|
||||||
|
_t = {
|
||||||
|
__name: "BatchDetail",
|
||||||
|
props: { batchName: { type: String, required: !0 } },
|
||||||
|
setup(c) {
|
||||||
|
const y = k("$dayjs"),
|
||||||
|
_ = c,
|
||||||
|
e = Y({
|
||||||
|
url: "lms.lms.utils.get_batch_details",
|
||||||
|
cache: ["batch", _.batchName],
|
||||||
|
params: { batch: _.batchName },
|
||||||
|
auto: !0,
|
||||||
|
}),
|
||||||
|
v = Y({
|
||||||
|
url: "lms.lms.utils.get_batch_courses",
|
||||||
|
params: { batch: _.batchName },
|
||||||
|
cache: ["batchCourses", _.batchName],
|
||||||
|
auto: !0,
|
||||||
|
}),
|
||||||
|
r = D(() => {
|
||||||
|
var i, n;
|
||||||
|
let d = [
|
||||||
|
{ label: "All Batches", route: { name: "Batches" } },
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
d.push({
|
||||||
|
label:
|
||||||
|
(i = e == null ? void 0 : e.data) == null
|
||||||
|
? void 0
|
||||||
|
: i.title,
|
||||||
|
route: {
|
||||||
|
name: "BatchDetail",
|
||||||
|
params: {
|
||||||
|
batchName:
|
||||||
|
(n = e == null ? void 0 : e.data) ==
|
||||||
|
null
|
||||||
|
? void 0
|
||||||
|
: n.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
d
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return (d, i) => {
|
||||||
|
const n = N("router-link");
|
||||||
|
return t(e).data
|
||||||
|
? (l(),
|
||||||
|
m("div", R, [
|
||||||
|
a("header", q, [
|
||||||
|
u(t(T), { items: r.value }, null, 8, ["items"]),
|
||||||
|
]),
|
||||||
|
a("div", I, [
|
||||||
|
a("div", null, [
|
||||||
|
a("div", K, s(t(e).data.title), 1),
|
||||||
|
a("div", P, s(t(e).data.description), 1),
|
||||||
|
a("div", X, [
|
||||||
|
a("div", Z, [
|
||||||
|
u(t($), {
|
||||||
|
class: "h-4 w-4 text-gray-700 mr-2",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(t(e).data.courses.length) +
|
||||||
|
" " +
|
||||||
|
s(d.__("Courses")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
t(e).data.courses
|
||||||
|
? (l(), m("span", G, "\xB7"))
|
||||||
|
: o("", !0),
|
||||||
|
a("div", J, [
|
||||||
|
u(t(B), {
|
||||||
|
class: "h-4 w-4 text-gray-700 mr-2",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(
|
||||||
|
t(y)(
|
||||||
|
t(e).data.start_date
|
||||||
|
).format("DD MMM YYYY")
|
||||||
|
) +
|
||||||
|
" - " +
|
||||||
|
s(
|
||||||
|
t(y)(
|
||||||
|
t(e).data.end_date
|
||||||
|
).format("DD MMM YYYY")
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
t(e).data.start_date
|
||||||
|
? (l(), m("span", Q, "\xB7"))
|
||||||
|
: o("", !0),
|
||||||
|
a("div", U, [
|
||||||
|
u(t(C), {
|
||||||
|
class: "h-4 w-4 text-gray-700 mr-2",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
s(t(p)(t(e).data.start_time)) +
|
||||||
|
" - " +
|
||||||
|
s(t(p)(t(e).data.end_time)),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
a("div", W, [
|
||||||
|
a("div", tt, [
|
||||||
|
a(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
innerHTML:
|
||||||
|
t(e).data.batch_details,
|
||||||
|
class: "batch-description",
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
at
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
a("div", null, [
|
||||||
|
u(F, { batch: t(e) }, null, 8, [
|
||||||
|
"batch",
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
a("div", null, [
|
||||||
|
a("div", et, s(d.__("Courses")), 1),
|
||||||
|
a("div", st, [
|
||||||
|
t(e).data.courses
|
||||||
|
? (l(!0),
|
||||||
|
m(
|
||||||
|
j,
|
||||||
|
{ key: 0 },
|
||||||
|
L(
|
||||||
|
t(v).data,
|
||||||
|
(h) => (
|
||||||
|
l(),
|
||||||
|
m(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
key: h.course,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
u(
|
||||||
|
n,
|
||||||
|
{
|
||||||
|
to: {
|
||||||
|
name: "CourseDetail",
|
||||||
|
params: {
|
||||||
|
courseName:
|
||||||
|
h.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
f(
|
||||||
|
() => [
|
||||||
|
(l(),
|
||||||
|
b(
|
||||||
|
O,
|
||||||
|
{
|
||||||
|
course: h,
|
||||||
|
key: h.name,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
"course",
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
["to"]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
128
|
||||||
|
))
|
||||||
|
: o("", !0),
|
||||||
|
]),
|
||||||
|
t(e).data.batch_details_raw
|
||||||
|
? (l(),
|
||||||
|
m("div", ct, [
|
||||||
|
a(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
innerHTML:
|
||||||
|
t(e).data
|
||||||
|
.batch_details_raw,
|
||||||
|
class: "batch-description",
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
lt
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
: o("", !0),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]))
|
||||||
|
: o("", !0);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export { _t as default };
|
||||||
1
lms/public/frontend/assets/BatchDetail.f109aa14.css
Normal file
1
lms/public/frontend/assets/BatchDetail.f109aa14.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.batch-description p{margin-bottom:1rem;line-height:1.7}.batch-description li{line-height:1.7}.batch-description ol{list-style:auto;margin:revert;padding:revert}.batch-description strong{font-weight:600;color:#171717!important}
|
||||||
1
lms/public/frontend/assets/Batches.70c9cf07.css
Normal file
1
lms/public/frontend/assets/Batches.70c9cf07.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.short-introduction{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;text-overflow:ellipsis;width:100%;overflow:hidden;margin:.25rem 0 1.25rem;line-height:1.5}
|
||||||
443
lms/public/frontend/assets/Batches.f9864378.js
Normal file
443
lms/public/frontend/assets/Batches.f9864378.js
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
import {
|
||||||
|
a as C,
|
||||||
|
s as n,
|
||||||
|
u,
|
||||||
|
y as g,
|
||||||
|
z as h,
|
||||||
|
X as _,
|
||||||
|
E as t,
|
||||||
|
D as c,
|
||||||
|
a0 as y,
|
||||||
|
F as x,
|
||||||
|
A as a,
|
||||||
|
C as i,
|
||||||
|
k as D,
|
||||||
|
r as Y,
|
||||||
|
j as m,
|
||||||
|
P as j,
|
||||||
|
B as $,
|
||||||
|
J as N,
|
||||||
|
K as V,
|
||||||
|
L as M,
|
||||||
|
Z as z,
|
||||||
|
$ as L,
|
||||||
|
a1 as P,
|
||||||
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
|
import { f as B } from "./index.05189aed.js";
|
||||||
|
import { B as A } from "./index.43e529db.js";
|
||||||
|
import { C as E, a as O } from "./clock.4d13ba48.js";
|
||||||
|
import { P as S } from "./plus.8f4bce9f.js";
|
||||||
|
const F = {
|
||||||
|
class: "flex flex-col border border-gray-200 rounded-md p-4 h-full",
|
||||||
|
style: { "min-height": "150px" },
|
||||||
|
},
|
||||||
|
T = { class: "text-xl font-semibold mb-1" },
|
||||||
|
U = { class: "short-introduction" },
|
||||||
|
I = { class: "mt-auto" },
|
||||||
|
J = { key: 0, class: "font-semibold text-lg mb-4" },
|
||||||
|
K = { class: "flex items-center mb-3" },
|
||||||
|
R = { class: "flex items-center mb-3" },
|
||||||
|
X = { class: "flex items-center" },
|
||||||
|
Z = {
|
||||||
|
__name: "BatchCard",
|
||||||
|
props: { batch: { type: Object, default: null } },
|
||||||
|
setup(s) {
|
||||||
|
const d = C("$dayjs");
|
||||||
|
return (o, v) => (
|
||||||
|
n(),
|
||||||
|
u("div", F, [
|
||||||
|
s.batch.seat_count && s.batch.seats_left > 0
|
||||||
|
? (n(),
|
||||||
|
g(
|
||||||
|
c(y),
|
||||||
|
{
|
||||||
|
key: 0,
|
||||||
|
theme: "green",
|
||||||
|
class: "self-start mb-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: h(() => [
|
||||||
|
_(
|
||||||
|
t(s.batch.seats_left) +
|
||||||
|
" " +
|
||||||
|
t(o.__("Seat Left")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: s.batch.seat_count && s.batch.seats_left <= 0
|
||||||
|
? (n(),
|
||||||
|
g(
|
||||||
|
c(y),
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
theme: "red",
|
||||||
|
class: "self-start mb-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: h(() => [
|
||||||
|
_(t(o.__("Sold Out")), 1),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: x("", !0),
|
||||||
|
a("div", T, t(s.batch.title), 1),
|
||||||
|
a("div", U, t(s.batch.description), 1),
|
||||||
|
a("div", I, [
|
||||||
|
s.batch.amount
|
||||||
|
? (n(), u("div", J, t(s.batch.price), 1))
|
||||||
|
: x("", !0),
|
||||||
|
a("div", K, [
|
||||||
|
i(c(A), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
t(s.batch.courses.length) +
|
||||||
|
" " +
|
||||||
|
t(o.__("Courses")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
a("div", R, [
|
||||||
|
i(c(E), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
t(
|
||||||
|
c(d)(s.batch.start_date).format(
|
||||||
|
"DD MMM YYYY"
|
||||||
|
)
|
||||||
|
) +
|
||||||
|
" - " +
|
||||||
|
t(
|
||||||
|
c(d)(s.batch.end_date).format(
|
||||||
|
"DD MMM YYYY"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
a("div", X, [
|
||||||
|
i(c(O), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 mr-2 text-gray-700",
|
||||||
|
}),
|
||||||
|
a(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
t(c(B)(s.batch.start_time)) +
|
||||||
|
" - " +
|
||||||
|
t(c(B)(s.batch.end_time)),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
q = { class: "h-screen text-base" },
|
||||||
|
G = {
|
||||||
|
class: "sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5",
|
||||||
|
},
|
||||||
|
H = { class: "flex" },
|
||||||
|
Q = { class: "mx-5 py-5" },
|
||||||
|
W = {
|
||||||
|
key: 0,
|
||||||
|
class: "grid grid-cols-1 sm:grid-cols-3 md:grid-cols-4 gap-8 mt-5",
|
||||||
|
},
|
||||||
|
ee = {
|
||||||
|
key: 1,
|
||||||
|
class: "grid flex-1 place-items-center text-xl font-medium text-gray-500",
|
||||||
|
},
|
||||||
|
te = { class: "flex flex-col items-center justify-center mt-4" },
|
||||||
|
re = {
|
||||||
|
__name: "Batches",
|
||||||
|
setup(s) {
|
||||||
|
var p, k;
|
||||||
|
const d = C("$user"),
|
||||||
|
o = D({
|
||||||
|
url: "lms.lms.utils.get_batches",
|
||||||
|
cache: [
|
||||||
|
"batches",
|
||||||
|
(p = d == null ? void 0 : d.data) == null
|
||||||
|
? void 0
|
||||||
|
: p.email,
|
||||||
|
],
|
||||||
|
auto: !0,
|
||||||
|
}),
|
||||||
|
v = Y(0),
|
||||||
|
f = [
|
||||||
|
{
|
||||||
|
label: "Upcoming",
|
||||||
|
batches: m(() => {
|
||||||
|
var e;
|
||||||
|
return (
|
||||||
|
((e = o.data) == null ? void 0 : e.upcoming) ||
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
count: m(() => {
|
||||||
|
var e, l;
|
||||||
|
return (l =
|
||||||
|
(e = o.data) == null ? void 0 : e.upcoming) ==
|
||||||
|
null
|
||||||
|
? void 0
|
||||||
|
: l.length;
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
(k = d.data) != null &&
|
||||||
|
k.is_moderator &&
|
||||||
|
(f.push({
|
||||||
|
label: "Archived",
|
||||||
|
batches: m(() => {
|
||||||
|
var e;
|
||||||
|
return (e = o.data) == null ? void 0 : e.archived;
|
||||||
|
}),
|
||||||
|
count: m(() => {
|
||||||
|
var e, l;
|
||||||
|
return (l =
|
||||||
|
(e = o.data) == null ? void 0 : e.archived) ==
|
||||||
|
null
|
||||||
|
? void 0
|
||||||
|
: l.length;
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
f.push({
|
||||||
|
label: "Private",
|
||||||
|
batches: m(() => {
|
||||||
|
var e;
|
||||||
|
return (e = o.data) == null ? void 0 : e.private;
|
||||||
|
}),
|
||||||
|
count: m(() => {
|
||||||
|
var e, l;
|
||||||
|
return (l =
|
||||||
|
(e = o.data) == null ? void 0 : e.private) ==
|
||||||
|
null
|
||||||
|
? void 0
|
||||||
|
: l.length;
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
d.data &&
|
||||||
|
f.push({
|
||||||
|
label: "Enrolled",
|
||||||
|
batches: m(() => {
|
||||||
|
var e;
|
||||||
|
return (e = o.data) == null ? void 0 : e.enrolled;
|
||||||
|
}),
|
||||||
|
count: m(() => {
|
||||||
|
var e, l;
|
||||||
|
return (l =
|
||||||
|
(e = o.data) == null ? void 0 : e.enrolled) ==
|
||||||
|
null
|
||||||
|
? void 0
|
||||||
|
: l.length;
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
(e, l) => {
|
||||||
|
const w = j("router-link");
|
||||||
|
return (
|
||||||
|
n(),
|
||||||
|
u("div", q, [
|
||||||
|
a("header", G, [
|
||||||
|
i(
|
||||||
|
c(z),
|
||||||
|
{
|
||||||
|
class: "h-7",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: e.__("All Batches"),
|
||||||
|
route: { name: "Batches" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
["items"]
|
||||||
|
),
|
||||||
|
a("div", H, [
|
||||||
|
i(
|
||||||
|
c(L),
|
||||||
|
{ variant: "solid" },
|
||||||
|
{
|
||||||
|
prefix: h(() => [
|
||||||
|
i(c(S), { class: "h-4 w-4" }),
|
||||||
|
]),
|
||||||
|
default: h(() => [
|
||||||
|
_(
|
||||||
|
" " + t(e.__("New Batch")),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
a("div", Q, [
|
||||||
|
i(
|
||||||
|
c(P),
|
||||||
|
{
|
||||||
|
class: "overflow-hidden",
|
||||||
|
modelValue: v.value,
|
||||||
|
"onUpdate:modelValue":
|
||||||
|
l[0] ||
|
||||||
|
(l[0] = (r) => (v.value = r)),
|
||||||
|
tabs: f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tab: h(({ tab: r, selected: b }) => [
|
||||||
|
a("div", null, [
|
||||||
|
a(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: $([
|
||||||
|
"group -mb-px flex items-center gap-2 border-b border-transparent py-2.5 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900",
|
||||||
|
{
|
||||||
|
"text-gray-900":
|
||||||
|
b,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
[
|
||||||
|
r.icon
|
||||||
|
? (n(),
|
||||||
|
g(N(r.icon), {
|
||||||
|
key: 0,
|
||||||
|
class: "h-5",
|
||||||
|
}))
|
||||||
|
: x("", !0),
|
||||||
|
_(
|
||||||
|
" " +
|
||||||
|
t(
|
||||||
|
e.__(
|
||||||
|
r.label
|
||||||
|
)
|
||||||
|
) +
|
||||||
|
" ",
|
||||||
|
1
|
||||||
|
),
|
||||||
|
i(
|
||||||
|
c(y),
|
||||||
|
{
|
||||||
|
class: $({
|
||||||
|
"text-gray-900 border border-gray-900":
|
||||||
|
b,
|
||||||
|
}),
|
||||||
|
variant:
|
||||||
|
"subtle",
|
||||||
|
theme: "gray",
|
||||||
|
size: "sm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: h(
|
||||||
|
() => [
|
||||||
|
_(
|
||||||
|
t(
|
||||||
|
r.count
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
["class"]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
2
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
default: h(({ tab: r }) => [
|
||||||
|
r.batches && r.batches.value.length
|
||||||
|
? (n(),
|
||||||
|
u("div", W, [
|
||||||
|
(n(!0),
|
||||||
|
u(
|
||||||
|
V,
|
||||||
|
null,
|
||||||
|
M(
|
||||||
|
r.batches.value,
|
||||||
|
(b) => (
|
||||||
|
n(),
|
||||||
|
g(
|
||||||
|
w,
|
||||||
|
{
|
||||||
|
to: {
|
||||||
|
name: "BatchDetail",
|
||||||
|
params: {
|
||||||
|
batchName:
|
||||||
|
b.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
h(
|
||||||
|
() => [
|
||||||
|
i(
|
||||||
|
Z,
|
||||||
|
{
|
||||||
|
batch: b,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
"batch",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
["to"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
256
|
||||||
|
)),
|
||||||
|
]))
|
||||||
|
: (n(),
|
||||||
|
u("div", ee, [
|
||||||
|
a("div", te, [
|
||||||
|
a(
|
||||||
|
"div",
|
||||||
|
null,
|
||||||
|
t(
|
||||||
|
e
|
||||||
|
.__(
|
||||||
|
"No {0} batches found"
|
||||||
|
)
|
||||||
|
.format(
|
||||||
|
r.label.toLowerCase()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
])),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
},
|
||||||
|
8,
|
||||||
|
["modelValue"]
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export { re as default };
|
||||||
@@ -1 +1 @@
|
|||||||
.course-image{height:168px;width:100%;background-size:cover;background-position:center;background-repeat:no-repeat}.course-card-pills{background:#ffffff;margin-left:0;margin-right:.5rem;padding:3.5px 8px;font-size:11px;text-align:center;letter-spacing:.011em;text-transform:uppercase;font-weight:600;width:-moz-fit-content;width:fit-content}.default-image{display:flex;flex-direction:column;align-items:center;background-color:#ededed;color:#525252}
|
.course-image{height:168px;width:100%;background-size:cover;background-position:center;background-repeat:no-repeat}.course-card-pills{background:#ffffff;margin-left:0;margin-right:.5rem;padding:3.5px 8px;font-size:11px;text-align:center;letter-spacing:.011em;text-transform:uppercase;font-weight:600;width:-moz-fit-content;width:fit-content}.default-image{display:flex;flex-direction:column;align-items:center;background-color:#ededed;color:#525252}.avatar-group{display:inline-flex;align-items:center}.avatar-group .avatar{transition:margin .1s ease-in-out}.image-placeholder{display:flex;align-items:center;flex:1;font-size:5rem;color:#525252;font-weight:600}.avatar-group.overlap .avatar+.avatar{margin-left:-8px}.short-introduction{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;text-overflow:ellipsis;width:100%;overflow:hidden;margin:.25rem 0 1.25rem;line-height:1.5}
|
||||||
298
lms/public/frontend/assets/CourseCard.6a41330a.js
Normal file
298
lms/public/frontend/assets/CourseCard.6a41330a.js
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
import { _ as f } from "./UserAvatar.b64a03ac.js";
|
||||||
|
import { s as g, B as v, U as y } from "./index.43e529db.js";
|
||||||
|
import {
|
||||||
|
s,
|
||||||
|
u as r,
|
||||||
|
A as o,
|
||||||
|
K as i,
|
||||||
|
L as d,
|
||||||
|
E as t,
|
||||||
|
F as c,
|
||||||
|
B as m,
|
||||||
|
a2 as h,
|
||||||
|
C as n,
|
||||||
|
D as a,
|
||||||
|
z as x,
|
||||||
|
X as b,
|
||||||
|
a0 as k,
|
||||||
|
y as w,
|
||||||
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
|
import { S as _ } from "./star.d3e8ecca.js";
|
||||||
|
const C = {
|
||||||
|
key: 0,
|
||||||
|
class: "flex flex-col border border-gray-200 h-full rounded-md shadow-sm text-base overflow-auto",
|
||||||
|
style: { "min-height": "320px" },
|
||||||
|
},
|
||||||
|
B = { class: "flex relative top-4 left-4 w-fit" },
|
||||||
|
S = { class: "course-card-pills rounded-md border border-gray-200" },
|
||||||
|
z = { key: 0, class: "image-placeholder" },
|
||||||
|
N = { class: "flex flex-col flex-auto p-4" },
|
||||||
|
U = { class: "flex items-center justify-between mb-2" },
|
||||||
|
V = { key: 0, class: "flex items-center space-x-1 py-1" },
|
||||||
|
j = { key: 1, class: "flex items-center space-x-1 py-1" },
|
||||||
|
A = { key: 2, class: "flex items-center space-x-1 py-1" },
|
||||||
|
D = { key: 3 },
|
||||||
|
E = { class: "text-xl font-semibold" },
|
||||||
|
F = { class: "short-introduction" },
|
||||||
|
I = { key: 0, class: "w-full bg-gray-200 rounded-full h-1 mb-2" },
|
||||||
|
L = { key: 1, class: "text-sm mb-4" },
|
||||||
|
M = { class: "flex items-center justify-between mt-auto" },
|
||||||
|
O = { class: "flex avatar-group overlap" },
|
||||||
|
R = { key: 0 },
|
||||||
|
$ = { key: 1 },
|
||||||
|
K = { key: 2 },
|
||||||
|
T = { class: "font-semibold" },
|
||||||
|
Q = {
|
||||||
|
__name: "CourseCard",
|
||||||
|
props: { course: { type: Object, default: null } },
|
||||||
|
setup(e) {
|
||||||
|
const { user: u } = g();
|
||||||
|
return (X, q) =>
|
||||||
|
e.course.title
|
||||||
|
? (s(),
|
||||||
|
r("div", C, [
|
||||||
|
o(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: m([
|
||||||
|
"course-image",
|
||||||
|
{ "default-image": !e.course.image },
|
||||||
|
]),
|
||||||
|
style: h({
|
||||||
|
backgroundImage:
|
||||||
|
"url(" +
|
||||||
|
encodeURI(e.course.image) +
|
||||||
|
")",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
[
|
||||||
|
o("div", B, [
|
||||||
|
(s(!0),
|
||||||
|
r(
|
||||||
|
i,
|
||||||
|
null,
|
||||||
|
d(
|
||||||
|
e.course.tags,
|
||||||
|
(l) => (
|
||||||
|
s(), r("div", S, t(l), 1)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
256
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
e.course.image
|
||||||
|
? c("", !0)
|
||||||
|
: (s(),
|
||||||
|
r("div", z, t(e.course.title[0]), 1)),
|
||||||
|
],
|
||||||
|
6
|
||||||
|
),
|
||||||
|
o("div", N, [
|
||||||
|
o("div", U, [
|
||||||
|
e.course.lesson_count
|
||||||
|
? (s(),
|
||||||
|
r("div", V, [
|
||||||
|
n(a(v), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 text-gray-700",
|
||||||
|
}),
|
||||||
|
o(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
t(e.course.lesson_count),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
: c("", !0),
|
||||||
|
e.course.enrollment_count
|
||||||
|
? (s(),
|
||||||
|
r("div", j, [
|
||||||
|
n(a(y), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 text-gray-700",
|
||||||
|
}),
|
||||||
|
o(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
t(
|
||||||
|
e.course
|
||||||
|
.enrollment_count
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
: c("", !0),
|
||||||
|
e.course.avg_rating
|
||||||
|
? (s(),
|
||||||
|
r("div", A, [
|
||||||
|
n(a(_), {
|
||||||
|
class: "h-4 w-4 stroke-1.5 text-gray-700",
|
||||||
|
}),
|
||||||
|
o(
|
||||||
|
"span",
|
||||||
|
null,
|
||||||
|
t(e.course.avg_rating),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
: c("", !0),
|
||||||
|
e.course.status != "Approved"
|
||||||
|
? (s(),
|
||||||
|
r("div", D, [
|
||||||
|
n(
|
||||||
|
a(k),
|
||||||
|
{
|
||||||
|
variant: "solid",
|
||||||
|
theme:
|
||||||
|
e.course.status ===
|
||||||
|
"Under Review"
|
||||||
|
? "orange"
|
||||||
|
: "blue",
|
||||||
|
size: "sm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: x(() => [
|
||||||
|
b(
|
||||||
|
t(
|
||||||
|
e.course
|
||||||
|
.status
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
},
|
||||||
|
8,
|
||||||
|
["theme"]
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
: c("", !0),
|
||||||
|
]),
|
||||||
|
o("div", E, t(e.course.title), 1),
|
||||||
|
o("div", F, t(e.course.short_introduction), 1),
|
||||||
|
a(u) && e.course.membership
|
||||||
|
? (s(),
|
||||||
|
r("div", I, [
|
||||||
|
o(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "bg-gray-900 h-1 rounded-full",
|
||||||
|
style: h({
|
||||||
|
width:
|
||||||
|
Math.ceil(
|
||||||
|
e.course
|
||||||
|
.membership
|
||||||
|
.progress
|
||||||
|
) + "%",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
4
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
: c("", !0),
|
||||||
|
a(u) && e.course.membership
|
||||||
|
? (s(),
|
||||||
|
r(
|
||||||
|
"div",
|
||||||
|
L,
|
||||||
|
t(
|
||||||
|
Math.ceil(
|
||||||
|
e.course.membership.progress
|
||||||
|
)
|
||||||
|
) + "% completed ",
|
||||||
|
1
|
||||||
|
))
|
||||||
|
: c("", !0),
|
||||||
|
o("div", M, [
|
||||||
|
o("div", O, [
|
||||||
|
o(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: m([
|
||||||
|
"mr-1",
|
||||||
|
{
|
||||||
|
"avatar-group overlap":
|
||||||
|
e.course.instructors
|
||||||
|
.length > 1,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
[
|
||||||
|
(s(!0),
|
||||||
|
r(
|
||||||
|
i,
|
||||||
|
null,
|
||||||
|
d(
|
||||||
|
e.course.instructors,
|
||||||
|
(l) => (
|
||||||
|
s(),
|
||||||
|
w(
|
||||||
|
f,
|
||||||
|
{ user: l },
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
["user"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
256
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
2
|
||||||
|
),
|
||||||
|
e.course.instructors.length == 1
|
||||||
|
? (s(),
|
||||||
|
r(
|
||||||
|
"span",
|
||||||
|
R,
|
||||||
|
t(
|
||||||
|
e.course.instructors[0]
|
||||||
|
.full_name
|
||||||
|
),
|
||||||
|
1
|
||||||
|
))
|
||||||
|
: c("", !0),
|
||||||
|
e.course.instructors.length == 2
|
||||||
|
? (s(),
|
||||||
|
r(
|
||||||
|
"span",
|
||||||
|
$,
|
||||||
|
t(
|
||||||
|
e.course.instructors[0]
|
||||||
|
.first_name
|
||||||
|
) +
|
||||||
|
" and " +
|
||||||
|
t(
|
||||||
|
e.course
|
||||||
|
.instructors[1]
|
||||||
|
.first_name
|
||||||
|
),
|
||||||
|
1
|
||||||
|
))
|
||||||
|
: c("", !0),
|
||||||
|
e.course.instructors.length > 2
|
||||||
|
? (s(),
|
||||||
|
r(
|
||||||
|
"span",
|
||||||
|
K,
|
||||||
|
t(
|
||||||
|
e.course.instructors[0]
|
||||||
|
.first_name
|
||||||
|
) +
|
||||||
|
" and " +
|
||||||
|
t(
|
||||||
|
e.course.instructors
|
||||||
|
.length - 1
|
||||||
|
) +
|
||||||
|
" others ",
|
||||||
|
1
|
||||||
|
))
|
||||||
|
: c("", !0),
|
||||||
|
]),
|
||||||
|
o("div", T, t(e.course.price), 1),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]))
|
||||||
|
: c("", !0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export { Q as _ };
|
||||||
1
lms/public/frontend/assets/CourseDetail.6888eccf.css
Normal file
1
lms/public/frontend/assets/CourseDetail.6888eccf.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.course-description p{margin-bottom:1rem;line-height:1.7}.course-description li{line-height:1.7}.course-description ol{list-style:auto;margin:revert;padding:revert}.avatar-group{display:inline-flex;align-items:center}.avatar-group .avatar{transition:margin .1s ease-in-out}
|
||||||
1046
lms/public/frontend/assets/CourseDetail.f6fd1d68.js
Normal file
1046
lms/public/frontend/assets/CourseDetail.f6fd1d68.js
Normal file
File diff suppressed because it is too large
Load Diff
1
lms/public/frontend/assets/CourseOutline.6dd858fb.css
Normal file
1
lms/public/frontend/assets/CourseOutline.6dd858fb.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.outline-lesson:has(.router-link-active){background-color:#f3f3f3;padding:.5rem 0 .5rem 2rem}
|
||||||
277
lms/public/frontend/assets/CourseOutline.df6c648a.js
Normal file
277
lms/public/frontend/assets/CourseOutline.df6c648a.js
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
import {
|
||||||
|
a8 as C,
|
||||||
|
k as b,
|
||||||
|
P as N,
|
||||||
|
s as e,
|
||||||
|
u as o,
|
||||||
|
A as r,
|
||||||
|
K as d,
|
||||||
|
L as h,
|
||||||
|
y as n,
|
||||||
|
z as c,
|
||||||
|
C as l,
|
||||||
|
D as t,
|
||||||
|
a9 as w,
|
||||||
|
B as M,
|
||||||
|
E as _,
|
||||||
|
aa as V,
|
||||||
|
F as z,
|
||||||
|
X as B,
|
||||||
|
ab as I,
|
||||||
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
|
import { c as i } from "./index.43e529db.js";
|
||||||
|
const L = i("ChevronRightIcon", [
|
||||||
|
["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }],
|
||||||
|
]),
|
||||||
|
F = i("FileTextIcon", [
|
||||||
|
[
|
||||||
|
"path",
|
||||||
|
{
|
||||||
|
d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z",
|
||||||
|
key: "1nnpy2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
["polyline", { points: "14 2 14 8 20 8", key: "1ew0cm" }],
|
||||||
|
["line", { x1: "16", x2: "8", y1: "13", y2: "13", key: "14keom" }],
|
||||||
|
["line", { x1: "16", x2: "8", y1: "17", y2: "17", key: "17nazh" }],
|
||||||
|
["line", { x1: "10", x2: "8", y1: "9", y2: "9", key: "1a5vjj" }],
|
||||||
|
]),
|
||||||
|
O = i("HelpCircleIcon", [
|
||||||
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
||||||
|
["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3", key: "1u773s" }],
|
||||||
|
["path", { d: "M12 17h.01", key: "p32p05" }],
|
||||||
|
]),
|
||||||
|
R = i("MonitorPlayIcon", [
|
||||||
|
["path", { d: "m10 7 5 3-5 3Z", key: "29ljg6" }],
|
||||||
|
[
|
||||||
|
"rect",
|
||||||
|
{
|
||||||
|
width: "20",
|
||||||
|
height: "14",
|
||||||
|
x: "2",
|
||||||
|
y: "3",
|
||||||
|
rx: "2",
|
||||||
|
key: "48i651",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
["path", { d: "M12 17v4", key: "1riwvh" }],
|
||||||
|
["path", { d: "M8 21h8", key: "1ev6f3" }],
|
||||||
|
]);
|
||||||
|
const j = { class: "course-outline text-base" },
|
||||||
|
q = { class: "mt-4" },
|
||||||
|
H = { class: "text-base" },
|
||||||
|
P = { class: "outline-lesson mb-2 pl-9" },
|
||||||
|
T = { class: "flex items-center text-sm" },
|
||||||
|
X = {
|
||||||
|
__name: "CourseOutline",
|
||||||
|
props: { courseName: { type: String, required: !0 } },
|
||||||
|
setup(m) {
|
||||||
|
const k = C(),
|
||||||
|
y = m,
|
||||||
|
x = b({
|
||||||
|
url: "lms.lms.utils.get_course_outline",
|
||||||
|
cache: ["course_outline", y.courseName],
|
||||||
|
params: { course: y.courseName },
|
||||||
|
auto: !0,
|
||||||
|
}),
|
||||||
|
v = (u) => u == k.params.chapterNumber || u == 1;
|
||||||
|
return (u, D) => {
|
||||||
|
const f = N("router-link");
|
||||||
|
return (
|
||||||
|
e(),
|
||||||
|
o("div", j, [
|
||||||
|
r("div", q, [
|
||||||
|
(e(!0),
|
||||||
|
o(
|
||||||
|
d,
|
||||||
|
null,
|
||||||
|
h(
|
||||||
|
t(x).data,
|
||||||
|
(a, g) => (
|
||||||
|
e(),
|
||||||
|
n(
|
||||||
|
t(I),
|
||||||
|
{
|
||||||
|
key: a.name,
|
||||||
|
defaultOpen: v(a.idx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: c(({ open: p }) => [
|
||||||
|
l(
|
||||||
|
t(w),
|
||||||
|
{
|
||||||
|
class: "flex w-full px-2 pt-2 pb-3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: c(() => [
|
||||||
|
l(
|
||||||
|
t(L),
|
||||||
|
{
|
||||||
|
class: M(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"rotate-90 transform duration-200":
|
||||||
|
p,
|
||||||
|
"duration-200":
|
||||||
|
!p,
|
||||||
|
open:
|
||||||
|
g ==
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
"h-5 w-5 text-gray-900 stroke-1 mr-2",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
["class"]
|
||||||
|
),
|
||||||
|
r(
|
||||||
|
"div",
|
||||||
|
H,
|
||||||
|
_(a.title),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1024
|
||||||
|
),
|
||||||
|
l(
|
||||||
|
t(V),
|
||||||
|
{ class: "pb-2" },
|
||||||
|
{
|
||||||
|
default: c(() => [
|
||||||
|
(e(!0),
|
||||||
|
o(
|
||||||
|
d,
|
||||||
|
null,
|
||||||
|
h(
|
||||||
|
a.lessons,
|
||||||
|
(s) => (
|
||||||
|
e(),
|
||||||
|
o(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
key: s.name,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
r(
|
||||||
|
"div",
|
||||||
|
P,
|
||||||
|
[
|
||||||
|
l(
|
||||||
|
f,
|
||||||
|
{
|
||||||
|
to: {
|
||||||
|
name: "Lesson",
|
||||||
|
params: {
|
||||||
|
courseName:
|
||||||
|
m.courseName,
|
||||||
|
chapterNumber:
|
||||||
|
s.number.split(
|
||||||
|
"."
|
||||||
|
)[0],
|
||||||
|
lessonNumber:
|
||||||
|
s.number.split(
|
||||||
|
"."
|
||||||
|
)[1],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
c(
|
||||||
|
() => [
|
||||||
|
r(
|
||||||
|
"div",
|
||||||
|
T,
|
||||||
|
[
|
||||||
|
s.icon ===
|
||||||
|
"icon-youtube"
|
||||||
|
? (e(),
|
||||||
|
n(
|
||||||
|
t(
|
||||||
|
R
|
||||||
|
),
|
||||||
|
{
|
||||||
|
key: 0,
|
||||||
|
class: "h-4 w-4 text-gray-900 stroke-1 mr-2",
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: s.icon ===
|
||||||
|
"icon-quiz"
|
||||||
|
? (e(),
|
||||||
|
n(
|
||||||
|
t(
|
||||||
|
O
|
||||||
|
),
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
class: "h-4 w-4 text-gray-900 stroke-1 mr-2",
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: s.icon ===
|
||||||
|
"icon-list"
|
||||||
|
? (e(),
|
||||||
|
n(
|
||||||
|
t(
|
||||||
|
F
|
||||||
|
),
|
||||||
|
{
|
||||||
|
key: 2,
|
||||||
|
class: "h-4 w-4 text-gray-900 stroke-1 mr-2",
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: z(
|
||||||
|
"",
|
||||||
|
!0
|
||||||
|
),
|
||||||
|
B(
|
||||||
|
" " +
|
||||||
|
_(
|
||||||
|
s.title
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
[
|
||||||
|
"to",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
128
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1024
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
["defaultOpen"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
128
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export { L as C, X as _ };
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
var N = Object.defineProperty,
|
|
||||||
S = Object.defineProperties;
|
|
||||||
var j = Object.getOwnPropertyDescriptors;
|
|
||||||
var h = Object.getOwnPropertySymbols;
|
|
||||||
var b = Object.prototype.hasOwnProperty,
|
|
||||||
w = Object.prototype.propertyIsEnumerable;
|
|
||||||
var p = (e, s, t) =>
|
|
||||||
s in e
|
|
||||||
? N(e, s, {
|
|
||||||
enumerable: !0,
|
|
||||||
configurable: !0,
|
|
||||||
writable: !0,
|
|
||||||
value: t,
|
|
||||||
})
|
|
||||||
: (e[s] = t),
|
|
||||||
m = (e, s) => {
|
|
||||||
for (var t in s || (s = {})) b.call(s, t) && p(e, t, s[t]);
|
|
||||||
if (h) for (var t of h(s)) w.call(s, t) && p(e, t, s[t]);
|
|
||||||
return e;
|
|
||||||
},
|
|
||||||
g = (e, s) => S(e, j(s));
|
|
||||||
var C = (e, s) => {
|
|
||||||
var t = {};
|
|
||||||
for (var a in e) b.call(e, a) && s.indexOf(a) < 0 && (t[a] = e[a]);
|
|
||||||
if (e != null && h)
|
|
||||||
for (var a of h(e)) s.indexOf(a) < 0 && w.call(e, a) && (t[a] = e[a]);
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
import {
|
|
||||||
l as $,
|
|
||||||
o,
|
|
||||||
d as c,
|
|
||||||
k as r,
|
|
||||||
F as v,
|
|
||||||
m as y,
|
|
||||||
t as l,
|
|
||||||
n as B,
|
|
||||||
p as z,
|
|
||||||
q as A,
|
|
||||||
e as n,
|
|
||||||
u,
|
|
||||||
v as O,
|
|
||||||
x as q,
|
|
||||||
y as U,
|
|
||||||
z as V,
|
|
||||||
} from "./frappe-ui.8966d601.js";
|
|
||||||
var _ = {
|
|
||||||
xmlns: "http://www.w3.org/2000/svg",
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
viewBox: "0 0 24 24",
|
|
||||||
fill: "none",
|
|
||||||
stroke: "currentColor",
|
|
||||||
"stroke-width": 2,
|
|
||||||
"stroke-linecap": "round",
|
|
||||||
"stroke-linejoin": "round",
|
|
||||||
};
|
|
||||||
const F = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(),
|
|
||||||
f =
|
|
||||||
(e, s) =>
|
|
||||||
(oe, { attrs: d, slots: x }) => {
|
|
||||||
var k = oe,
|
|
||||||
{
|
|
||||||
size: t,
|
|
||||||
strokeWidth: a = 2,
|
|
||||||
absoluteStrokeWidth: i,
|
|
||||||
color: M,
|
|
||||||
} = k,
|
|
||||||
I = C(k, [
|
|
||||||
"size",
|
|
||||||
"strokeWidth",
|
|
||||||
"absoluteStrokeWidth",
|
|
||||||
"color",
|
|
||||||
]);
|
|
||||||
return $(
|
|
||||||
"svg",
|
|
||||||
m(
|
|
||||||
g(
|
|
||||||
m(
|
|
||||||
g(m({}, _), {
|
|
||||||
width: t || _.width,
|
|
||||||
height: t || _.height,
|
|
||||||
stroke: M || _.stroke,
|
|
||||||
"stroke-width": i
|
|
||||||
? (Number(a) * 24) / Number(t)
|
|
||||||
: a,
|
|
||||||
}),
|
|
||||||
d
|
|
||||||
),
|
|
||||||
{
|
|
||||||
class: [
|
|
||||||
"lucide",
|
|
||||||
`lucide-${F(e)}`,
|
|
||||||
(d == null ? void 0 : d.class) || "",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
),
|
|
||||||
I
|
|
||||||
),
|
|
||||||
[...s.map((L) => $(...L)), ...(x.default ? [x.default()] : [])]
|
|
||||||
);
|
|
||||||
},
|
|
||||||
H = f("BookOpenIcon", [
|
|
||||||
[
|
|
||||||
"path",
|
|
||||||
{ d: "M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z", key: "vv98re" },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"path",
|
|
||||||
{ d: "M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z", key: "1cyq3y" },
|
|
||||||
],
|
|
||||||
]),
|
|
||||||
D = f("StarIcon", [
|
|
||||||
[
|
|
||||||
"polygon",
|
|
||||||
{
|
|
||||||
points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2",
|
|
||||||
key: "8f66p6",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
]),
|
|
||||||
E = f("UsersIcon", [
|
|
||||||
[
|
|
||||||
"path",
|
|
||||||
{ d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2", key: "1yyitq" },
|
|
||||||
],
|
|
||||||
["circle", { cx: "9", cy: "7", r: "4", key: "nufk8" }],
|
|
||||||
["path", { d: "M22 21v-2a4 4 0 0 0-3-3.87", key: "kshegd" }],
|
|
||||||
["path", { d: "M16 3.13a4 4 0 0 1 0 7.75", key: "1da9ce" }],
|
|
||||||
]);
|
|
||||||
const K = {
|
|
||||||
class: "flex flex-col h-full border border-gray-200 rounded-md shadow-sm mt-5",
|
|
||||||
},
|
|
||||||
P = { class: "flex relative top-4 left-4" },
|
|
||||||
R = { class: "course-card-pills rounded-md border border-gray-200" },
|
|
||||||
Z = { key: 0, class: "flex flex-1 text-4xl font-bold" },
|
|
||||||
G = { class: "p-4" },
|
|
||||||
J = { class: "flex text-base items-center justify-between" },
|
|
||||||
Q = { class: "flex items-center space-x-1 py-1" },
|
|
||||||
T = { class: "flex items-center space-x-1 py-1" },
|
|
||||||
X = { class: "flex items-center space-x-1 py-1" },
|
|
||||||
Y = { class: "text-2xl font-semibold" },
|
|
||||||
W = { class: "text-ellipsis truncate text-base" },
|
|
||||||
ee = {
|
|
||||||
__name: "CourseCard",
|
|
||||||
props: { course: { type: Object, default: null } },
|
|
||||||
setup(e) {
|
|
||||||
return (s, t) => (
|
|
||||||
o(),
|
|
||||||
c("div", K, [
|
|
||||||
r(
|
|
||||||
"div",
|
|
||||||
{
|
|
||||||
class: z([
|
|
||||||
"course-image",
|
|
||||||
{ "default-image": !e.course.image },
|
|
||||||
]),
|
|
||||||
style: A({
|
|
||||||
backgroundImage: "url(" + e.course.image + ")",
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[
|
|
||||||
r("div", P, [
|
|
||||||
(o(!0),
|
|
||||||
c(
|
|
||||||
v,
|
|
||||||
null,
|
|
||||||
y(
|
|
||||||
e.course.tags,
|
|
||||||
(a) => (o(), c("div", R, l(a), 1))
|
|
||||||
),
|
|
||||||
256
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
e.course.image
|
|
||||||
? B("", !0)
|
|
||||||
: (o(), c("div", Z, l(e.course.title[0]), 1)),
|
|
||||||
],
|
|
||||||
6
|
|
||||||
),
|
|
||||||
r("div", G, [
|
|
||||||
r("div", J, [
|
|
||||||
r("div", Q, [
|
|
||||||
n(u(H), { class: "h-4 w-4 text-gray-700" }),
|
|
||||||
r("span", null, l(e.course.lesson_count), 1),
|
|
||||||
]),
|
|
||||||
r("div", T, [
|
|
||||||
n(u(E), { class: "h-4 w-4 text-gray-700" }),
|
|
||||||
r(
|
|
||||||
"span",
|
|
||||||
null,
|
|
||||||
l(e.course.enrollment_count),
|
|
||||||
1
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
r("div", X, [
|
|
||||||
n(u(D), { class: "h-4 w-4 text-gray-700" }),
|
|
||||||
r("span", null, l(e.course.avg_rating), 1),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
r("div", Y, l(e.course.title), 1),
|
|
||||||
r("div", W, l(e.course.short_introduction), 1),
|
|
||||||
(o(!0),
|
|
||||||
c(
|
|
||||||
v,
|
|
||||||
null,
|
|
||||||
y(e.course.instructors, (a) => (o(), c("div"))),
|
|
||||||
256
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
se = {
|
|
||||||
__name: "UserAvatar",
|
|
||||||
props: { user: { type: Object, default: null } },
|
|
||||||
setup(e) {
|
|
||||||
return (s, t) =>
|
|
||||||
e.user
|
|
||||||
? (o(),
|
|
||||||
O(
|
|
||||||
u(U),
|
|
||||||
q(
|
|
||||||
{
|
|
||||||
key: 0,
|
|
||||||
class: "",
|
|
||||||
label: e.user.full_name,
|
|
||||||
image: e.user.user_image,
|
|
||||||
},
|
|
||||||
s.$attrs
|
|
||||||
),
|
|
||||||
null,
|
|
||||||
16,
|
|
||||||
["label", "image"]
|
|
||||||
))
|
|
||||||
: B("", !0);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
te = { class: "container" },
|
|
||||||
ae = r("div", { class: "text-2xl font-semibold" }, " All Courses ", -1),
|
|
||||||
re = { class: "grid grid-cols-3 gap-8" },
|
|
||||||
ne = {
|
|
||||||
__name: "Courses",
|
|
||||||
setup(e) {
|
|
||||||
const s = V({
|
|
||||||
type: "list",
|
|
||||||
doctype: "LMS Course",
|
|
||||||
url: "lms.lms.utils.get_courses",
|
|
||||||
auto: !0,
|
|
||||||
});
|
|
||||||
return (t, a) => (
|
|
||||||
o(),
|
|
||||||
c("div", te, [
|
|
||||||
ae,
|
|
||||||
r("div", re, [
|
|
||||||
(o(!0),
|
|
||||||
c(
|
|
||||||
v,
|
|
||||||
null,
|
|
||||||
y(
|
|
||||||
u(s).data,
|
|
||||||
(i) => (
|
|
||||||
o(),
|
|
||||||
c("div", null, [
|
|
||||||
n(ee, { course: i }, null, 8, [
|
|
||||||
"course",
|
|
||||||
]),
|
|
||||||
n(
|
|
||||||
se,
|
|
||||||
{ user: i.instructors[0] },
|
|
||||||
null,
|
|
||||||
8,
|
|
||||||
["user"]
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
),
|
|
||||||
256
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
export { ne as default };
|
|
||||||
433
lms/public/frontend/assets/Courses.3f5a0719.js
Normal file
433
lms/public/frontend/assets/Courses.3f5a0719.js
Normal file
@@ -0,0 +1,433 @@
|
|||||||
|
import {
|
||||||
|
a as k,
|
||||||
|
Y as w,
|
||||||
|
r as L,
|
||||||
|
j as o,
|
||||||
|
P as V,
|
||||||
|
s as n,
|
||||||
|
u as m,
|
||||||
|
D as c,
|
||||||
|
A as i,
|
||||||
|
C as d,
|
||||||
|
z as u,
|
||||||
|
X as h,
|
||||||
|
E as p,
|
||||||
|
B as y,
|
||||||
|
y as x,
|
||||||
|
J as $,
|
||||||
|
F as C,
|
||||||
|
K as B,
|
||||||
|
L as j,
|
||||||
|
Z as z,
|
||||||
|
$ as D,
|
||||||
|
a0 as E,
|
||||||
|
a1 as P,
|
||||||
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
|
import { _ as U } from "./CourseCard.6a41330a.js";
|
||||||
|
import { P as A } from "./plus.8f4bce9f.js";
|
||||||
|
import "./UserAvatar.b64a03ac.js";
|
||||||
|
import "./index.43e529db.js";
|
||||||
|
import "./star.d3e8ecca.js";
|
||||||
|
const F = { class: "h-screen" },
|
||||||
|
R = { key: 0 },
|
||||||
|
S = {
|
||||||
|
class: "sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5",
|
||||||
|
},
|
||||||
|
I = { class: "flex" },
|
||||||
|
J = { class: "mx-5 py-5" },
|
||||||
|
K = {
|
||||||
|
key: 0,
|
||||||
|
class: "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5",
|
||||||
|
},
|
||||||
|
M = {
|
||||||
|
key: 1,
|
||||||
|
class: "grid flex-1 place-items-center text-xl font-medium text-gray-500",
|
||||||
|
},
|
||||||
|
T = { class: "flex flex-col items-center justify-center mt-4" },
|
||||||
|
Q = {
|
||||||
|
__name: "Courses",
|
||||||
|
setup(X) {
|
||||||
|
var g, b, v;
|
||||||
|
const l = k("$user"),
|
||||||
|
a = w({
|
||||||
|
type: "list",
|
||||||
|
doctype: "LMS Course",
|
||||||
|
cache: [
|
||||||
|
"courses",
|
||||||
|
(g = l == null ? void 0 : l.data) == null
|
||||||
|
? void 0
|
||||||
|
: g.email,
|
||||||
|
],
|
||||||
|
url: "lms.lms.utils.get_courses",
|
||||||
|
auto: !0,
|
||||||
|
}),
|
||||||
|
f = L(0),
|
||||||
|
_ = [
|
||||||
|
{
|
||||||
|
label: "Live",
|
||||||
|
courses: o(() => {
|
||||||
|
var e;
|
||||||
|
return (
|
||||||
|
((e = a.data) == null ? void 0 : e.live) || []
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
count: o(() => {
|
||||||
|
var e, s;
|
||||||
|
return (s =
|
||||||
|
(e = a.data) == null ? void 0 : e.live) == null
|
||||||
|
? void 0
|
||||||
|
: s.length;
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Upcoming",
|
||||||
|
courses: o(() => {
|
||||||
|
var e;
|
||||||
|
return (e = a.data) == null ? void 0 : e.upcoming;
|
||||||
|
}),
|
||||||
|
count: o(() => {
|
||||||
|
var e, s;
|
||||||
|
return (s =
|
||||||
|
(e = a.data) == null ? void 0 : e.upcoming) ==
|
||||||
|
null
|
||||||
|
? void 0
|
||||||
|
: s.length;
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
l.data &&
|
||||||
|
(_.push({
|
||||||
|
label: "Enrolled",
|
||||||
|
courses: o(() => {
|
||||||
|
var e;
|
||||||
|
return (e = a.data) == null ? void 0 : e.enrolled;
|
||||||
|
}),
|
||||||
|
count: o(() => {
|
||||||
|
var e, s;
|
||||||
|
return (s =
|
||||||
|
(e = a.data) == null ? void 0 : e.enrolled) ==
|
||||||
|
null
|
||||||
|
? void 0
|
||||||
|
: s.length;
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
(l.data.is_moderator ||
|
||||||
|
l.data.is_instructor ||
|
||||||
|
((v = (b = a.data) == null ? void 0 : b.created) == null
|
||||||
|
? void 0
|
||||||
|
: v.length)) &&
|
||||||
|
_.push({
|
||||||
|
label: "Created",
|
||||||
|
courses: o(() => {
|
||||||
|
var e;
|
||||||
|
return (e = a.data) == null
|
||||||
|
? void 0
|
||||||
|
: e.created;
|
||||||
|
}),
|
||||||
|
count: o(() => {
|
||||||
|
var e, s;
|
||||||
|
return (s =
|
||||||
|
(e = a.data) == null
|
||||||
|
? void 0
|
||||||
|
: e.created) == null
|
||||||
|
? void 0
|
||||||
|
: s.length;
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
l.data.is_moderator &&
|
||||||
|
_.push({
|
||||||
|
label: "Under Review",
|
||||||
|
courses: o(() => {
|
||||||
|
var e;
|
||||||
|
return (e = a.data) == null
|
||||||
|
? void 0
|
||||||
|
: e.under_review;
|
||||||
|
}),
|
||||||
|
count: o(() => {
|
||||||
|
var e, s;
|
||||||
|
return (s =
|
||||||
|
(e = a.data) == null
|
||||||
|
? void 0
|
||||||
|
: e.under_review) == null
|
||||||
|
? void 0
|
||||||
|
: s.length;
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
(e, s) => {
|
||||||
|
const N = V("router-link");
|
||||||
|
return (
|
||||||
|
n(),
|
||||||
|
m("div", F, [
|
||||||
|
c(a).data
|
||||||
|
? (n(),
|
||||||
|
m("div", R, [
|
||||||
|
i("header", S, [
|
||||||
|
d(
|
||||||
|
c(z),
|
||||||
|
{
|
||||||
|
class: "h-7",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: e.__(
|
||||||
|
"All Courses"
|
||||||
|
),
|
||||||
|
route: {
|
||||||
|
name: "Courses",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
["items"]
|
||||||
|
),
|
||||||
|
i("div", I, [
|
||||||
|
d(
|
||||||
|
c(D),
|
||||||
|
{ variant: "solid" },
|
||||||
|
{
|
||||||
|
prefix: u(() => [
|
||||||
|
d(c(A), {
|
||||||
|
class: "h-4 w-4",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
default: u(() => [
|
||||||
|
h(
|
||||||
|
" " +
|
||||||
|
p(
|
||||||
|
e.__(
|
||||||
|
"New Course"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
i("div", J, [
|
||||||
|
d(
|
||||||
|
c(P),
|
||||||
|
{
|
||||||
|
class: "overflow-hidden",
|
||||||
|
modelValue: f.value,
|
||||||
|
"onUpdate:modelValue":
|
||||||
|
s[0] ||
|
||||||
|
(s[0] = (r) =>
|
||||||
|
(f.value = r)),
|
||||||
|
tabs: _,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tab: u(
|
||||||
|
({
|
||||||
|
tab: r,
|
||||||
|
selected: t,
|
||||||
|
}) => [
|
||||||
|
i("div", null, [
|
||||||
|
i(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: y(
|
||||||
|
[
|
||||||
|
"group -mb-px flex items-center gap-2 border-b border-transparent py-2.5 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900",
|
||||||
|
{
|
||||||
|
"text-gray-900":
|
||||||
|
t,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
},
|
||||||
|
[
|
||||||
|
r.icon
|
||||||
|
? (n(),
|
||||||
|
x(
|
||||||
|
$(
|
||||||
|
r.icon
|
||||||
|
),
|
||||||
|
{
|
||||||
|
key: 0,
|
||||||
|
class: "h-5",
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: C(
|
||||||
|
"",
|
||||||
|
!0
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
" " +
|
||||||
|
p(
|
||||||
|
e.__(
|
||||||
|
r.label
|
||||||
|
)
|
||||||
|
) +
|
||||||
|
" ",
|
||||||
|
1
|
||||||
|
),
|
||||||
|
d(
|
||||||
|
c(
|
||||||
|
E
|
||||||
|
),
|
||||||
|
{
|
||||||
|
class: y(
|
||||||
|
{
|
||||||
|
"text-gray-900 border border-gray-900":
|
||||||
|
t,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
variant:
|
||||||
|
"subtle",
|
||||||
|
theme: "gray",
|
||||||
|
size: "sm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
u(
|
||||||
|
() => [
|
||||||
|
h(
|
||||||
|
p(
|
||||||
|
r.count
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
[
|
||||||
|
"class",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
2
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
default: u(({ tab: r }) => [
|
||||||
|
r.courses &&
|
||||||
|
r.courses.value.length
|
||||||
|
? (n(),
|
||||||
|
m("div", K, [
|
||||||
|
(n(!0),
|
||||||
|
m(
|
||||||
|
B,
|
||||||
|
null,
|
||||||
|
j(
|
||||||
|
r
|
||||||
|
.courses
|
||||||
|
.value,
|
||||||
|
(
|
||||||
|
t
|
||||||
|
) => (
|
||||||
|
n(),
|
||||||
|
x(
|
||||||
|
N,
|
||||||
|
{
|
||||||
|
to:
|
||||||
|
t.membership &&
|
||||||
|
t.current_lesson
|
||||||
|
? {
|
||||||
|
name: "Lesson",
|
||||||
|
params: {
|
||||||
|
courseName:
|
||||||
|
t.name,
|
||||||
|
chapterNumber:
|
||||||
|
t.current_lesson.split(
|
||||||
|
"."
|
||||||
|
)[0],
|
||||||
|
lessonNumber:
|
||||||
|
t.current_lesson.split(
|
||||||
|
"."
|
||||||
|
)[1],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: t.membership
|
||||||
|
? {
|
||||||
|
name: "Lesson",
|
||||||
|
params: {
|
||||||
|
courseName:
|
||||||
|
t.name,
|
||||||
|
chapterNumber: 1,
|
||||||
|
lessonNumber: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
name: "CourseDetail",
|
||||||
|
params: {
|
||||||
|
courseName:
|
||||||
|
t.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
u(
|
||||||
|
() => [
|
||||||
|
d(
|
||||||
|
U,
|
||||||
|
{
|
||||||
|
course: t,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
"course",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
_: 2,
|
||||||
|
},
|
||||||
|
1032,
|
||||||
|
[
|
||||||
|
"to",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
256
|
||||||
|
)),
|
||||||
|
]))
|
||||||
|
: (n(),
|
||||||
|
m("div", M, [
|
||||||
|
i(
|
||||||
|
"div",
|
||||||
|
T,
|
||||||
|
[
|
||||||
|
i(
|
||||||
|
"div",
|
||||||
|
null,
|
||||||
|
p(
|
||||||
|
e
|
||||||
|
.__(
|
||||||
|
"No {0} courses found"
|
||||||
|
)
|
||||||
|
.format(
|
||||||
|
r.label.toLowerCase()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
])),
|
||||||
|
]),
|
||||||
|
_: 1,
|
||||||
|
},
|
||||||
|
8,
|
||||||
|
["modelValue"]
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
]))
|
||||||
|
: C("", !0),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export { Q as default };
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
import {
|
import {
|
||||||
b as f,
|
q as f,
|
||||||
P as g,
|
ai as g,
|
||||||
T as _,
|
T as _,
|
||||||
r as d,
|
P as c,
|
||||||
o,
|
s as o,
|
||||||
v as l,
|
y as l,
|
||||||
w as r,
|
z as r,
|
||||||
A as p,
|
I as p,
|
||||||
B as C,
|
aj as C,
|
||||||
C as k,
|
ak as k,
|
||||||
k as a,
|
A as a,
|
||||||
d as c,
|
u as d,
|
||||||
F as u,
|
K as u,
|
||||||
m,
|
L as m,
|
||||||
q as h,
|
a2 as h,
|
||||||
p as b,
|
B as b,
|
||||||
} from "./frappe-ui.8966d601.js";
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
const v = {
|
const v = {
|
||||||
name: "FontColor",
|
name: "FontColor",
|
||||||
props: ["editor"],
|
props: ["editor"],
|
||||||
@@ -67,17 +67,17 @@ const v = {
|
|||||||
B = a("div", { class: "text-sm text-gray-700" }, "Text Color", -1),
|
B = a("div", { class: "text-sm text-gray-700" }, "Text Color", -1),
|
||||||
P = { class: "mt-1 grid grid-cols-8 gap-1" },
|
P = { class: "mt-1 grid grid-cols-8 gap-1" },
|
||||||
F = ["aria-label", "onClick"],
|
F = ["aria-label", "onClick"],
|
||||||
w = a(
|
D = a(
|
||||||
"div",
|
"div",
|
||||||
{ class: "mt-2 text-sm text-gray-700" },
|
{ class: "mt-2 text-sm text-gray-700" },
|
||||||
"Background Color",
|
"Background Color",
|
||||||
-1
|
-1
|
||||||
),
|
),
|
||||||
D = { class: "mt-1 grid grid-cols-8 gap-1" },
|
w = { class: "mt-1 grid grid-cols-8 gap-1" },
|
||||||
T = ["aria-label", "onClick"];
|
T = ["aria-label", "onClick"];
|
||||||
function A(t, z, E, R, $, n) {
|
function z(t, A, j, E, R, n) {
|
||||||
const i = d("Tooltip"),
|
const i = c("Tooltip"),
|
||||||
x = d("Popover");
|
x = c("Popover");
|
||||||
return (
|
return (
|
||||||
o(),
|
o(),
|
||||||
l(
|
l(
|
||||||
@@ -96,7 +96,7 @@ function A(t, z, E, R, $, n) {
|
|||||||
B,
|
B,
|
||||||
a("div", P, [
|
a("div", P, [
|
||||||
(o(!0),
|
(o(!0),
|
||||||
c(
|
d(
|
||||||
u,
|
u,
|
||||||
null,
|
null,
|
||||||
m(
|
m(
|
||||||
@@ -141,10 +141,10 @@ function A(t, z, E, R, $, n) {
|
|||||||
128
|
128
|
||||||
)),
|
)),
|
||||||
]),
|
]),
|
||||||
w,
|
D,
|
||||||
a("div", D, [
|
a("div", w, [
|
||||||
(o(!0),
|
(o(!0),
|
||||||
c(
|
d(
|
||||||
u,
|
u,
|
||||||
null,
|
null,
|
||||||
m(
|
m(
|
||||||
@@ -202,5 +202,5 @@ function A(t, z, E, R, $, n) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const G = f(v, [["render", A]]);
|
const G = f(v, [["render", z]]);
|
||||||
export { G as default };
|
export { G as default };
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
import {
|
import {
|
||||||
b as d,
|
q as d,
|
||||||
D as g,
|
O as g,
|
||||||
r,
|
P as r,
|
||||||
o as m,
|
s as m,
|
||||||
d as f,
|
u as f,
|
||||||
e as t,
|
C as s,
|
||||||
w as s,
|
z as t,
|
||||||
j as l,
|
X as l,
|
||||||
k as p,
|
A as u,
|
||||||
t as u,
|
E as p,
|
||||||
} from "./frappe-ui.8966d601.js";
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
const D = {
|
const D = {
|
||||||
name: "Home",
|
name: "Home",
|
||||||
data() {
|
data() {
|
||||||
@@ -19,13 +19,13 @@ const D = {
|
|||||||
components: { Dialog: g },
|
components: { Dialog: g },
|
||||||
},
|
},
|
||||||
_ = { class: "max-w-3xl py-12 mx-auto" };
|
_ = { class: "max-w-3xl py-12 mx-auto" };
|
||||||
function k(e, o, w, C, n, V) {
|
function C(e, o, k, w, n, V) {
|
||||||
const a = r("Button"),
|
const a = r("Button"),
|
||||||
c = r("Dialog");
|
c = r("Dialog");
|
||||||
return (
|
return (
|
||||||
m(),
|
m(),
|
||||||
f("div", _, [
|
f("div", _, [
|
||||||
t(
|
s(
|
||||||
a,
|
a,
|
||||||
{
|
{
|
||||||
"icon-left": "code",
|
"icon-left": "code",
|
||||||
@@ -33,20 +33,20 @@ function k(e, o, w, C, n, V) {
|
|||||||
loading: e.$resources.ping.loading,
|
loading: e.$resources.ping.loading,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
default: s(() => [l(" Click to send 'ping' request ")]),
|
default: t(() => [l(" Click to send 'ping' request ")]),
|
||||||
_: 1,
|
_: 1,
|
||||||
},
|
},
|
||||||
8,
|
8,
|
||||||
["onClick", "loading"]
|
["onClick", "loading"]
|
||||||
),
|
),
|
||||||
p("div", null, u(e.$resources.ping.data), 1),
|
u("div", null, p(e.$resources.ping.data), 1),
|
||||||
p("pre", null, u(e.$resources.ping), 1),
|
u("pre", null, p(e.$resources.ping), 1),
|
||||||
t(
|
s(
|
||||||
a,
|
a,
|
||||||
{ onClick: o[0] || (o[0] = (i) => (n.showDialog = !0)) },
|
{ onClick: o[0] || (o[0] = (i) => (n.showDialog = !0)) },
|
||||||
{ default: s(() => [l("Open Dialog")]), _: 1 }
|
{ default: t(() => [l("Open Dialog")]), _: 1 }
|
||||||
),
|
),
|
||||||
t(
|
s(
|
||||||
c,
|
c,
|
||||||
{
|
{
|
||||||
title: "Title",
|
title: "Title",
|
||||||
@@ -54,12 +54,12 @@ function k(e, o, w, C, n, V) {
|
|||||||
"onUpdate:modelValue":
|
"onUpdate:modelValue":
|
||||||
o[1] || (o[1] = (i) => (n.showDialog = i)),
|
o[1] || (o[1] = (i) => (n.showDialog = i)),
|
||||||
},
|
},
|
||||||
{ default: s(() => [l(" Dialog content ")]), _: 1 },
|
{ default: t(() => [l(" Dialog content ")]), _: 1 },
|
||||||
8,
|
8,
|
||||||
["modelValue"]
|
["modelValue"]
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const B = d(D, [["render", k]]);
|
const B = d(D, [["render", C]]);
|
||||||
export { B as default };
|
export { B as default };
|
||||||
@@ -1,30 +1,30 @@
|
|||||||
import {
|
import {
|
||||||
b as f,
|
q as I,
|
||||||
h as I,
|
$ as f,
|
||||||
D,
|
O as D,
|
||||||
G as h,
|
an as h,
|
||||||
r as d,
|
P as d,
|
||||||
o as m,
|
s as m,
|
||||||
d as c,
|
u as c,
|
||||||
A as _,
|
I as _,
|
||||||
B as y,
|
aj as y,
|
||||||
C,
|
ak as C,
|
||||||
e as n,
|
C as n,
|
||||||
w as s,
|
z as s,
|
||||||
k as r,
|
A as i,
|
||||||
t as w,
|
E as k,
|
||||||
n as b,
|
F as v,
|
||||||
j as u,
|
X as u,
|
||||||
F as k,
|
K as w,
|
||||||
} from "./frappe-ui.8966d601.js";
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
const v = {
|
const b = {
|
||||||
name: "InsertImage",
|
name: "InsertImage",
|
||||||
props: ["editor"],
|
props: ["editor"],
|
||||||
expose: ["openDialog"],
|
expose: ["openDialog"],
|
||||||
data() {
|
data() {
|
||||||
return { addImageDialog: { url: "", file: null, show: !1 } };
|
return { addImageDialog: { url: "", file: null, show: !1 } };
|
||||||
},
|
},
|
||||||
components: { Button: I, Dialog: D },
|
components: { Button: f, Dialog: D },
|
||||||
methods: {
|
methods: {
|
||||||
openDialog() {
|
openDialog() {
|
||||||
this.addImageDialog.show = !0;
|
this.addImageDialog.show = !0;
|
||||||
@@ -33,8 +33,8 @@ const v = {
|
|||||||
let e = t.target.files[0];
|
let e = t.target.files[0];
|
||||||
!e ||
|
!e ||
|
||||||
((this.addImageDialog.file = e),
|
((this.addImageDialog.file = e),
|
||||||
h(e).then((i) => {
|
h(e).then((r) => {
|
||||||
this.addImageDialog.url = i;
|
this.addImageDialog.url = r;
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
addImage(t) {
|
addImage(t) {
|
||||||
@@ -46,18 +46,18 @@ const v = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
B = {
|
x = {
|
||||||
class: "relative cursor-pointer rounded-lg bg-gray-100 py-1 focus-within:bg-gray-200 hover:bg-gray-200",
|
class: "relative cursor-pointer rounded-lg bg-gray-100 py-1 focus-within:bg-gray-200 hover:bg-gray-200",
|
||||||
},
|
},
|
||||||
x = { class: "absolute inset-0 select-none px-2 py-1 text-base" },
|
B = { class: "absolute inset-0 select-none px-2 py-1 text-base" },
|
||||||
S = ["src"];
|
S = ["src"];
|
||||||
function V(t, e, i, A, a, o) {
|
function V(t, e, r, A, a, o) {
|
||||||
const g = d("Button"),
|
const g = d("Button"),
|
||||||
p = d("Dialog");
|
p = d("Dialog");
|
||||||
return (
|
return (
|
||||||
m(),
|
m(),
|
||||||
c(
|
c(
|
||||||
k,
|
w,
|
||||||
null,
|
null,
|
||||||
[
|
[
|
||||||
_(t.$slots, "default", y(C({ onClick: o.openDialog }))),
|
_(t.$slots, "default", y(C({ onClick: o.openDialog }))),
|
||||||
@@ -72,8 +72,8 @@ function V(t, e, i, A, a, o) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"body-content": s(() => [
|
"body-content": s(() => [
|
||||||
r("label", B, [
|
i("label", x, [
|
||||||
r(
|
i(
|
||||||
"input",
|
"input",
|
||||||
{
|
{
|
||||||
type: "file",
|
type: "file",
|
||||||
@@ -88,10 +88,10 @@ function V(t, e, i, A, a, o) {
|
|||||||
null,
|
null,
|
||||||
32
|
32
|
||||||
),
|
),
|
||||||
r(
|
i(
|
||||||
"span",
|
"span",
|
||||||
x,
|
B,
|
||||||
w(
|
k(
|
||||||
a.addImageDialog.file
|
a.addImageDialog.file
|
||||||
? "Select another image"
|
? "Select another image"
|
||||||
: "Select an image"
|
: "Select an image"
|
||||||
@@ -112,7 +112,7 @@ function V(t, e, i, A, a, o) {
|
|||||||
8,
|
8,
|
||||||
S
|
S
|
||||||
))
|
))
|
||||||
: b("", !0),
|
: v("", !0),
|
||||||
]),
|
]),
|
||||||
actions: s(() => [
|
actions: s(() => [
|
||||||
n(
|
n(
|
||||||
@@ -147,5 +147,5 @@ function V(t, e, i, A, a, o) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const F = f(v, [["render", V]]);
|
const P = I(b, [["render", V]]);
|
||||||
export { F as default };
|
export { P as default };
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
import {
|
import {
|
||||||
b as d,
|
q as d,
|
||||||
h as g,
|
$ as g,
|
||||||
I as L,
|
al as L,
|
||||||
D as m,
|
O as m,
|
||||||
r as i,
|
P as i,
|
||||||
o as p,
|
s as p,
|
||||||
d as f,
|
u as f,
|
||||||
A as D,
|
I as D,
|
||||||
B as h,
|
aj as c,
|
||||||
C as c,
|
ak as h,
|
||||||
e as l,
|
C as l,
|
||||||
w as a,
|
z as a,
|
||||||
E as w,
|
am as _,
|
||||||
j as _,
|
X as v,
|
||||||
F as v,
|
K as w,
|
||||||
} from "./frappe-ui.8966d601.js";
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
const x = {
|
const x = {
|
||||||
name: "InsertLink",
|
name: "InsertLink",
|
||||||
props: ["editor"],
|
props: ["editor"],
|
||||||
@@ -56,10 +56,10 @@ function V(t, e, C, B, n, s) {
|
|||||||
return (
|
return (
|
||||||
p(),
|
p(),
|
||||||
f(
|
f(
|
||||||
v,
|
w,
|
||||||
null,
|
null,
|
||||||
[
|
[
|
||||||
D(t.$slots, "default", h(c({ onClick: s.openDialog }))),
|
D(t.$slots, "default", c(h({ onClick: s.openDialog }))),
|
||||||
l(
|
l(
|
||||||
k,
|
k,
|
||||||
{
|
{
|
||||||
@@ -83,7 +83,7 @@ function V(t, e, C, B, n, s) {
|
|||||||
(n.setLinkDialog.url = o)),
|
(n.setLinkDialog.url = o)),
|
||||||
onKeydown:
|
onKeydown:
|
||||||
e[1] ||
|
e[1] ||
|
||||||
(e[1] = w(
|
(e[1] = _(
|
||||||
(o) => s.setLink(o.target.value),
|
(o) => s.setLink(o.target.value),
|
||||||
["enter"]
|
["enter"]
|
||||||
)),
|
)),
|
||||||
@@ -103,7 +103,7 @@ function V(t, e, C, B, n, s) {
|
|||||||
(e[2] = (o) =>
|
(e[2] = (o) =>
|
||||||
s.setLink(n.setLinkDialog.url)),
|
s.setLink(n.setLinkDialog.url)),
|
||||||
},
|
},
|
||||||
{ default: a(() => [_(" Save ")]), _: 1 }
|
{ default: a(() => [v(" Save ")]), _: 1 }
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
_: 1,
|
_: 1,
|
||||||
@@ -116,5 +116,5 @@ function V(t, e, C, B, n, s) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const b = d(x, [["render", V]]);
|
const y = d(x, [["render", V]]);
|
||||||
export { b as default };
|
export { y as default };
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
import {
|
import {
|
||||||
b as _,
|
q as _,
|
||||||
h as C,
|
$ as C,
|
||||||
D as k,
|
O as k,
|
||||||
H as v,
|
ao as v,
|
||||||
r,
|
P as r,
|
||||||
o as u,
|
s as u,
|
||||||
d as c,
|
u as c,
|
||||||
A as h,
|
I as h,
|
||||||
B,
|
aj as x,
|
||||||
C as w,
|
ak as y,
|
||||||
e as t,
|
C as a,
|
||||||
w as l,
|
z as l,
|
||||||
k as x,
|
A as B,
|
||||||
j as n,
|
X as n,
|
||||||
t as y,
|
E as w,
|
||||||
v as U,
|
y as U,
|
||||||
n as p,
|
F as p,
|
||||||
F,
|
K as F,
|
||||||
} from "./frappe-ui.8966d601.js";
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
const A = {
|
const I = {
|
||||||
name: "InsertImage",
|
name: "InsertImage",
|
||||||
props: ["editor"],
|
props: ["editor"],
|
||||||
expose: ["openDialog"],
|
expose: ["openDialog"],
|
||||||
@@ -47,9 +47,9 @@ const A = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
I = { class: "flex items-center space-x-2" },
|
A = { class: "flex items-center space-x-2" },
|
||||||
N = ["src"];
|
N = ["src"];
|
||||||
function S(i, o, b, L, e, a) {
|
function S(i, o, P, z, e, t) {
|
||||||
const s = r("Button"),
|
const s = r("Button"),
|
||||||
V = r("FileUploader"),
|
V = r("FileUploader"),
|
||||||
g = r("Dialog");
|
g = r("Dialog");
|
||||||
@@ -59,19 +59,19 @@ function S(i, o, b, L, e, a) {
|
|||||||
F,
|
F,
|
||||||
null,
|
null,
|
||||||
[
|
[
|
||||||
h(i.$slots, "default", B(w({ onClick: a.openDialog }))),
|
h(i.$slots, "default", x(y({ onClick: t.openDialog }))),
|
||||||
t(
|
a(
|
||||||
g,
|
g,
|
||||||
{
|
{
|
||||||
options: { title: "Add Video" },
|
options: { title: "Add Video" },
|
||||||
modelValue: e.addVideoDialog.show,
|
modelValue: e.addVideoDialog.show,
|
||||||
"onUpdate:modelValue":
|
"onUpdate:modelValue":
|
||||||
o[2] || (o[2] = (d) => (e.addVideoDialog.show = d)),
|
o[2] || (o[2] = (d) => (e.addVideoDialog.show = d)),
|
||||||
onAfterLeave: a.reset,
|
onAfterLeave: t.reset,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"body-content": l(() => [
|
"body-content": l(() => [
|
||||||
t(
|
a(
|
||||||
V,
|
V,
|
||||||
{
|
{
|
||||||
"file-types": "video/*",
|
"file-types": "video/*",
|
||||||
@@ -89,14 +89,14 @@ function S(i, o, b, L, e, a) {
|
|||||||
uploading: m,
|
uploading: m,
|
||||||
openFileSelector: D,
|
openFileSelector: D,
|
||||||
}) => [
|
}) => [
|
||||||
x("div", I, [
|
B("div", A, [
|
||||||
t(
|
a(
|
||||||
s,
|
s,
|
||||||
{ onClick: D },
|
{ onClick: D },
|
||||||
{
|
{
|
||||||
default: l(() => [
|
default: l(() => [
|
||||||
n(
|
n(
|
||||||
y(
|
w(
|
||||||
m
|
m
|
||||||
? `Uploading ${f}%`
|
? `Uploading ${f}%`
|
||||||
: e
|
: e
|
||||||
@@ -164,23 +164,23 @@ function S(i, o, b, L, e, a) {
|
|||||||
: p("", !0),
|
: p("", !0),
|
||||||
]),
|
]),
|
||||||
actions: l(() => [
|
actions: l(() => [
|
||||||
t(
|
a(
|
||||||
s,
|
s,
|
||||||
{
|
{
|
||||||
variant: "solid",
|
variant: "solid",
|
||||||
onClick:
|
onClick:
|
||||||
o[1] ||
|
o[1] ||
|
||||||
(o[1] = (d) =>
|
(o[1] = (d) =>
|
||||||
a.addVideo(e.addVideoDialog.url)),
|
t.addVideo(e.addVideoDialog.url)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
default: l(() => [n(" Insert Video ")]),
|
default: l(() => [n(" Insert Video ")]),
|
||||||
_: 1,
|
_: 1,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
t(
|
a(
|
||||||
s,
|
s,
|
||||||
{ onClick: a.reset },
|
{ onClick: t.reset },
|
||||||
{ default: l(() => [n("Cancel")]), _: 1 },
|
{ default: l(() => [n("Cancel")]), _: 1 },
|
||||||
8,
|
8,
|
||||||
["onClick"]
|
["onClick"]
|
||||||
@@ -196,5 +196,5 @@ function S(i, o, b, L, e, a) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const R = _(A, [["render", S]]);
|
const L = _(I, [["render", S]]);
|
||||||
export { R as default };
|
export { L as default };
|
||||||
1
lms/public/frontend/assets/Lesson.3532a62c.css
Normal file
1
lms/public/frontend/assets/Lesson.3532a62c.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.avatar-group{display:inline-flex;align-items:center}.avatar-group .avatar{transition:margin .1s ease-in-out}iframe{border:1px solid #ddd;border-radius:.5rem;margin-bottom:1rem}.lesson-content p{margin-bottom:1rem;line-height:1.7}.lesson-content li{line-height:1.7}.lesson-content ol{list-style:auto;margin:revert;padding:1rem}.lesson-content ul{list-style:auto;padding:1rem;margin:revert}.lesson-content img{border:1px solid #EDEDED;border-radius:.5rem}.lesson-content code{display:block;overflow-x:auto;padding:1rem 1.25rem;background:#011627;color:#d6deeb;border-radius:.5rem;margin-bottom:1rem}.lesson-content a{color:#171717;text-decoration:underline;font-weight:500}
|
||||||
5877
lms/public/frontend/assets/Lesson.c80fc3b7.js
Normal file
5877
lms/public/frontend/assets/Lesson.c80fc3b7.js
Normal file
File diff suppressed because one or more lines are too long
35
lms/public/frontend/assets/UserAvatar.b64a03ac.js
Normal file
35
lms/public/frontend/assets/UserAvatar.b64a03ac.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import {
|
||||||
|
s as r,
|
||||||
|
y as s,
|
||||||
|
a3 as t,
|
||||||
|
D as l,
|
||||||
|
a4 as u,
|
||||||
|
F as n,
|
||||||
|
} from "./frappe-ui.f2211ca2.js";
|
||||||
|
const i = {
|
||||||
|
__name: "UserAvatar",
|
||||||
|
props: { user: { type: Object, default: null }, size: { type: String } },
|
||||||
|
setup(e) {
|
||||||
|
return (a, m) =>
|
||||||
|
e.user
|
||||||
|
? (r(),
|
||||||
|
s(
|
||||||
|
l(u),
|
||||||
|
t(
|
||||||
|
{
|
||||||
|
key: 0,
|
||||||
|
class: "avatar border border-gray-300",
|
||||||
|
label: e.user.full_name,
|
||||||
|
image: e.user.user_image,
|
||||||
|
size: e.size,
|
||||||
|
},
|
||||||
|
a.$attrs
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
16,
|
||||||
|
["label", "image", "size"]
|
||||||
|
))
|
||||||
|
: n("", !0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export { i as _ };
|
||||||
23
lms/public/frontend/assets/clock.4d13ba48.js
Normal file
23
lms/public/frontend/assets/clock.4d13ba48.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { c as e } from "./index.43e529db.js";
|
||||||
|
const c = e("CalendarIcon", [
|
||||||
|
[
|
||||||
|
"rect",
|
||||||
|
{
|
||||||
|
width: "18",
|
||||||
|
height: "18",
|
||||||
|
x: "3",
|
||||||
|
y: "4",
|
||||||
|
rx: "2",
|
||||||
|
ry: "2",
|
||||||
|
key: "eu3xkr",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
["line", { x1: "16", x2: "16", y1: "2", y2: "6", key: "m3sa8f" }],
|
||||||
|
["line", { x1: "8", x2: "8", y1: "2", y2: "6", key: "18kwsl" }],
|
||||||
|
["line", { x1: "3", x2: "21", y1: "10", y2: "10", key: "xt86sb" }],
|
||||||
|
]),
|
||||||
|
l = e("ClockIcon", [
|
||||||
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
||||||
|
["polyline", { points: "12 6 12 12 16 14", key: "68esgv" }],
|
||||||
|
]);
|
||||||
|
export { c as C, l as a };
|
||||||
@@ -1 +1 @@
|
|||||||
.form-select{background-image:url("data:image/svg+xml;utf8,<svg fill='none' width='8' xmlns='http://www.w3.org/2000/svg' viewBox='-4 -2 16 16'><path d='M4.5 3.636 6.136 2l1.637 1.636M4.5 8.364 6.136 10l1.637-1.636' stroke='%23333C44' stroke-linecap='round' stroke-linejoin='round'/></svg>")}.spinner[data-v-10b50c78]{animation:rotate-10b50c78 2s linear infinite}.spinner-path[data-v-10b50c78]{stroke-linecap:round;animation:dash-10b50c78 1.5s ease-in-out infinite}@keyframes rotate-10b50c78{to{transform:rotate(360deg)}}@keyframes dash-10b50c78{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:120,150;stroke-dashoffset:-124}}.item{display:block;margin:0;width:100%;text-align:left;background:transparent;border-radius:.4rem;border:1px solid transparent;padding:.2rem .4rem}.item.is-selected{border-color:#000}.ProseMirror{outline:none;caret-color:#171717;word-break:break-word}.ProseMirror-focused:focus-visible{outline:none}.ProseMirror:not(.ProseMirror-focused) p.is-editor-empty:first-child:before{content:attr(data-placeholder);float:left;color:#999;pointer-events:none;height:0}.ProseMirror-selectednode video,img.ProseMirror-selectednode{outline:2px solid #E2E2E2}.mention{font-weight:600;-webkit-box-decoration-break:clone;box-decoration-break:clone}.prose table p{margin:0}.ProseMirror table .selectedCell:after{z-index:2;position:absolute;content:"";inset:0;pointer-events:none;background:#E3F1FD;opacity:.3}.ProseMirror table .column-resize-handle{position:absolute;right:-1px;top:0;bottom:-2px;width:4px;background-color:#e3f1fd;pointer-events:none}.resize-cursor{cursor:ew-resize;cursor:col-resize}.ProseMirror mark{border-radius:3px;padding:0 2px}
|
.form-select{background-image:url("data:image/svg+xml;utf8,<svg fill='none' width='8' xmlns='http://www.w3.org/2000/svg' viewBox='-4 -2 16 16'><path d='M4.5 3.636 6.136 2l1.637 1.636M4.5 8.364 6.136 10l1.637-1.636' stroke='%23333C44' stroke-linecap='round' stroke-linejoin='round'/></svg>")}.spinner[data-v-d1174afc]{animation:rotate-d1174afc 2s linear infinite}.spinner-path[data-v-d1174afc]{stroke-linecap:round;animation:dash-d1174afc 1.5s ease-in-out infinite}@keyframes rotate-d1174afc{to{transform:rotate(360deg)}}@keyframes dash-d1174afc{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:120,150;stroke-dashoffset:-124}}.item{display:block;margin:0;width:100%;text-align:left;background:transparent;border-radius:.4rem;border:1px solid transparent;padding:.2rem .4rem}.item.is-selected{border-color:#000}.ProseMirror{outline:none;caret-color:#171717;word-break:break-word}.ProseMirror-focused:focus-visible{outline:none}.ProseMirror:not(.ProseMirror-focused) p.is-editor-empty:first-child:before{content:attr(data-placeholder);float:left;color:#999;pointer-events:none;height:0}.ProseMirror-selectednode video,img.ProseMirror-selectednode{outline:2px solid #E2E2E2}.mention{font-weight:600;-webkit-box-decoration-break:clone;box-decoration-break:clone}.prose table p{margin:0}.ProseMirror table .selectedCell:after{z-index:2;position:absolute;content:"";inset:0;pointer-events:none;background:#E3F1FD;opacity:.3}.ProseMirror table .column-resize-handle{position:absolute;right:-1px;top:0;bottom:-2px;width:4px;background-color:#e3f1fd;pointer-events:none}.resize-cursor{cursor:ew-resize;cursor:col-resize}.ProseMirror mark{border-radius:3px;padding:0 2px}
|
||||||
File diff suppressed because it is too large
Load Diff
45
lms/public/frontend/assets/index.05189aed.js
Normal file
45
lms/public/frontend/assets/index.05189aed.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
var u = Object.defineProperty;
|
||||||
|
var o = Object.getOwnPropertySymbols;
|
||||||
|
var i = Object.prototype.hasOwnProperty,
|
||||||
|
c = Object.prototype.propertyIsEnumerable;
|
||||||
|
var n = (t, e, r) =>
|
||||||
|
e in t
|
||||||
|
? u(t, e, {
|
||||||
|
enumerable: !0,
|
||||||
|
configurable: !0,
|
||||||
|
writable: !0,
|
||||||
|
value: r,
|
||||||
|
})
|
||||||
|
: (t[e] = r),
|
||||||
|
a = (t, e) => {
|
||||||
|
for (var r in e || (e = {})) i.call(e, r) && n(t, r, e[r]);
|
||||||
|
if (o) for (var r of o(e)) c.call(e, r) && n(t, r, e[r]);
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
import { ac as s, ad as f } from "./frappe-ui.f2211ca2.js";
|
||||||
|
function y(t) {
|
||||||
|
s(a({ position: "bottom-right" }, t));
|
||||||
|
}
|
||||||
|
function d(t) {
|
||||||
|
return f(t).value;
|
||||||
|
}
|
||||||
|
function g(t) {
|
||||||
|
if (!t) return "";
|
||||||
|
const [e, r] = t.split(":").map(Number),
|
||||||
|
m = new Date(0, 0, 0, e, r);
|
||||||
|
return new Intl.DateTimeFormat("en-US", {
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
hour12: !0,
|
||||||
|
}).format(m);
|
||||||
|
}
|
||||||
|
function h(t, e) {
|
||||||
|
return t
|
||||||
|
? t.toLocaleString("en-IN", {
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
style: "currency",
|
||||||
|
currency: e,
|
||||||
|
})
|
||||||
|
: "";
|
||||||
|
}
|
||||||
|
export { h as a, y as c, g as f, d as t };
|
||||||
1790
lms/public/frontend/assets/index.43e529db.js
Normal file
1790
lms/public/frontend/assets/index.43e529db.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,88 +0,0 @@
|
|||||||
import {
|
|
||||||
c as u,
|
|
||||||
a as l,
|
|
||||||
_ as i,
|
|
||||||
b as f,
|
|
||||||
r as p,
|
|
||||||
o as d,
|
|
||||||
d as m,
|
|
||||||
e as _,
|
|
||||||
f as h,
|
|
||||||
g as y,
|
|
||||||
h as g,
|
|
||||||
s as v,
|
|
||||||
i as L,
|
|
||||||
} from "./frappe-ui.8966d601.js";
|
|
||||||
(function () {
|
|
||||||
const o = document.createElement("link").relList;
|
|
||||||
if (o && o.supports && o.supports("modulepreload")) return;
|
|
||||||
for (const e of document.querySelectorAll('link[rel="modulepreload"]'))
|
|
||||||
c(e);
|
|
||||||
new MutationObserver((e) => {
|
|
||||||
for (const t of e)
|
|
||||||
if (t.type === "childList")
|
|
||||||
for (const s of t.addedNodes)
|
|
||||||
s.tagName === "LINK" && s.rel === "modulepreload" && c(s);
|
|
||||||
}).observe(document, { childList: !0, subtree: !0 });
|
|
||||||
function n(e) {
|
|
||||||
const t = {};
|
|
||||||
return (
|
|
||||||
e.integrity && (t.integrity = e.integrity),
|
|
||||||
e.referrerpolicy && (t.referrerPolicy = e.referrerpolicy),
|
|
||||||
e.crossorigin === "use-credentials"
|
|
||||||
? (t.credentials = "include")
|
|
||||||
: e.crossorigin === "anonymous"
|
|
||||||
? (t.credentials = "omit")
|
|
||||||
: (t.credentials = "same-origin"),
|
|
||||||
t
|
|
||||||
);
|
|
||||||
}
|
|
||||||
function c(e) {
|
|
||||||
if (e.ep) return;
|
|
||||||
e.ep = !0;
|
|
||||||
const t = n(e);
|
|
||||||
fetch(e.href, t);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
const E = [
|
|
||||||
{
|
|
||||||
path: "/",
|
|
||||||
name: "Home",
|
|
||||||
component: () =>
|
|
||||||
i(
|
|
||||||
() => import("./Home.24891fef.js"),
|
|
||||||
[
|
|
||||||
"assets/Home.24891fef.js",
|
|
||||||
"assets/frappe-ui.8966d601.js",
|
|
||||||
"assets/frappe-ui.e894a05e.css",
|
|
||||||
]
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/courses",
|
|
||||||
name: "Courses",
|
|
||||||
component: () =>
|
|
||||||
i(
|
|
||||||
() => import("./Courses.10129947.js"),
|
|
||||||
[
|
|
||||||
"assets/Courses.10129947.js",
|
|
||||||
"assets/frappe-ui.8966d601.js",
|
|
||||||
"assets/frappe-ui.e894a05e.css",
|
|
||||||
"assets/Courses.4fd15046.css",
|
|
||||||
]
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
let O = u({ history: l("/"), routes: E });
|
|
||||||
const P = {};
|
|
||||||
function b(a, o) {
|
|
||||||
const n = p("router-view");
|
|
||||||
return d(), m("div", null, [_(n)]);
|
|
||||||
}
|
|
||||||
const A = f(P, [["render", b]]);
|
|
||||||
let r = h(A);
|
|
||||||
v("resourceFetcher", L);
|
|
||||||
r.use(O);
|
|
||||||
r.use(y);
|
|
||||||
r.component("Button", g);
|
|
||||||
r.mount("#app");
|
|
||||||
1
lms/public/frontend/assets/index.64bc1bc1.css
Normal file
1
lms/public/frontend/assets/index.64bc1bc1.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6
lms/public/frontend/assets/plus.8f4bce9f.js
Normal file
6
lms/public/frontend/assets/plus.8f4bce9f.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { c as e } from "./index.43e529db.js";
|
||||||
|
const n = e("PlusIcon", [
|
||||||
|
["line", { x1: "12", x2: "12", y1: "5", y2: "19", key: "pwfkuu" }],
|
||||||
|
["line", { x1: "5", x2: "19", y1: "12", y2: "12", key: "13b5wn" }],
|
||||||
|
]);
|
||||||
|
export { n as P };
|
||||||
11
lms/public/frontend/assets/star.d3e8ecca.js
Normal file
11
lms/public/frontend/assets/star.d3e8ecca.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { c as o } from "./index.43e529db.js";
|
||||||
|
const c = o("StarIcon", [
|
||||||
|
[
|
||||||
|
"polygon",
|
||||||
|
{
|
||||||
|
points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2",
|
||||||
|
key: "8f66p6",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
export { c as S };
|
||||||
@@ -5,10 +5,10 @@
|
|||||||
<link rel="icon" href="/favicon.png" />
|
<link rel="icon" href="/favicon.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Frappe UI App</title>
|
<title>Frappe UI App</title>
|
||||||
<script type="module" crossorigin src="/assets/index.52b6e5cb.js"></script>
|
<script type="module" crossorigin src="/assets/index.43e529db.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/assets/frappe-ui.8966d601.js">
|
<link rel="modulepreload" crossorigin href="/assets/frappe-ui.f2211ca2.js">
|
||||||
<link rel="stylesheet" href="/assets/frappe-ui.e894a05e.css">
|
<link rel="stylesheet" href="/assets/frappe-ui.7692ed2d.css">
|
||||||
<link rel="stylesheet" href="/assets/index.943a3ec2.css">
|
<link rel="stylesheet" href="/assets/index.64bc1bc1.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
from lms.www.utils import get_assessments, is_student
|
from lms.www.utils import is_student
|
||||||
from lms.lms.utils import (
|
from lms.lms.utils import (
|
||||||
has_course_moderator_role,
|
has_course_moderator_role,
|
||||||
has_course_evaluator_role,
|
has_course_evaluator_role,
|
||||||
@@ -12,6 +12,7 @@ from lms.lms.utils import (
|
|||||||
get_lesson_url,
|
get_lesson_url,
|
||||||
get_lesson_icon,
|
get_lesson_icon,
|
||||||
get_membership,
|
get_membership,
|
||||||
|
get_assessments,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,89 +61,6 @@ def get_current_lesson_details(lesson_number, context, is_edit=False):
|
|||||||
return lesson_info
|
return lesson_info
|
||||||
|
|
||||||
|
|
||||||
def get_assessments(batch, member=None):
|
|
||||||
if not member:
|
|
||||||
member = frappe.session.user
|
|
||||||
|
|
||||||
assessments = frappe.get_all(
|
|
||||||
"LMS Assessment",
|
|
||||||
{"parent": batch},
|
|
||||||
["name", "assessment_type", "assessment_name"],
|
|
||||||
)
|
|
||||||
|
|
||||||
for assessment in assessments:
|
|
||||||
if assessment.assessment_type == "LMS Assignment":
|
|
||||||
assessment = get_assignment_details(assessment, member)
|
|
||||||
|
|
||||||
elif assessment.assessment_type == "LMS Quiz":
|
|
||||||
assessment = get_quiz_details(assessment, member)
|
|
||||||
|
|
||||||
return assessments
|
|
||||||
|
|
||||||
|
|
||||||
def get_assignment_details(assessment, member):
|
|
||||||
assessment.title = frappe.db.get_value(
|
|
||||||
"LMS Assignment", assessment.assessment_name, "title"
|
|
||||||
)
|
|
||||||
|
|
||||||
existing_submission = frappe.db.exists(
|
|
||||||
{
|
|
||||||
"doctype": "LMS Assignment Submission",
|
|
||||||
"member": member,
|
|
||||||
"assignment": assessment.assessment_name,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
assessment.completed = False
|
|
||||||
if existing_submission:
|
|
||||||
assessment.submission = frappe.db.get_value(
|
|
||||||
"LMS Assignment Submission",
|
|
||||||
existing_submission,
|
|
||||||
["name", "status", "comments"],
|
|
||||||
as_dict=True,
|
|
||||||
)
|
|
||||||
assessment.completed = True
|
|
||||||
|
|
||||||
assessment.edit_url = f"/assignments/{assessment.assessment_name}"
|
|
||||||
submission_name = existing_submission if existing_submission else "new-submission"
|
|
||||||
assessment.url = (
|
|
||||||
f"/assignment-submission/{assessment.assessment_name}/{submission_name}"
|
|
||||||
)
|
|
||||||
|
|
||||||
return assessment
|
|
||||||
|
|
||||||
|
|
||||||
def get_quiz_details(assessment, member):
|
|
||||||
assessment_details = frappe.db.get_value(
|
|
||||||
"LMS Quiz", assessment.assessment_name, ["title", "passing_percentage"], as_dict=1
|
|
||||||
)
|
|
||||||
assessment.title = assessment_details.title
|
|
||||||
|
|
||||||
existing_submission = frappe.get_all(
|
|
||||||
"LMS Quiz Submission",
|
|
||||||
{
|
|
||||||
"member": member,
|
|
||||||
"quiz": assessment.assessment_name,
|
|
||||||
},
|
|
||||||
["name", "score", "percentage"],
|
|
||||||
order_by="percentage desc",
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(existing_submission):
|
|
||||||
assessment.submission = existing_submission[0]
|
|
||||||
|
|
||||||
assessment.completed = False
|
|
||||||
if assessment.submission:
|
|
||||||
assessment.completed = True
|
|
||||||
|
|
||||||
assessment.edit_url = f"/quizzes/{assessment.assessment_name}"
|
|
||||||
submission_name = (
|
|
||||||
existing_submission[0].name if len(existing_submission) else "new-submission"
|
|
||||||
)
|
|
||||||
assessment.url = f"/quiz-submission/{assessment.assessment_name}/{submission_name}"
|
|
||||||
|
|
||||||
return assessment
|
|
||||||
|
|
||||||
|
|
||||||
def is_student(batch, member=None):
|
def is_student(batch, member=None):
|
||||||
if not member:
|
if not member:
|
||||||
member = frappe.session.user
|
member = frappe.session.user
|
||||||
|
|||||||
Reference in New Issue
Block a user