File size: 1,607 Bytes
b24b684 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | import { Alert, Snackbar } from "@mui/material";
import {
createContext,
useCallback,
useContext,
useMemo,
useState,
type ReactNode,
} from "react";
type Severity = "success" | "error" | "info" | "warning";
interface ToastContextValue {
notify: (message: string, severity?: Severity) => void;
}
const ToastContext = createContext<ToastContextValue | undefined>(undefined);
export function ToastProvider({ children }: { children: ReactNode }) {
const [open, setOpen] = useState(false);
const [message, setMessage] = useState("");
const [severity, setSeverity] = useState<Severity>("success");
const notify = useCallback((msg: string, sev: Severity = "success") => {
setMessage(msg);
setSeverity(sev);
setOpen(true);
}, []);
const value = useMemo(() => ({ notify }), [notify]);
return (
<ToastContext.Provider value={value}>
{children}
<Snackbar
open={open}
autoHideDuration={3500}
onClose={() => setOpen(false)}
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
>
<Alert
onClose={() => setOpen(false)}
severity={severity}
variant="filled"
sx={{ borderRadius: 2 }}
>
{message}
</Alert>
</Snackbar>
</ToastContext.Provider>
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useToast() {
const ctx = useContext(ToastContext);
if (!ctx) throw new Error("useToast must be used within ToastProvider");
return ctx;
}
|