feat: course analytics (#574)

* feat: added anaytics for the course page

* feat: Added pagination

* feat: cleanup

* feat: added translations

* feat: added fixes

* my improvements

---------

Co-authored-by: Rotimi Best <best@classroomio.com>
This commit is contained in:
Nwosu Emmanuel
2025-09-18 01:00:49 +01:00
committed by GitHub
co-authored by Rotimi Best
parent f3de6a063e
commit ec3875bac2
28 changed files with 1322 additions and 40 deletions
@@ -861,6 +861,9 @@
"cancel": "Stornieren",
"post": "Post"
}
},
"analytics": {
"title": "Analyse"
}
},
"navItems": {
@@ -872,7 +875,8 @@
"nav_certificates": "Zertifikate",
"nav_landing_page": "Landingpage",
"nav_settings": "Einstellungen",
"nav_content": "Inhalt"
"nav_content": "Inhalt",
"nav_analytics": "Analyse"
},
"not_permitted": {
"header": "Keine Erlaubnis",
@@ -1552,11 +1556,27 @@
"assignment_completion": "Abschluss der Aufgabe",
"assignment_completion_description": "Prozentsatz der abgeschlossenen Aufgaben",
"average_grade": "Durchschnittsnote",
"average_grade_description": "Durchschnittsnote aller abgeschlossenen Aufgaben"
"average_grade_description": "Durchschnittsnote aller abgeschlossenen Aufgaben",
"students": "Studenten",
"lessons": "Unterricht",
"tutors": "Tutoren",
"avg_grade": "AVG -Note",
"completion_rate": "Abschlussrate",
"student_progress_overview": "Übersicht über den Fortschritt der Schüler",
"student_name": "Schülername",
"lessons_completed": "Lektionen abgeschlossen",
"exercises_submitted": "Übungen eingereicht",
"actions": "Aktionen",
"view_details": "Details anzeigen",
"no_students_found": "Keine Schüler gefunden",
"no_students_description": "In diesem Kurs sind noch keine Studenten eingeschrieben. Die Schüler werden hier erscheinen, sobald sie sich dem Kurs anschließen.",
"showing_students": "Zeigen {Start} bis {End} von {Total} -Studenten",
"no_analytics_data": "Keine Analysedaten",
"no_analytics_description": "Analysedaten für diesen Kurs können nicht geladen werden. Bitte versuchen Sie es später erneut oder wenden Sie sich an Support, wenn das Problem bestehen bleibt."
},
"common": {
"unsaved_changes": {
"message": "Sie haben nicht gerettete Änderungen. Bist du sicher, dass du gehen willst?"
}
}
}
}
@@ -535,6 +535,7 @@
"nav_submissions": "Submissions",
"nav_marks": "Marks",
"nav_people": "People",
"nav_analytics": "Analytics",
"nav_certificates": "Certificates",
"nav_landing_page": "Landing Page",
"nav_settings": "Settings"
@@ -1147,6 +1148,10 @@
"courses": "courses"
},
"analytics": {
"title": "Analytics"
},
"settings": {
"heading": "Settings",
"cover_image": "Cover Image",
@@ -1257,8 +1262,24 @@
"overall_course_progress_user_description": "Based on lesson completion",
"assignment_completion": "Assignment Completion",
"assignment_completion_description": "Percentage of completed assignments",
"average_grade_description": "Average grade of all completed assignments",
"students": "Students",
"lessons": "Lessons",
"tutors": "tutors",
"avg_grade": "Avg grade",
"completion_rate": "Completion rate",
"student_progress_overview": "Student Progress Overview",
"student_name": "Student Name",
"lessons_completed": "Lessons Completed",
"exercises_submitted": "Exercises Submitted",
"average_grade": "Average Grade",
"average_grade_description": "Average grade of all completed assignments"
"actions": "Actions",
"view_details": "View Details",
"no_students_found": "No Students Found",
"no_students_description": "There are no students enrolled in this course yet. Students will appear here once they join the course.",
"showing_students": "Showing {start} to {end} of {total} students",
"no_analytics_data": "No Analytics Data",
"no_analytics_description": "Unable to load analytics data for this course. Please try again later or contact support if the issue persists."
},
"upgrade": {
@@ -861,6 +861,9 @@
"cancel": "Cancelar",
"post": "Correo"
}
},
"analytics": {
"title": "Analítica"
}
},
"navItems": {
@@ -872,7 +875,8 @@
"nav_certificates": "Certificados",
"nav_landing_page": "Página de destino",
"nav_settings": "Ajustes",
"nav_content": "Contenido"
"nav_content": "Contenido",
"nav_analytics": "Analítica"
},
"not_permitted": {
"header": "Sin autorización",
@@ -1552,11 +1556,27 @@
"assignment_completion": "Finalización de la tarea",
"assignment_completion_description": "Porcentaje de tareas completadas",
"average_grade": "Calificación promedio",
"average_grade_description": "Calificación promedio de todas las tareas completadas"
"average_grade_description": "Calificación promedio de todas las tareas completadas",
"students": "Estudiantes",
"lessons": "Lecciones",
"tutors": "tutores",
"avg_grade": "AVG Grado",
"completion_rate": "Tasa de finalización",
"student_progress_overview": "Descripción general del progreso del estudiante",
"student_name": "Nombre de estudiante",
"lessons_completed": "Lecciones completadas",
"exercises_submitted": "Ejercicios presentados",
"actions": "Comportamiento",
"view_details": "Ver detalles",
"no_students_found": "No se encontraron estudiantes",
"no_students_description": "Todavía no hay estudiantes matriculados en este curso. Los estudiantes aparecerán aquí una vez que se unan al curso.",
"showing_students": "Mostrando {inicio} a {final} de {Total} Estudiantes",
"no_analytics_data": "Sin datos de análisis",
"no_analytics_description": "No se puede cargar datos de análisis para este curso. Vuelva a intentarlo más tarde o comuníquese con el soporte si el problema persiste."
},
"common": {
"unsaved_changes": {
"message": "Tienes cambios no salvos. ¿Estás seguro de que quieres irte?"
}
}
}
}
@@ -861,6 +861,9 @@
"cancel": "Annuler",
"post": "Poste"
}
},
"analytics": {
"title": "Analytique"
}
},
"navItems": {
@@ -872,7 +875,8 @@
"nav_certificates": "Certificats",
"nav_landing_page": "Page de destination",
"nav_settings": "Paramètres",
"nav_content": "Contenu"
"nav_content": "Contenu",
"nav_analytics": "Analytique"
},
"not_permitted": {
"header": "Aucune autorisation",
@@ -1552,7 +1556,23 @@
"assignment_completion": "Achèvement de la mission",
"assignment_completion_description": "Pourcentage de missions terminées",
"average_grade": "Note moyenne",
"average_grade_description": "Note moyenne de tous les devoirs terminés"
"average_grade_description": "Note moyenne de tous les devoirs terminés",
"students": "Étudiants",
"lessons": "Leçons",
"tutors": "tuteurs",
"avg_grade": "Grade AVG",
"completion_rate": "Taux d'achèvement",
"student_progress_overview": "Aperçu des progrès des étudiants",
"student_name": "Nom de l'étudiant",
"lessons_completed": "Leçons terminées",
"exercises_submitted": "Exercices soumis",
"actions": "Actes",
"view_details": "Afficher les détails",
"no_students_found": "Aucun étudiant trouvé",
"no_students_description": "Il n'y a pas encore d'étudiants inscrits à ce cours. Les étudiants apparaîtront ici une fois qu'ils auront participé au cours.",
"showing_students": "Affichage {démarrer} à {fin} des étudiants {totaux}",
"no_analytics_data": "Aucune donnée d'analyse",
"no_analytics_description": "Impossible de charger des données d'analyse pour ce cours. Veuillez réessayer plus tard ou contacter le support si le problème persiste."
},
"common": {
"unsaved_changes": {
@@ -861,6 +861,9 @@
"cancel": "रद्द करना",
"post": "डाक"
}
},
"analytics": {
"title": "एनालिटिक्स"
}
},
"navItems": {
@@ -872,7 +875,8 @@
"nav_certificates": "प्रमाण पत्र",
"nav_landing_page": "लैंडिंग पृष्ठ",
"nav_settings": "समायोजन",
"nav_content": "सामग्री"
"nav_content": "सामग्री",
"nav_analytics": "एनालिटिक्स"
},
"not_permitted": {
"header": "अनुमति नहीं",
@@ -1552,11 +1556,27 @@
"assignment_completion": "असाइनमेंट पूरा करना",
"assignment_completion_description": "पूर्ण किये गये कार्यों का प्रतिशत",
"average_grade": "औसत क्षेणी",
"average_grade_description": "सभी पूर्ण किए गए असाइनमेंट का औसत ग्रेड"
"average_grade_description": "सभी पूर्ण किए गए असाइनमेंट का औसत ग्रेड",
"students": "छात्र",
"lessons": "पाठ",
"tutors": "ट्यूटर्स",
"avg_grade": "AVG ग्रेड",
"completion_rate": "पूर्णता दर",
"student_progress_overview": "छात्र प्रगति अवलोकन",
"student_name": "छात्र नाम",
"lessons_completed": "सबक पूरा हुआ",
"exercises_submitted": "प्रस्तुत अभ्यास",
"actions": "कार्रवाई",
"view_details": "विवरण देखें",
"no_students_found": "कोई छात्र नहीं मिला",
"no_students_description": "इस पाठ्यक्रम में अभी तक कोई छात्र नामांकित नहीं हैं। पाठ्यक्रम में शामिल होने के बाद छात्र यहां दिखाई देंगे।",
"showing_students": "{TOTAL} {TOTAL} छात्रों के {अंत} को दिखा रहा है",
"no_analytics_data": "कोई एनालिटिक्स डेटा नहीं",
"no_analytics_description": "इस पाठ्यक्रम के लिए एनालिटिक्स डेटा लोड करने में असमर्थ। यदि समस्या बनी रहती है, तो कृपया बाद में पुनः प्रयास करें या समर्थन से संपर्क करें।"
},
"common": {
"unsaved_changes": {
"message": "आपके पास अनसुना परिवर्तन हैं। क्या आपकी वाकई छोड़ने की इच्छा है?"
}
}
}
}
@@ -331,7 +331,23 @@
"assignment_completion": "Zakończenie przypisania",
"assignment_completion_description": "Procent wypełnionych zadań",
"average_grade": "Średnia ocena",
"average_grade_description": "Średnia ocena wszystkich zakończonych zadań"
"average_grade_description": "Średnia ocena wszystkich zakończonych zadań",
"students": "Studenci",
"lessons": "Lekcje",
"tutors": "Tutorzy",
"avg_grade": "Klasa AVG",
"completion_rate": "Wskaźnik zakończenia",
"student_progress_overview": "Przegląd postępu uczniów",
"student_name": "Nazwa ucznia",
"lessons_completed": "Ukończone lekcje",
"exercises_submitted": "Przedstawione ćwiczenia",
"actions": "Działania",
"view_details": "Zobacz szczegóły",
"no_students_found": "Nie znaleziono uczniów",
"no_students_description": "Na ten kurs nie zapisano jeszcze studentów. Studenci pojawią się tutaj, gdy dołączą do kursu.",
"showing_students": "Pokazuje {start} do {end} studentów {total}",
"no_analytics_data": "Brak danych analitycznych",
"no_analytics_description": "Nie można załadować danych analitycznych dla tego kursu. Spróbuj ponownie później lub skontaktuj się z wsparciem, jeśli problem będzie się utrzymywał."
},
"audience": {
"title": "Publiczność",
@@ -1000,6 +1016,9 @@
"cancel": "Anulować",
"post": "Post"
}
},
"analytics": {
"title": "Analityka"
}
},
"navItems": {
@@ -1011,7 +1030,8 @@
"nav_people": "Ludzie",
"nav_certificates": "Certyfikaty",
"nav_landing_page": "Strona docelowa",
"nav_settings": "Ustawienia"
"nav_settings": "Ustawienia",
"nav_analytics": "Analityka"
}
},
"courses": {
@@ -1523,5 +1543,10 @@
"resend_in": "Ponownie weryfikacja w",
"seconds": "towary drugiej jakości",
"snackbar_error": "Błąd podczas wysyłania kodu"
},
"common": {
"unsaved_changes": {
"message": "Masz niezbawione zmiany. Czy na pewno chcesz odejść?"
}
}
}
}
@@ -861,6 +861,9 @@
"cancel": "Cancelar",
"post": "Publicar"
}
},
"analytics": {
"title": "Análise"
}
},
"navItems": {
@@ -872,7 +875,8 @@
"nav_certificates": "Certificados",
"nav_landing_page": "Página inicial",
"nav_settings": "Configurações",
"nav_content": "Contente"
"nav_content": "Contente",
"nav_analytics": "Análise"
},
"not_permitted": {
"header": "Sem permissão",
@@ -1552,11 +1556,27 @@
"assignment_completion": "Conclusão da tarefa",
"assignment_completion_description": "Porcentagem de tarefas concluídas",
"average_grade": "Nota Média",
"average_grade_description": "Nota média de todas as tarefas concluídas"
"average_grade_description": "Nota média de todas as tarefas concluídas",
"students": "Alunos",
"lessons": "Lições",
"tutors": "tutores",
"avg_grade": "Grau AVG",
"completion_rate": "Taxa de conclusão",
"student_progress_overview": "Visão geral do progresso do aluno",
"student_name": "Nome do aluno",
"lessons_completed": "Lições concluídas",
"exercises_submitted": "Exercícios enviados",
"actions": "Ações",
"view_details": "Ver detalhes",
"no_students_found": "Nenhum aluno encontrado",
"no_students_description": "Ainda não há alunos matriculados neste curso. Os alunos aparecerão aqui quando ingressarem no curso.",
"showing_students": "Mostrando {start} para {end} de {total} alunos",
"no_analytics_data": "Sem dados de análise",
"no_analytics_description": "Não é possível carregar dados de análise para este curso. Tente novamente mais tarde ou entre em contato com o suporte se o problema persistir."
},
"common": {
"unsaved_changes": {
"message": "Você tem mudanças não salvas. Tem certeza de que deseja sair?"
}
}
}
}
@@ -861,6 +861,9 @@
"cancel": "Отмена",
"post": "Почта"
}
},
"analytics": {
"title": "Аналитика"
}
},
"navItems": {
@@ -872,7 +875,8 @@
"nav_certificates": "Сертификаты",
"nav_landing_page": "Целевая страница",
"nav_settings": "Настройки",
"nav_content": "Содержание"
"nav_content": "Содержание",
"nav_analytics": "Аналитика"
},
"not_permitted": {
"header": "Нет разрешения",
@@ -1552,7 +1556,23 @@
"assignment_completion": "Выполнение задания",
"assignment_completion_description": "Процент выполненных заданий",
"average_grade": "Средняя оценка",
"average_grade_description": "Средняя оценка за все выполненные задания"
"average_grade_description": "Средняя оценка за все выполненные задания",
"students": "Студенты",
"lessons": "Уроки",
"tutors": "репетиторы",
"avg_grade": "AVG Grade",
"completion_rate": "Коэффициент завершения",
"student_progress_overview": "Студенческий прогресс обзор",
"student_name": "Студенческое имя",
"lessons_completed": "Уроки завершены",
"exercises_submitted": "Упражнения представлены",
"actions": "Действия",
"view_details": "Просмотреть детали",
"no_students_found": "Никаких студентов не нашли",
"no_students_description": "В этом курсе еще нет студентов. Студенты появятся здесь, как только они присоединятся к курсу.",
"showing_students": "Показ {start} to {end} {otto} Студенты",
"no_analytics_data": "Нет аналитических данных",
"no_analytics_description": "Невозможно загрузить данные аналитики для этого курса. Пожалуйста, попробуйте еще раз или свяжитесь с поддержкой, если проблема сохранится."
},
"common": {
"unsaved_changes": {
@@ -861,6 +861,9 @@
"cancel": "Hủy bỏ",
"post": "Bưu kiện"
}
},
"analytics": {
"title": "Phân tích"
}
},
"navItems": {
@@ -872,7 +875,8 @@
"nav_certificates": "Chứng chỉ",
"nav_landing_page": "Trang đích",
"nav_settings": "Cài đặt",
"nav_content": "Nội dung"
"nav_content": "Nội dung",
"nav_analytics": "Phân tích"
},
"not_permitted": {
"header": "Không cho phép",
@@ -1552,11 +1556,27 @@
"assignment_completion": "Hoàn thành bài tập",
"assignment_completion_description": "Tỷ lệ bài tập đã hoàn thành",
"average_grade": "Điểm trung bình",
"average_grade_description": "Điểm trung bình của tất cả các bài tập đã hoàn thành"
"average_grade_description": "Điểm trung bình của tất cả các bài tập đã hoàn thành",
"students": "Sinh viên",
"lessons": "Bài học",
"tutors": "gia sư",
"avg_grade": "Lớp AVG",
"completion_rate": "Tỷ lệ hoàn thành",
"student_progress_overview": "Tổng quan về tiến trình học sinh",
"student_name": "Tên sinh viên",
"lessons_completed": "Bài học hoàn thành",
"exercises_submitted": "Bài tập được gửi",
"actions": "Hành động",
"view_details": "Xem chi tiết",
"no_students_found": "Không có học sinh tìm thấy",
"no_students_description": "Không có sinh viên đăng ký vào khóa học này. Học sinh sẽ xuất hiện ở đây khi họ tham gia khóa học.",
"showing_students": "Hiển thị {start} đến {end} của {Total} sinh viên",
"no_analytics_data": "Không có dữ liệu phân tích",
"no_analytics_description": "Không thể tải dữ liệu phân tích cho khóa học này. Vui lòng thử lại sau hoặc liên hệ với hỗ trợ nếu vấn đề vẫn còn."
},
"common": {
"unsaved_changes": {
"message": "Bạn có những thay đổi chưa được lưu. Bạn có chắc bạn muốn rời đi?"
}
}
}
}
@@ -1,3 +1,64 @@
export interface CourseAnalytics {
totalTutors: number;
totalStudents: number;
totalLessons: number;
totalExercises: number;
lessonCompletionRate: number;
exerciseCompletionRate: number;
averageGrade: number;
students: StudentOverview[];
}
export interface StudentOverview {
id: string;
profile: {
fullname: string;
email: string;
avatar_url: string;
};
lessonsCompleted: number;
totalLessons: number;
exercisesSubmitted: number;
totalExercises: number;
averageGrade: number;
lastSeen: string;
progressPercentage: number;
}
export interface StudentDetailModal {
student: {
profile: {
id: string;
fullname: string;
email: string;
avatar_url: string;
};
overallStats: {
totalCourses: number;
totalLessonsCompleted: number;
totalExercisesSubmitted: number;
overallAverageGrade: number;
lastSeen: string;
};
courses: StudentCourseAnalytics[];
};
}
export interface StudentCourseAnalytics {
courseId: string;
courseTitle: string;
courseLogo: string;
role: 'student' | 'tutor' | 'admin';
lessonsCompleted: number;
totalLessons: number;
exercisesSubmitted: number;
totalExercises: number;
averageGrade: number;
progressPercentage: number;
lastActivity: string;
enrollmentDate: string;
}
interface User {
id: string;
fullName: string;