From 74c87fb72a0e619ca341d42de16e88b144329487 Mon Sep 17 00:00:00 2001 From: Rotimi Best Date: Wed, 11 Mar 2026 11:21:41 +0100 Subject: [PATCH] feat: centralize baseURL and app experience for cloud and self hosted --- .../src/lib/components/Navigation/app.svelte | 4 +- .../lib/components/Navigation/index.svelte | 10 ++--- .../src/lib/features/app/init.svelte.ts | 18 +++----- .../src/lib/features/app/layout-setup.ts | 5 ++- .../community/api/community.svelte.ts | 42 ++++++++----------- .../components/ask-community-button.svelte | 7 ++-- .../community/pages/ask-community.svelte | 18 ++------ .../community/pages/community-question.svelte | 15 +++---- .../features/community/pages/community.svelte | 8 ++-- .../sidebar/course-sidebar-navigation.svelte | 4 +- .../features/ui/sidebar/footer/menu.svelte | 9 +--- .../ui/sidebar/org-sidebar/org-logo.svelte | 8 ++-- apps/dashboard/src/lib/utils/store/app.ts | 21 +++++++++- .../src/routes/lms/community/+page.svelte | 4 +- .../routes/lms/community/[slug]/+page.svelte | 2 +- .../src/routes/lms/community/ask/+page.svelte | 2 +- .../org/[slug]/community/[cslug]/+page.svelte | 2 +- .../org/[slug]/community/ask/+page.svelte | 2 +- 18 files changed, 81 insertions(+), 100 deletions(-) diff --git a/apps/dashboard/src/lib/components/Navigation/app.svelte b/apps/dashboard/src/lib/components/Navigation/app.svelte index e9f451e3..51d9e736 100644 --- a/apps/dashboard/src/lib/components/Navigation/app.svelte +++ b/apps/dashboard/src/lib/components/Navigation/app.svelte @@ -5,7 +5,7 @@ import ArrowLeftIcon from '@lucide/svelte/icons/arrow-left'; import { IconButton } from '@cio/ui/custom/icon-button'; - import { globalStore } from '$lib/utils/store/app'; + import { isStudentExperience } from '$lib/utils/store/app'; import { currentOrgPath } from '$lib/utils/store/org'; import { t } from '$lib/utils/functions/translations'; @@ -18,7 +18,7 @@ let { title = $bindable(''), navClass = '', isCoursePage = false }: Props = $props(); let coursesPath = $derived( - $globalStore.isStudent ? '/lms/mylearning' : isCoursePage ? `${$currentOrgPath}/courses` : $currentOrgPath + $isStudentExperience ? '/lms/mylearning' : isCoursePage ? `${$currentOrgPath}/courses` : $currentOrgPath ); diff --git a/apps/dashboard/src/lib/components/Navigation/index.svelte b/apps/dashboard/src/lib/components/Navigation/index.svelte index 7704f4c9..268427e5 100644 --- a/apps/dashboard/src/lib/components/Navigation/index.svelte +++ b/apps/dashboard/src/lib/components/Navigation/index.svelte @@ -1,9 +1,8 @@ diff --git a/apps/dashboard/src/lib/features/community/pages/ask-community.svelte b/apps/dashboard/src/lib/features/community/pages/ask-community.svelte index 5a210e02..4abe0945 100644 --- a/apps/dashboard/src/lib/features/community/pages/ask-community.svelte +++ b/apps/dashboard/src/lib/features/community/pages/ask-community.svelte @@ -9,12 +9,6 @@ import { currentOrg } from '$lib/utils/store/org'; import { communityApi } from '$features/community/api/community.svelte'; - interface Props { - isLMS?: boolean; - } - - let { isLMS = false }: Props = $props(); - let fields = $state({ title: '', body: '', @@ -45,10 +39,8 @@

- {#each communityApi.courses as course} - {#if course.id} - {course.title} - {/if} + {#each communityApi.courses as course (course.id)} + {course.title} {/each} @@ -68,11 +60,7 @@
-
diff --git a/apps/dashboard/src/lib/features/community/pages/community-question.svelte b/apps/dashboard/src/lib/features/community/pages/community-question.svelte index 98d48d6c..190964b3 100644 --- a/apps/dashboard/src/lib/features/community/pages/community-question.svelte +++ b/apps/dashboard/src/lib/features/community/pages/community-question.svelte @@ -26,11 +26,10 @@ interface Props { slug: string; - isLMS?: boolean; question?: CommunityQuestionSuccess['data'] | null; } - let { isLMS = false, question }: Props = $props(); + let { question }: Props = $props(); let commentEditor: TiptapEditor | undefined = $state(); let isValidAnswer = false; // V2 allow admin mark an answer as accepted @@ -86,7 +85,7 @@ }} onDelete={() => { if (communityApi.question) { - communityApi.deleteQuestion(String(communityApi.question.id), isLMS); + communityApi.deleteQuestion(String(communityApi.question.id)); } }} /> @@ -119,10 +118,8 @@ - {#each communityApi.courses as course} - {#if course.id} - {course.title} - {/if} + {#each communityApi.courses as course (course.id)} + {course.title} {/each} @@ -224,7 +221,7 @@
- {#each communityApi.question?.comments as commentItem} + {#each communityApi.question?.comments as commentItem (commentItem.id)} { + communityApi.createComment(Number(communityApi.question.id), () => { commentEditor?.commands?.clearContent?.(); }); } diff --git a/apps/dashboard/src/lib/features/community/pages/community.svelte b/apps/dashboard/src/lib/features/community/pages/community.svelte index 4fd40596..8c8d90c2 100644 --- a/apps/dashboard/src/lib/features/community/pages/community.svelte +++ b/apps/dashboard/src/lib/features/community/pages/community.svelte @@ -11,18 +11,18 @@ import { profile } from '$lib/utils/store/user'; import { t } from '$lib/utils/functions/translations'; import { calDateDiff } from '$lib/utils/functions/date'; - import { currentOrg, currentOrgPath } from '$lib/utils/store/org'; + import { currentOrg } from '$lib/utils/store/org'; + import { basePath } from '$lib/utils/store/app'; import { CommunityListLoader, AskCommunityButton } from '../components'; import { communityApi } from '../api/community.svelte'; import type { CommunityQuestionData } from '../utils/types'; interface Props { - isLMS?: boolean; questions?: CommunityQuestionData; } - let { isLMS = false, questions }: Props = $props(); + let { questions }: Props = $props(); let searchValue = $state(''); let selectedId = $state(''); @@ -80,7 +80,7 @@ {#each filteredQuestions as question} {#snippet child({ props })} - + diff --git a/apps/dashboard/src/lib/features/course/components/sidebar/course-sidebar-navigation.svelte b/apps/dashboard/src/lib/features/course/components/sidebar/course-sidebar-navigation.svelte index 9b01c8f3..7c2615c6 100644 --- a/apps/dashboard/src/lib/features/course/components/sidebar/course-sidebar-navigation.svelte +++ b/apps/dashboard/src/lib/features/course/components/sidebar/course-sidebar-navigation.svelte @@ -31,7 +31,7 @@ import { courseApi } from '$features/course/api'; import { t } from '$lib/utils/functions/translations'; import { currentOrg, isFreePlan, currentOrgPath } from '$lib/utils/store/org'; - import { globalStore } from '$lib/utils/store/app'; + import { isStudentExperience } from '$lib/utils/store/app'; import { getNavItemRoute, getLessonsRoute } from '$features/course/utils/functions'; import { useSidebar } from '@cio/ui/base/sidebar'; import { IconButton } from '@cio/ui/custom/icon-button'; @@ -45,7 +45,7 @@ let { path, id, isStudent = false }: Props = $props(); - const coursesListPath = $derived($globalStore.isStudent ? '/lms/mylearning' : `${$currentOrgPath}/courses`); + const coursesListPath = $derived($isStudentExperience ? '/lms/mylearning' : `${$currentOrgPath}/courses`); const contentData = $derived(getCourseContent(courseApi.course)); const sidebar = useSidebar(); const contentCount = $derived.by(() => { diff --git a/apps/dashboard/src/lib/features/ui/sidebar/footer/menu.svelte b/apps/dashboard/src/lib/features/ui/sidebar/footer/menu.svelte index f780a7e8..635930e7 100644 --- a/apps/dashboard/src/lib/features/ui/sidebar/footer/menu.svelte +++ b/apps/dashboard/src/lib/features/ui/sidebar/footer/menu.svelte @@ -1,5 +1,5 @@ @@ -16,7 +14,7 @@ class="ui:data-[state=open]:bg-sidebar-accent ui:data-[state=open]:text-sidebar-accent-foreground" > {#snippet child({ props })} - + {#if $currentOrg.name} diff --git a/apps/dashboard/src/lib/utils/store/app.ts b/apps/dashboard/src/lib/utils/store/app.ts index b99c3295..49d6bc23 100644 --- a/apps/dashboard/src/lib/utils/store/app.ts +++ b/apps/dashboard/src/lib/utils/store/app.ts @@ -1,4 +1,6 @@ -import { writable } from 'svelte/store'; +import { derived, writable } from 'svelte/store'; +import { PUBLIC_IS_SELFHOSTED } from '$env/static/public'; +import { currentOrgPath } from './org'; export const globalStore = writable<{ isDark: boolean; @@ -11,3 +13,20 @@ export const globalStore = writable<{ orgSiteName: '', isStudent: undefined }); + +/** + * Single source of truth: is this a student experience? + * Cloud: orgSite is always student. Self-hosted: check role. + */ +export const isStudentExperience = derived(globalStore, ($gs) => { + const isCloud = PUBLIC_IS_SELFHOSTED !== 'true'; + if (isCloud) return $gs.isOrgSite; + return $gs.isStudent ?? false; +}); + +/** + * The root path for navigation: '/lms' for students, '/org/{siteName}' for admin/teacher + */ +export const basePath = derived([isStudentExperience, currentOrgPath], ([$isStudent, $orgPath]) => + $isStudent ? '/lms' : $orgPath +); diff --git a/apps/dashboard/src/routes/lms/community/+page.svelte b/apps/dashboard/src/routes/lms/community/+page.svelte index 4678f007..29367316 100644 --- a/apps/dashboard/src/routes/lms/community/+page.svelte +++ b/apps/dashboard/src/routes/lms/community/+page.svelte @@ -15,12 +15,12 @@ {$t('community.title')} - + {#snippet child()} - + {/snippet} diff --git a/apps/dashboard/src/routes/lms/community/[slug]/+page.svelte b/apps/dashboard/src/routes/lms/community/[slug]/+page.svelte index 4369da58..ef1eb235 100644 --- a/apps/dashboard/src/routes/lms/community/[slug]/+page.svelte +++ b/apps/dashboard/src/routes/lms/community/[slug]/+page.svelte @@ -8,4 +8,4 @@ Question - ClassroomIO - + diff --git a/apps/dashboard/src/routes/lms/community/ask/+page.svelte b/apps/dashboard/src/routes/lms/community/ask/+page.svelte index a9ddc45d..804ac7f2 100644 --- a/apps/dashboard/src/routes/lms/community/ask/+page.svelte +++ b/apps/dashboard/src/routes/lms/community/ask/+page.svelte @@ -16,7 +16,7 @@ {#snippet child()} - + {/snippet} diff --git a/apps/dashboard/src/routes/org/[slug]/community/[cslug]/+page.svelte b/apps/dashboard/src/routes/org/[slug]/community/[cslug]/+page.svelte index da1df7ef..b6c84537 100644 --- a/apps/dashboard/src/routes/org/[slug]/community/[cslug]/+page.svelte +++ b/apps/dashboard/src/routes/org/[slug]/community/[cslug]/+page.svelte @@ -8,4 +8,4 @@ Question - ClassroomIO - + diff --git a/apps/dashboard/src/routes/org/[slug]/community/ask/+page.svelte b/apps/dashboard/src/routes/org/[slug]/community/ask/+page.svelte index 29265e58..804ac7f2 100644 --- a/apps/dashboard/src/routes/org/[slug]/community/ask/+page.svelte +++ b/apps/dashboard/src/routes/org/[slug]/community/ask/+page.svelte @@ -16,7 +16,7 @@ {#snippet child()} - + {/snippet}