chore: merge admin repo history into monorepo at admin/
git-subtree-dir: admin git-subtree-mainline:35f5084005git-subtree-split:9f1eccd2f7
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useState,
|
||||
ReactNode,
|
||||
} from "react";
|
||||
import { CheckCircle2, XCircle } from "lucide-react";
|
||||
|
||||
interface Toast {
|
||||
id: number;
|
||||
message: string;
|
||||
tone: "success" | "error";
|
||||
}
|
||||
|
||||
interface ToastContextValue {
|
||||
showSuccess: (message: string) => void;
|
||||
showError: (message: string) => void;
|
||||
}
|
||||
|
||||
const ToastContext = createContext<ToastContextValue | null>(null);
|
||||
|
||||
let idCounter = 0;
|
||||
|
||||
export function ToastProvider({ children }: { children: ReactNode }) {
|
||||
const [toasts, setToasts] = useState<Toast[]>([]);
|
||||
|
||||
const push = useCallback((message: string, tone: Toast["tone"]) => {
|
||||
const id = ++idCounter;
|
||||
setToasts((prev) => [...prev, { id, message, tone }]);
|
||||
setTimeout(() => {
|
||||
setToasts((prev) => prev.filter((t) => t.id !== id));
|
||||
}, 3500);
|
||||
}, []);
|
||||
|
||||
const showSuccess = useCallback((m: string) => push(m, "success"), [push]);
|
||||
const showError = useCallback((m: string) => push(m, "error"), [push]);
|
||||
|
||||
return (
|
||||
<ToastContext.Provider value={{ showSuccess, showError }}>
|
||||
{children}
|
||||
<div className="fixed bottom-6 left-1/2 -translate-x-1/2 z-[100] flex flex-col gap-2 items-center">
|
||||
{toasts.map((t) => (
|
||||
<div
|
||||
key={t.id}
|
||||
className={`flex items-center gap-2 rounded-(--radius-md) px-4 py-3 shadow-(--shadow-cute-lg) text-[13px] font-semibold text-white [animation:bounce-in_0.3s_ease-out] ${
|
||||
t.tone === "success" ? "bg-(--color-status-success)" : "bg-(--color-status-error)"
|
||||
}`}
|
||||
>
|
||||
{t.tone === "success" ? <CheckCircle2 size={16} /> : <XCircle size={16} />}
|
||||
{t.message}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</ToastContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useToast() {
|
||||
const ctx = useContext(ToastContext);
|
||||
if (!ctx) throw new Error("useToast باید داخل ToastProvider استفاده بشه");
|
||||
return ctx;
|
||||
}
|
||||
Reference in New Issue
Block a user