import * as React from "react"; type ToastType = "success" | "error" | "info"; interface Toast { id: string; message: string; type: ToastType; } let subscribers: ((toasts: Toast[]) => void)[] = []; let toasts: Toast[] = []; const notify = () => { for (const sub of subscribers) { sub(toasts); } }; const toastBase = (message: string, type: ToastType = "success") => { const id = Math.random().toString(36).substring(2, 9); toasts = [...toasts, { id, message, type }]; notify(); setTimeout(() => { toasts = toasts.filter((t) => t.id !== id); notify(); }, 3000); }; export const toast = Object.assign(toastBase, { success: (message: string, options?: { description?: string }) => { const finalMessage = options?.description ? `${message} ${options.description}` : message; toastBase(finalMessage, "success"); }, error: (message: string, options?: { description?: string }) => { const finalMessage = options?.description ? `${message} ${options.description}` : message; toastBase(finalMessage, "error"); }, info: (message: string, options?: { description?: string }) => { const finalMessage = options?.description ? `${message} ${options.description}` : message; toastBase(finalMessage, "info"); }, }); export const useToastState = () => { const [state, setState] = React.useState(toasts); React.useEffect(() => { subscribers.push(setState); return () => { subscribers = subscribers.filter((sub) => sub !== setState); }; }, []); return state; };