feat: lesson pagination

This commit is contained in:
Jannat Patel
2023-12-18 19:17:17 +05:30
parent 372425bed2
commit 5928b8e5f9
7 changed files with 35 additions and 16 deletions

View File

@@ -24,6 +24,12 @@
<Star class="h-4 w-4 text-gray-700" /> <Star class="h-4 w-4 text-gray-700" />
<span> {{ course.avg_rating }} </span> <span> {{ course.avg_rating }} </span>
</div> </div>
<div v-if="course.status != 'Approved'">
<Badge variant="solid" :theme="course.status === 'Under Review' ? 'orange' : 'blue'" size="sm">
{{ course.status }}
</Badge>
</div>
</div> </div>
<div class="text-xl font-semibold"> <div class="text-xl font-semibold">
@@ -65,9 +71,9 @@
</template> </template>
<script setup> <script setup>
import { BookOpen, Users, Star } from 'lucide-vue-next' import { BookOpen, Users, Star } from 'lucide-vue-next'
import { computed } from 'vue'
import UserAvatar from '@/components/UserAvatar.vue' import UserAvatar from '@/components/UserAvatar.vue'
import { sessionStore } from '@/stores/session' import { sessionStore } from '@/stores/session'
import { Badge } from "frappe-ui"
const { isLoggedIn, user } = sessionStore() const { isLoggedIn, user } = sessionStore()

View File

@@ -13,7 +13,7 @@
</DisclosureButton> </DisclosureButton>
<DisclosurePanel class="px-10 pb-4" :static="index == 0"> <DisclosurePanel class="px-10 pb-4" :static="index == 0">
<div v-for="lesson in chapter.lessons" :key="lesson.name"> <div v-for="lesson in chapter.lessons" :key="lesson.name">
<div class="flex items-center text-base mb-2"> <div class="flex items-center text-base mb-3">
<MonitorPlay v-if="lesson.icon === 'icon-youtube'" class="h-4 w-4 text-gray-900 stroke-1 mr-2"/> <MonitorPlay v-if="lesson.icon === 'icon-youtube'" class="h-4 w-4 text-gray-900 stroke-1 mr-2"/>
<HelpCircle v-else-if="lesson.icon === 'icon-quiz'" class="h-4 w-4 text-gray-900 stroke-1 mr-2"/> <HelpCircle v-else-if="lesson.icon === 'icon-quiz'" class="h-4 w-4 text-gray-900 stroke-1 mr-2"/>
<FileText v-else-if="lesson.icon === 'icon-list'" class="h-4 w-4 text-gray-900 stroke-1 mr-2"/> <FileText v-else-if="lesson.icon === 'icon-list'" class="h-4 w-4 text-gray-900 stroke-1 mr-2"/>

View File

@@ -107,7 +107,6 @@ const rating_percent = computed(() => {
} }
[1,2,3,4,5].forEach((key) => { [1,2,3,4,5].forEach((key) => {
console.log(key, rating_count[key], reviews.data.length);
rating_percent[key] = (rating_count[key] / reviews.data.length * 100).toFixed(2); rating_percent[key] = (rating_count[key] / reviews.data.length * 100).toFixed(2);
}); });
return rating_percent; return rating_percent;

View File

@@ -1,10 +1,12 @@
<template> <template>
<div class="h-screen">
this is a batch
</div>
</template> </template>
<script setup> <script setup>
const props = defineProps({ const props = defineProps({
batchName: { batchName: {
type: Object, type: String,
required: true, required: true,
}, },
}) })

View File

@@ -15,20 +15,20 @@
{{ course.data.short_introduction }} {{ course.data.short_introduction }}
</div> </div>
<div class="flex items-center justify-between mt-3 w-1/3"> <div class="flex items-center justify-between mt-3 w-1/3">
<div class="flex items-center"> <div v-if="course.data.avg_rating" class="flex items-center">
<Star class="h-5 w-5 text-gray-100 fill-orange-500"/> <Star class="h-5 w-5 text-gray-100 fill-orange-500"/>
<span class="ml-1"> <span class="ml-1">
{{ course.data.avg_rating }} {{ course.data.avg_rating }}
</span> </span>
</div> </div>
&middot; <span v-if="course.data.avg_rating">&middot;</span>
<div class="flex items-center"> <div v-if="course.data.enrollment_count" class="flex items-center">
<Users class="h-4 w-4 text-gray-700"/> <Users class="h-4 w-4 text-gray-700"/>
<span class="ml-1"> <span class="ml-1">
{{ course.data.enrollment_count_formatted }} {{ course.data.enrollment_count_formatted }}
</span> </span>
</div> </div>
&middot; <span v-if="course.data.enrollment_count">&middot;</span>
<div class="flex items-center"> <div class="flex items-center">
<span class="mr-1" :class="{ 'avatar-group overlap': course.data.instructors.length > 1 }"> <span class="mr-1" :class="{ 'avatar-group overlap': course.data.instructors.length > 1 }">
<UserAvatar v-for="instructor in course.data.instructors" :user="instructor"/> <UserAvatar v-for="instructor in course.data.instructors" :user="instructor"/>
@@ -54,7 +54,7 @@
</div> </div>
<CourseOutline :courseName="course.data.name"/> <CourseOutline :courseName="course.data.name"/>
</div> </div>
<CourseReviews :courseName="course.data.name" :avg_rating="course.data.avg_rating"/> <CourseReviews v-if="course.data.avg_rating" :courseName="course.data.name" :avg_rating="course.data.avg_rating"/>
</div> </div>
<div> <div>
<CourseCardOverlay :course="course"/> <CourseCardOverlay :course="course"/>

View File

@@ -30,7 +30,17 @@
<template #default="{ tab }"> <template #default="{ tab }">
<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"> <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">
<router-link v-for="course in tab.courses.value" <router-link v-for="course in tab.courses.value"
:to="{ name: 'CourseDetail', params: { courseName: course.name } }"> :to="
course.membership && course.current_lesson
? {name: 'Lesson', params: {
courseName: course.name,
chapterNumber: course.current_lesson.split('.')[0],
lessonNumber: course.current_lesson.split('.')[1] }}
: course.membership ? { name: 'Lesson', params: {
courseName: course.name,
chapterNumber: 1,
lessonNumber: 1 }
} : { name: 'CourseDetail', params: { courseName: course.name } }">
<CourseCard :course="course" /> <CourseCard :course="course" />
</router-link> </router-link>
</div> </div>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div v-if="lesson.data && course.data" class="h-screen text-base"> <div v-if="lesson.data && course.data" class="h-screen text-base">
<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 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 class="grid grid-cols-[70%,30%] h-full"> <div class="grid grid-cols-[70%,30%] h-full">
<div class="border-r-2 container pt-5 pb-10"> <div class="border-r-2 container pt-5 pb-10">
@@ -10,7 +10,7 @@
</div> </div>
<div class="flex items-center mt-2"> <div class="flex items-center mt-2">
<span class="mr-1" :class="{ 'avatar-group overlap': course.data.instructors.length > 1 }"> <span class="mr-1" :class="{ 'avatar-group overlap': course.data.instructors.length > 1 }">
<UserAvatar v-for="instructor in course.data.instructors" :user="instructor"/> <UserAvatar v-for="instructor in course.data.instructors" :user="instructor" />
</span> </span>
<span v-if="course.data.instructors.length == 1"> <span v-if="course.data.instructors.length == 1">
{{ course.data.instructors[0].full_name }} {{ course.data.instructors[0].full_name }}
@@ -33,10 +33,11 @@
{{ Math.ceil(course.data.membership.progress) }}% completed {{ Math.ceil(course.data.membership.progress) }}% completed
</div> </div>
<div v-if="user && course.data.membership" class="w-full bg-gray-200 rounded-full h-1 my-2"> <div v-if="user && course.data.membership" class="w-full bg-gray-200 rounded-full h-1 my-2">
<div class="bg-gray-900 h-1 rounded-full" :style="{ width: Math.ceil(course.data.membership.progress) + '%' }"></div> <div class="bg-gray-900 h-1 rounded-full"
:style="{ width: Math.ceil(course.data.membership.progress) + '%' }"></div>
</div> </div>
</div> </div>
<CourseOutline :courseName="lesson.data.course"/> <CourseOutline :courseName="lesson.data.course" />
</div> </div>
</div> </div>
</div> </div>
@@ -111,13 +112,14 @@ onUnmounted(() => {
.youtube-video { .youtube-video {
border: 1px solid #ddd; border: 1px solid #ddd;
} }
.avatar-group { .avatar-group {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
} }
.avatar-group .avatar { .avatar-group .avatar {
transition: margin 0.1s ease-in-out; transition: margin 0.1s ease-in-out;
} }
iframe { iframe {