From 53b704c7def12ca23afbf568cc50d6501730312e Mon Sep 17 00:00:00 2001 From: a2nr Date: Wed, 16 Sep 2026 20:15:20 +0700 Subject: [PATCH] fix(teacher): align student and teacher counters on progress tree view - Count only distinct students for sub-chapter folder completion badge - Separate teacher attempts from student counter on lesson header with a dedicated '+Y guru' badge - Differentiate teacher rows with teacher icon and dashed styling --- .../src/routes/teacher/progress/+page.svelte | 50 +++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/frontend/src/routes/teacher/progress/+page.svelte b/frontend/src/routes/teacher/progress/+page.svelte index e31ed77..5892958 100644 --- a/frontend/src/routes/teacher/progress/+page.svelte +++ b/frontend/src/routes/teacher/progress/+page.svelte @@ -48,7 +48,7 @@ title: string; lessons: LessonNode[]; totalLessons: number; - totalCompletions: number; + uniqueStudentsCount: number; } // Parse `_diag_unmastered` JSON string @@ -202,7 +202,7 @@ if (group.lessons.length === 0) continue; const lessonNodes: LessonNode[] = []; - let totalCompletions = 0; + const uniqueStudentIds = new Set(); for (const lesson of group.lessons) { const key = lesson.filename.replace('.md', ''); @@ -225,11 +225,13 @@ diag_score: String(s[key + '_diag'] ?? ''), diag_unmastered: parseUnmastered(s[key + '_diag_unmastered']) }); + + if (s.role === 'student') { + uniqueStudentIds.add(s.id); + } } } - totalCompletions += completedStudents.length; - // Filter pencarian jika ada const matchesQuery = !query || lesson.title.toLowerCase().includes(query) || @@ -253,7 +255,7 @@ title: group.title, lessons: lessonNodes, totalLessons: group.lessons.length, - totalCompletions + uniqueStudentsCount: uniqueStudentIds.size }); } } @@ -261,7 +263,7 @@ // Kelompok materi tanpa sub-bab if (uncategorizedLessons.length > 0) { const lessonNodes: LessonNode[] = []; - let totalCompletions = 0; + const uniqueStudentIds = new Set(); for (const lesson of uncategorizedLessons) { const key = lesson.filename.replace('.md', ''); @@ -284,11 +286,13 @@ diag_score: String(s[key + '_diag'] ?? ''), diag_unmastered: parseUnmastered(s[key + '_diag_unmastered']) }); + + if (s.role === 'student') { + uniqueStudentIds.add(s.id); + } } } - totalCompletions += completedStudents.length; - const matchesQuery = !query || lesson.title.toLowerCase().includes(query) || lesson.filename.toLowerCase().includes(query) || @@ -309,7 +313,7 @@ title: 'Lainnya (Materi Umum)', lessons: lessonNodes, totalLessons: uncategorizedLessons.length, - totalCompletions + uniqueStudentsCount: uniqueStudentIds.size }); } } @@ -415,7 +419,7 @@
{group.lessons.length} materi - {group.totalCompletions} penyelesaian + {group.uniqueStudentsCount} siswa selesai
@@ -424,7 +428,8 @@
{#each group.lessons as item (item.key)} {@const isLessonOpen = openLessons[item.key] ?? (searchQuery !== '' && item.completedStudents.length > 0)} - {@const studentCount = item.completedStudents.length} + {@const studentCount = item.completedStudents.filter((s) => s.role === 'student').length} + {@const teacherCount = item.completedStudents.filter((s) => s.role === 'teacher').length}
{#if isLessonOpen}
- {#if studentCount === 0} + {#if item.completedStudents.length === 0}
Belum ada siswa yang menyelesaikan materi ini. @@ -462,8 +473,8 @@ {@const isTeacher = student.role === 'teacher'}
-
- 👤 +
+ {#if isTeacher}👨‍🏫{:else}👤{/if} {student.nama_siswa} {#if isTeacher} @@ -989,6 +1000,13 @@ color: #c62828; border: 1px solid #ffcdd2; } + .badge-teacher-test { + background: color-mix(in srgb, var(--color-primary) 8%, var(--color-bg)); + border: 1px dashed color-mix(in srgb, var(--color-primary) 35%, var(--color-bg)); + color: var(--color-primary); + font-size: 0.68rem; + font-weight: 600; + } .teacher-badge { background: color-mix(in srgb, var(--color-primary) 10%, var(--color-bg)); border: 1px solid color-mix(in srgb, var(--color-primary) 40%, var(--color-bg)); @@ -996,6 +1014,10 @@ font-size: 0.65rem; margin-left: 0.25rem; } + .student-main.is-teacher { + background: color-mix(in srgb, var(--color-primary) 3%, var(--color-bg)); + border-style: dashed; + } .btn-reset { margin-left: auto;