fix: surface errors and polish UX across Step Library and Batch pages (#92)

- StepLibraryPage: replace silent console.error with toast.error on edit/save
  failures; replace manual setTimeout toast with toast.success helper
- BatchStatusPage: add error state with retry button for failed session loads
  instead of showing ambiguous "No sessions found"
- StepDetailModal: guard clipboard copy against browser denial (no false
  "Copied!" state on permission error); fix dead "See all reviews" button
  with inline expand/collapse toggle
- StepLibraryBrowser: add "Try again" retry button to error state; retry
  increments a counter that re-triggers both load effects

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #92.
This commit is contained in:
chihlasm
2026-02-26 03:00:14 -05:00
committed by GitHub
parent 8fa6ee1801
commit 1f77b7fc32
4 changed files with 53 additions and 29 deletions

View File

@@ -21,6 +21,7 @@ export default function BatchStatusPage() {
const [sessions, setSessions] = useState<Session[]>([])
const [isLoading, setIsLoading] = useState(true)
const [isRefreshing, setIsRefreshing] = useState(false)
const [loadError, setLoadError] = useState<string | null>(null)
const [batchDate, setBatchDate] = useState<Date | null>(null)
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)
@@ -30,9 +31,12 @@ export default function BatchStatusPage() {
try {
const data = await sessionsApi.list({ batch_id: batchId, size: 100 })
setSessions(Array.isArray(data) ? data : [])
setLoadError(null)
if (data.length > 0 && data[0].started_at) {
setBatchDate(new Date(data[0].started_at))
}
} catch {
setLoadError('Failed to load batch sessions')
} finally {
if (showRefreshing) setIsRefreshing(false)
}
@@ -48,6 +52,8 @@ export default function BatchStatusPage() {
loadSessions(),
])
setTree(treeData)
} catch {
setLoadError('Failed to load batch data')
} finally {
setIsLoading(false)
}
@@ -178,7 +184,17 @@ export default function BatchStatusPage() {
{/* Target cards */}
<div className="space-y-2">
{sessions.length === 0 ? (
{loadError ? (
<div className="rounded-lg border border-red-400/20 bg-red-400/10 p-4 text-center">
<p className="text-sm text-red-400 mb-3">{loadError}</p>
<button
onClick={() => loadSessions(true)}
className="rounded-md border border-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
>
Try again
</button>
</div>
) : sessions.length === 0 ? (
<p className="text-center text-[0.875rem] text-muted-foreground py-8">
No sessions found for this batch.
</p>
@@ -207,3 +223,4 @@ export default function BatchStatusPage() {
</div>
)
}