/* eslint-disable react-refresh/only-export-components */
import React, { createContext, useContext, useState, useCallback } from 'react';
import { AnimatePresence } from 'framer-motion';
import { Toast } from '../components/ui/Toast';
import type { ToastType } from '../components/ui/Toast';
import styles from '../components/ui/Toast.module.css';
interface ToastData {
id: string;
type: ToastType;
message: string;
duration?: number;
}
interface ToastContextType {
showToast: (type: ToastType, message: string, duration?: number) => void;
success: (message: string, duration?: number) => void;
error: (message: string, duration?: number) => void;
info: (message: string, duration?: number) => void;
warning: (message: string, duration?: number) => void;
}
const ToastContext = createContext<ToastContextType | undefined>(undefined);
export const ToastProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [toasts, setToasts] = useState<ToastData[]>([]);
const removeToast = useCallback((id: string) => {
setToasts((prev) => prev.filter((toast) => toast.id !== id));
}, []);
const showToast = useCallback((type: ToastType, message: string, duration = 5000) => {
const id = Math.random().toString(36).substring(2, 9);
setToasts((prev) => [...prev, { id, type, message, duration }]);
}, []);
const success = useCallback((message: string, duration?: number) => showToast('success', message, duration), [showToast]);
const error = useCallback((message: string, duration?: number) => showToast('error', message, duration), [showToast]);
const info = useCallback((message: string, duration?: number) => showToast('info', message, duration), [showToast]);
const warning = useCallback((message: string, duration?: number) => showToast('warning', message, duration), [showToast]);
return (
<ToastContext.Provider value={{ showToast, success, error, info, warning }}>
{children}
<div className={styles.toastContainer}>
<AnimatePresence>
{toasts.map((toast) => (
<Toast
key={toast.id}
{...toast}
onClose={removeToast}
/>
))}
</AnimatePresence>
</div>
</ToastContext.Provider>
);
};
export const useToast = () => {
const context = useContext(ToastContext);
if (context === undefined) {
throw new Error('useToast must be used within a ToastProvider');
}
return context;
};