Files
Dwinzo_beta/app/src/components/templates/ToastProvider.tsx
2025-03-22 18:33:02 +05:30

75 lines
2.0 KiB
TypeScript

import React, { createContext, useContext, useState, ReactNode } from "react";
type Toast = {
id: string;
message: string;
type: "success" | "error" | "info" | "warning";
position?: ToastPosition; // Optional position for each toast
};
type ToastPosition =
| "top-left"
| "top-center"
| "top-right"
| "bottom-left"
| "bottom-center"
| "bottom-right";
type ToastContextType = {
addToast: (
message: string,
type: Toast["type"],
position?: ToastPosition
) => void;
removeToast: (id: string) => void;
};
const ToastContext = createContext<ToastContextType | undefined>(undefined);
const ToastProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [toasts, setToasts] = useState<Toast[]>([]);
const addToast = (
message: string,
type: Toast["type"],
position: ToastPosition = "bottom-center" // Default position
) => {
const id = Math.random().toString(36).substr(2, 9); // Generate a unique ID
setToasts((prev) => [...prev, { id, message, type, position }]);
// Auto-remove toast after 3 seconds
setTimeout(() => removeToast(id), 3000);
};
const removeToast = (id: string) => {
setToasts((prev) => prev.filter((toast) => toast.id !== id));
};
return (
<ToastContext.Provider value={{ addToast, removeToast }}>
{children}
<div className={`toast-container ${"bottom-center"}`}>
{toasts.map((toast) => (
<div
key={toast.id}
className={`toast ${toast.type}`}
onClick={() => removeToast(toast.id)} // Allow manual dismissal
>
{toast.message}
</div>
))}
</div>
</ToastContext.Provider>
);
};
export const useToast = (): ToastContextType => {
const context = useContext(ToastContext);
if (!context) {
throw new Error("useToast must be used within a ToastProvider");
}
return context;
};
export default ToastProvider;