Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create reusable CopyButton component #9498

Open
wants to merge 36 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e836004
refactor all copy functionalities
rajku-dev Dec 19, 2024
59b9bfb
Update src/Utils/utils.ts
rajku-dev Dec 19, 2024
029b390
create CopyButton component
rajku-dev Dec 19, 2024
56d858a
use CopyButton component across
rajku-dev Dec 19, 2024
ec05b19
disable serial copyBtn
rajku-dev Dec 19, 2024
2c58284
revert tooltip class
rajku-dev Dec 19, 2024
68da53b
use cva instead
rajku-dev Dec 19, 2024
ae2426c
Update src/components/Licenses/SBOMViewer.tsx
rajku-dev Dec 20, 2024
4f383e6
remove console logs
rajku-dev Dec 20, 2024
c14a04d
drop error handling
rajku-dev Dec 20, 2024
1588cff
Update src/components/Shifting/ShiftDetails.tsx
rajku-dev Dec 20, 2024
1ccce49
Update src/components/Assets/AssetWarrantyCard.tsx
rajku-dev Dec 20, 2024
ae494c0
fix lint
rajku-dev Dec 20, 2024
12a262a
Merge branch 'develop' into issue/9494/revamp-clipboard
rajku-dev Dec 20, 2024
d10c5be
Merge branch 'develop' into issue/9494/revamp-clipboard
nihal467 Dec 20, 2024
ba35911
Merge branch 'develop' into issue/9494/revamp-clipboard
rajku-dev Dec 21, 2024
bc9a831
add CopyButton in DoctorVideoSlideover
rajku-dev Dec 21, 2024
5f4dd02
Merge branch 'issue/9494/revamp-clipboard' of https://github.com/rajk…
rajku-dev Dec 21, 2024
98f484e
add disable logic
rajku-dev Dec 21, 2024
50edfb9
fix disable logic
rajku-dev Dec 21, 2024
2c7ab78
fix lint
rajku-dev Dec 21, 2024
d9ed226
format with prettier
rajku-dev Dec 21, 2024
f84ba5b
Move content handling logic to CopyButton component
rajku-dev Dec 21, 2024
6c99e4e
format with prettier
rajku-dev Dec 21, 2024
6183a19
format ShiftDetails
rajku-dev Dec 21, 2024
ce9c578
add translations
rajku-dev Dec 21, 2024
70c0cc4
edit CopyButton
rajku-dev Dec 21, 2024
90eea5a
Merge branch 'develop' into issue/9494/revamp-clipboard
rajku-dev Dec 21, 2024
6f48ef6
Update src/components/Common/CopyButton.tsx
rajku-dev Dec 22, 2024
6ba3268
Update src/components/Common/CopyButton.tsx
rajku-dev Dec 22, 2024
df97cd0
fix lint
rajku-dev Dec 22, 2024
fe561d7
Merge branch 'develop' into issue/9494/revamp-clipboard
rajku-dev Dec 23, 2024
1bb5cac
Handle conditional rendering of CopyButton in AssetWaarantyCard | Fi…
rajku-dev Dec 23, 2024
541aa66
Merge branch 'issue/9494/revamp-clipboard' of https://github.com/rajk…
rajku-dev Dec 23, 2024
92a17cd
Merge branch 'develop' into issue/9494/revamp-clipboard
rajku-dev Dec 23, 2024
9c0a815
Update src/components/Common/CopyButton.tsx
rajku-dev Dec 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 6 additions & 30 deletions src/components/Assets/AssetWarrantyCard.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { t } from "i18next";
import { useEffect, useState } from "react";
import CopyToClipboard from "react-copy-to-clipboard";

import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon";

import { AssetData } from "@/components/Assets/AssetTypes";
import CopyButton from "@/components/Common/CopyButton";

import { formatDate } from "@/Utils/utils";

Expand All @@ -19,17 +16,6 @@ export default function AssetWarrantyCard(props: { asset: AssetData }) {
Vendor: asset.vendor_name,
};

const [isCopied, setIsCopied] = useState(false);

useEffect(() => {
if (isCopied) {
const timeout = setTimeout(() => {
setIsCopied(false);
}, 2000);
return () => clearTimeout(timeout);
}
}, [isCopied]);

return (
<div className="warranty-card relative z-10 flex h-full w-screen flex-col overflow-hidden p-6 text-white transition-all hover:scale-[1.01] hover:from-primary-600 hover:to-primary-700 md:w-full md:rounded-xl xl:w-96">
<div className="mb-3 text-right text-lg font-bold italic">
Expand All @@ -45,21 +31,11 @@ export default function AssetWarrantyCard(props: { asset: AssetData }) {
<div className="flex items-center gap-2 font-semibold">
{details[key as keyof typeof details] || "--"}
{key === "Serial Number" && (
<button className="tooltip tooltip-bottom">
<CopyToClipboard
text={details[key as keyof typeof details] || "--"}
onCopy={() => setIsCopied(true)}
>
{isCopied ? (
<span className="text-sm text-white">
{t("copied_to_clipboard")}
</span>
) : (
<CareIcon icon="l-copy" className="text-lg" />
)}
</CopyToClipboard>
<span className="tooltip-text">Copy to clipboard</span>
</button>
<CopyButton
content={details[key as keyof typeof details] || ""}
tooltipContent="Copy to clipboard"
iconClassName="text-lg"
/>
)}
</div>
</div>
Expand Down
58 changes: 58 additions & 0 deletions src/components/Common/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useState } from "react";

import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon";

import { TooltipComponent, TooltipProvider } from "@/components/ui/tooltip";

import { copyToClipboard } from "@/Utils/utils";
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved

interface CopyButtonProps {
content: string;
tooltipContent?: string;
btnContent?: string;
resetDuration?: number;
iconClassName?: string;
btnClassName?: string;
icons?: {
copied: IconName;
copy: IconName;
};
}
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved

const CopyButton = ({
content,
tooltipContent = "Copy to clipboard",
btnContent = "",
resetDuration = 2500,
iconClassName = "text-lg",
btnClassName = "",
icons = { copied: "l-check", copy: "l-copy" },
}: CopyButtonProps) => {
const [isCopied, setIsCopied] = useState(false);

return (
<TooltipProvider>
<TooltipComponent content={isCopied ? "Copied!" : tooltipContent}>
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
<button
onClick={() => {
copyToClipboard(content);
setIsCopied(true);
setTimeout(() => setIsCopied(false), resetDuration);
}}
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
className={btnClassName}
>
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
{btnContent ? (
btnContent
) : (
<CareIcon
icon={isCopied ? icons.copied : icons.copy}
className={iconClassName}
/>
)}
</button>
</TooltipComponent>
</TooltipProvider>
);
};

export default CopyButton;
28 changes: 8 additions & 20 deletions src/components/Licenses/SBOMViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import dayjs from "dayjs";
import React, { useState } from "react";
import { CopyToClipboard } from "react-copy-to-clipboard";

import Card from "@/CAREUI/display/Card";
import CareIcon from "@/CAREUI/icons/CareIcon";

import CopyButton from "@/components/Common/CopyButton";
import beBomData from "@/components/Licenses/be-sbom.json";
import feBomData from "@/components/Licenses/fe-sbom.json";
import licenseUrls from "@/components/Licenses/licenseUrls.json";
Expand All @@ -13,6 +13,7 @@ const getLicenseUrl = (licenseId: string | undefined): string | null => {
if (!licenseId) return null;
return licenseUrls[licenseId as keyof typeof licenseUrls] || null;
};

interface CycloneDXExternalRef {
url?: string;
type?: string;
Expand Down Expand Up @@ -64,15 +65,9 @@ interface CycloneDXBOM {
}

const BOMDisplay: React.FC = () => {
const [copyStatus, setCopyStatus] = useState(false);
const [showExternalRefs, setShowExternalRefs] = useState<number | null>(null);
const [activeTab, setActiveTab] = useState<string>("bom");

const handleCopy = () => {
setCopyStatus(true);
setTimeout(() => setCopyStatus(false), 2000);
};

const bomData = (activeTab === "bom" ? feBomData : beBomData) as CycloneDXBOM;

return (
Expand Down Expand Up @@ -182,19 +177,12 @@ const BOMDisplay: React.FC = () => {
))}
</div>
<div className="mt-4">
<CopyToClipboard
text={JSON.stringify(bomData, null, 2)}
onCopy={handleCopy}
>
<button className="text-md hover:bg-primary-dark w-full rounded-md bg-primary px-4 py-2 text-white transition-all duration-300 focus:outline-none md:w-auto">
Copy BOM JSON
</button>
</CopyToClipboard>
{copyStatus && (
<span className="mt-2 block text-sm text-gray-600">
Copied to clipboard!
</span>
)}
<CopyButton
content={JSON.stringify(bomData, null, 2)}
tooltipContent="Copy BOM JSON to clipboard"
btnContent="Copy BOM JSON"
btnClassName="text-md hover:bg-primary-dark w-full rounded-md bg-primary px-4 py-2 text-white transition-all duration-300 focus:outline-none md:w-auto"
/>
</div>
</Card>
</div>
Expand Down
26 changes: 6 additions & 20 deletions src/components/Shifting/ShiftDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import careConfig from "@careConfig";
import { QRCodeSVG } from "qrcode.react";
import { Link, navigate } from "raviger";
import { useState } from "react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { useTranslation } from "react-i18next";

import RecordMeta from "@/CAREUI/display/RecordMeta";
Expand All @@ -12,6 +11,7 @@ import PrintPreview from "@/CAREUI/misc/PrintPreview";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

import ButtonV2 from "@/components/Common/ButtonV2";
import CopyButton from "@/components/Common/CopyButton";
import Loading from "@/components/Common/Loading";
import Page from "@/components/Common/Page";
import { ConsultationModel } from "@/components/Facility/models";
Expand All @@ -30,7 +30,6 @@ import { formatDateTime, formatName, formatPatientAge } from "@/Utils/utils";

export default function ShiftDetails(props: { id: string }) {
const [isPrintMode, setIsPrintMode] = useState(false);
const [isCopied, setIsCopied] = useState(false);
const { t } = useTranslation();

const shiftStatusOptions = careConfig.wartimeShifting
Expand All @@ -42,20 +41,11 @@ export default function ShiftDetails(props: { id: string }) {
});
const showCopyToclipBoard = (data: any) => {
return (
<a href="#">
<CopyToClipboard
text={copyContent(data)}
onCopy={() => setIsCopied(true)}
>
{isCopied ? (
<span className="copied-to-cb">{t("copied_to_clipboard")}</span>
) : (
<span className="copy-to-cb">
<CareIcon icon="l-clipboard" className="text-2xl" />
</span>
)}
</CopyToClipboard>
</a>
<CopyButton
content={copyContent(data)}
tooltipContent="Copy Details to Clipboard"
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
iconClassName="h-6 w-6"
/>
);
};

Expand Down Expand Up @@ -93,10 +83,6 @@ export default function ShiftDetails(props: { id: string }) {
return formattedText;
};

setTimeout(() => {
setIsCopied(false);
}, 5000);

const showPatientCard = (patientData: PatientModel) => {
const patientGender = GENDER_TYPES.find(
(i) => i.id === patientData?.gender,
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const TooltipComponent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md bg-gray-900 px-3 py-1.5 text-xs text-gray-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:bg-gray-50 dark:text-gray-900",
"z-50 overflow-hidden rounded-md bg-gray-800 px-3 py-1.5 text-sm text-gray-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:bg-gray-50 dark:text-gray-900",
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
className,
)}
>
Expand Down
Loading