mirror of
https://github.com/frappe/lms.git
synced 2026-05-02 13:39:31 +03:00
@@ -62,7 +62,7 @@
|
||||
<Tooltip :text="__('Enrolled Students')">
|
||||
<span class="flex items-center">
|
||||
<Users class="h-4 w-4 stroke-1.5 mr-1" />
|
||||
{{ course.enrollments }}
|
||||
{{ formatAmount(course.enrollments) }}
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@@ -116,27 +116,30 @@
|
||||
<CourseInstructors :instructors="course.instructors" />
|
||||
</div>
|
||||
|
||||
<div v-if="course.paid_course" class="font-semibold">
|
||||
{{ course.price }}
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<div v-if="course.paid_course" class="font-semibold">
|
||||
{{ course.price }}
|
||||
</div>
|
||||
|
||||
<Tooltip
|
||||
v-if="course.paid_certificate || course.enable_certification"
|
||||
:text="__('Get Certified')"
|
||||
>
|
||||
<GraduationCap class="size-5 stroke-1.5 text-ink-gray-7" />
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
v-if="course.paid_certificate || course.enable_certification"
|
||||
:text="__('Get Certified')"
|
||||
>
|
||||
<GraduationCap class="size-5 stroke-1.5 text-ink-gray-7" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Award, BookOpen, GraduationCap, Star, Users } from 'lucide-vue-next'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { Tooltip } from 'frappe-ui'
|
||||
import { theme } from '@/utils/theme'
|
||||
import { formatAmount } from '@/utils'
|
||||
import CourseInstructors from '@/components/CourseInstructors.vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import ProgressBar from '@/components/ProgressBar.vue'
|
||||
|
||||
const { user } = sessionStore()
|
||||
|
||||
@@ -165,6 +165,14 @@ const addAssignments = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const addProgrammingExercises = () => {
|
||||
otherLinks.value.push({
|
||||
label: 'Programming Exercises',
|
||||
icon: 'Code',
|
||||
to: 'ProgrammingExercises',
|
||||
})
|
||||
}
|
||||
|
||||
const addPrograms = async () => {
|
||||
let canAddProgram = await checkIfCanAddProgram()
|
||||
if (!canAddProgram) return
|
||||
|
||||
@@ -260,12 +260,14 @@
|
||||
v-if="course.paid_course || course.paid_certificate"
|
||||
v-model="course.course_price"
|
||||
:label="__('Amount')"
|
||||
:required="course.paid_course || course.paid_certificate"
|
||||
/>
|
||||
<Link
|
||||
v-if="course.paid_certificate"
|
||||
doctype="Course Evaluator"
|
||||
v-model="course.evaluator"
|
||||
:label="__('Evaluator')"
|
||||
:required="course.paid_certificate"
|
||||
:onCreate="
|
||||
(value, close) => openSettings('Evaluators', close)
|
||||
"
|
||||
@@ -278,11 +280,13 @@
|
||||
v-model="course.currency"
|
||||
:filters="{ enabled: 1 }"
|
||||
:label="__('Currency')"
|
||||
:required="course.paid_course || course.paid_certificate"
|
||||
/>
|
||||
<FormControl
|
||||
v-if="course.paid_certificate"
|
||||
v-model="course.timezone"
|
||||
:label="__('Timezone')"
|
||||
:required="course.paid_certificate"
|
||||
:placeholder="__('e.g. IST, UTC, GMT...')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -5,27 +5,28 @@
|
||||
<Breadcrumbs :items="[{ label: __('Home'), route: { name: 'Home' } }]" />
|
||||
</header> -->
|
||||
<div class="w-full px-5 pt-5 pb-10">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="space-y-2">
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xl font-bold text-ink-gray-9">
|
||||
{{ __('Hey') }}, {{ user.data?.full_name }} 👋
|
||||
</div>
|
||||
<div class="text-lg text-ink-gray-6">
|
||||
{{ subtitle }}
|
||||
<div>
|
||||
<TabButtons v-if="isAdmin" v-model="currentTab" :buttons="tabs" />
|
||||
<div
|
||||
v-else
|
||||
@click="showStreakModal = true"
|
||||
class="bg-surface-amber-2 px-2 py-1 rounded-md cursor-pointer"
|
||||
>
|
||||
<span> 🔥 </span>
|
||||
<span>
|
||||
{{ streakInfo.data?.current_streak }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<TabButtons v-if="isAdmin" v-model="currentTab" :buttons="tabs" />
|
||||
<div
|
||||
v-else
|
||||
@click="showStreakModal = true"
|
||||
class="bg-surface-amber-2 px-2 py-1 rounded-md cursor-pointer"
|
||||
>
|
||||
<span> 🔥 </span>
|
||||
<span>
|
||||
{{ streakInfo.data?.current_streak }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="text-lg text-ink-gray-6 leading-6">
|
||||
{{ subtitle }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+14
-4
@@ -2,15 +2,15 @@ import hashlib
|
||||
import json
|
||||
import re
|
||||
import string
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timedelta
|
||||
|
||||
import frappe
|
||||
import razorpay
|
||||
import requests
|
||||
from frappe import _
|
||||
from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_result
|
||||
from frappe.desk.doctype.notification_log.notification_log import make_notification_logs
|
||||
from frappe.desk.notifications import extract_mentions
|
||||
from frappe.rate_limiter import rate_limit
|
||||
from frappe.utils import (
|
||||
add_months,
|
||||
ceil,
|
||||
@@ -18,7 +18,6 @@ from frappe.utils import (
|
||||
cstr,
|
||||
flt,
|
||||
fmt_money,
|
||||
format_date,
|
||||
format_datetime,
|
||||
get_datetime,
|
||||
get_fullname,
|
||||
@@ -27,7 +26,6 @@ from frappe.utils import (
|
||||
nowtime,
|
||||
pretty_date,
|
||||
)
|
||||
from frappe.utils.dateutils import get_period
|
||||
|
||||
from lms.lms.md import find_macros, markdown_to_html
|
||||
|
||||
@@ -203,6 +201,7 @@ def get_lesson_icon(body, content):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_tags(course):
|
||||
tags = frappe.db.get_value("LMS Course", course, "tags")
|
||||
return tags.split(",") if tags else []
|
||||
@@ -247,6 +246,7 @@ def get_average_rating(course):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_reviews(course):
|
||||
reviews = frappe.get_all(
|
||||
"LMS Course Review",
|
||||
@@ -737,6 +737,7 @@ def has_lessons(course):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_chart_data(
|
||||
chart_name,
|
||||
timespan="Select Date Range",
|
||||
@@ -784,6 +785,7 @@ def get_chart_data(
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_course_completion_data():
|
||||
all_membership = frappe.db.count("LMS Enrollment")
|
||||
completed = frappe.db.count("LMS Enrollment", {"progress": ["like", "%100%"]})
|
||||
@@ -959,6 +961,7 @@ def change_currency(amount, currency, country=None):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_courses(filters=None, start=0):
|
||||
"""Returns the list of courses."""
|
||||
|
||||
@@ -1099,6 +1102,7 @@ def get_course_fields():
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_course_details(course):
|
||||
course_details = frappe.db.get_value(
|
||||
"LMS Course",
|
||||
@@ -1193,6 +1197,7 @@ def get_categorized_courses(courses):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_course_outline(course, progress=False):
|
||||
"""Returns the course outline."""
|
||||
outline = []
|
||||
@@ -1220,6 +1225,7 @@ def get_course_outline(course, progress=False):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_lesson(course, chapter, lesson):
|
||||
chapter_name = frappe.db.get_value("Chapter Reference", {"parent": course, "idx": chapter}, "chapter")
|
||||
lesson_name = frappe.db.get_value("Lesson Reference", {"parent": chapter_name, "idx": lesson}, "lesson")
|
||||
@@ -1330,6 +1336,7 @@ def get_neighbour_lesson(course, chapter, lesson):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_batch_details(batch):
|
||||
batch_students = frappe.get_all("LMS Batch Enrollment", {"batch": batch}, pluck="member")
|
||||
if (
|
||||
@@ -1450,6 +1457,7 @@ def get_question_details(question):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_batch_courses(batch):
|
||||
courses = []
|
||||
course_list = frappe.get_all("Batch Course", {"parent": batch}, ["name", "course"])
|
||||
@@ -2024,6 +2032,7 @@ def enroll_in_program(program):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_batches(filters=None, start=0, order_by="start_date"):
|
||||
if not filters:
|
||||
filters = {}
|
||||
@@ -2137,6 +2146,7 @@ def get_palette(full_name):
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def get_related_courses(course):
|
||||
related_course_details = []
|
||||
related_courses = frappe.get_all("Related Courses", {"parent": course}, order_by="idx", pluck="course")
|
||||
|
||||
Reference in New Issue
Block a user