milestone 18: collapse duplicated infrastructure into shared listener core, crud list helper, resource shells, transport race, name and line helpers, ui modules
CI / test (push) Successful in 1m22s
CI / test-aarch64 (push) Successful in 5m6s
CI / frontend (push) Successful in 45s
CI / cross (push) Successful in 7m53s
CI / docker (push) Failing after 1h10m57s

This commit is contained in:
2026-08-07 18:20:30 +02:00
parent c50c6d285a
commit 6f67940995
82 changed files with 3167 additions and 3114 deletions
+14 -2
View File
@@ -1,8 +1,12 @@
import { useEffect, useState } from "react";
import { ApiError } from "@/lib/api";
import { focusRing } from "@/ui/classes";
/** Inline mutation error per ruling 17: 400/409 messages verbatim, 429 with countdown. */
export default function InlineError({ error }: { error: unknown }) {
/**
* Inline mutation error per ruling 17: 400/409 messages verbatim, 429 with
* countdown. Pass `onRetry` to append a retry button for a failed query.
*/
export default function InlineError({ error, onRetry }: { error: unknown; onRetry?: () => void }) {
const retryAfter = error instanceof ApiError && error.status === 429 ? (error.retryAfter ?? null) : null;
const [remaining, setRemaining] = useState<number | null>(retryAfter);
@@ -34,6 +38,14 @@ export default function InlineError({ error }: { error: unknown }) {
return (
<p role="alert" className="mt-2 text-sm text-red-600 dark:text-red-400">
{message}
{onRetry !== undefined && (
<>
{" "}
<button type="button" onClick={onRetry} className={`font-medium underline ${focusRing}`}>
Retry
</button>
</>
)}
</p>
);
}