From 09f986f43e63c745b9b7fe5d1e46a6ba71df51fd Mon Sep 17 00:00:00 2001 From: rotimi-best Date: Sun, 5 Sep 2021 22:16:42 +0300 Subject: [PATCH] Take attendance + fix point count --- .../Lesson/Exercise/ViewMode.svelte | 4 +- src/components/Snackbar/index.svelte | 3 +- src/routes/courses/[id]/attendance.svelte | 149 +++++++++++++++--- src/utils/services/attendance/index.js | 5 + src/utils/services/courses/index.js | 6 +- src/utils/store/attendance.js | 3 + 6 files changed, 148 insertions(+), 22 deletions(-) create mode 100644 src/utils/services/attendance/index.js create mode 100644 src/utils/store/attendance.js diff --git a/src/components/Course/components/Lesson/Exercise/ViewMode.svelte b/src/components/Course/components/Lesson/Exercise/ViewMode.svelte index e7a8dfbd..3a60b8d2 100644 --- a/src/components/Course/components/Lesson/Exercise/ViewMode.svelte +++ b/src/components/Course/components/Lesson/Exercise/ViewMode.svelte @@ -67,6 +67,8 @@ // If last question send to server if (isFinished) { $questionnaireMetaData.status = 1; + $questionnaireMetaData.totalPossibleGrade = getTotalPossibleGrade(); + $questionnaireMetaData.grades = {}; submitExercise( $questionnaireMetaData.answers, questions, @@ -95,7 +97,7 @@ function getTotalPossibleGrade() { return $questionnaire.questions.reduce((acc, question) => { - acc += question.points; + acc += parseInt(question.points, 10); return acc; }, 0); } diff --git a/src/components/Snackbar/index.svelte b/src/components/Snackbar/index.svelte index ff5e5e13..1afe4015 100644 --- a/src/components/Snackbar/index.svelte +++ b/src/components/Snackbar/index.svelte @@ -8,7 +8,7 @@ import { SNACKBAR_SEVERITY, SNACKBAR_SEVERITY_COLOR } from './constants'; import { snackbarStore } from './store'; - let severityColor = SNACKBAR_SEVERITY_COLOR[$snackbarStore.severity]; + let severityColor; function handleClose() { if (typeof $snackbarStore.handleClose === 'number') { @@ -32,6 +32,7 @@ } $: handleOpen($snackbarStore.open); + $: severityColor = SNACKBAR_SEVERITY_COLOR[$snackbarStore.severity]; {#if $snackbarStore.open} diff --git a/src/routes/courses/[id]/attendance.svelte b/src/routes/courses/[id]/attendance.svelte index 4d2647f4..314555b7 100644 --- a/src/routes/courses/[id]/attendance.svelte +++ b/src/routes/courses/[id]/attendance.svelte @@ -1,17 +1,6 @@ @@ -20,16 +9,140 @@ import CourseContainer from '../../../components/CourseContainer/index.svelte'; import PageNav from '../../../components/PageNav/index.svelte'; import PageBody from '../../../components/PageBody/index.svelte'; - import { setCourseData } from '../../../components/Course/store'; + import { + course, + group, + setCourseData, + } from '../../../components/Course/store'; + import { getLectureNo } from '../../../components/Course/function'; + import { fetchCourse } from '../../../utils/services/courses'; + import { lessons } from '../../../components/Course/components/Lesson/store/lessons'; + import { ROLE } from '../../../utils/constants/roles'; + import { takeAttendance } from '../../../utils/services/attendance'; + import { snackbarStore } from '../../../components/Snackbar/store'; + import { SNACKBAR_SEVERITY } from '../../../components/Snackbar/constants'; + import { attendance } from '../../../utils/store/attendance'; - export let courseData = {}; + export let courseId; - onMount(() => { - setCourseData(courseData); + let borderBottomGrey = 'border-r-0 border-b border-l-0 border-gray-300'; + let students = []; + + function setAttendance(courseData) { + for (const attendanceItem of courseData.attendance) { + const { student_id, lesson_id, is_present, id } = attendanceItem; + + if (!$attendance[student_id]) { + $attendance[student_id] = { + [lesson_id]: { + id, + is_present, + }, + }; + } else { + $attendance[student_id] = { + ...$attendance[student_id], + [lesson_id]: { + id, + is_present, + }, + }; + } + } + } + + onMount(async () => { + if ($course.id) return; + + const { data } = await fetchCourse(courseId); + setCourseData(data); + setAttendance(data); }); + + $: students = $group.people.filter( + (person) => !!person.profile && person.role_id === ROLE.STUDENT + ); - + +
+
+

Student

+ {#each $lessons as lesson, index} +

+ {getLectureNo(index + 1)} +

+ {/each} +
+ + {#each students as student} +
+
+ Student avatar +
+

{student.profile.fullname}

+

{`#${student.assigned_student_id}` || '-'}

+
+
+ {#each $lessons as lesson} +

+ { + const attendanceItem = $attendance[student.id] + ? $attendance[student.id][lesson.id] || {} + : {}; + const data = { + id: attendanceItem.id, + student_id: student.id, + is_present: e.target.checked, + lesson_id: lesson.id, + course_id: courseId, + }; + + takeAttendance(data).then((res) => { + if (res.error) { + console.error(`res.error`, res.error); + $snackbarStore.open = true; + $snackbarStore.severity = SNACKBAR_SEVERITY.ERROR; + $snackbarStore.message = "Something isn't right."; + } else { + console.log('res', res); + const { id, is_present } = res.data[0]; + $attendance[student.id][lesson.id] = { + id, + is_present, + }; + } + }); + }} + /> +

+ {/each} +
+ {/each} +
+
+ + diff --git a/src/utils/services/attendance/index.js b/src/utils/services/attendance/index.js new file mode 100644 index 00000000..94803ec1 --- /dev/null +++ b/src/utils/services/attendance/index.js @@ -0,0 +1,5 @@ +import { supabase } from '../../functions/supabase'; + +export async function takeAttendance(update) { + return supabase.from('group_attendance').upsert(update); +} diff --git a/src/utils/services/courses/index.js b/src/utils/services/courses/index.js index 780a44eb..70e7f613 100644 --- a/src/utils/services/courses/index.js +++ b/src/utils/services/courses/index.js @@ -36,7 +36,8 @@ export async function fetchCourse(courseId, session) { lessons:lesson( id, title,public, lesson_at, call_url, is_complete,created_at, profile:teacher_id(id, avatar_url, fullname) - ) + ), + attendance:group_attendance(*) ` ) .match({ id: courseId }) @@ -45,7 +46,8 @@ export async function fetchCourse(courseId, session) { if (!data || error) { console.log(`data`, data); console.log(`fetchCourse => error`, error); - return this.redirect(301, '/courses'); + // return this.redirect(301, '/courses'); + return; } return { diff --git a/src/utils/store/attendance.js b/src/utils/store/attendance.js new file mode 100644 index 00000000..c73220ee --- /dev/null +++ b/src/utils/store/attendance.js @@ -0,0 +1,3 @@ +import { writable } from 'svelte/store'; + +export const attendance = writable({});