diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c3d422..4abf65a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,11 @@ All notable changes to SourceDraft are documented here. The project uses [Semant with an accessible in-Studio dialog (labelled fields, Enter to submit, Escape to cancel, bare-domain URLs gain `https://`). Removed the unused legacy `MarkdownToolbar`. +- **Onboarding / settings staging (Phase 4c)** — Settings now opens with a clear + title and is staged into steps that surface publishing readiness as the + obvious first action, with advanced configuration behind progressive + disclosure. Tokenized the onboarding/settings surfaces (spacing, radius, and + off-scale font sizes) onto the design system. ## v0.1.0 diff --git a/apps/studio/e2e/smoke.spec.ts b/apps/studio/e2e/smoke.spec.ts index 4369f04..0291db1 100644 --- a/apps/studio/e2e/smoke.spec.ts +++ b/apps/studio/e2e/smoke.spec.ts @@ -181,14 +181,29 @@ test.describe("Studio smoke", () => { await expect(page.getByRole("heading", { name: "Content quality" })).toBeVisible(); }); - test("settings setup health renders", async ({ page }) => { + test("settings is staged with readiness as the first step", async ({ page }) => { await enterDemoMode(page); await page.getByRole("button", { name: "Settings", exact: true }).click(); + + // Page is oriented: a clear title and staged steps. await expect( - page.getByRole("heading", { name: "Status & configuration" }), + page.getByRole("heading", { name: "Settings", level: 1 }), ).toBeVisible(); - await expect(page.getByRole("heading", { name: "Welcome to SourceDraft" })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Publishing readiness" })).toBeVisible(); + await expect(page.getByText("Step 1 · Publishing")).toBeVisible(); + await expect(page.getByText("Step 2 · How it works")).toBeVisible(); + + // Publishing readiness (step 1) appears before the explainer (step 2). + const readiness = page.getByRole("heading", { name: "Publishing readiness" }); + const welcome = page.getByRole("heading", { name: "Welcome to SourceDraft" }); + await expect(readiness).toBeVisible(); + await expect(welcome).toBeVisible(); + const readinessBox = await readiness.boundingBox(); + const welcomeBox = await welcome.boundingBox(); + expect(readinessBox && welcomeBox).toBeTruthy(); + expect(readinessBox!.y).toBeLessThan(welcomeBox!.y); + + // Advanced config stays behind progressive disclosure. + await expect(page.getByRole("heading", { name: "Diagnostics" })).toBeHidden(); await page.locator("summary.settings-view__advanced-summary").click(); await expect(page.getByRole("heading", { name: "Diagnostics" })).toBeVisible(); await expect(page.getByRole("heading", { name: "Setup detection" })).toBeVisible(); @@ -204,7 +219,7 @@ test.describe("Studio smoke", () => { await nav.getByRole("button", { name: "Settings", exact: true }).click(); await expect( - page.getByRole("heading", { name: "Status & configuration" }), + page.getByRole("heading", { name: "Settings", level: 1 }), ).toBeVisible(); await expect( nav.getByRole("button", { name: "Settings", exact: true }), diff --git a/apps/studio/src/components/SettingsPanel.tsx b/apps/studio/src/components/SettingsPanel.tsx index f83ca76..3a099fe 100644 --- a/apps/studio/src/components/SettingsPanel.tsx +++ b/apps/studio/src/components/SettingsPanel.tsx @@ -10,17 +10,36 @@ type SettingsPanelProps = { }; export function SettingsPanel({ config }: SettingsPanelProps) { + const connected = + config.githubOwner.trim().length > 0 && config.githubRepo.trim().length > 0; + return (
+ {connected + ? "Your blog is connected. Check publishing readiness below before you send." + : "Connect your blog and confirm publishing is ready. Prefer to explore first? Demo mode needs no setup."} +
+Step 1 · Publishing
Step 2 · How it works
+