46 lines
1.3 KiB
JavaScript
46 lines
1.3 KiB
JavaScript
/**
|
|
* Notification Store — Zustand-based global toast notification system.
|
|
* Centralized feedback for dashboard actions.
|
|
*/
|
|
|
|
import { create } from "zustand";
|
|
|
|
let idCounter = 0;
|
|
|
|
export const useNotificationStore = create((set, get) => ({
|
|
notifications: [],
|
|
|
|
addNotification: (notification) => {
|
|
const id = ++idCounter;
|
|
const entry = {
|
|
id,
|
|
type: notification.type || "info",
|
|
message: notification.message,
|
|
title: notification.title || null,
|
|
duration: notification.duration ?? 5000,
|
|
dismissible: notification.dismissible ?? true,
|
|
createdAt: Date.now(),
|
|
};
|
|
|
|
set((s) => ({ notifications: [...s.notifications, entry] }));
|
|
|
|
// Auto-dismiss
|
|
if (entry.duration > 0) {
|
|
setTimeout(() => get().removeNotification(id), entry.duration);
|
|
}
|
|
|
|
return id;
|
|
},
|
|
|
|
removeNotification: (id) => {
|
|
set((s) => ({ notifications: s.notifications.filter((n) => n.id !== id) }));
|
|
},
|
|
|
|
clearAll: () => set({ notifications: [] }),
|
|
|
|
success: (message, title) => get().addNotification({ type: "success", message, title }),
|
|
error: (message, title) => get().addNotification({ type: "error", message, title, duration: 8000 }),
|
|
warning: (message, title) => get().addNotification({ type: "warning", message, title }),
|
|
info: (message, title) => get().addNotification({ type: "info", message, title }),
|
|
}));
|