improve web ui

This commit is contained in:
2026-06-26 05:43:34 +00:00
parent 00cf51d610
commit 803573b4ec
73 changed files with 3373 additions and 2847 deletions
+34 -27
View File
@@ -9,43 +9,50 @@
/** A failed API call. `status` is the HTTP code; `data` is the parsed `ApiError` body if any. */
export class ApiError extends Error {
status: number
data: unknown
constructor(status: number, data: unknown, message?: string) {
super(message ?? `API error ${status}`)
this.name = 'ApiError'
this.status = status
this.data = data
}
status: number;
data: unknown;
constructor(status: number, data: unknown, message?: string) {
super(message ?? `API error ${status}`);
this.name = "ApiError";
this.status = status;
this.data = data;
}
}
export async function apiFetch<T>(url: string, options?: RequestInit): Promise<T> {
const headers = new Headers(options?.headers)
headers.set('Accept', 'application/json')
export async function apiFetch<T>(
url: string,
options?: RequestInit,
): Promise<T> {
const headers = new Headers(options?.headers);
headers.set("Accept", "application/json");
const res = await fetch(url, { ...options, headers, credentials: 'same-origin' })
const res = await fetch(url, {
...options,
headers,
credentials: "same-origin",
});
const text = await res.text()
const body = text ? safeJson(text) : undefined
if (res.status === 401) redirectToLogin()
if (!res.ok) throw new ApiError(res.status, body, res.statusText)
return body as T
const text = await res.text();
const body = text ? safeJson(text) : undefined;
if (res.status === 401) redirectToLogin();
if (!res.ok) throw new ApiError(res.status, body, res.statusText);
return body as T;
}
/** On lost session, send the user to the login screen, remembering where they were. */
function redirectToLogin(): void {
if (typeof window === 'undefined') return
if (window.location.pathname === '/login') return
const next = encodeURIComponent(window.location.pathname)
window.location.href = `/login?next=${next}`
if (typeof window === "undefined") return;
if (window.location.pathname === "/login") return;
const next = encodeURIComponent(window.location.pathname);
window.location.href = `/login?next=${next}`;
}
function safeJson(text: string): unknown {
try {
return JSON.parse(text)
} catch {
return text
}
try {
return JSON.parse(text);
} catch {
return text;
}
}
export default apiFetch
export default apiFetch;