From e0ab4f11e93b90268555ad2d95dbf7b44b6baad7 Mon Sep 17 00:00:00 2001 From: malmen237 Date: Fri, 12 Jul 2024 14:50:42 +0200 Subject: [PATCH] feat: added copy production-urls to clipboard --- .../landing-page/create-production.tsx | 85 ++++++++++++++++++- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/src/components/landing-page/create-production.tsx b/src/components/landing-page/create-production.tsx index 1ea1bf2d..390a48bc 100644 --- a/src/components/landing-page/create-production.tsx +++ b/src/components/landing-page/create-production.tsx @@ -17,6 +17,8 @@ import { useGlobalState } from "../../global-state/context-provider.tsx"; import { Spinner } from "../loader/loader.tsx"; import { FlexContainer } from "../generic-components.ts"; import { RemoveLineButton } from "../remove-line-button/remove-line-button.tsx"; +import { useFetchProduction } from "./use-fetch-production.ts"; +import { darkText, errorColour } from "../../css-helpers/defaults.ts"; type FormValues = { productionName: string; @@ -38,17 +40,36 @@ const ButtonWrapper = styled.div` const ProductionConfirmation = styled.div` background: #91fa8c; padding: 1rem; + margin-bottom: 1rem; border-radius: 0.5rem; border: 1px solid #b2ffa1; color: #1a1a1a; `; +const CopyToClipboardWrapper = styled.div` + display: flex; + flex-direction: row; + align-items: center; +`; + +const CopyConfirmation = styled.p` + padding-left: 1rem; +`; + +const FetchErrorMessage = styled.div` + background: ${errorColour}; + color: ${darkText}; + padding: 0.5rem; + margin: 1rem 0; +`; + export const CreateProduction = () => { const [, dispatch] = useGlobalState(); const [createdProductionId, setCreatedProductionId] = useState( null ); const [loading, setLoading] = useState(false); + const [copiedUrl, setCopiedUrl] = useState(false); const { formState: { errors }, control, @@ -64,6 +85,10 @@ export const CreateProduction = () => { }, }); + const { error: productionFetchError, production } = useFetchProduction( + createdProductionId ? parseInt(createdProductionId, 10) : null + ); + const onSubmit: SubmitHandler = (value) => { setLoading(true); API.createProduction({ @@ -97,6 +122,32 @@ export const CreateProduction = () => { } }, [createdProductionId, dispatch, reset]); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const handleCopyProdUrlsToClipboard = (input: any) => { + if (input !== null) { + navigator.clipboard + .writeText(input) + .then(() => { + let timeout: number | null = null; + setCopiedUrl(true); + console.log("Text copied to clipboard"); + + timeout = window.setTimeout(() => { + setCopiedUrl(false); + }, 11500); + + return () => { + if (timeout !== null) { + window.clearTimeout(timeout); + } + }; + }) + .catch((err) => { + console.error("Failed to copy text: ", err); + }); + } + }; + return ( Create Production @@ -178,10 +229,36 @@ export const CreateProduction = () => { - {createdProductionId !== null && ( - - The production ID is: {createdProductionId.toString()} - + {createdProductionId !== null && production && ( + <> + + The production ID is: {createdProductionId.toString()} + + {!productionFetchError && ( + + + handleCopyProdUrlsToClipboard( + production.lines.map((item) => { + return ` ${item.name}: ${window.location.origin}/production/${production.productionId}/line/${item.id}`; + }) + ) + } + disabled={copiedUrl} + > + Copy Links + + {copiedUrl && Copied} + + )} + {productionFetchError && ( + + The production information could not be fetched, not able to copy + to clipboard. + + )} + )} );