import { createContext, useCallback, useContext, useEffect, useState } from 'react'; type Kind = 'info' | 'success' | 'error'; interface ToastMsg { id: number; kind: Kind; text: string } interface Ctx { push: (text: string, kind?: Kind) => void } const ToastCtx = createContext(null); export function useToast(): Ctx { const ctx = useContext(ToastCtx); if (!ctx) throw new Error('useToast must be used inside '); return ctx; } export function ToastProvider({ children }: { children: React.ReactNode }) { const [items, setItems] = useState([]); const push = useCallback((text: string, kind: Kind = 'info') => { const id = Date.now() + Math.random(); setItems(prev => [...prev, { id, kind, text }]); setTimeout(() => setItems(prev => prev.filter(t => t.id !== id)), 4000); }, []); return ( {children}
{items.map(t => ( ))}
); } function ToastItem({ msg }: { msg: ToastMsg }) { const [open, setOpen] = useState(false); useEffect(() => { requestAnimationFrame(() => setOpen(true)); }, []); const colors = msg.kind === 'success' ? 'bg-success/15 text-success border-success/30' : msg.kind === 'error' ? 'bg-danger/15 text-danger border-danger/30' : 'bg-ink-800 text-ink-100 border-ink-700'; return (
{msg.text}
); }