'use client'; import { createContext, useContext, useState, useCallback, ReactNode } from 'react'; import { useAccentColor } from './AccentColorContext'; type ToastType = 'success' | 'error' | 'info'; interface Toast { id: string; message: string; type: ToastType; } interface ToastContextType { toasts: Toast[]; showToast: (message: string, type?: ToastType) => void; removeToast: (id: string) => void; } const ToastContext = createContext(null); // Check if a color is light (needs dark text) function isLightColor(hex: string): boolean { const color = hex.replace('#', ''); const r = parseInt(color.slice(0, 2), 16); const g = parseInt(color.slice(2, 4), 16); const b = parseInt(color.slice(4, 6), 16); const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255; return luminance > 0.6; } export function ToastProvider({ children }: { children: ReactNode }) { const [toasts, setToasts] = useState([]); const showToast = useCallback((message: string, type: ToastType = 'info') => { const id = Math.random().toString(36).slice(2); setToasts(prev => [...prev, { id, message, type }]); setTimeout(() => { setToasts(prev => prev.filter(t => t.id !== id)); }, 3500); }, []); const removeToast = useCallback((id: string) => { setToasts(prev => prev.filter(t => t.id !== id)); }, []); return ( {children} ); } export function useToast() { const context = useContext(ToastContext); if (!context) { throw new Error('useToast must be used within a ToastProvider'); } return context; } function ToastContainer({ toasts, removeToast }: { toasts: Toast[]; removeToast: (id: string) => void }) { const { accentColor } = useAccentColor(); const needsDarkText = isLightColor(accentColor); if (toasts.length === 0) return null; return (
{toasts.map(toast => (
removeToast(toast.id)} style={{ pointerEvents: 'auto', cursor: 'pointer', padding: '12px 16px', borderRadius: '8px', background: toast.type === 'error' ? 'var(--danger)' : toast.type === 'success' ? 'var(--accent)' : 'var(--background-secondary)', color: toast.type === 'error' ? '#fff' : toast.type === 'success' ? (needsDarkText ? '#000' : '#fff') : 'var(--foreground)', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)', fontSize: '14px', fontWeight: 500, maxWidth: '320px', animation: 'toastSlideIn 0.2s ease-out', border: '1px solid var(--border)', }} > {toast.message}
))}
); }