The repo's first frontend test setup: Vitest, React Testing Library, jsdom. Scoped to the flows that lose money or leak data when broken, per spec 4. lib/api.ts collapses every failure into three the UI can act on: NotConnected (unreachable, or no URL baked in), ApiError 401 (redirect), and ApiError with the backend's own message, which is customer-facing and shown verbatim rather than replaced with something vaguer. The not-connected panel names the variable, the value baked in, and both reasons it fails -- unreachable from the browser, or missing from admin's ADMIN_ORIGIN. Proven by test before it existed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
29 lines
1.3 KiB
TypeScript
29 lines
1.3 KiB
TypeScript
/*
|
|
* The deployment failure this repo makes most often, made legible. It names the
|
|
* variable, the value baked in, and both reasons it fails — unreachable from
|
|
* the browser, or missing from admin's ADMIN_ORIGIN.
|
|
*/
|
|
export function NotConnectedPanel({ url }: { url: string }) {
|
|
return (
|
|
<div className="grid max-w-2xl gap-3 rounded border border-expired bg-panel p-5">
|
|
<h2 className="text-xl text-expired">Not connected to the licensing service</h2>
|
|
{url ? (
|
|
<p className="text-ink-2">
|
|
This build points at <code className="text-ink">ADMIN_API_URL</code> ={" "}
|
|
<code className="text-ink">{url}</code>, which did not respond.
|
|
</p>
|
|
) : (
|
|
<p className="text-ink-2">
|
|
<code className="text-ink">ADMIN_API_URL</code> was not set when this app was
|
|
built, so there is nowhere to send requests.
|
|
</p>
|
|
)}
|
|
<p className="text-[0.82rem] text-ink-3">
|
|
The value is baked in when the image is built and has to be reachable from your
|
|
browser, not just from the server. It also has to appear in the licensing
|
|
service’s <code>ADMIN_ORIGIN</code>, or the browser blocks every request.
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|