redThread / client /src /contexts /ToastContext.jsx
3v324v23's picture
Initial commit of RedThread project
0dd2082
'use client';
import { createContext, useContext, useState, useCallback } from 'react';
import './ToastContext.css';
const ToastContext = createContext(null);
export function ToastProvider({ children }) {
const [toasts, setToasts] = useState([]);
const addToast = useCallback((message, type = 'info', duration = 3000) => {
const id = Date.now();
setToasts(prev => [...prev, { id, message, type }]);
setTimeout(() => {
setToasts(prev => prev.filter(t => t.id !== id));
}, duration);
}, []);
const removeToast = useCallback(id => {
setToasts(prev => prev.filter(t => t.id !== id));
}, []);
return (
<ToastContext.Provider value={{ addToast }}>
{children}
<div className="toast-container" aria-live="polite">
{toasts.map(toast => (
<div key={toast.id} className={`toast toast-${toast.type} fade-in-up`}>
{toast.type === 'success' && '✅ '}
{toast.type === 'error' && '❌ '}
{toast.type === 'info' && '💡 '}
{toast.message}
<button
className="toast-close"
onClick={() => removeToast(toast.id)}
aria-label="Close"
>
×
</button>
</div>
))}
</div>
</ToastContext.Provider>
);
}
export function useToast() {
const context = useContext(ToastContext);
if (!context) {
throw new Error('useToast must be used within a ToastProvider');
}
return context;
}