- {{ course.data.price }}
+
+ {{ __('This course has:') }}
-
-
-
- {{ course.data.enrollment_count_formatted }} {{ __('Enrolled') }}
-
-
-
-
-
+
+
+
{{ course.data.lesson_count }} {{ __('Lessons') }}
+
+
+
+ {{ course.data.enrollment_count_formatted }}
+ {{ __('Enrolled Students') }}
+
+
-
-
+
+
{{ course.data.avg_rating }} {{ __('Rating') }}
diff --git a/frontend/src/components/CourseOutline.vue b/frontend/src/components/CourseOutline.vue
index d620e056..294cbf0e 100644
--- a/frontend/src/components/CourseOutline.vue
+++ b/frontend/src/components/CourseOutline.vue
@@ -1,28 +1,40 @@
-
-
+
+
+
+ {{ __('Course Content') }}
+
+
+
+
-
+
-
+
{{ chapter.title }}
+
+ {{ chapter.lessons.length }}
+ {{ chapter.lessons.length == 1 ? __('lesson') : __('lessons') }}
+
-
+
-
- {{ __('Reviews') }}
+
+
+
+
+ {{ avg_rating }} {{ __('ratings and ') }} {{ reviews.data.length }}
+ {{ __('reviews') }}
-
-
-
- {{ avg_rating }}
-
-
-
-
-
{{ reviews.data.length }} {{ __('reviews') }}
-
-
-
-
-
-
-
{{ index }} {{ __('stars') }}
-
-
{{ Math.floor(rating_percent[index]) }}%
-
-
-
-
-
+
-
-
-
-
-
- {{ review.owner_details.full_name }}
-
-
- {{ review.creation }}
-
-
-
-
+
+
+
+
+ {{ review.owner_details.full_name }}
+
+
+ {{ review.creation }}
+
+
+
-
- {{ review.review }}
-
-
+
+ {{ review.review }}
+
@@ -106,6 +71,19 @@ const props = defineProps({
},
})
+const hasReviewed = createResource({
+ url: 'frappe.client.get_count',
+ cache: ['eligible_to_review', props.courseName, props.membership.member],
+ params: {
+ doctype: 'LMS Course Review',
+ filters: {
+ course: props.courseName,
+ owner: props.membership.member,
+ },
+ },
+ auto: true,
+})
+
const reversedRange = (count) =>
Array.from({ length: count }, (_, index) => count - index)
diff --git a/frontend/src/components/Modals/ReviewModal.vue b/frontend/src/components/Modals/ReviewModal.vue
index 5e9f3784..ca0fcf06 100644
--- a/frontend/src/components/Modals/ReviewModal.vue
+++ b/frontend/src/components/Modals/ReviewModal.vue
@@ -39,6 +39,8 @@ import { createToast } from '@/utils/'
const show = defineModel()
const reviews = defineModel('reloadReviews')
+const hasReviewed = defineModel('hasReviewed')
+
let review = reactive({
review: '',
rating: 0,
@@ -73,6 +75,7 @@ function submitReview(close) {
},
onSuccess() {
reviews.value.reload()
+ hasReviewed.value.reload()
},
onError(err) {
createToast({
diff --git a/frontend/src/pages/CourseDetail.vue b/frontend/src/pages/CourseDetail.vue
index 771f1bc7..2d27f405 100644
--- a/frontend/src/pages/CourseDetail.vue
+++ b/frontend/src/pages/CourseDetail.vue
@@ -6,65 +6,84 @@
-
-
- {{ course.data.title }}
-
-
- {{ course.data.short_introduction }}
-
-
-
-
-
- {{ course.data.avg_rating }}
-
+
+
+
+ {{ course.data.title }}
-
·
-
-
-
- {{ course.data.enrollment_count_formatted }}
-
+
+ {{ course.data.short_introduction }}
-
·
-
-
-
-
- {{ course.data.instructors[0].full_name }}
-
-
- {{ course.data.instructors[0].first_name }} and
- {{ course.data.instructors[1].first_name }}
-
-
- {{ course.data.instructors[0].first_name }} and
- {{ course.data.instructors.length - 1 }} others
-
+
+
+ {{ course.data.avg_rating }}
+
+
+
·
+
+
+
+ {{ course.data.enrollment_count_formatted }}
+
+
+
·
+
+
+
+
+
+ {{ course.data.instructors[0].full_name }}
+
+
+ {{ course.data.instructors[0].first_name }} and
+ {{ course.data.instructors[1].first_name }}
+
+
+ {{ course.data.instructors[0].first_name }} and
+ {{ course.data.instructors.length - 1 }} others
+
+
+
+
+
+ {{ tag }}
+
-
-
-
-
-
- {{ __('Course Content') }}
-
-
+
-
@@ -81,7 +100,7 @@