feat: centralized error notification service (issue #15)

- Create NotificationService with context provider for centralized error/success messaging
- Add NotificationContainer component to render notification stack
- Integrate NotificationProvider into App root
- Refactor BanUnbanForm to use notification service instead of local error state
- Update fetchError utility to optionally use notification callbacks
- Add comprehensive error handling guidelines to Web-Development.md
- Prevent duplicate notifications with deduplication logic
- Support auto-dismiss with configurable TTL per notification type

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-28 08:41:33 +02:00
parent da6433b2cf
commit ae34d98859
8 changed files with 557 additions and 152 deletions

View File

@@ -0,0 +1,53 @@
/**
* Notification type definitions.
* Defines the contract for error, success, warning, and info messages
* rendered through the centralized notification service.
*/
/** Severity level of a notification. */
export type NotificationIntent = "error" | "success" | "warning" | "info";
/** Unique notification message. */
export interface Notification {
/** Unique identifier for this notification (auto-generated). */
id: string;
/** Severity level. */
intent: NotificationIntent;
/** User-facing message text. */
message: string;
/** Auto-dismiss after this many milliseconds. Null means manual dismiss only. */
autoCloseMsec?: number | null;
}
/** Notification service public API. */
export interface NotificationService {
/**
* Show a success notification.
* @param message User-facing message text.
* @param autoCloseMsec Auto-dismiss after this many ms. Defaults to 5000.
*/
success(message: string, autoCloseMsec?: number): void;
/**
* Show an error notification.
* @param message User-facing message text.
* @param autoCloseMsec Auto-dismiss after this many ms. Defaults to 8000.
*/
error(message: string, autoCloseMsec?: number): void;
/**
* Show a warning notification.
* @param message User-facing message text.
* @param autoCloseMsec Auto-dismiss after this many ms. Defaults to 6000.
*/
warning(message: string, autoCloseMsec?: number): void;
/**
* Show an info notification.
* @param message User-facing message text.
* @param autoCloseMsec Auto-dismiss after this many ms. Defaults to 5000.
*/
info(message: string, autoCloseMsec?: number): void;
/**
* Remove a notification by ID.
* Called automatically on auto-dismiss; can also be called manually.
*/
dismiss(id: string): void;
}