forked from carrydela/Rs_blog_front
69 lines
1.6 KiB
TypeScript
69 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect, useRef } from "react";
|
|
import clsx from "clsx";
|
|
import { Button } from "./ui/Button";
|
|
|
|
interface DeleteButtonProps {
|
|
onDelete: () => Promise<void>;
|
|
className?: string;
|
|
size?: "sm" | "md" | "lg";
|
|
}
|
|
|
|
const CONFIRM_TIMEOUT = 3000;
|
|
|
|
export function DeleteButton({ onDelete, className, size = "sm" }: DeleteButtonProps) {
|
|
const [confirming, setConfirming] = useState(false);
|
|
const [deleting, setDeleting] = useState(false);
|
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
if (timeoutRef.current) {
|
|
clearTimeout(timeoutRef.current);
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
const handleClick = async () => {
|
|
if (deleting) return;
|
|
|
|
if (!confirming) {
|
|
setConfirming(true);
|
|
timeoutRef.current = setTimeout(() => {
|
|
setConfirming(false);
|
|
}, CONFIRM_TIMEOUT);
|
|
return;
|
|
}
|
|
|
|
if (timeoutRef.current) {
|
|
clearTimeout(timeoutRef.current);
|
|
}
|
|
|
|
setDeleting(true);
|
|
try {
|
|
await onDelete();
|
|
} catch {
|
|
setDeleting(false);
|
|
setConfirming(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Button
|
|
size={size}
|
|
onClick={handleClick}
|
|
disabled={deleting}
|
|
className={clsx(
|
|
"transition-all duration-200",
|
|
confirming
|
|
? "border-red-500 text-red-500 hover:bg-red-500 hover:text-white"
|
|
: "border-neutral-400 text-neutral-500 hover:border-neutral-600 hover:text-neutral-700",
|
|
className
|
|
)}
|
|
>
|
|
{deleting ? "Deleting..." : confirming ? "Confirm Delete" : "Delete"}
|
|
</Button>
|
|
);
|
|
}
|