CLASSROOMIO-T-168: Mark lesson as complete
This commit is contained in:
@@ -50,7 +50,7 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={`root ${$apps.open ? 'open dark:bg-slate-800' : 'close dark:bg-slate-800'}`}>
|
<div class={`root ${$apps.open ? 'open dark:bg-black' : 'close dark:bg-black'}`}>
|
||||||
<div class={`apps`}>
|
<div class={`apps`}>
|
||||||
<div class="lg:hidden">
|
<div class="lg:hidden">
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root w-full min-h-screen flex items-center justify-center">
|
<div class="app-background w-full min-h-screen flex items-center justify-center">
|
||||||
<div class="container border border-gray bg-white dark:bg-black">
|
<div class="container border border-gray bg-white dark:bg-black">
|
||||||
<div class="flex items-center flex-col p-2 lg:px-8 lg:py-3">
|
<div class="flex items-center flex-col p-2 lg:px-8 lg:py-3">
|
||||||
{#if !showOnlyContent || showLogo}
|
{#if !showOnlyContent || showLogo}
|
||||||
@@ -93,9 +93,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.root {
|
|
||||||
background: radial-gradient(circle at 10% 20%, rgb(239, 246, 249) 0%, rgb(206, 239, 253) 90%);
|
|
||||||
}
|
|
||||||
.container {
|
.container {
|
||||||
width: 450px;
|
width: 450px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,19 +15,20 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
export let openModal = false;
|
export let openModal = false;
|
||||||
export let isStudent;
|
export let isStudent = false;
|
||||||
let errors = {};
|
let errors = {
|
||||||
|
title: ''
|
||||||
|
};
|
||||||
let lesson = {
|
let lesson = {
|
||||||
id: null,
|
id: null,
|
||||||
title: '',
|
title: '',
|
||||||
profile: undefined,
|
profile: undefined,
|
||||||
call_url: undefined,
|
call_url: undefined,
|
||||||
lesson_at: new Date(),
|
lesson_at: new Date(),
|
||||||
is_unlocked: false,
|
is_unlocked: false
|
||||||
is_complete: false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function getLessonOrder(id) {
|
function getLessonOrder(id = '') {
|
||||||
const index = $lessons.findIndex((lesson) => lesson.id === id);
|
const index = $lessons.findIndex((lesson) => lesson.id === id);
|
||||||
if (index < 9) {
|
if (index < 9) {
|
||||||
return '0' + (index + 1);
|
return '0' + (index + 1);
|
||||||
|
|||||||
+11
-2
@@ -1,4 +1,6 @@
|
|||||||
export function getUniqueValue(label) {
|
import type { LessonCompletion } from '$lib/utils/types';
|
||||||
|
|
||||||
|
export function getUniqueValue(label: string) {
|
||||||
return label.toLowerCase().replace(' ', '');
|
return label.toLowerCase().replace(' ', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,9 +17,16 @@ export function generateQuestion(questions) {
|
|||||||
generatedQuestions.push({
|
generatedQuestions.push({
|
||||||
...question,
|
...question,
|
||||||
name,
|
name,
|
||||||
options,
|
options
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return generatedQuestions;
|
return generatedQuestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getIsLessonComplete(completions: LessonCompletion[], profileId: string | null) {
|
||||||
|
if (!Array.isArray(completions)) return false;
|
||||||
|
return completions.find((c) => {
|
||||||
|
return c.is_complete && c.profile_id === profileId;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -12,15 +12,16 @@ export const lessons: Writable<Lesson[]> = writable([]);
|
|||||||
export const lesson = writable<LessonPage>({
|
export const lesson = writable<LessonPage>({
|
||||||
id: null,
|
id: null,
|
||||||
totalExercises: 0,
|
totalExercises: 0,
|
||||||
is_complete: false,
|
|
||||||
isSaving: false,
|
isSaving: false,
|
||||||
materials: {
|
materials: {
|
||||||
note: '',
|
note: '',
|
||||||
slide_url: '',
|
slide_url: '',
|
||||||
videos: []
|
videos: []
|
||||||
},
|
},
|
||||||
exercises: []
|
exercises: [],
|
||||||
|
lesson_completion: []
|
||||||
});
|
});
|
||||||
|
|
||||||
export const isLessonDirty = writable(false);
|
export const isLessonDirty = writable(false);
|
||||||
|
|
||||||
export function handleAddLesson() {
|
export function handleAddLesson() {
|
||||||
@@ -33,8 +34,7 @@ export function handleAddLesson() {
|
|||||||
// profile: undefined,
|
// profile: undefined,
|
||||||
call_url: undefined,
|
call_url: undefined,
|
||||||
lesson_at: new Date(),
|
lesson_at: new Date(),
|
||||||
is_unlocked: false,
|
is_unlocked: false
|
||||||
is_complete: false
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}) as Updater<any>);
|
}) as Updater<any>);
|
||||||
@@ -60,12 +60,11 @@ export async function handleSaveLesson(lesson: Lesson, course_id: Course['id'])
|
|||||||
console.log(`handleSaveLesson lesson`, lesson);
|
console.log(`handleSaveLesson lesson`, lesson);
|
||||||
const newLesson = {
|
const newLesson = {
|
||||||
title: lesson.title,
|
title: lesson.title,
|
||||||
lesson_at: lesson.lesson_at,
|
lesson_at: lesson?.lesson_at,
|
||||||
call_url: lesson.call_url,
|
call_url: lesson?.call_url,
|
||||||
teacher_id: lesson.profile ? lesson.profile.id : undefined,
|
teacher_id: lesson?.profile ? lesson?.profile.id : undefined,
|
||||||
course_id,
|
course_id,
|
||||||
is_unlocked: lesson.is_unlocked,
|
is_unlocked: lesson.is_unlocked
|
||||||
is_complete: lesson.is_complete
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let newLessonData: any[] | null = null;
|
let newLessonData: any[] | null = null;
|
||||||
@@ -85,7 +84,7 @@ export async function handleUpdateLessonMaterials(lesson: any, lessonId: Lesson[
|
|||||||
const materials = {
|
const materials = {
|
||||||
...lesson.materials
|
...lesson.materials
|
||||||
};
|
};
|
||||||
|
delete materials.lesson_completion;
|
||||||
delete materials.profile;
|
delete materials.profile;
|
||||||
delete materials.totalExercises;
|
delete materials.totalExercises;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<script>
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
@@ -11,40 +11,40 @@
|
|||||||
import TextChip from '$lib/components/Chip/Text.svelte';
|
import TextChip from '$lib/components/Chip/Text.svelte';
|
||||||
import { lessons } from '../Lesson/store/lessons';
|
import { lessons } from '../Lesson/store/lessons';
|
||||||
import { course } from '$lib/components/Course/store';
|
import { course } from '$lib/components/Course/store';
|
||||||
import { updateCourse } from '$lib/utils/services/courses';
|
|
||||||
import { NavClasses } from '$lib/utils/constants/reusableClass';
|
import { NavClasses } from '$lib/utils/constants/reusableClass';
|
||||||
import { isMobile } from '$lib/utils/store/useMobile';
|
import { isMobile } from '$lib/utils/store/useMobile';
|
||||||
import { menu } from '$lib/components/Org/store';
|
import { menu } from '$lib/components/Org/store';
|
||||||
|
import { profile } from '$lib/utils/store/user';
|
||||||
|
import { getIsLessonComplete } from '../Lesson/functions';
|
||||||
|
|
||||||
export let path;
|
export let path: string;
|
||||||
export let isStudent = null;
|
export let isStudent: boolean = false;
|
||||||
|
|
||||||
let show = null;
|
interface NavItem {
|
||||||
|
label: string;
|
||||||
|
to: string;
|
||||||
|
hideSortIcon: boolean;
|
||||||
|
isLecture?: boolean;
|
||||||
|
show?: () => boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
let show: boolean = false;
|
||||||
let isLessonActive = false;
|
let isLessonActive = false;
|
||||||
|
|
||||||
const toggleSidebar = () => {
|
const toggleSidebar = () => {
|
||||||
$menu.hidden = !$menu.hidden;
|
$menu.hidden = !$menu.hidden;
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleMainGroupClick(href) {
|
function handleMainGroupClick(href: string) {
|
||||||
return () => {
|
return () => {
|
||||||
goto(href);
|
goto(href);
|
||||||
toggleSidebar();
|
toggleSidebar();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let navItems = [];
|
let navItems: NavItem[] = [];
|
||||||
|
|
||||||
function getHref(item) {
|
function handleMobileChange(isMobile: boolean) {
|
||||||
return item.to;
|
|
||||||
// return item.is_unlocked ? item.to : path || $page.url.pathname
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSaveTitle() {
|
|
||||||
updateCourse($course.id, { title: $course.title });
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMobileChange(isMobile) {
|
|
||||||
if (isMobile) show = false;
|
if (isMobile) show = false;
|
||||||
else show = true;
|
else show = true;
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@
|
|||||||
<span class="text-md ml-2" title="This lesson is locked.">
|
<span class="text-md ml-2" title="This lesson is locked.">
|
||||||
<LockedIcon class="carbon-icon dark:text-white" />
|
<LockedIcon class="carbon-icon dark:text-white" />
|
||||||
</span>
|
</span>
|
||||||
{:else if item.is_complete}
|
{:else if getIsLessonComplete(item.lesson_completion, $profile.id)}
|
||||||
<span class="ml-2" title="You have completed this lesson">
|
<span class="ml-2" title="You have completed this lesson">
|
||||||
<CheckmarkFilled class="carbon-icon dark:text-white" />
|
<CheckmarkFilled class="carbon-icon dark:text-white" />
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -58,14 +58,16 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
{#if isCoursePage}
|
{#if isCoursePage}
|
||||||
<IconButton
|
<div class="hidden md:block">
|
||||||
onClick={() => {
|
<IconButton
|
||||||
goto(`${$currentOrgPath}/courses`);
|
onClick={() => {
|
||||||
}}
|
goto(`${$currentOrgPath}/courses`);
|
||||||
size="small"
|
}}
|
||||||
>
|
size="small"
|
||||||
<CourseIcon color="#fff" />
|
>
|
||||||
</IconButton>
|
<CourseIcon color="#fff" />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<a
|
<a
|
||||||
href={getPathName(isCoursePage, $course.slug)}
|
href={getPathName(isCoursePage, $course.slug)}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
export let logo;
|
export let logo;
|
||||||
export let orgName;
|
export let orgName;
|
||||||
export let isOrgSite = false;
|
export let isOrgSite = false;
|
||||||
export let backgroundColor = 'bg-white';
|
export let backgroundColor = 'bg-white dark:bg-black';
|
||||||
|
|
||||||
let navClass = '';
|
let navClass = '';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
import { supabase } from '$lib/utils/functions/supabase';
|
import { supabase } from '$lib/utils/functions/supabase';
|
||||||
import { isUUID } from '$lib/utils/functions/isUUID';
|
import { isUUID } from '$lib/utils/functions/isUUID';
|
||||||
import { QUESTION_TYPE } from '$lib/components/Question/constants';
|
import { QUESTION_TYPE } from '$lib/components/Question/constants';
|
||||||
import type { Lesson, Course, Group, Groupmember, Exercise } from '$lib/utils/types';
|
import type {
|
||||||
|
Lesson,
|
||||||
|
Course,
|
||||||
|
Group,
|
||||||
|
Groupmember,
|
||||||
|
Exercise,
|
||||||
|
LessonCompletion
|
||||||
|
} from '$lib/utils/types';
|
||||||
import { STATUS } from '$lib/utils/constants/course';
|
import { STATUS } from '$lib/utils/constants/course';
|
||||||
|
|
||||||
export async function fetchCourse(courseId?: Course['id'], slug?: Course['slug']) {
|
export async function fetchCourse(courseId?: Course['id'], slug?: Course['slug']) {
|
||||||
@@ -36,9 +43,10 @@ export async function fetchCourse(courseId?: Course['id'], slug?: Course['slug']
|
|||||||
is_certificate_downloadable,
|
is_certificate_downloadable,
|
||||||
certificate_theme,
|
certificate_theme,
|
||||||
lessons:lesson(
|
lessons:lesson(
|
||||||
id, title,public, lesson_at, call_url, is_unlocked, is_complete, order, created_at,
|
id, title,public, lesson_at, call_url, is_unlocked, order, created_at,
|
||||||
note, videos, slide_url, call_url, totalExercises:exercise(count),
|
note, videos, slide_url, call_url, totalExercises:exercise(count),
|
||||||
profile:teacher_id(id, avatar_url, fullname)
|
profile:teacher_id(id, avatar_url, fullname),
|
||||||
|
lesson_completion(id, profile_id, is_complete)
|
||||||
),
|
),
|
||||||
attendance:group_attendance(*)
|
attendance:group_attendance(*)
|
||||||
`
|
`
|
||||||
@@ -138,7 +146,9 @@ export function deleteGroupMember(groupMemberId: Groupmember['id']) {
|
|||||||
export function fetchLesson(lessonId: Lesson['id']) {
|
export function fetchLesson(lessonId: Lesson['id']) {
|
||||||
return supabase
|
return supabase
|
||||||
.from('lesson')
|
.from('lesson')
|
||||||
.select(`id, note, videos, slide_url, call_url, totalExercises:exercise(count)`)
|
.select(
|
||||||
|
`id, note, videos, slide_url, call_url, totalExercises:exercise(count), lesson_completion(id, profile_id, is_complete)`
|
||||||
|
)
|
||||||
.eq('id', lessonId)
|
.eq('id', lessonId)
|
||||||
.single();
|
.single();
|
||||||
}
|
}
|
||||||
@@ -154,6 +164,10 @@ export function updateLesson(lesson: any, lessonId: Lesson['id']) {
|
|||||||
.match({ id: lessonId });
|
.match({ id: lessonId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateLessonCompletion(completion: LessonCompletion) {
|
||||||
|
return supabase.from('lesson_completion').upsert(completion);
|
||||||
|
}
|
||||||
|
|
||||||
export function deleteLesson(lessonId: Lesson['id']) {
|
export function deleteLesson(lessonId: Lesson['id']) {
|
||||||
// Need to implement soft delete
|
// Need to implement soft delete
|
||||||
return supabase.from('lesson').delete().match({ id: lessonId });
|
return supabase.from('lesson').delete().match({ id: lessonId });
|
||||||
|
|||||||
@@ -143,14 +143,14 @@ export interface Group_attendance {
|
|||||||
groupmember?: Groupmember;
|
groupmember?: Groupmember;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VideoType {
|
export enum VideoType {
|
||||||
youtube,
|
youtube,
|
||||||
muse
|
muse
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LessonPage {
|
export interface LessonPage {
|
||||||
id?: string | null;
|
id?: string | null;
|
||||||
totalExercises: Number;
|
totalExercises: Number;
|
||||||
is_complete: Boolean;
|
|
||||||
isSaving: Boolean;
|
isSaving: Boolean;
|
||||||
materials: {
|
materials: {
|
||||||
note: string;
|
note: string;
|
||||||
@@ -162,6 +162,16 @@ export interface LessonPage {
|
|||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
exercises: [];
|
exercises: [];
|
||||||
|
lesson_completion: LessonCompletion[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LessonCompletion {
|
||||||
|
id?: number;
|
||||||
|
lesson_id: string;
|
||||||
|
profile_id: string;
|
||||||
|
is_complete: boolean;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Lesson {
|
export interface Lesson {
|
||||||
@@ -169,19 +179,19 @@ export interface Lesson {
|
|||||||
videos?: []; // type unknown;
|
videos?: []; // type unknown;
|
||||||
slide_url?: any; // type unknown;
|
slide_url?: any; // type unknown;
|
||||||
course_id: string /* foreign key to course.id */;
|
course_id: string /* foreign key to course.id */;
|
||||||
id?: string /* primary key */;
|
id: string /* primary key */;
|
||||||
created_at?: string;
|
created_at?: string;
|
||||||
updated_at?: string;
|
updated_at?: string;
|
||||||
title: any; // type unknown;
|
title: string; // type unknown;
|
||||||
public?: boolean;
|
public?: boolean;
|
||||||
lesson_at?: string;
|
lesson_at?: string;
|
||||||
teacher_id?: string /* foreign key to profile.id */;
|
teacher_id?: string /* foreign key to profile.id */;
|
||||||
is_unlocked?: boolean;
|
is_unlocked?: boolean;
|
||||||
is_complete?: boolean;
|
|
||||||
call_url?: string;
|
call_url?: string;
|
||||||
order?: number;
|
order?: number;
|
||||||
course?: Course;
|
course?: Course;
|
||||||
profile?: Profile;
|
profile?: Profile;
|
||||||
|
lesson_completion: LessonCompletion[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Exercise {
|
export interface Exercise {
|
||||||
|
|||||||
@@ -368,11 +368,15 @@
|
|||||||
rgb(239, 246, 249) 0%,
|
rgb(239, 246, 249) 0%,
|
||||||
rgb(206, 239, 253) 90%
|
rgb(206, 239, 253) 90%
|
||||||
);
|
);
|
||||||
|
--dark-app-background: radial-gradient(circle at 10% 20%, rgb(0 0 0) 0%, rgb(27 60 74) 90%);
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.app-background) {
|
:global(.app-background) {
|
||||||
background: var(--app-background);
|
background: var(--app-background);
|
||||||
}
|
}
|
||||||
|
:global(.dark .app-background) {
|
||||||
|
background: var(--dark-app-background);
|
||||||
|
}
|
||||||
|
|
||||||
:global(.bx--data-table-container) {
|
:global(.bx--data-table-container) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script lang="ts">
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||||
import { fetchCourse, fetchLesson } from '$lib/utils/services/courses';
|
import { fetchCourse, fetchLesson, updateLessonCompletion } from '$lib/utils/services/courses';
|
||||||
import CheckmarkOutlineIcon from 'carbon-icons-svelte/lib/CheckmarkOutline.svelte';
|
import CheckmarkOutlineIcon from 'carbon-icons-svelte/lib/CheckmarkOutline.svelte';
|
||||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||||
@@ -26,7 +26,9 @@
|
|||||||
import { currentOrg } from '$lib/utils/store/org';
|
import { currentOrg } from '$lib/utils/store/org';
|
||||||
import { snackbarStore } from '$lib/components/Snackbar/store';
|
import { snackbarStore } from '$lib/components/Snackbar/store';
|
||||||
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
||||||
import { FaceSatisfied } from 'carbon-icons-svelte';
|
import type { LessonCompletion, LessonPage } from '$lib/utils/types';
|
||||||
|
import { profile } from '$lib/utils/store/user.js';
|
||||||
|
import { getIsLessonComplete } from '$lib/components/Course/components/Lesson/functions';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
@@ -39,7 +41,7 @@
|
|||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
let isSaving = false;
|
let isSaving = false;
|
||||||
|
|
||||||
function getLessonOrder(id) {
|
function getLessonOrder(id: string) {
|
||||||
const index = $lessons.findIndex((lesson) => lesson.id === id);
|
const index = $lessons.findIndex((lesson) => lesson.id === id);
|
||||||
|
|
||||||
if (index < 10) {
|
if (index < 10) {
|
||||||
@@ -56,7 +58,8 @@
|
|||||||
if (!$course.id) {
|
if (!$course.id) {
|
||||||
const { data: _data } = await fetchCourse(data.courseId);
|
const { data: _data } = await fetchCourse(data.courseId);
|
||||||
|
|
||||||
lessonData = _data?.lessons.find((lesson = { id: '' }) => lesson.id === lessonId);
|
lessonData = _data?.lessons.find((lesson) => lesson.id === lessonId);
|
||||||
|
|
||||||
setCourse(_data);
|
setCourse(_data);
|
||||||
} else if (prevLessonId !== lessonId) {
|
} else if (prevLessonId !== lessonId) {
|
||||||
const lesson = await fetchLesson(lessonId);
|
const lesson = await fetchLesson(lessonId);
|
||||||
@@ -71,9 +74,40 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function markLessonComplete() {
|
async function markLessonComplete() {
|
||||||
|
let found = false;
|
||||||
isMarkingComplete = true;
|
isMarkingComplete = true;
|
||||||
$lesson.is_complete = !$lesson.is_complete;
|
|
||||||
await handleSaveLesson($lesson, $course.id);
|
let completion: LessonCompletion = {
|
||||||
|
is_complete: true,
|
||||||
|
profile_id: $profile.id || '',
|
||||||
|
lesson_id: $lesson.id || '',
|
||||||
|
created_at: new Date().toDateString(),
|
||||||
|
updated_at: new Date().toDateString()
|
||||||
|
};
|
||||||
|
const completions: LessonCompletion[] = $lesson.lesson_completion.map((_completion) => {
|
||||||
|
if (_completion.profile_id === $profile.id) {
|
||||||
|
found = true;
|
||||||
|
_completion.is_complete = !_completion.is_complete;
|
||||||
|
|
||||||
|
completion = _completion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _completion;
|
||||||
|
});
|
||||||
|
if (!found) {
|
||||||
|
completions.push(completion);
|
||||||
|
}
|
||||||
|
|
||||||
|
$lesson.lesson_completion = completions;
|
||||||
|
$lessons = $lessons.map((l) => {
|
||||||
|
if (l.id === $lesson.id) {
|
||||||
|
l.lesson_completion = completions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return l;
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateLessonCompletion(completion);
|
||||||
isMarkingComplete = false;
|
isMarkingComplete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,11 +173,18 @@
|
|||||||
function setLesson(lessonData, totalExercises) {
|
function setLesson(lessonData, totalExercises) {
|
||||||
if (!lessonData) return;
|
if (!lessonData) return;
|
||||||
|
|
||||||
|
let lesson_completion: LessonCompletion[] = [];
|
||||||
|
|
||||||
|
if (Array.isArray(lessonData.lesson_completion)) {
|
||||||
|
lesson_completion = [...lessonData.lesson_completion];
|
||||||
|
}
|
||||||
|
|
||||||
lesson.update((l) => ({
|
lesson.update((l) => ({
|
||||||
...l,
|
...l,
|
||||||
id: data.lessonId,
|
id: data.lessonId,
|
||||||
totalExercises,
|
totalExercises,
|
||||||
materials: lessonData
|
materials: lessonData,
|
||||||
|
lesson_completion
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +232,7 @@
|
|||||||
<div
|
<div
|
||||||
class={`flex-row ${
|
class={`flex-row ${
|
||||||
$apps.dropdown && $apps.open
|
$apps.dropdown && $apps.open
|
||||||
? 'absolute lg:relative top-[85px] lg:top-0 right-14 lg:right-0 z-40 dark:bg-slate-800 p-3 lg:p-0'
|
? 'absolute lg:relative top-[85px] lg:top-0 right-14 lg:right-0 z-40 dark:bg-neutral-800 p-3 lg:p-0'
|
||||||
: 'hidden'
|
: 'hidden'
|
||||||
} lg:flex items-center`}
|
} lg:flex items-center`}
|
||||||
>
|
>
|
||||||
@@ -240,7 +281,9 @@
|
|||||||
className="mt-10"
|
className="mt-10"
|
||||||
>
|
>
|
||||||
<CheckmarkOutlineIcon size={24} class="carbon-icon mr-2" />
|
<CheckmarkOutlineIcon size={24} class="carbon-icon mr-2" />
|
||||||
Mark as {$lesson.is_complete ? 'Incomplete' : 'Complete'}
|
Mark as {getIsLessonComplete($lesson.lesson_completion, $profile.id)
|
||||||
|
? 'Incomplete'
|
||||||
|
: 'Complete'}
|
||||||
</PrimaryButton>
|
</PrimaryButton>
|
||||||
</div>
|
</div>
|
||||||
</PageBody>
|
</PageBody>
|
||||||
|
|||||||
Reference in New Issue
Block a user