import { useMemo, useRef, useState } from "react"; export default function useNotifications() { const [toasts, setToasts] = useState([]); const toastTimers = useRef(new Map()); const [notifications, setNotifications] = useState([]); const [notificationFilter, setNotificationFilter] = useState("all"); const showNotification = (text, tone = "info") => { if (!text) return; const key = `${tone}|${text}`; const now = Date.now(); setNotifications((prev) => { const existingIndex = prev.findIndex((item) => item.key === key); if (existingIndex >= 0) { const updated = { ...prev[existingIndex], count: (prev[existingIndex].count || 1) + 1, lastAt: now }; const next = [updated, ...prev.filter((_, index) => index !== existingIndex)]; return next.slice(0, 20); } const entry = { text, tone, id: `${now}-${Math.random().toString(36).slice(2)}`, key, count: 1, lastAt: now }; return [entry, ...prev].slice(0, 20); }); setToasts((prev) => { const existingIndex = prev.findIndex((item) => item.key === key); if (existingIndex >= 0) { const updated = { ...prev[existingIndex], count: (prev[existingIndex].count || 1) + 1, lastAt: now }; const next = [updated, ...prev.filter((_, index) => index !== existingIndex)]; return next.slice(0, 4); } const entry = { text, tone, id: `${now}-${Math.random().toString(36).slice(2)}`, key, count: 1, lastAt: now }; return [entry, ...prev].slice(0, 4); }); if (toastTimers.current.has(key)) { clearTimeout(toastTimers.current.get(key)); } const timeoutId = setTimeout(() => { setToasts((prev) => prev.filter((item) => item.key !== key)); toastTimers.current.delete(key); }, 6000); toastTimers.current.set(key, timeoutId); }; const dismissToast = (toast) => { setToasts((prev) => prev.filter((item) => item.id !== toast.id)); if (toast.key && toastTimers.current.has(toast.key)) { clearTimeout(toastTimers.current.get(toast.key)); toastTimers.current.delete(toast.key); } }; const filteredNotifications = useMemo(() => { if (notificationFilter === "all") return notifications; return notifications.filter((item) => item.tone === notificationFilter); }, [notifications, notificationFilter]); return { toasts, notifications, setNotifications, notificationFilter, setNotificationFilter, filteredNotifications, showNotification, dismissToast }; }