Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
25 changes: 20 additions & 5 deletions apps/studio/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 }),
Expand Down
27 changes: 23 additions & 4 deletions apps/studio/src/components/SettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,36 @@ type SettingsPanelProps = {
};

export function SettingsPanel({ config }: SettingsPanelProps) {
const connected =
config.githubOwner.trim().length > 0 && config.githubRepo.trim().length > 0;

return (
<div className="settings-view">
<header className="settings-view__intro">
<h1 className="settings-view__heading">Settings</h1>
<p className="settings-view__subhead">
{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."}
</p>
</header>

<section
className="settings-view__group"
aria-label="Status and configuration"
className="settings-view__step"
aria-labelledby="setup-health-title"
>
<h2 className="settings-view__group-title">Status &amp; configuration</h2>
<WriterWelcomeCard variant="settings" />
<p className="settings-view__step-eyebrow">Step 1 · Publishing</p>
<SetupHealthPanel />
</section>

<section
className="settings-view__step"
aria-labelledby="welcome-card-title"
>
<p className="settings-view__step-eyebrow">Step 2 · How it works</p>
<WriterWelcomeCard variant="settings" />
</section>

<details className="settings-view__advanced">
<summary className="settings-view__advanced-summary">
Advanced configuration
Expand Down
78 changes: 55 additions & 23 deletions apps/studio/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,45 @@ code {
.settings-view {
display: flex;
flex-direction: column;
gap: 16px;
gap: var(--space-5);
}

.settings-view__intro {
display: flex;
flex-direction: column;
gap: var(--space-1);
}

.settings-view__heading {
font-size: var(--text-2xl);
font-weight: 600;
color: var(--text);
}

.settings-view__subhead {
font-size: var(--text-base);
color: var(--text-muted);
max-width: 60ch;
}

.settings-view__step {
display: flex;
flex-direction: column;
gap: var(--space-2);
}

.settings-view__step-eyebrow {
font-size: var(--text-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--accent);
}

.settings-view__group {
display: flex;
flex-direction: column;
gap: 12px;
gap: var(--space-3);
}

.settings-view__group-title {
Expand Down Expand Up @@ -1959,7 +1991,7 @@ select.field__input:focus-visible {

.settings-panel__note {
margin: 0;
padding: 12px 14px;
padding: var(--space-3) var(--space-4);
font-size: var(--text-sm);
color: var(--text-muted);
line-height: 1.55;
Expand All @@ -1969,8 +2001,8 @@ select.field__input:focus-visible {
.settings-panel__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
padding: 14px;
gap: var(--space-3);
padding: var(--space-4);
}

.validation-panel {
Expand Down Expand Up @@ -2327,14 +2359,14 @@ select.field__input:focus-visible {
flex-wrap: wrap;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
padding: 12px 16px;
gap: var(--space-3);
padding: var(--space-3) var(--space-4);
border-bottom: 1px solid var(--border);
background: var(--bg-raised);
}

.post-login-welcome__title {
margin: 0 0 4px;
margin: 0 0 var(--space-1);
font-size: var(--text-sm);
font-weight: 600;
color: var(--text);
Expand All @@ -2349,8 +2381,8 @@ select.field__input:focus-visible {
}

.post-login-welcome__tips {
margin: 8px 0 0;
padding-left: 18px;
margin: var(--space-2) 0 0;
padding-left: var(--space-5);
font-size: var(--text-xs);
color: var(--text-muted);
line-height: 1.45;
Expand All @@ -2359,12 +2391,12 @@ select.field__input:focus-visible {
.post-login-welcome__actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
gap: var(--space-2);
flex-shrink: 0;
}

.settings-view__advanced {
margin-top: 8px;
margin-top: var(--space-2);
}

.settings-view__advanced-summary {
Expand All @@ -2376,10 +2408,10 @@ select.field__input:focus-visible {
}

.setup-health__advanced {
margin-top: 12px;
margin-top: var(--space-3);
display: flex;
flex-direction: column;
gap: 10px;
gap: var(--space-2);
}

.setup-health__advanced-toggle {
Expand All @@ -2389,8 +2421,8 @@ select.field__input:focus-visible {
.login-screen__form {
display: flex;
flex-direction: column;
gap: 14px;
padding: 14px;
gap: var(--space-4);
padding: var(--space-4);
}

.login-screen__intro {
Expand Down Expand Up @@ -2482,7 +2514,7 @@ select.field__input:focus-visible {
}

.setup-health__next-action {
margin-bottom: 12px;
margin-bottom: var(--space-3);
}

.setup-health__list {
Expand All @@ -2491,17 +2523,17 @@ select.field__input:focus-visible {
padding: 0;
display: flex;
flex-direction: column;
gap: 8px;
gap: var(--space-2);
}

.setup-health__item {
display: grid;
grid-template-columns: 88px 140px minmax(0, 1fr);
gap: 10px;
gap: var(--space-2);
align-items: start;
padding: 10px 12px;
padding: var(--space-2) var(--space-3);
border: 1px solid var(--border);
border-radius: 6px;
border-radius: var(--radius-md);
background: var(--bg);
}

Expand All @@ -2516,7 +2548,7 @@ select.field__input:focus-visible {
}

.setup-health__status {
font-size: 10px;
font-size: var(--text-xs);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
Expand All @@ -2529,7 +2561,7 @@ select.field__input:focus-visible {
}

.setup-health__detail {
font-size: 11px;
font-size: var(--text-xs);
color: var(--text-muted);
line-height: 1.45;
}
Expand Down
Loading