| 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>
|
| );
|
| }
|
|
|
|
|
| export function useToast() {
|
| const ctx = useContext(ToastContext);
|
| if (!ctx) throw new Error("useToast must be used within ToastProvider");
|
| return ctx;
|
| }
|
|
|