"use client"; import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react"; import NotificationsToaster, { type NotificationItem, type NotificationTone } from "@/shared/components/feedback/notifications-toaster"; type NotifyInput = { title: string; message?: string; tone?: NotificationTone; durationMs?: number; }; type NotificationsContextValue = { notify: (input: NotifyInput) => void; }; const NotificationsContext = createContext(null); function createId() { if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID(); return `${Date.now()}-${Math.random().toString(16).slice(2)}`; } export function NotificationsProvider({ children }: { children: React.ReactNode }) { const [items, setItems] = useState([]); const timersRef = useRef([]); function dismiss(id: string) { setItems(prev => prev.map(item => item.id === id ? { ...item, closing: true } : item)); const t = window.setTimeout(() => { setItems(prev => prev.filter(item => item.id !== id)); }, 250); timersRef.current.push(t); } function notify(input: NotifyInput) { const id = createId(); const durationMs = Math.max(1200, input.durationMs ?? 4200); const tone = input.tone ?? "info"; setItems(prev => [ ...prev, { id, title: input.title, message: input.message, tone, closing: false } ]); const fadeMs = 250; const t1 = window.setTimeout(() => { setItems(prev => prev.map(item => item.id === id ? { ...item, closing: true } : item)); }, Math.max(0, durationMs - fadeMs)); const t2 = window.setTimeout(() => { setItems(prev => prev.filter(item => item.id !== id)); }, durationMs); timersRef.current.push(t1, t2); } useEffect(() => { return () => { timersRef.current.forEach(timer => window.clearTimeout(timer)); timersRef.current = []; }; }, []); const value = useMemo(() => ({ notify }), []); return ( {children} ); } export function useNotificationsContext() { const ctx = useContext(NotificationsContext); if (!ctx) throw new Error("NotificationsProvider is missing"); return ctx; }