fix(dashboard): repair certificates tab handler so main can build (#929)

* fix(dashboard): repair certificates tab handler so main can build

#854 left a duplicated, unclosed handleActiveTabChange that made the dashboard production build fail with a Svelte parse error. Keep the active tab in local state and sync the query string with replaceState so UnsavedChanges is not triggered.

Co-authored-by: best <best@classroomio.com>

* fix(dashboard): resync certificate tab when the course page is reused

SvelteKit reuses courses/[id]/certificates across course ids, so a one-time tab initializer could stick. Resync from page.url in $effect.pre without reading local tab state, since replaceState does not update page.url.

Co-authored-by: best <best@classroomio.com>

---------
This commit is contained in:
Rotimi Best
2026-08-18 13:58:26 +01:00
committed by GitHub
parent 4cd2f5f295
commit 913db2a525
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/state'; import { page } from '$app/state';
import { goto } from '$app/navigation'; import { replaceState } from '$app/navigation';
import { resolve } from '$app/paths'; import { resolve } from '$app/paths';
import { CertificatesPage } from '$features/course/pages'; import { CertificatesPage } from '$features/course/pages';
import * as Page from '@cio/ui/base/page'; import * as Page from '@cio/ui/base/page';
@@ -18,9 +18,15 @@
let errors = $state<Record<string, string>>({}); let errors = $state<Record<string, string>>({});
const certificateActiveTab = $derived.by(() => { function normalizeCertificateTab(tab: string | null) {
const tabInParam = page.url.searchParams.get('tab'); return tab === 'settings' ? 'settings' : 'design';
return tabInParam === 'settings' ? 'settings' : 'design'; }
// replaceState does not update page.url; local state handles tab clicks, this resyncs on navigation.
let certificateActiveTab = $state(normalizeCertificateTab(page.url.searchParams.get('tab')));
$effect.pre(() => {
certificateActiveTab = normalizeCertificateTab(page.url.searchParams.get('tab'));
}); });
let hasUnsavedChanges = $state(false); let hasUnsavedChanges = $state(false);
@@ -144,12 +150,17 @@
} }
function handleActiveTabChange(tab: string) { function handleActiveTabChange(tab: string) {
const nextTab = normalizeCertificateTab(tab);
if (nextTab === certificateActiveTab) {
return;
}
certificateActiveTab = nextTab;
const url = new URL(page.url); const url = new URL(page.url);
url.searchParams.set('tab', tab); url.searchParams.set('tab', nextTab);
function handleActiveTabChange(tab: string) { replaceState(resolve(`${url.pathname}${url.search}`, {}), page.state);
const url = new URL(page.url);
url.searchParams.set('tab', tab);
replaceState(url, {});
} }
</script> </script>