import React, { useEffect, useState, useContext, createContext } from "react"; import { Toast } from "react-bootstrap"; interface IToast { header?: string; content: JSX.Element | string; delay?: number; variant?: "success" | "danger" | "warning"; } interface IActiveToast extends IToast { id: number; } let toastID = 0; const ToastContext = createContext<(item: IToast) => void>(() => {}); export const ToastProvider: React.FC = ({ children }) => { const [toasts, setToasts] = useState([]); const removeToast = (id: number) => setToasts(toasts.filter((item) => item.id !== id)); const toastItems = toasts.map((toast) => ( removeToast(toast.id)} className={toast.variant ?? "success"} delay={toast.delay ?? 3000} > {toast.header} {toast.content} )); const addToast = (toast: IToast) => setToasts([...toasts, { ...toast, id: toastID++ }]); return ( {children}
{toastItems}
); }; function createHookObject(toastFunc: (toast: IToast) => void) { return { success: toastFunc, error: (error: Error) => { // eslint-disable-next-line no-console console.error(error.message); toastFunc({ variant: "danger", header: "Error", content: error.message ?? error.toString(), }); }, }; } const useToasts = () => { const setToast = useContext(ToastContext); const [hookObject, setHookObject] = useState(createHookObject(setToast)); useEffect(() => setHookObject(createHookObject(setToast)), [setToast]); return hookObject; }; export default useToasts;