You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.2 KiB
73 lines
2.2 KiB
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { IoAlertCircle, IoClose, IoCheckmarkCircle } from "react-icons/io5";
|
|
|
|
type ErrorToastProps = {
|
|
message: string;
|
|
onClose: () => void;
|
|
duration?: number;
|
|
variant?: "error" | "success";
|
|
};
|
|
|
|
export default function ErrorToast({
|
|
message,
|
|
onClose,
|
|
duration = 4000,
|
|
variant = "error",
|
|
}: ErrorToastProps) {
|
|
const [isVisible, setIsVisible] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const timer = setTimeout(() => {
|
|
setIsVisible(false);
|
|
setTimeout(onClose, 300); // Wait for fade-out animation to complete
|
|
}, duration);
|
|
|
|
return () => clearTimeout(timer);
|
|
}, [duration, onClose]);
|
|
|
|
const handleClose = () => {
|
|
setIsVisible(false);
|
|
setTimeout(onClose, 300);
|
|
};
|
|
|
|
const isSuccess = variant === "success";
|
|
|
|
return (
|
|
<div
|
|
className={[
|
|
"fixed top-4 left-1/2 z-50 flex w-[calc(100%-34px)] max-w-[341px] -translate-x-1/2 items-center gap-3 rounded-xl border p-4 shadow-lg backdrop-blur-md transition-all duration-300",
|
|
isVisible
|
|
? "translate-y-0 opacity-100 scale-100"
|
|
: "-translate-y-4 opacity-0 scale-95",
|
|
isSuccess
|
|
? "bg-green-50/95 dark:bg-green-950/95 text-green-800 dark:text-green-200 border-green-100/80 dark:border-green-900/50"
|
|
: "bg-red-50/95 dark:bg-red-950/95 text-red-800 dark:text-red-200 border-red-100/80 dark:border-red-900/50",
|
|
].join(" ")}
|
|
role="alert"
|
|
>
|
|
{isSuccess ? (
|
|
<IoCheckmarkCircle className="size-5 shrink-0 text-green-500" />
|
|
) : (
|
|
<IoAlertCircle className="size-5 shrink-0 text-red-500" />
|
|
)}
|
|
<span className="flex-1 text-sm font-semibold leading-normal">
|
|
{message}
|
|
</span>
|
|
<button
|
|
type="button"
|
|
onClick={handleClose}
|
|
className={[
|
|
"flex size-6 items-center justify-center rounded-lg transition-colors",
|
|
isSuccess
|
|
? "text-green-500 hover:bg-green-100/50 dark:hover:bg-green-900/50"
|
|
: "text-red-500 hover:bg-red-100/50 dark:hover:bg-red-900/50",
|
|
].join(" ")}
|
|
aria-label="Close toast"
|
|
>
|
|
<IoClose className="size-4" />
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|