feat(ui): notification center with leveled toasts and error capture
- Replace the toast store with a notification store: levels (info/success/ warning/error/fatal), requiresInteraction, and a persisted history. - Move toasts to the top-right, styled per level, with manual dismiss. - Add a bell in the header opening a Notification Center (history, unread badge, 'needs attention' vs info, clear all). - Capture network failures and 5xx responses (api layer) and render crashes (ErrorBoundary) as notifications. - Sound + server-sourced events + per-account settings remain for 6b.
This commit is contained in:
parent
1a01657c1f
commit
42150edb92
9 changed files with 403 additions and 68 deletions
|
|
@ -1,3 +1,5 @@
|
|||
import { notify } from "./notifications";
|
||||
|
||||
export interface Me {
|
||||
id: number;
|
||||
email: string;
|
||||
|
|
@ -67,12 +69,34 @@ class HttpError extends Error {
|
|||
}
|
||||
|
||||
async function req(url: string, opts: RequestInit = {}): Promise<any> {
|
||||
const r = await fetch(url, {
|
||||
credentials: "include",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
...opts,
|
||||
});
|
||||
if (!r.ok) throw new HttpError(r.status);
|
||||
const method = opts.method ?? "GET";
|
||||
let r: Response;
|
||||
try {
|
||||
r = await fetch(url, {
|
||||
credentials: "include",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
...opts,
|
||||
});
|
||||
} catch (e) {
|
||||
// Network/connection failure — surface it in the notification center.
|
||||
notify({
|
||||
level: "error",
|
||||
title: "Network error",
|
||||
message: `Couldn't reach the server (${method} ${url}).`,
|
||||
});
|
||||
throw e;
|
||||
}
|
||||
if (!r.ok) {
|
||||
// Server faults are worth logging; 401/403/404 etc. are handled by callers.
|
||||
if (r.status >= 500) {
|
||||
notify({
|
||||
level: "error",
|
||||
title: `Server error ${r.status}`,
|
||||
message: `${method} ${url}`,
|
||||
});
|
||||
}
|
||||
throw new HttpError(r.status);
|
||||
}
|
||||
return r.status === 204 ? null : r.json();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue