61 lines
1.4 KiB
TypeScript
61 lines
1.4 KiB
TypeScript
// Global toast notification store
|
|
import { browser } from '$app/environment';
|
|
|
|
export interface ToastNotification {
|
|
id: string;
|
|
message: string;
|
|
type: 'error' | 'success' | 'info';
|
|
duration: number;
|
|
}
|
|
|
|
const DEFAULT_DURATION = 3000;
|
|
|
|
class ToastStore {
|
|
notifications = $state<ToastNotification[]>([]);
|
|
|
|
private generateId(): string {
|
|
return `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
}
|
|
|
|
show(message: string, type: ToastNotification['type'] = 'info', duration = DEFAULT_DURATION) {
|
|
if (!browser) return;
|
|
|
|
const notification: ToastNotification = {
|
|
id: this.generateId(),
|
|
message,
|
|
type,
|
|
duration,
|
|
};
|
|
|
|
this.notifications.push(notification);
|
|
|
|
if (duration > 0) {
|
|
setTimeout(() => {
|
|
this.dismiss(notification.id);
|
|
}, duration);
|
|
}
|
|
}
|
|
|
|
error(message: string, duration = DEFAULT_DURATION) {
|
|
this.show(message, 'error', duration);
|
|
}
|
|
|
|
success(message: string, duration = DEFAULT_DURATION) {
|
|
this.show(message, 'success', duration);
|
|
}
|
|
|
|
info(message: string, duration = DEFAULT_DURATION) {
|
|
this.show(message, 'info', duration);
|
|
}
|
|
|
|
dismiss(id: string) {
|
|
this.notifications = this.notifications.filter(n => n.id !== id);
|
|
}
|
|
|
|
clear() {
|
|
this.notifications = [];
|
|
}
|
|
}
|
|
|
|
export const toastStore = new ToastStore();
|