import React, { createContext, useCallback, useContext, useMemo, useState } from "react"; import { Alert, Button, Snackbar } from "@mui/material"; type Severity = "success" | "info" | "warning" | "error"; type Toast = { open: boolean; message: string; severity: Severity; actionLabel?: string; onAction?: () => void; }; type ToastApi = { toast: ( message: string, severity?: Severity, action?: { label: string; onClick: () => void }, ) => void; }; const ToastContext = createContext(null); export function ToastProvider({ children }: { children: React.ReactNode }) { const [t, setT] = useState({ open: false, message: "", severity: "info" }); const toast = useCallback( (message: string, severity: Severity = "info", action?: { label: string; onClick: () => void }) => { setT({ open: true, message, severity, actionLabel: action?.label, onAction: action?.onClick, }); }, [], ); const value = useMemo(() => ({ toast }), [toast]); return ( {children} setT((p) => ({ ...p, open: false }))} anchorOrigin={{ vertical: "bottom", horizontal: "right" }} > setT((p) => ({ ...p, open: false }))} severity={t.severity} variant="filled" sx={{ maxWidth: 420 }} action={ t.actionLabel && t.onAction ? ( ) : undefined } > {t.message} ); } export function useToast(): ToastApi { const v = useContext(ToastContext); if (!v) throw new Error("useToast must be used within ToastProvider"); return v; }