Refactor app state management: replace globalStore.isStudent with isOrgStudent across multiple components for improved clarity and consistency. Update related logic to utilize isSelfPacedLikeCourse for self-paced course checks.

This commit is contained in:
Rotimi Best
2026-04-12 18:07:33 +01:00
parent 31cc45a277
commit 8ea0ab0a76
16 changed files with 57 additions and 64 deletions
@@ -8,7 +8,7 @@
import { profile } from '$lib/utils/store/user';
import { ROLE } from '@cio/utils/constants';
import { globalStore } from '$lib/utils/store/app';
import { isOrgStudent } from '$lib/utils/store/app';
import { t } from '$lib/utils/functions/translations';
import { courseApi, attendanceApi } from '$features/course/api';
import { getLectureNo } from '$features/course/utils/functions';
@@ -23,7 +23,7 @@
let { courseId }: Props = $props();
const students: CourseMembers = $derived(
$globalStore.isStudent
$isOrgStudent
? courseApi.group.people.filter((person) => !!person.profile && person.profile.id === $profile.id)
: courseApi.group.people.filter((person) => !!person.profile && Number(person.roleId) === ROLE.STUDENT)
);
@@ -71,7 +71,7 @@
}
async function handleAttendanceChange(e: any, student: CourseMember, lesson: CourseContentItem) {
if ($globalStore.isStudent) return;
if ($isOrgStudent) return;
const isPresent = e.target.checked;
@@ -167,7 +167,7 @@
<Table.Cell class="text-center">
<div class="flex justify-center">
<Checkbox
disabled={$globalStore.isStudent}
disabled={$isOrgStudent}
checked={getAttendanceStatus(student.id, lesson.id)}
onCheckedChange={(checked) => {
const e = { target: { checked } };
@@ -24,7 +24,7 @@
import { ZExerciseUpdate } from '@cio/utils/validation/exercise';
import { mapZodErrorsToTranslations } from '$lib/utils/validation';
import { transformQuestionsToApiFormat } from '$features/course/components/exercise/functions';
import { globalStore } from '$lib/utils/store/app';
import { isOrgStudent } from '$lib/utils/store/app';
import { t } from '$lib/utils/functions/translations';
import { snackbar } from '$features/ui/snackbar/store';
import { exerciseApi } from '$features/course/api';
@@ -37,6 +37,7 @@
import UpdateDescription from '$features/course/components/exercise/update-description.svelte';
import { ContentNavigationActions } from '$features/course/components/lesson';
import { RefreshPageData, RoleBasedSecurity } from '$features/ui';
import { isSelfPacedLikeCourse } from '$features/course/utils/compliance-utils';
import { getOrderedNavigableContent } from '$features/course/utils/content';
import { Empty } from '@cio/ui/custom/empty';
import VideoIcon from '@lucide/svelte/icons/video';
@@ -94,7 +95,7 @@
}
async function handleSave() {
if ($globalStore.isStudent || !courseApi.course?.id) return;
if ($isOrgStudent || !courseApi.course?.id) return;
// Transform questionnaire to API format for validation
// Include all non-deleted options (even empty ones) so Zod can catch validation errors
@@ -231,7 +232,7 @@
);
const isExerciseUnlocked = $derived(exerciseContentItem?.isUnlocked ?? false);
const isSelfPacedCourse = $derived(courseApi.course?.type === 'SELF_PACED');
const isSelfPacedCourse = $derived(isSelfPacedLikeCourse(courseApi.course?.type));
const activeQuestionTypeIds = $derived(
($questionnaire.questions ?? []).filter((q) => !q.deletedAt).map((q) => getQuestionTypeId(q))
);
@@ -244,7 +245,7 @@
isSelfPacedCourse && isExerciseFullyAutoGradable(activeQuestionTypeIds)
);
const teacherAutoGradeBadge = $derived.by(() => {
if ($globalStore.isStudent || !isSelfPacedCourse || activeQuestionTypeIds.length === 0) return null;
if ($isOrgStudent || !isSelfPacedCourse || activeQuestionTypeIds.length === 0) return null;
return isExerciseFullyAutoGradable(activeQuestionTypeIds) ? ('auto' as const) : ('manual' as const);
});
</script>
@@ -268,7 +269,7 @@
</Page.HeaderContent>
<Page.Action>
<div class="flex items-center gap-2">
{#if $globalStore.isStudent && courseApi.course?.id && exerciseId}
{#if $isOrgStudent && courseApi.course?.id && exerciseId}
<ContentNavigationActions courseId={courseApi.course.id} {exerciseId} />
{/if}
@@ -332,7 +333,7 @@
<Page.Body>
{#snippet child()}
<div class="overflow-x-hidden">
{#if $globalStore.isStudent}
{#if $isOrgStudent}
{#if isExerciseUnlocked}
<ViewMode {preview} {exerciseId} isFetchingExercise={isFetching} {mySubmissions} />
{:else}
@@ -15,7 +15,7 @@
import MODES from '$lib/utils/constants/mode';
import { profile } from '$lib/utils/store/user';
import { globalStore } from '$lib/utils/store/app';
import { isOrgStudent } from '$lib/utils/store/app';
import { currentOrg } from '$lib/utils/store/org';
import { snackbar } from '$features/ui/snackbar/store';
import { RefreshPageData, UnsavedChanges } from '$features/ui';
@@ -365,7 +365,7 @@
</Page.HeaderContent>
<Page.Action>
<div class="flex items-center gap-2">
{#if mode === MODES.view && $globalStore.isStudent}
{#if mode === MODES.view && $isOrgStudent}
<ContentNavigationActions {lessonId} {courseId} />
{/if}
@@ -406,7 +406,7 @@
<Page.Body>
{#snippet child()}
<div class="overflow-x-hidden lg:w-full xl:w-11/12">
{#if $globalStore.isStudent && lessonApi.lesson && !isLessonUnlocked}
{#if $isOrgStudent && lessonApi.lesson && !isLessonUnlocked}
<Empty
title={$t('course.navItem.lessons.content_locked_title')}
description={$t('course.navItem.lessons.content_locked_description')}
@@ -488,7 +488,7 @@
variant="page"
class="text-center"
>
{#if !$globalStore.isStudent}
{#if !$isOrgStudent}
<Button onclick={toggleMode}>
{$t('course.navItem.lessons.materials.get_started')}
</Button>