diff --git a/src/lib/components/Course/components/Lesson/Exercise/Analytics/index.svelte b/src/lib/components/Course/components/Lesson/Exercise/Analytics/index.svelte new file mode 100644 index 00000000..7883cbcf --- /dev/null +++ b/src/lib/components/Course/components/Lesson/Exercise/Analytics/index.svelte @@ -0,0 +1,31 @@ + + +{#if isLoading} + Loading data +{:else} + Analytics data +{/if} diff --git a/src/lib/components/Course/components/Lesson/Exercise/EditMode.svelte b/src/lib/components/Course/components/Lesson/Exercise/EditMode.svelte index fa8d88b6..bed304f2 100644 --- a/src/lib/components/Course/components/Lesson/Exercise/EditMode.svelte +++ b/src/lib/components/Course/components/Lesson/Exercise/EditMode.svelte @@ -17,11 +17,11 @@ import CheckmarkFilledIcon from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte'; import CheckmarkOutlineIcon from 'carbon-icons-svelte/lib/CheckmarkOutline.svelte'; + import TextField from '$lib/components/Form/TextField.svelte'; import Modal from '$lib/components/Modal/index.svelte'; import TextArea from '$lib/components/Form/TextArea.svelte'; import Checkbox from '$lib/components/Form/Checkbox.svelte'; import RadioItem from '$lib/components/Form/RadioItem.svelte'; - import AutoGrowTextField from '$lib/components/Form/AutoGrowTextField.svelte'; import IconButton from '$lib/components/IconButton/index.svelte'; import ErrorMessage from '$lib/components/ErrorMessage/index.svelte'; import PrimaryButton from '$lib/components/PrimaryButton/index.svelte'; @@ -34,10 +34,9 @@ import { deleteExercise } from '$lib/utils/services/courses'; import { lesson } from '../store/lessons'; - const extraActions = ['Code Snippets', 'Upload image']; const initialQuestionsLength = $questionnaire.questions.length; - export let editDescription = false; + export let shouldDeleteExercise = false; export let exerciseId; export let goBack = () => {}; @@ -65,21 +64,6 @@ handleRemoveQuestion(questionIdToDelete)(); } - function handleOptionClick(questionIndex) { - return (actionIndex) => { - switch (actionIndex) { - case 0: - handleCode(questionIndex, true); - break; - case 1: - // uploadImage(questionIndex); - break; - default: - console.log('No option'); - } - }; - } - function getQuestionErrorMsg(errors, question, errorKey) { return errors[question.id] ? errors[question.id][errorKey] : null; } @@ -108,13 +92,13 @@ (editDescription = false)} - bind:open={editDescription} + onClose={() => (shouldDeleteExercise = false)} + bind:open={shouldDeleteExercise} width="w-2/4" - modalHeading="Update description" + modalHeading="Delete Modal" >
-

Are you sure?

+

Are you sure you want to delete this exercise?

(editDescription = false)} + onClick={() => (shouldDeleteExercise = false)} /> -
+
- { - question.title = e.target?.textContent; + isRequired={true} + onChange={() => { question.is_dirty = true; }} - placeholder="Question" />
diff --git a/src/lib/components/Course/components/Lesson/Exercise/UpdateDescription.svelte b/src/lib/components/Course/components/Lesson/Exercise/UpdateDescription.svelte index ce3707cd..a6e5ef93 100644 --- a/src/lib/components/Course/components/Lesson/Exercise/UpdateDescription.svelte +++ b/src/lib/components/Course/components/Lesson/Exercise/UpdateDescription.svelte @@ -7,7 +7,7 @@ export let preview: boolean; - function getTotalPossibleGrade(questions) { + function getTotalPossibleGrade(questions: { points: string }[]) { return questions.reduce((acc, question) => { acc += parseFloat(question.points, 10); return acc; diff --git a/src/lib/components/Course/components/Lesson/Exercise/ViewMode.svelte b/src/lib/components/Course/components/Lesson/Exercise/ViewMode.svelte index 96d00939..548d49ae 100644 --- a/src/lib/components/Course/components/Lesson/Exercise/ViewMode.svelte +++ b/src/lib/components/Course/components/Lesson/Exercise/ViewMode.svelte @@ -1,4 +1,4 @@ - - - - -
- {#if $exerciseMode.editMode} + + + + + + + {#if selectedIndex === 0} +
+ +
- {/if} - {#if $exerciseMode.editMode} (preview = !preview)} - toolTipProps={{ title: 'Toggle preview', direction: 'right' }} - selected={preview} - contained={true} - size="small" + contained={preview} + toolTipProps={{ + title: 'Preview', + direction: 'bottom', + hotkeys: [] + }} > {#if preview} @@ -98,50 +102,32 @@ {/if} - {/if} -
+ handleAddQuestion()} size="small"> + + + + ($questionnaireOrder.open = true)} + /> + (shouldDeleteExercise = true)} + /> + +
+ +
+ + - - {#if $exerciseMode.editMode} -
- handleAddQuestion()} - toolTipProps={{ title: 'Add question', direction: 'bottom' }} - size="small" - > - - - ($questionnaireOrder.open = true)} - toolTipProps={{ title: 'Order questionnaire', direction: 'bottom' }} - size="small" - > - - - (editDescription = true)} - toolTipProps={{ title: 'Delete Exercise', direction: 'bottom' }} - size="small" - > - - - - -
+ {#if !isStudent && !preview} + + {:else} + {/if} -
- - {#if $exerciseMode.editMode} - - {/if} - {#if $exerciseMode.editMode && !preview} - - {:else} - + {:else if selectedIndex === 1} + {/if}
diff --git a/src/lib/components/Course/components/Lesson/Exercise/store.js b/src/lib/components/Course/components/Lesson/Exercise/store.js deleted file mode 100644 index 3c77cac0..00000000 --- a/src/lib/components/Course/components/Lesson/Exercise/store.js +++ /dev/null @@ -1,5 +0,0 @@ -import { writable } from 'svelte/store'; - -export const exerciseMode = writable({ - editMode: true -}); diff --git a/src/lib/components/Course/components/Lesson/Exercises/index.svelte b/src/lib/components/Course/components/Lesson/Exercises/index.svelte index f734d5a7..32097da8 100644 --- a/src/lib/components/Course/components/Lesson/Exercises/index.svelte +++ b/src/lib/components/Course/components/Lesson/Exercises/index.svelte @@ -13,7 +13,6 @@ import { QUESTION_TYPES } from '$lib/components/Question/constants'; import { lesson } from '../store/lessons'; import { questionnaire, isQuestionnaireFetching } from '../store/exercise'; - import { exerciseMode } from '../Exercise/store'; import NewExerciseModal from '$lib/components/Course/components/Lesson/Exercises/NewExerciseModal.svelte'; import type { ExerciseTemplate } from '$lib/utils/types'; @@ -124,7 +123,6 @@ data.is_due_by_dirty = false; questionnaire.set(data); - console.log('getExercise', exerciseId, $questionnaire); isQuestionnaireFetching.update(() => false); isFetching = false; @@ -139,8 +137,6 @@ }); $: getExercise(exerciseId); - - $: $exerciseMode.editMode = !isStudent; {#if isFetching} diff --git a/src/lib/components/IconButton/index.svelte b/src/lib/components/IconButton/index.svelte index b5b39e54..6974892f 100644 --- a/src/lib/components/IconButton/index.svelte +++ b/src/lib/components/IconButton/index.svelte @@ -1,5 +1,6 @@ {#if !!title} diff --git a/src/lib/utils/services/submissions/index.ts b/src/lib/utils/services/submissions/index.ts index b5c7a502..ad850a12 100644 --- a/src/lib/utils/services/submissions/index.ts +++ b/src/lib/utils/services/submissions/index.ts @@ -1,10 +1,12 @@ +import type { PostgrestSingleResponse } from '@supabase/supabase-js'; import { supabase } from '$lib/utils/functions/supabase'; +import type { ExerciseSubmissions } from '$lib/utils/types'; export function fetchSubmissionStatus() { return supabase.from('submissionstatus').select(`*`); } -export function fetchSubmissions(course_id) { +export function fetchSubmissions(course_id: string) { return supabase .from('submission') .select( @@ -33,28 +35,58 @@ export function fetchSubmissions(course_id) { }); } -export async function fetchSubmission({ courseId, exerciseId, submittedBy }) { +export async function fetchSubmission({ + courseId, + exerciseId, + submittedBy +}: { + exerciseId: string; + courseId?: string; + submittedBy?: string; +}) { + const query: { + exercise_id: string; + course_id?: string; + submitted_by?: string; + } = { + exercise_id: exerciseId + }; + + if (courseId) { + query.course_id = courseId; + } + if (submittedBy) { + query.submitted_by = submittedBy; + } + return supabase .from('submission') .select( ` id, answers:question_answer(*), - status_id + status_id, + submitted_by:groupmember!inner( + profile!inner( + id, + fullname, + avatar_url + ) + ) ` ) - .match({ - submitted_by: submittedBy, - exercise_id: exerciseId, - course_id: courseId - }); + .match(query) + .returns(); } export async function updateSubmission( { id, status_id, total }: { id?: number; status_id?: number; total?: number }, otherArgs?: any ) { - const toUpdate = { + const toUpdate: { + status_id?: number; + total?: number; + } = { status_id }; @@ -65,6 +97,6 @@ export async function updateSubmission( return supabase.from('submission').update(toUpdate, otherArgs).match({ id }); } -export async function updateQuestionAnswer(update, match) { +export async function updateQuestionAnswer(update: any, match: any) { return supabase.from('question_answer').update(update).match(match); } diff --git a/src/lib/utils/types/index.ts b/src/lib/utils/types/index.ts index b7e829c5..ee8e36ed 100644 --- a/src/lib/utils/types/index.ts +++ b/src/lib/utils/types/index.ts @@ -35,6 +35,26 @@ export interface ExerciseTemplate { }[]; }; } +export interface ExerciseSubmissions { + id: string; + status_id: number; + submitted_by: { + profile: { + id: string; + fullname: string; + avatar_url: string; + }; + }; + answers: { + answers: string[]; + group_member_id: string; + id: number; + open_answer: string; + point: number; + question_id: number; + submission_id: string; + }[]; +} //=========================================== interface CourseMetadata {