68 lines
		
	
	
		
			2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
		
			2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { Alert, Snackbar, useTheme } from "@mui/material";
 | 
						|
import { FC, ReactNode, createContext, useContext, useState } from "react";
 | 
						|
import { v4 } from "uuid";
 | 
						|
 | 
						|
type Notification = {
 | 
						|
  id: string;
 | 
						|
  message: string;
 | 
						|
  color?: string;
 | 
						|
  duration?: number;
 | 
						|
};
 | 
						|
 | 
						|
type NotificationContextProps = {
 | 
						|
  notifications: Notification[];
 | 
						|
  openNotification: (message: string, color?: string, duration?: number) => void;
 | 
						|
  closeNotification: (id: string) => void;
 | 
						|
};
 | 
						|
 | 
						|
const NotificationContext = createContext<NotificationContextProps | undefined>(undefined);
 | 
						|
 | 
						|
export const NotificationProvider: FC<{ children: ReactNode }> = ({ children }) => {
 | 
						|
  const theme = useTheme();
 | 
						|
  const [notifications, setNotifications] = useState<Notification[]>([]);
 | 
						|
 | 
						|
  const openNotification = (message: string, color?: string, duration: number = 3000) => {
 | 
						|
    const id = v4();
 | 
						|
    setNotifications((prevNotifications) => [...prevNotifications, { id, message, color, duration }]);
 | 
						|
 | 
						|
    setTimeout(() => {
 | 
						|
      closeNotification(id);
 | 
						|
    }, duration);
 | 
						|
  };
 | 
						|
 | 
						|
  const closeNotification = (id: string) => {
 | 
						|
    setNotifications((prevNotifications) => prevNotifications.filter((notification) => notification.id !== id));
 | 
						|
  };
 | 
						|
 | 
						|
  return (
 | 
						|
    <NotificationContext.Provider value={{ notifications, openNotification, closeNotification }}>
 | 
						|
      {children}
 | 
						|
      {notifications.map((notification) => (
 | 
						|
        <Snackbar
 | 
						|
          key={notification.id}
 | 
						|
          autoHideDuration={notification.duration}
 | 
						|
          open={true}
 | 
						|
        >
 | 
						|
          <Alert
 | 
						|
            icon={false}
 | 
						|
            variant='filled'
 | 
						|
            sx={{
 | 
						|
              backgroundColor: notification.color || theme.palette.primary.main,
 | 
						|
            }}
 | 
						|
          >
 | 
						|
            {notification.message}
 | 
						|
          </Alert>
 | 
						|
        </Snackbar>
 | 
						|
      ))}
 | 
						|
    </NotificationContext.Provider>
 | 
						|
  );
 | 
						|
};
 | 
						|
 | 
						|
export const useNotification = () => {
 | 
						|
  const context = useContext(NotificationContext);
 | 
						|
  if (context === undefined) {
 | 
						|
    throw new Error("useNotification must be used within a NotificationProvider");
 | 
						|
  }
 | 
						|
  return context;
 | 
						|
};
 |