الملفات
back_end_oudelaa/oudelaa_dashboard/components/ui/toast.tsx
boutmoun123 8863f61d00
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled
Add Oudelaa dashboard API integration
2026-05-25 20:36:52 +03:00

81 أسطر
2.6 KiB
TypeScript

"use client";
import * as React from "react";
import { X } from "lucide-react";
import { cn } from "@/lib/utils";
type ToastVariant = "default" | "success" | "warning" | "danger";
type ToastItem = {
id: string;
title: string;
description?: string;
variant?: ToastVariant;
};
type ToastContextValue = {
toast: (item: Omit<ToastItem, "id">) => void;
};
const ToastContext = React.createContext<ToastContextValue | null>(null);
function getToastId() {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return `toast_${Date.now()}_${Math.random().toString(16).slice(2)}`;
}
const variantStyles: Record<ToastVariant, string> = {
default: "border-border bg-card text-foreground",
success: "border-emerald-500/40 bg-emerald-500/10 text-emerald-100",
warning: "border-amber-500/40 bg-amber-500/10 text-amber-100",
danger: "border-rose-500/40 bg-rose-500/10 text-rose-100",
};
export function ToastProvider({ children }: { children: React.ReactNode }) {
const [toasts, setToasts] = React.useState<ToastItem[]>([]);
const toast = React.useCallback((item: Omit<ToastItem, "id">) => {
const id = getToastId();
setToasts((prev) => [...prev, { id, ...item }]);
window.setTimeout(() => {
setToasts((prev) => prev.filter((toastItem) => toastItem.id !== id));
}, 3200);
}, []);
const remove = React.useCallback((id: string) => {
setToasts((prev) => prev.filter((toastItem) => toastItem.id !== id));
}, []);
return (
<ToastContext.Provider value={{ toast }}>
{children}
<div className="fixed bottom-6 left-6 z-50 flex w-[90vw] max-w-sm flex-col gap-3">
{toasts.map((item) => (
<div key={item.id} className={cn("frame-panel border px-4 py-3 shadow-glow", variantStyles[item.variant ?? "default"])}>
<div className="flex items-start justify-between gap-3">
<div>
<p className="text-sm font-semibold">{item.title}</p>
{item.description ? <p className="mt-1 text-xs text-muted-foreground">{item.description}</p> : null}
</div>
<button className="rounded-md p-1 text-muted-foreground hover:text-foreground" onClick={() => remove(item.id)}>
<X className="h-4 w-4" />
</button>
</div>
</div>
))}
</div>
</ToastContext.Provider>
);
}
export function useToast() {
const context = React.useContext(ToastContext);
if (!context) {
throw new Error("useToast must be used within ToastProvider");
}
return context;
}