upload ai slop

This commit is contained in:
2026-02-25 22:49:38 +02:00
parent 49ebbc34fa
commit 0d60f5a83d
146 changed files with 4343 additions and 317 deletions

View File

@@ -0,0 +1,55 @@
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>
);
}