gitscope
← marzneshin / v0.3.0-alpha2 / dashboard/src/components/copy-button/index.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/components/copy-button/index.tsx · TypeScript
Blame Raw
 1import { Button } from '@marzneshin/components';
 2import CopyToClipboard from 'react-copy-to-clipboard';
 3import { useEffect, useState } from 'react';
 4import { useTranslation } from 'react-i18next';
 5import { CopyCheck, CopyX, ClipboardCopy, LucideIcon } from 'lucide-react';
 6import { toast } from 'sonner';
 7import { cn } from '@marzneshin/utils';
 8
 9interface CopyToClipboardButtonProps {
10    text: string;
11    disabled?: boolean;
12    successMessage: string;
13    copyIcon?: LucideIcon;
14    copyLabel: string;
15    errorLabel: string;
16    className?: string;
17}
18
19export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
20    text,
21    disabled = false,
22    successMessage,
23    copyIcon,
24    copyLabel,
25    errorLabel, className
26}) => {
27    const { t } = useTranslation();
28    const [copied, setCopied] = useState(false);
29    const [healthy, setHealthy] = useState(false);
30
31    useEffect(() => {
32        if (copied) {
33            toast.success(t(successMessage));
34            setTimeout(() => {
35                setCopied(false);
36            }, 1000);
37        }
38    }, [copied, successMessage, t]);
39
40    useEffect(() => {
41        setHealthy(text !== '');
42    }, [text]);
43
44    const handleClick = () => {
45        if (!disabled) {
46            setCopied(true);
47        }
48    };
49
50    const Icon = copied ? CopyCheck : (healthy ? (copyIcon ? copyIcon : ClipboardCopy) : CopyX)
51
52    return (
53        <CopyToClipboard text={text}>
54            <Button className={cn(className, "p-2 flex flex-row items-center gap-2")} disabled={disabled || !healthy} onClick={handleClick}>
55                <Icon />
56                {t(copied ? successMessage : (healthy ? copyLabel : errorLabel))}
57            </Button>
58        </CopyToClipboard>
59    );
60};