From 8a5d7015323dcf69bf1c930e7e7dabb4baff625f Mon Sep 17 00:00:00 2001 From: Varshavia Date: Sun, 26 Jul 2026 02:32:16 +0300 Subject: [PATCH] fix(dashboard): stop onboarding calling a seeded site's page step Not started The onboarding checklist's third step required two pages before it flipped to done, but it was labelled "Create your first page" and reported "Not started" on a fresh install that already ships a seeded Home page. Users who edited and published that page saw the Pages widget report "1 Published" next to a checklist step insisting no page existed. Keep the two-page rule -- the step's intent is a page the user made -- and make both signals honest instead: the step now reads "Add a page of your own", says the starter Home page does not count, and reports "In progress" while the seed is the only page. Closes #223 --- docs/e2e/feature-matrix.md | 2 +- docs/features/dashboard.md | 4 ++-- src/admin/pages/dashboard/components/OnboardingPanel.tsx | 4 ++-- src/admin/pages/dashboard/hooks/useOnboardingState.ts | 8 +++++--- tests/e2e/dashboard.e2e.ts | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/e2e/feature-matrix.md b/docs/e2e/feature-matrix.md index 545466ede..151140759 100644 --- a/docs/e2e/feature-matrix.md +++ b/docs/e2e/feature-matrix.md @@ -97,7 +97,7 @@ DASH-001 note: `dashboard.e2e.ts` verifies the default owner dashboard route, Ov DASH-002 note: `dashboard.e2e.ts` verifies customize mode, the Block library, adding the built-in AI usage widget, server-backed `dashboard-layout` preference persistence, reload restoration, grid drag move, right-edge resize, drag-to-library removal, final reload absence, and 390px customize/library containment. DEF-20260623-DASH002-01 fixed invalid nested buttons in Block library live previews by rendering preview widget chrome in edit mode. -DASH-003 note: `dashboard.e2e.ts` runs in a dedicated post-setup, pre-persona project and verifies onboarding progress from genuinely clean E2E state (1/5: identity complete; framework in progress; first page, plugin, and team not started), all five step labels/actions, the Settings modal action, workspace routes for New page/Browse plugins/Add members, 390px mobile containment, and server-backed dismiss persistence through `dashboard-layout`. +DASH-003 note: `dashboard.e2e.ts` runs in a dedicated post-setup, pre-persona project and verifies onboarding progress from genuinely clean E2E state (1/5: identity complete; framework and first page in progress; plugin and team not started), all five step labels/actions, the Settings modal action, workspace routes for New page/Browse plugins/Add members, 390px mobile containment, and server-backed dismiss persistence through `dashboard-layout`. ## Capabilities And Access Control diff --git a/docs/features/dashboard.md b/docs/features/dashboard.md index 029e3bf3f..f8acb4b51 100644 --- a/docs/features/dashboard.md +++ b/docs/features/dashboard.md @@ -265,11 +265,11 @@ Each CMS hook fetches on mount through `useAsyncResource` + `apiRequest`, valida - [ ] Set site identity - [ ] Choose Core Framework import -- [ ] Create your first page +- [ ] Add a page of your own - [ ] Install a plugin - [ ] Invite your team -State lives in `useOnboardingState(...)`. It reads the current site, installed plugins, and users concurrently. The seed Home page does not satisfy "Create your first page"; that step flips done when the site has at least two pages. Framework import defaults to `active` until the user picks a framework mode. +State lives in `useOnboardingState(...)`. It reads the current site, installed plugins, and users concurrently. The seeded Home page does not satisfy "Add a page of your own"; that step flips done when the site has at least two pages, and reads `active` while only the seed exists so the checklist never reports "Not started" for a site that already has a live page. Framework import defaults to `active` until the user picks a framework mode. The panel is dismissible per-user and persisted with the dashboard layout preference (`dashboard-layout`). `useDashboardLayout.restoreOnboarding()` flips the same preference flag back to visible. diff --git a/src/admin/pages/dashboard/components/OnboardingPanel.tsx b/src/admin/pages/dashboard/components/OnboardingPanel.tsx index 709f18988..ac6d527fb 100644 --- a/src/admin/pages/dashboard/components/OnboardingPanel.tsx +++ b/src/admin/pages/dashboard/components/OnboardingPanel.tsx @@ -83,9 +83,9 @@ const STEPS: readonly StepDef[] = [ }, { id: 'firstPage', - title: 'Create your first page', + title: 'Add a page of your own', desc: - 'Start from a blank canvas, a starter layout, or import HTML and we will scaffold a tree.', + 'Beyond the starter Home page — begin from a blank canvas, a starter layout, or import HTML and we will scaffold a tree.', cta: 'New page', icon: FileTextSolidIcon, action: { kind: 'navigate', to: '/admin/site' }, diff --git a/src/admin/pages/dashboard/hooks/useOnboardingState.ts b/src/admin/pages/dashboard/hooks/useOnboardingState.ts index 166545067..56182b928 100644 --- a/src/admin/pages/dashboard/hooks/useOnboardingState.ts +++ b/src/admin/pages/dashboard/hooks/useOnboardingState.ts @@ -7,8 +7,10 @@ * • Framework import — derived from `site.settings.framework` being * populated. Defaults to `'active'` so the user is nudged to make a * deliberate decision; once they pick a mode the step flips to done. - * • First page — done when ≥ 2 pages exist (the seed Home page - * doesn't count). + * • First page — done when ≥ 2 pages exist (the seeded Home page + * doesn't count). While only the seed exists the step reads + * 'active', not 'todo': the site already has a page, so "Not + * started" would contradict the Pages widget's published count. * • First plugin — done when any plugin is installed. * • Team — done when more than the owner is in the users table. * @@ -71,7 +73,7 @@ export function useOnboardingState(): OnboardingStateResult { loading: false, identity: hasIdentity || hasFavicon ? 'done' : 'active', framework: hasFramework ? 'done' : 'active', - firstPage: pageCount >= 2 ? 'done' : 'todo', + firstPage: pageCount >= 2 ? 'done' : pageCount >= 1 ? 'active' : 'todo', plugin: plugins.length > 0 ? 'done' : 'todo', team: users.length > 1 ? 'done' : 'todo', } diff --git a/tests/e2e/dashboard.e2e.ts b/tests/e2e/dashboard.e2e.ts index 1f98bfae7..15c0fe1ea 100644 --- a/tests/e2e/dashboard.e2e.ts +++ b/tests/e2e/dashboard.e2e.ts @@ -212,7 +212,7 @@ test.describe('dashboard', () => { await expectOnboardingStep(panel, 'Set site identity', 'Completed', 'Open settings') await expectOnboardingStep(panel, 'Choose Core Framework import', 'In progress', 'Import') - await expectOnboardingStep(panel, 'Create your first page', 'Not started', 'New page') + await expectOnboardingStep(panel, 'Add a page of your own', 'In progress', 'New page') await expectOnboardingStep(panel, 'Install a plugin', 'Not started', 'Browse plugins') await expectOnboardingStep(panel, 'Invite your team', 'Not started', 'Add members')