Skip to content

Commit 595e7be

Browse files
committed
Tighten feed result surface
1 parent 5eb27c3 commit 595e7be

5 files changed

Lines changed: 63 additions & 30 deletions

File tree

frontend/src/__tests__/App.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@ describe('App', () => {
126126

127127
render(<App />);
128128

129-
expect(screen.getByText('Feed ready')).toBeInTheDocument();
129+
expect(screen.getByText('Ready')).toBeInTheDocument();
130130
expect(screen.getByRole('button', { name: 'Create another feed' })).toBeInTheDocument();
131+
expect(screen.queryByText('Run your own instance')).not.toBeInTheDocument();
131132

132133
await waitFor(() => {
133134
expect(screen.getByText('Example Feed')).toBeInTheDocument();

frontend/src/__tests__/ResultDisplay.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('ResultDisplay', () => {
2525
it('renders utility actions and preview state', async () => {
2626
render(<ResultDisplay result={mockResult} onCreateAnother={mockOnCreateAnother} />);
2727

28-
expect(screen.getByText('Feed ready')).toBeInTheDocument();
28+
expect(screen.getByText('Ready')).toBeInTheDocument();
2929
expect(screen.getByText('Test Feed')).toBeInTheDocument();
3030
expect(screen.getByRole('button', { name: 'Copy feed URL' })).toBeInTheDocument();
3131
expect(screen.getByRole('link', { name: 'Open feed' })).toBeInTheDocument();

frontend/src/components/App.tsx

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,15 @@ export function App() {
146146

147147
return (
148148
<section class="workspace-shell">
149-
<header class="workspace-frame">
149+
<header class={`workspace-frame${result ? ' workspace-frame--compact' : ''}`}>
150150
<div class="workspace-frame__masthead">
151151
<BrandLockup />
152152
</div>
153-
<div class="workspace-frame__titleblock">
154-
<h1>Turn web pages into stable feeds.</h1>
155-
</div>
153+
{!result && (
154+
<div class="workspace-frame__titleblock">
155+
<h1>Turn web pages into stable feeds.</h1>
156+
</div>
157+
)}
156158
</header>
157159

158160
{(metadataError || tokenStateError) && (
@@ -197,15 +199,17 @@ export function App() {
197199
</div>
198200
)}
199201

200-
<InstanceInfo
201-
feedCreationEnabled={feedCreation.enabled}
202-
accessTokenRequired={feedCreation.access_token_required}
203-
hasAccessToken={hasToken}
204-
onClearToken={() => {
205-
clearToken();
206-
setShowTokenPrompt(false);
207-
}}
208-
/>
202+
{!result && (
203+
<InstanceInfo
204+
feedCreationEnabled={feedCreation.enabled}
205+
accessTokenRequired={feedCreation.access_token_required}
206+
hasAccessToken={hasToken}
207+
onClearToken={() => {
208+
clearToken();
209+
setShowTokenPrompt(false);
210+
}}
211+
/>
212+
)}
209213
</section>
210214
);
211215
}

frontend/src/components/ResultDisplay.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,14 @@ export function ResultDisplay({ result, onCreateAnother }: ResultDisplayProps) {
8080
return (
8181
<section id="feed-result" class="surface surface--primary surface--result" aria-live="polite">
8282
<div class="surface__header">
83-
<p class="eyebrow">Feed ready</p>
83+
<p class="eyebrow">Ready</p>
8484
<h2>{displayTitle}</h2>
85-
<p class="muted-copy">
86-
Copy the generated feed URL immediately, or open the endpoint to inspect the rendered output.
87-
</p>
85+
<p class="muted-copy">The endpoint is live.</p>
8886
</div>
8987

9088
<div class="result-layout">
91-
<section class="surface__section surface__section--strong">
92-
<label class="field-block" htmlFor="feed-url">
89+
<section class="surface__section surface__section--strong result-primary">
90+
<label class="field-block result-url" htmlFor="feed-url">
9391
<span class="field-label">Feed URL</span>
9492
<input
9593
id="feed-url"
@@ -108,27 +106,30 @@ export function ResultDisplay({ result, onCreateAnother }: ResultDisplayProps) {
108106
<a href={fullUrl} class="btn btn--secondary" target="_blank" rel="noopener noreferrer">
109107
Open feed
110108
</a>
111-
<button type="button" class="btn btn--ghost" onClick={onCreateAnother}>
112-
Create another feed
113-
</button>
114109
</div>
115110

116111
{copyNotice && (
117112
<div class="notice notice--success" role="status">
118113
<p>{copyNotice}</p>
119114
</div>
120115
)}
116+
117+
<div class="result-secondary">
118+
<button type="button" class="btn btn--ghost" onClick={onCreateAnother}>
119+
Create another feed
120+
</button>
121+
</div>
121122
</section>
122123

123124
<aside class="surface__section feed-preview" aria-label="Feed preview">
124125
<div class="feed-preview__header">
125-
<p class="eyebrow">Preview</p>
126-
<h3>{feedTitle || 'Previewing feed items'}</h3>
126+
<p class="eyebrow">Recent entries</p>
127+
<h3>Preview</h3>
127128
</div>
128129
{isLoadingPreview ? (
129130
<div class="preview-loading">
130131
<span class="status-card__spinner" aria-hidden="true" />
131-
<p>Loading recent entries</p>
132+
<p>Loading entries</p>
132133
</div>
133134
) : feedItems.length > 0 ? (
134135
<ol class="feed-preview__list">
@@ -137,9 +138,7 @@ export function ResultDisplay({ result, onCreateAnother }: ResultDisplayProps) {
137138
))}
138139
</ol>
139140
) : (
140-
<p class="muted-copy">
141-
The feed endpoint is live. Preview items were not available for this response.
142-
</p>
141+
<p class="muted-copy">Preview items were not available for this response.</p>
143142
)}
144143
</aside>
145144
</div>

frontend/src/styles/main.css

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ textarea {
163163
gap: var(--space-3);
164164
}
165165

166+
.workspace-frame--compact {
167+
padding-top: 0.9rem;
168+
padding-bottom: 0.9rem;
169+
}
170+
166171
.workspace-frame__masthead,
167172
.result-actions,
168173
.surface__toolbar,
@@ -483,6 +488,24 @@ a:focus-visible {
483488
align-items: start;
484489
}
485490

491+
.result-primary,
492+
.result-secondary {
493+
display: grid;
494+
}
495+
496+
.result-primary {
497+
gap: var(--space-4);
498+
}
499+
500+
.result-secondary {
501+
justify-items: start;
502+
}
503+
504+
.result-url .input {
505+
min-height: 3.25rem;
506+
font-size: var(--font-size-00);
507+
}
508+
486509
.field-stack--dense {
487510
gap: var(--space-4);
488511
}
@@ -507,6 +530,8 @@ a:focus-visible {
507530

508531
.result-actions {
509532
align-items: stretch;
533+
grid-template-columns: repeat(2, minmax(0, auto));
534+
justify-content: start;
510535
}
511536

512537
.feed-preview__header h3 {
@@ -648,6 +673,10 @@ a:focus-visible {
648673
.form-toolbar {
649674
grid-template-columns: 1fr;
650675
}
676+
677+
.result-secondary {
678+
justify-items: stretch;
679+
}
651680
}
652681

653682
@keyframes spin {

0 commit comments

Comments
 (0)