diff --git a/apps/dashboard/src/lib/features/course/components/lesson/content-navigation-actions.svelte b/apps/dashboard/src/lib/features/course/components/lesson/content-navigation-actions.svelte index 105cec4b..e4368b49 100644 --- a/apps/dashboard/src/lib/features/course/components/lesson/content-navigation-actions.svelte +++ b/apps/dashboard/src/lib/features/course/components/lesson/content-navigation-actions.svelte @@ -8,6 +8,7 @@ import * as Tooltip from '@cio/ui/base/tooltip'; import { PercentRingProgress } from '@cio/ui/custom/percent-ring-progress'; import { isOrgStudent } from '$lib/utils/store/app'; + import { getStudentContentLockReason } from '$features/ai-assistant/utils/content-ask-ai-bar'; import { t } from '$lib/utils/functions/translations'; import { courseApi, lessonApi } from '$features/course/api'; import { getOrderedNavigableContent, getContentRoute } from '$features/course/utils/content'; @@ -69,8 +70,10 @@ const showMarkComplete = $derived(!!lessonId && !exerciseId); const currentLessonItem = $derived(lessonId ? lessonItems.find((l) => l.id === lessonId) : null); - const isTeacherLocked = $derived($isOrgStudent && currentLessonItem && !(currentLessonItem.isUnlocked ?? false)); - const isProgressionLocked = $derived($isOrgStudent && currentLessonItem?.accessible === false && !isTeacherLocked); + const contentLockReason = $derived( + lessonId ? getStudentContentLockReason(courseApi.course, lessonId, ContentType.Lesson) : null + ); + const isLessonLocked = $derived($isOrgStudent === true && contentLockReason !== null); const isVideoWatchLesson = $derived.by(() => { if (!lessonId) return false; @@ -98,7 +101,6 @@ const watchVideosRequired = $derived(lessonApi.lesson?.watchProgress?.videosRequired ?? 0); const watchVideosComplete = $derived(lessonApi.lesson?.watchProgress?.videosComplete ?? 0); - const isLessonLocked = $derived(isTeacherLocked || isProgressionLocked); const isVideoWatchComplete = $derived(isVideoWatchLesson && (lessonApi.lesson?.watchProgress?.isComplete ?? false)); const showVideoWatchCompleteState = $derived(isVideoWatchComplete || (isVideoWatchLesson && isLessonComplete)); const isMarkCompleteDisabled = $derived( diff --git a/apps/dashboard/src/lib/features/course/components/sidebar/course-content-tree.svelte b/apps/dashboard/src/lib/features/course/components/sidebar/course-content-tree.svelte index 27ff5dfd..8cb598b3 100644 --- a/apps/dashboard/src/lib/features/course/components/sidebar/course-content-tree.svelte +++ b/apps/dashboard/src/lib/features/course/components/sidebar/course-content-tree.svelte @@ -14,6 +14,7 @@ import { IconButton } from '@cio/ui/custom/icon-button'; import { RadioIcon } from '@cio/ui/custom/moving-icons'; import CourseContentIcon from '$features/course/components/course-content-icon.svelte'; + import { isOrgStudent } from '$lib/utils/store/app'; interface Props { path: string; @@ -85,7 +86,8 @@ {#snippet child({ props })} {@const isContentLocked = (contentItem.isUnlocked ?? true) === false} - {@const isLockedForStudent = isStudent && (isContentLocked || contentItem.accessible === false)} + {@const isLockedForStudent = + $isOrgStudent === true && (isContentLocked || contentItem.accessible === false)} {#snippet child({ props })} {@const isContentLocked = (contentItem.isUnlocked ?? true) === false} - {@const isLockedForStudent = isStudent && (isContentLocked || contentItem.accessible === false)} + {@const isLockedForStudent = + $isOrgStudent === true && (isContentLocked || contentItem.accessible === false)} { - if ($isOrgStudent && currentLessonContentItem) { - return (currentLessonContentItem.isUnlocked ?? false) === false; + const contentLockReason = $derived(getStudentContentLockReason(courseApi.course, lessonId, ContentType.Lesson)); + const isLessonLockedForStudent = $derived($isOrgStudent === true && contentLockReason !== null); + const isStudentLessonStateReady = $derived.by(() => { + if ($isOrgStudent !== true) { + return true; } - return (lessonApi.lesson?.isUnlocked ?? false) === false; + if (courseApi.course?.id !== courseId) { + return false; + } + + if (contentLockReason !== null) { + return true; + } + + if (currentLessonContentItem) { + return true; + } + + if (lessonApi.lesson?.id === lessonId) { + return true; + } + + return courseApi.course?.content != null; }); - const isProgressionLocked = $derived( - $isOrgStudent && currentLessonContentItem?.accessible === false && !isTeacherLocked - ); - const isLessonUnlocked = $derived(!isTeacherLocked && !isProgressionLocked); const lessonSlug = $derived(lessonApi.lesson?.slug ?? ''); const isPublicCourse = $derived(courseApi.course?.type === 'PUBLIC'); const isLiveSessionLesson = $derived(Boolean(lessonApi.lesson?.callUrl && lessonApi.lesson?.lessonAt)); @@ -450,7 +466,7 @@ {#snippet child()}
- {#if isLiveSessionLesson && mode === MODES.view && !($isOrgStudent && !isLessonUnlocked)} + {#if isLiveSessionLesson && mode === MODES.view && !isLessonLockedForStudent}
{/if} - {#if $isOrgStudent && !isLessonUnlocked} - + {#if $isOrgStudent === true && !isStudentLessonStateReady} +
+ +
+ {:else if isLessonLockedForStudent && contentLockReason} + {:else if mode === MODES.edit} {/key} + {:else if $isOrgStudent === true} + {:else} - {#if !$isOrgStudent} - - {/if} + {/if}
diff --git a/apps/dashboard/src/routes/(app)/courses/[id]/lessons/[lessonId]/+page.svelte b/apps/dashboard/src/routes/(app)/courses/[id]/lessons/[lessonId]/+page.svelte index 3aa76e87..7a13b964 100644 --- a/apps/dashboard/src/routes/(app)/courses/[id]/lessons/[lessonId]/+page.svelte +++ b/apps/dashboard/src/routes/(app)/courses/[id]/lessons/[lessonId]/+page.svelte @@ -16,7 +16,16 @@ let { data }: Props = $props(); $effect(() => { - if (!data.lesson) return; + if (!data.lessonId) return; + + if (!data.lesson) { + if (lessonApi.lesson?.id === data.lessonId) { + lessonApi.lesson = null; + } + + return; + } + const lesson = data.lesson; if (lessonApi.lesson?.id === lesson.id) return;