44 lines
1.0 KiB
TypeScript
Executable File
44 lines
1.0 KiB
TypeScript
Executable File
import { create } from 'zustand';
|
|
|
|
/** Eine einzelne Toast-Benachrichtigung. */
|
|
export interface Toast {
|
|
id: string;
|
|
type: 'success' | 'error' | 'info';
|
|
message: string;
|
|
}
|
|
|
|
interface ToastState {
|
|
toasts: Toast[];
|
|
addToast: (type: Toast['type'], message: string) => void;
|
|
removeToast: (id: string) => void;
|
|
}
|
|
|
|
/**
|
|
* Store für temporäre Benachrichtigungen.
|
|
*
|
|
* Toasts verschwinden nach 3 Sekunden automatisch.
|
|
* Wird aus anderen Stores via `useToastStore.getState().addToast()` aufgerufen,
|
|
* um Store-zu-Store-Abhängigkeiten zu vermeiden.
|
|
*/
|
|
export const useToastStore = create<ToastState>((set) => ({
|
|
toasts: [],
|
|
|
|
addToast: (type, message) => {
|
|
const id = crypto.randomUUID();
|
|
set((state) => ({
|
|
toasts: [...state.toasts, { id, type, message }],
|
|
}));
|
|
setTimeout(() => {
|
|
set((state) => ({
|
|
toasts: state.toasts.filter((t) => t.id !== id),
|
|
}));
|
|
}, 3000);
|
|
},
|
|
|
|
removeToast: (id) => {
|
|
set((state) => ({
|
|
toasts: state.toasts.filter((t) => t.id !== id),
|
|
}));
|
|
},
|
|
}));
|