diff --git a/public/locale/en.json b/public/locale/en.json index b9d5c60539c..3a8bcfacc68 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -551,6 +551,7 @@ "copied_to_clipboard": "Copied to clipboard", "copilot_thinking": "Copilot is thinking...", "copy_phone_number": "Copy Phone Number", + "copy_to_clipboard": "Copy to clipboard", "could_not_autofill": "We could not autofill any fields from what you said", "countries_travelled": "Countries travelled", "covid_19_cat_gov": "Covid_19 Clinical Category as per Govt. of Kerala guideline (A/B/C)", diff --git a/src/components/Assets/AssetWarrantyCard.tsx b/src/components/Assets/AssetWarrantyCard.tsx index 9f37394957a..7e8e544dc03 100644 --- a/src/components/Assets/AssetWarrantyCard.tsx +++ b/src/components/Assets/AssetWarrantyCard.tsx @@ -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"; @@ -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 (
@@ -44,23 +30,12 @@ export default function AssetWarrantyCard(props: { asset: AssetData }) {
{details[key as keyof typeof details] || "--"} - {key === "Serial Number" && ( - - )} + {key === "Serial Number" && + details[key as keyof typeof details] && ( + + )}
))} diff --git a/src/components/Common/CopyButton.tsx b/src/components/Common/CopyButton.tsx new file mode 100644 index 00000000000..b984e31cb28 --- /dev/null +++ b/src/components/Common/CopyButton.tsx @@ -0,0 +1,62 @@ +import { VariantProps } from "class-variance-authority"; +import { useState } from "react"; +import * as React from "react"; +import { useTranslation } from "react-i18next"; + +import CareIcon from "@/CAREUI/icons/CareIcon"; + +import { Button, buttonVariants } from "@/components/ui/button"; +import { TooltipComponent, TooltipProvider } from "@/components/ui/tooltip"; + +import { copyToClipboard } from "@/Utils/utils"; + +export interface CopyButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + children?: React.ReactNode; + content: string | undefined; + tooltipContent?: string; +} + +const CopyButton = ({ + content, + tooltipContent, + children, + size, +}: CopyButtonProps) => { + const [isCopied, setIsCopied] = useState(false); + const { t } = useTranslation(); + + if (!content) return null; + + return ( + + + + + + ); +}; + +export default CopyButton; diff --git a/src/components/Facility/DoctorVideoSlideover.tsx b/src/components/Facility/DoctorVideoSlideover.tsx index 98058fd4bfb..3478b94afb9 100644 --- a/src/components/Facility/DoctorVideoSlideover.tsx +++ b/src/components/Facility/DoctorVideoSlideover.tsx @@ -5,6 +5,7 @@ import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; import SlideOver from "@/CAREUI/interactive/SlideOver"; import Switch from "@/CAREUI/interactive/Switch"; +import CopyButton from "@/components/Common/CopyButton"; import Loading from "@/components/Common/Loading"; import { SkillObjectModel } from "@/components/Users/models"; import { UserAssignedModel } from "@/components/Users/models"; @@ -18,7 +19,6 @@ import routes from "@/Utils/request/api"; import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, - copyToClipboard, formatName, isUserOnline, relativeTime, @@ -185,7 +185,11 @@ function UserListItem({ user }: { user: UserAnnotatedWithGroup }) { e.stopPropagation(); if (!user.alt_phone_number) return; const phoneNumber = user.alt_phone_number?.replace(/\D+/g, ""); - const message = `${courtesyTitle(user)} ${formatName(user)}, I have a query regarding a patient.\n\nPatient Link: ${window.location.href}`; + const message = `${courtesyTitle(user)} ${formatName( + user, + )}, I have a query regarding a patient.\n\nPatient Link: ${ + window.location.href + }`; const encodedMessage = encodeURIComponent(message); const whatsappAppURL = `whatsapp://send?phone=${phoneNumber}&text=${encodedMessage}`; const whatsappWebURL = `https://wa.me/${phoneNumber}?text=${encodedMessage}`; @@ -241,7 +245,6 @@ function UserListItem({ user }: { user: UserAnnotatedWithGroup }) { } const { t } = useTranslation(); - const [copied, setCopied] = useState(false); return (
- -
- { - // Show online icon based on last_login - user.last_login && isUserOnline(user) ? ( - <> - - - - ) : ( - - ) - } +
+ { + // Show online icon based on last_login + user.last_login && isUserOnline(user) ? ( + <> + + + + ) : ( + + ) + } +
+
+
+ + {formatName(user)} + +
-
-
- - {formatName(user)} - - -
- {!!user.skills.length && ( -
-
- {user.skills?.map((skill: SkillObjectModel) => ( - -

{skill.name}

-
- ))} -
-
- )} -
); } diff --git a/src/components/Licenses/SBOMViewer.tsx b/src/components/Licenses/SBOMViewer.tsx index d8a7cdc93df..e2cd75d372e 100644 --- a/src/components/Licenses/SBOMViewer.tsx +++ b/src/components/Licenses/SBOMViewer.tsx @@ -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"; @@ -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; @@ -64,15 +65,9 @@ interface CycloneDXBOM { } const BOMDisplay: React.FC = () => { - const [copyStatus, setCopyStatus] = useState(false); const [showExternalRefs, setShowExternalRefs] = useState(null); const [activeTab, setActiveTab] = useState("bom"); - const handleCopy = () => { - setCopyStatus(true); - setTimeout(() => setCopyStatus(false), 2000); - }; - const bomData = (activeTab === "bom" ? feBomData : beBomData) as CycloneDXBOM; return ( @@ -182,19 +177,13 @@ const BOMDisplay: React.FC = () => { ))}
- - - - {copyStatus && ( - - Copied to clipboard! - - )} + Copy BOM JSON +
diff --git a/src/components/Shifting/ShiftDetails.tsx b/src/components/Shifting/ShiftDetails.tsx index 58685d20fb1..df5942a479a 100644 --- a/src/components/Shifting/ShiftDetails.tsx +++ b/src/components/Shifting/ShiftDetails.tsx @@ -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"; @@ -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"; @@ -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 @@ -41,22 +40,7 @@ export default function ShiftDetails(props: { id: string }) { pathParams: { id: props.id }, }); const showCopyToclipBoard = (data: any) => { - return ( - - setIsCopied(true)} - > - {isCopied ? ( - {t("copied_to_clipboard")} - ) : ( - - - - )} - - - ); + return ; }; const copyContent = (data: any) => { @@ -93,10 +77,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,