1import {
2 Button,
3 Tooltip,
4 TooltipContent,
5 TooltipTrigger,
6} from "@marzneshin/components";
7import CopyToClipboard from "react-copy-to-clipboard";
8import { useEffect, useState } from "react";
9import { useTranslation } from "react-i18next";
10import { CopyCheck, CopyX, ClipboardCopy, LucideIcon } from "lucide-react";
11import { toast } from "sonner";
12import { cn } from "@marzneshin/utils";
13
14interface CopyToClipboardButtonProps {
15 text: string;
16 disabled?: boolean;
17 successMessage: string;
18 copyIcon?: LucideIcon;
19 copyLabel?: string;
20 errorLabel?: string;
21 className?: string;
22 tooltipMsg?: string;
23}
24
25export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
26 text,
27 disabled = false,
28 successMessage,
29 copyIcon,
30 copyLabel,
31 errorLabel,
32 className,
33 tooltipMsg,
34}) => {
35 const { t } = useTranslation();
36 const [copied, setCopied] = useState(false);
37 const [healthy, setHealthy] = useState(false);
38
39 useEffect(() => {
40 if (copied) {
41 toast.success(t(successMessage));
42 setTimeout(() => {
43 setCopied(false);
44 }, 1000);
45 }
46 }, [copied, successMessage, t]);
47
48 useEffect(() => {
49 setHealthy(text !== "");
50 }, [text]);
51
52 const handleClick = () => {
53 if (!disabled) {
54 setCopied(true);
55 }
56 };
57
58 const tooltip = tooltipMsg ? tooltipMsg : copyLabel ? copyLabel : undefined;
59
60 const Icon = copied ? CopyCheck : healthy ? copyIcon || ClipboardCopy : CopyX;
61 const isWithLabel = successMessage && copyLabel && errorLabel;
62
63 return (
64 <Tooltip>
65 <CopyToClipboard text={text}>
66 <TooltipTrigger asChild>
67 <Button
68 className={cn(className, "p-2 flex flex-row items-center gap-2")}
69 disabled={disabled || !healthy}
70 onClick={handleClick}
71 >
72 <Icon />
73 {isWithLabel &&
74 t(copied ? successMessage : healthy ? copyLabel : errorLabel)}
75 </Button>
76 </TooltipTrigger>
77 </CopyToClipboard>
78 {tooltip && <TooltipContent>{tooltip}</TooltipContent>}
79 </Tooltip>
80 );
81};