mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-04-07 02:53:38 +00:00
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import React, { useState, useCallback, useMemo, useRef, type ReactNode } from "react";
|
|
import { Box, type AlertColor } from "@mui/material";
|
|
import { NotificationContext } from "contexts/NotificationContext";
|
|
import NotificationItem from "contexts/NotificationItem";
|
|
import type { Notification } from "contexts/Notification";
|
|
|
|
export function NotificationProvider({ children }: { children: ReactNode }): React.JSX.Element {
|
|
const nextId = useRef(0);
|
|
const [notifications, setNotifications] = useState<Notification[]>([]);
|
|
|
|
const addNotification = useCallback((title: string, message: string, severity: AlertColor) => {
|
|
const id = nextId.current++;
|
|
setNotifications((prev) => [...prev, { id, title, message, severity }]);
|
|
}, []);
|
|
|
|
const removeNotification = useCallback((id: number) => {
|
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
}, []);
|
|
|
|
const showSuccess = useCallback(
|
|
(title: string, message: string) => addNotification(title, message, "success"),
|
|
[addNotification],
|
|
);
|
|
const showError = useCallback(
|
|
(title: string, message: string) => addNotification(title, message, "error"),
|
|
[addNotification],
|
|
);
|
|
|
|
const value = useMemo(() => ({ showSuccess, showError }), [showSuccess, showError]);
|
|
|
|
return (
|
|
<NotificationContext.Provider value={value}>
|
|
{children}
|
|
<Box
|
|
sx={{
|
|
position: "fixed",
|
|
top: 16,
|
|
left: "50%",
|
|
transform: "translateX(-50%)",
|
|
zIndex: (theme) => theme.zIndex.snackbar,
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
gap: 1,
|
|
maxWidth: 500,
|
|
width: "100%",
|
|
pointerEvents: "none",
|
|
}}
|
|
>
|
|
{notifications.map((n) => (
|
|
<NotificationItem key={n.id} notification={n} onClose={removeNotification} />
|
|
))}
|
|
</Box>
|
|
</NotificationContext.Provider>
|
|
);
|
|
}
|