Skip to content

Commit d6f7fb3

Browse files
committed
fix: simplify result actions and surface feed errors
1 parent 9d9cd22 commit d6f7fb3

3 files changed

Lines changed: 37 additions & 43 deletions

File tree

frontend/src/components/ResultDisplay.module.css

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
.heroName {
1919
margin: 0;
20-
color: var(--sl-color-gray-2);
20+
color: var(--app-text-muted);
2121
font-size: 0.9rem;
2222
}
2323

@@ -41,15 +41,15 @@
4141
margin: 0;
4242
font-weight: 500;
4343
font-size: 0.9rem;
44-
color: var(--sl-color-text);
44+
color: var(--app-text);
4545
}
4646

4747
.previewList {
4848
margin: 0;
4949
padding-left: 1.1rem;
5050
display: grid;
5151
gap: 0.35rem;
52-
color: var(--sl-color-text);
52+
color: var(--app-text);
5353
}
5454

5555
.previewList li {
@@ -58,22 +58,18 @@
5858

5959
.previewLoading {
6060
margin: 0;
61-
color: var(--sl-color-text-accent);
61+
color: var(--app-text-muted);
6262
font-size: 0.9rem;
6363
}
6464

6565
.actionHint {
6666
margin: -0.2rem 0 0;
67-
color: var(--sl-color-gray-2);
67+
color: var(--app-text-muted);
6868
font-size: 0.8rem;
6969
}
7070

7171
.guestCue {
7272
margin: 0;
73-
color: var(--sl-color-text-accent);
73+
color: var(--app-text-muted);
7474
font-size: 0.85rem;
7575
}
76-
77-
.footer {
78-
justify-self: start;
79-
}

frontend/src/components/ResultDisplay.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,13 @@ export function ResultDisplay({
103103
<div class="panel-meta">
104104
<span class="panel-meta__primary">{isAuthenticated ? (username ?? '') : ''}</span>
105105
<span class="panel-meta__actions">
106-
<button type="button" class="btn btn--link btn--meta" onClick={onClose}>
107-
← Convert another
106+
<button
107+
type="button"
108+
class="btn btn--link btn--meta"
109+
onClick={onClose}
110+
aria-label="Convert another website"
111+
>
112+
← Convert another website
108113
</button>
109114
{isAuthenticated && onLogout && (
110115
<button type="button" class="btn btn--link btn--meta" onClick={onLogout}>
@@ -166,12 +171,6 @@ export function ResultDisplay({
166171
)}
167172
</section>
168173
)}
169-
170-
<div class={styles.footer}>
171-
<button type="button" class="btn btn--link btn--meta" onClick={onClose}>
172-
← Convert another website
173-
</button>
174-
</div>
175174
</section>
176175
);
177176
}

frontend/src/hooks/useFeedConversion.ts

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
import { useState } from 'preact/hooks';
22
import { createFeed } from '../api/generated';
33
import { apiClient, bearerHeaders } from '../api/client';
4-
5-
interface ConversionResult {
6-
id: string;
7-
name: string;
8-
url: string;
9-
strategy: string;
10-
public_url: string;
11-
created_at: string;
12-
updated_at: string;
13-
}
4+
import type { FeedRecord } from '../api/contracts';
145

156
interface ConversionState {
167
isConverting: boolean;
17-
result: ConversionResult | null;
8+
result: FeedRecord | null;
189
error: string | null;
1910
}
2011

@@ -48,30 +39,21 @@ export function useFeedConversion() {
4839
url: url.trim(),
4940
strategy: strategy.trim(),
5041
},
42+
responseStyle: 'data',
43+
throwOnError: true,
5144
});
5245

53-
const errorPayload = response.error as { error?: { message?: string } } | undefined;
54-
if (response.error) {
55-
const networkMessage = response.error instanceof Error ? response.error.message : undefined;
56-
throw new Error(networkMessage || errorPayload?.error?.message || 'Request failed');
57-
}
58-
59-
const typed = response.data as {
60-
success?: boolean;
61-
data?: { feed?: ConversionResult };
62-
};
63-
64-
if (!typed?.success || !typed?.data?.feed) {
46+
if (!response?.success || !response.data?.feed) {
6547
throw new Error('Invalid response format');
6648
}
6749

68-
const result = typed.data.feed;
50+
const result = response.data.feed;
6951
setState((prev) => ({ ...prev, isConverting: false, result, error: null }));
7052
} catch (error) {
7153
setState((prev) => ({
7254
...prev,
7355
isConverting: false,
74-
error: error instanceof Error ? error.message : 'An unexpected error occurred',
56+
error: toErrorMessage(error),
7557
result: null,
7658
}));
7759
}
@@ -95,3 +77,20 @@ export function useFeedConversion() {
9577
clearResult,
9678
};
9779
}
80+
81+
const toErrorMessage = (error: unknown): string => {
82+
if (error instanceof Error) return error.message;
83+
if (typeof error === 'string' && error.trim()) return error;
84+
85+
const message = extractMessage(error);
86+
return message ?? 'An unexpected error occurred';
87+
};
88+
89+
const extractMessage = (error: unknown): string | null => {
90+
if (!error || typeof error !== 'object') return null;
91+
92+
const candidate = (error as { error?: { message?: unknown }; message?: unknown }).error?.message ??
93+
(error as { message?: unknown }).message;
94+
95+
return typeof candidate === 'string' && candidate.trim() ? candidate : null;
96+
};

0 commit comments

Comments
 (0)