From d827a10c8466d66be31ff2abbcb7def85441917d Mon Sep 17 00:00:00 2001 From: Alexandrina-Kuzeleva Date: Mon, 10 Nov 2025 17:28:26 +0300 Subject: [PATCH] UPD 3 - checked and fixed problems: timer in lesson, sing-up, page length in courses - add Points and Courses in ProfileAbout NEW: - add icon for RuTube --- frontend/src/pages/Courses.vue | 2 +- frontend/src/pages/Lesson.vue | 2 +- frontend/src/pages/ProfileAbout.vue | 146 ++++++++++++++++++++++++++++ lms/hooks.py | 2 +- lms/lms/utils.py | 3 +- 5 files changed, 151 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/Courses.vue b/frontend/src/pages/Courses.vue index e99a622c..1355650c 100644 --- a/frontend/src/pages/Courses.vue +++ b/frontend/src/pages/Courses.vue @@ -134,7 +134,7 @@ const courses = createListResource({ doctype: 'LMS Course', url: 'lms.lms.utils.get_courses', cache: ['courses', user.data?.name], - pageLength: pageLength.value, + //pageLength: pageLength.value, start: start.value, onSuccess(data) { setCategories(data) diff --git a/frontend/src/pages/Lesson.vue b/frontend/src/pages/Lesson.vue index b99ba6f7..7643d35c 100644 --- a/frontend/src/pages/Lesson.vue +++ b/frontend/src/pages/Lesson.vue @@ -734,7 +734,7 @@ const updateVideoTime = (video) => { const startTimer = () => { let timerInterval = setInterval(() => { timer.value++ - if (timer.value == 30) { + if (timer.value == 5) { clearInterval(timerInterval) markProgress() } diff --git a/frontend/src/pages/ProfileAbout.vue b/frontend/src/pages/ProfileAbout.vue index 47477d38..171848b7 100644 --- a/frontend/src/pages/ProfileAbout.vue +++ b/frontend/src/pages/ProfileAbout.vue @@ -29,6 +29,62 @@ {{ __('No introduction') }} + + +
+

+ {{ __('Points') }} +

+

+ {{ __('The last 10 score records have been uploaded') }} +

+ +
+
+ {{ __('Total Points') }}: {{ totalPoints }} +
+
+ {{ __('Additional Points for MPGU Admission') }}: {{ additionalPoints }} +
+
+
+
+ {{ __('No points yet') }} +
+ + +
+

+ {{ __('Completed Courses') }} +

+
+
+ + {{ course.title || course.course }} + +
+ {{ __('Completed on') }}: {{ dayjs(course.creation).format('DD MMM YYYY') }} +
+
+
+
+
+ {{ __('No completed courses yet') }} +
+

{{ __('Achievements') }} @@ -153,6 +209,96 @@ const badges = createResource({ }, }) +const courses = createResource({ + url: 'frappe.client.get_list', + params: { + doctype: 'LMS Course Progress', + fields: ['name', 'member', 'course', 'status', 'creation'], + filters: { + member: props.profile.data.email, + status: 'Complete', + }, + }, + auto: true, + onSuccess(data) { + console.log('LMS Course Progress data:', data) // Отладка + }, +}) + +const courseTitles = ref({}) +const coursesWithTitles = computed(() => { + if (!courses.data) return [] + const result = courses.data.map(course => ({ + ...course, + title: courseTitles.value[course.course] || null, + })) + console.log('Courses with titles:', result) // Отладка + return result +}) + +// Запрашиваем title для каждого курса +watch( + () => courses.data, + (newCourses) => { + if (newCourses && newCourses.length) { + const courseIds = newCourses.map(course => course.course) + console.log('Course IDs:', courseIds) // Отладка + createResource({ + url: 'frappe.client.get_list', + params: { + doctype: 'LMS Course', + fields: ['name', 'title'], + filters: { + name: ['in', courseIds], + }, + }, + auto: true, + onSuccess(data) { + console.log('Raw course titles data:', data) // Отладка сырых данных + const titles = {} + data.forEach(course => { + titles[course.name] = course.title + }) + courseTitles.value = titles + console.log('Processed course titles:', titles) // Отладка обработанных titles + }, + onError(error) { + console.error('Error fetching course titles:', error) // Отладка ошибок + }, + }) + } + }, + { immediate: true } +) + +const energyPoints = createResource({ + url: 'frappe.client.get_list', + params: { + doctype: 'Energy Point Log', + fields: ['name', 'user', 'points', 'rule', 'creation'], + filters: { + user: props.profile.data.email, + }, + limit_page_length: 1000, + }, + auto: true, + onSuccess(data) { + console.log('Energy Points data:', data) // Отладка + data.forEach(item => { + console.log('Points for', item.name, ':', item.points, typeof item.points) + }) + }, +}) + +const totalPoints = computed(() => { + return energyPoints.data?.reduce((sum, item) => sum + (item.points || 0), 0) || 0 +}) + +const additionalPoints = computed(() => { + const points = Math.floor(totalPoints.value / 100) + return points < 10 ? points : 10 +}) + const shareOnSocial = (badge, medium) => { let shareUrl const url = encodeURIComponent( diff --git a/lms/hooks.py b/lms/hooks.py index 06573095..cef3b3a5 100644 --- a/lms/hooks.py +++ b/lms/hooks.py @@ -105,7 +105,7 @@ doc_events = { "Notification Log": {"on_change": "lms.lms.utils.publish_notifications"}, "User": { "validate": "lms.lms.user.validate_username_duplicates", - "after_insert": "lms.lms.user.after_insert", + #"after_insert": "lms.lms.user.after_insert", }, } diff --git a/lms/lms/utils.py b/lms/lms/utils.py index d9d6a69d..af1865ab 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -180,6 +180,7 @@ def get_lesson_icon(body, content): if block.get("type") == "embed" and block.get("data").get("service") in [ "youtube", + "rutube", "vimeo", "cloudflareStream", "bunnyStream", @@ -193,7 +194,7 @@ def get_lesson_icon(body, content): macros = find_macros(body) for macro in macros: - if macro[0] == "YouTubeVideo" or macro[0] == "Video": + if macro[0] == "YouTubeVideo" or macro[0] == "Video" or macro[0] == "RuTubeVideo" : return "icon-youtube" elif macro[0] == "Quiz": return "icon-quiz"