From 08387fc406351117d67fd83d3c093e25f6cd40d8 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Mon, 17 Jun 2024 21:07:25 +0530 Subject: [PATCH] feat: optimize design for high-resolution monitors --- apps/OpenSign/src/components/pdf/PdfZoom.js | 53 + .../src/components/pdf/Placeholder.js | 81 +- .../src/components/pdf/PlaceholderBorder.js | 23 +- .../src/components/pdf/PlaceholderType.js | 45 +- apps/OpenSign/src/components/pdf/PrevNext.js | 6 +- .../src/components/pdf/RecipientList.js | 12 +- .../src/components/pdf/RenderAllPdfPage.js | 113 ++- apps/OpenSign/src/components/pdf/RenderPdf.js | 344 +++---- apps/OpenSign/src/components/pdf/Signedby.js | 8 +- .../src/components/pdf/SignerListComponent.js | 56 ++ .../src/components/pdf/SignerListPlace.js | 10 +- .../src/components/pdf/TextFontSetting.js | 76 ++ .../src/components/pdf/WidgetComponent.js | 5 +- .../OpenSign/src/components/pdf/WidgetList.js | 8 +- apps/OpenSign/src/constant/Utils.js | 271 ++--- apps/OpenSign/src/layout/HomeLayout.js | 5 +- apps/OpenSign/src/pages/PdfRequestFiles.js | 650 ++++++------ apps/OpenSign/src/pages/PlaceHolderSign.js | 922 ++++++++++-------- apps/OpenSign/src/pages/SignyourselfPdf.js | 572 ++++++----- .../OpenSign/src/pages/TemplatePlaceholder.js | 625 +++++++----- apps/OpenSign/src/redux/reducers/index.js | 4 +- .../OpenSign/src/redux/reducers/showHeader.js | 14 + apps/OpenSign/src/redux/store.js | 4 +- apps/OpenSign/src/styles/signature.css | 32 +- 24 files changed, 2234 insertions(+), 1705 deletions(-) create mode 100644 apps/OpenSign/src/components/pdf/PdfZoom.js create mode 100644 apps/OpenSign/src/components/pdf/SignerListComponent.js create mode 100644 apps/OpenSign/src/components/pdf/TextFontSetting.js create mode 100644 apps/OpenSign/src/redux/reducers/showHeader.js diff --git a/apps/OpenSign/src/components/pdf/PdfZoom.js b/apps/OpenSign/src/components/pdf/PdfZoom.js new file mode 100644 index 000000000..055a37e24 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/PdfZoom.js @@ -0,0 +1,53 @@ +import React from "react"; + +function PdfZoom(props) { + const onClickZoomIn = () => { + props.setScale(props.scale + 0.1 * props.scale); + props.setZoomPercent(props.zoomPercent + 10); + }; + const onClickZoomOut = () => { + if (props.zoomPercent > 0) { + if (props.zoomPercent === 10) { + props.setScale(1); + } else { + props.setScale(props.scale - 0.1 * props.scale); + } + props.setZoomPercent(props.zoomPercent - 10); + } + }; + const handleReset = () => { + props.setScale(1); + props.setZoomPercent(0); + }; + return ( + // md:mt-[41px] xl:mt-[63px]mt=[] + + + + + + + + 0 ? "pointer" : "default" + }} + title="Zoom out" + > + + + + ); +} + +export default PdfZoom; diff --git a/apps/OpenSign/src/components/pdf/Placeholder.js b/apps/OpenSign/src/components/pdf/Placeholder.js index b11e514e6..2d956019f 100644 --- a/apps/OpenSign/src/components/pdf/Placeholder.js +++ b/apps/OpenSign/src/components/pdf/Placeholder.js @@ -88,6 +88,7 @@ const getDefaultdate = (selectedDate, format = "dd-MM-yyyy") => { const getDefaultFormat = (dateFormat) => dateFormat || "MM/dd/yyyy"; function Placeholder(props) { + const [placeholderBorder, setPlaceholderBorder] = useState({ w: 0, h: 0 }); const [isDraggingEnabled, setDraggingEnabled] = useState(true); const [isShowDateFormat, setIsShowDateFormat] = useState(false); const [selectDate, setSelectDate] = useState({ @@ -119,6 +120,7 @@ function Placeholder(props) { width: null, height: null }); + const containerScale = props.containerWH.width / props.pdfOriginalWH.width; const dateFormatArr = [ "L", "DD-MM-YYYY", @@ -293,12 +295,27 @@ function Placeholder(props) { props?.setShowDropdown(true); } else if (props.pos.type === "checkbox") { props?.setIsCheckbox(true); + } else if ( + [ + textInputWidget, + textWidget, + "name", + "company", + "job title", + "email" + ].includes(props.pos.type) + ) { + props.handleTextSettingModal(true); } else { - props?.handleNameModal(true); + props?.handleNameModal && props?.handleNameModal(true); } - if (props.isPlaceholder && props.type !== textWidget) { - props.setUniqueId(props.data.Id); + if (props.data && props?.pos?.type !== textWidget) { + props.setSignerObjId(props?.data?.signerObjId); + props.setUniqueId(props?.data?.Id); + } else if (props.data && props.pos.type === textWidget) { + props.setTempSignerId(props.uniqueId); + props.setUniqueId(props?.data?.Id); } props.setSignKey(props.pos.key); props.setWidgetType(props.pos.type); @@ -375,7 +392,15 @@ function Placeholder(props) { <> {(props.isPlaceholder || props.isSignYourself) && ( <> - {props.pos.type === "checkbox" && props.isSignYourself ? ( + {[ + "checkbox", + textInputWidget, + textWidget, + "name", + "company", + "job title", + "email" + ].includes(props.pos.type) && props.isSignYourself ? ( { e.stopPropagation(); @@ -395,9 +420,7 @@ function Placeholder(props) { ) : ( ((!props?.pos?.type && props.pos.isStamp) || (props?.pos?.type && - !["date", textWidget, "signature"].includes( - props.pos.type - ) && + !["date", "signature"].includes(props.pos.type) && !props.isSignYourself)) && ( { @@ -409,7 +432,11 @@ function Placeholder(props) { handleOnClickSettingIcon(); }} className="fa-solid fa-gear settingIcon" - style={{ color: "#188ae2", right: "47px", top: "-19px" }} + style={{ + color: "#188ae2", + right: props?.pos?.type === textWidget ? "32px" : "47px", + top: "-19px" + }} > ) )} @@ -620,8 +647,20 @@ function Placeholder(props) { setDraggingEnabled(true); props.setIsResize && props.setIsResize(true); }} - onResizeStop={() => { + onResizeStop={(e, direction, ref) => { props.setIsResize && props.setIsResize(false); + props.handleSignYourselfImageResize && + props.handleSignYourselfImageResize( + ref, + props.pos.key, + props.xyPostion, + props.setXyPostion, + props.index, + containerScale, + props.scale, + props.data && props.data.Id, + props.isResize + ); }} disableDragging={ props.isNeedSign @@ -634,21 +673,15 @@ function Placeholder(props) { props.handleStop && props.handleStop(event, dragElement, props.data?.Id, props.pos?.key) } - default={{ + position={{ x: props.xPos(props.pos, props.isSignYourself), y: props.yPos(props.pos, props.isSignYourself) }} onResize={(e, direction, ref) => { - props.handleSignYourselfImageResize && - props.handleSignYourselfImageResize( - ref, - props.pos.key, - props.xyPostion, - props.setXyPostion, - props.index, - props.data && props.data.Id, - false - ); + setPlaceholderBorder({ + w: ref.offsetWidth / (props.scale * containerScale), + h: ref.offsetHeight / (props.scale * containerScale) + }); }} onClick={() => handleOnClickPlaceholder()} > @@ -677,10 +710,14 @@ function Placeholder(props) { pos={props.pos} isPlaceholder={props.isPlaceholder} getCheckboxRenderWidth={getCheckboxRenderWidth} + scale={props.scale} + containerScale={containerScale} + placeholderBorder={placeholderBorder} /> )} {isMobile ? (
) : ( @@ -749,6 +785,7 @@ function Placeholder(props) { setStartDate={setStartDate} startDate={startDate} handleSaveDate={handleSaveDate} + xPos={props.xPos} /> )} diff --git a/apps/OpenSign/src/components/pdf/PlaceholderBorder.js b/apps/OpenSign/src/components/pdf/PlaceholderBorder.js index d64aab3c2..095ae58f8 100644 --- a/apps/OpenSign/src/components/pdf/PlaceholderBorder.js +++ b/apps/OpenSign/src/components/pdf/PlaceholderBorder.js @@ -11,23 +11,34 @@ function PlaceholderBorder(props) { const getResizeBorderExtraWidth = resizeBorderExtraWidth(); const defaultWidth = defaultWidthHeight(props.pos.type).width; const defaultHeight = defaultWidthHeight(props.pos.type).height; + const width = () => { + const getWidth = + props.placeholderBorder.w || props.pos.Width || defaultWidth; + return ( + getWidth * props.scale * props.containerScale + getResizeBorderExtraWidth + ); + }; + const height = () => { + const getHeight = + props.placeholderBorder.h || props.pos.Height || defaultHeight; + + return ( + getHeight * props.scale * props.containerScale + getResizeBorderExtraWidth + ); + }; const handleMinWidth = () => { if (props.pos.type === "checkbox" || props.pos.type === radioButtonWidget) { return props.getCheckboxRenderWidth.width + getResizeBorderExtraWidth; } else { - return props.pos.Width - ? props.pos.Width + getResizeBorderExtraWidth - : defaultWidth + getResizeBorderExtraWidth; + return width(); } }; const handleMinHeight = () => { if (props.pos.type === "checkbox" || props.pos.type === radioButtonWidget) { return props.getCheckboxRenderWidth.height + getResizeBorderExtraWidth; } else { - return props.pos.Height - ? props.pos.Height + getResizeBorderExtraWidth - : defaultHeight + getResizeBorderExtraWidth; + return height(); } }; return ( diff --git a/apps/OpenSign/src/components/pdf/PlaceholderType.js b/apps/OpenSign/src/components/pdf/PlaceholderType.js index f54768692..9e4dd1c7b 100644 --- a/apps/OpenSign/src/components/pdf/PlaceholderType.js +++ b/apps/OpenSign/src/components/pdf/PlaceholderType.js @@ -145,32 +145,32 @@ function PlaceholderType(props) { ref={ref} > {value} - + )); ExampleCustomInput.displayName = "ExampleCustomInput"; - useEffect(() => { - if ( - ["name", "email", "job title", "company"].includes(type) && - props.isNeedSign && - props.data?.signerObjId === props.signerObjId - ) { - const isDefault = true; - const senderUser = localStorage.getItem(`Extand_Class`); - const jsonSender = JSON.parse(senderUser); - onChangeInput( - jsonSender && jsonSender[0], - null, - props.xyPostion, - null, - props.setXyPostion, - props.data.Id, - isDefault - ); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [type]); + // useEffect(() => { + // if ( + // ["name", "email", "job title", "company"].includes(type) && + // props.isNeedSign && + // props.data?.signerObjId === props.signerObjId + // ) { + // const isDefault = true; + // const senderUser = localStorage.getItem(`Extand_Class`); + // const jsonSender = JSON.parse(senderUser); + // onChangeInput( + // jsonSender && jsonSender[0], + // null, + // props.xyPostion, + // null, + // props.setXyPostion, + // props.data.Id, + // isDefault + // ); + // } + // // eslint-disable-next-line react-hooks/exhaustive-deps + // }, [type]); const calculateFontSize = () => { const fontSize = 10 + Math.min(props.pos.Width, props.pos.Height) * 0.1; @@ -319,6 +319,7 @@ function PlaceholderType(props) { props?.data?.Role, props?.pos?.type )} + {/* {props.xPos(props.pos, props.isSignYourself)} */} ); case "stamp": diff --git a/apps/OpenSign/src/components/pdf/PrevNext.js b/apps/OpenSign/src/components/pdf/PrevNext.js index bf9786296..13d298ae3 100644 --- a/apps/OpenSign/src/components/pdf/PrevNext.js +++ b/apps/OpenSign/src/components/pdf/PrevNext.js @@ -20,9 +20,9 @@ function PrevNext({ pageNumber, allPages, changePage }) { - Prev + Prev - + {pageNumber || (allPages ? 1 : "--")} of {allPages || "--"} ); diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index df912759a..a81d29465 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -15,7 +15,6 @@ const RecipientList = (props) => { const [isEdit, setIsEdit] = useState(false); //function for onhover signer name change background color const inputRef = useRef(null); - const isWidgetExist = (Id) => { return props.signerPos.some((x) => x.Id === Id); }; @@ -72,7 +71,6 @@ const RecipientList = (props) => { props.setRoleName(remainingItems[index]?.Role); props.setBlockColor(remainingItems[index]?.blockColor); }; - return ( <> {props.signersdata.length > 0 && @@ -145,7 +143,7 @@ const RecipientList = (props) => {
{obj.Name ? ( @@ -175,7 +173,7 @@ const RecipientList = (props) => { {isEdit?.[obj.Id] && props.handleRoleChange ? ( props.handleRoleChange(e, obj.Id)} onBlur={() => { @@ -190,7 +188,9 @@ const RecipientList = (props) => { }} /> ) : ( - {obj.Role} + + {obj.Role} + )} )} @@ -251,7 +251,7 @@ const RecipientList = (props) => { : "text-base-content" } cursor-pointer ml-[5px]`} > - +
)}
diff --git a/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js b/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js index 660f8c7e7..8435c0b12 100644 --- a/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js +++ b/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js @@ -1,6 +1,6 @@ -import React, { useState } from "react"; -import RSC from "react-scrollbars-custom"; +import React, { useEffect, useRef, useState } from "react"; import { Document, Page } from "react-pdf"; +import { useSelector } from "react-redux"; function RenderAllPdfPage({ signPdfUrl, @@ -33,7 +33,22 @@ function RenderAllPdfPage({ } } } + const pageContainer = useRef(); + const isHeader = useSelector((state) => state.showHeader); + const [pageWidth, setPageWidth] = useState(""); + useEffect(() => { + const updateSize = () => { + if (pageContainer.current) { + setPageWidth(pageContainer.current.offsetWidth); + } + }; + + // Use setTimeout to wait for the transition to complete + const timer = setTimeout(updateSize, 100); // match the transition duration + + return () => clearTimeout(timer); + }, [isHeader, pageContainer]); //'function `addSignatureBookmark` is used to display the page where the user's signature is located. const addSignatureBookmark = (index) => { const ispageNumber = signPageNumber.includes(index + 1); @@ -48,62 +63,52 @@ function RenderAllPdfPage({ ) ); }; - return ( -
-
-
-
- Pages -
-
- +
+ Pages +
+
+ + {Array.from(new Array(allPages), (el, index) => ( +
{ + setPageNumber(index + 1); + if (setSignBtnPosition) { + setSignBtnPosition([]); + } }} > - - {Array.from(new Array(allPages), (el, index) => ( -
{ - setPageNumber(index + 1); - if (setSignBtnPosition) { - setSignBtnPosition([]); - } - }} - > - {signerPos && addSignatureBookmark(index)} + {signerPos && addSignatureBookmark(index)} -
- -
-
- ))} -
- -
-
-
+
+ +
+
+ ))} +
); diff --git a/apps/OpenSign/src/components/pdf/RenderPdf.js b/apps/OpenSign/src/components/pdf/RenderPdf.js index 875f4177b..3fb0bcfe0 100644 --- a/apps/OpenSign/src/components/pdf/RenderPdf.js +++ b/apps/OpenSign/src/components/pdf/RenderPdf.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState, useEffect } from "react"; import RSC from "react-scrollbars-custom"; import { Document, Page } from "react-pdf"; import { @@ -11,8 +11,6 @@ import Alert from "../../primitives/Alert"; function RenderPdf({ pageNumber, - pdfOriginalWidth, - pdfNewWidth, drop, signerPos, successEmail, @@ -34,7 +32,6 @@ function RenderPdf({ signedSigners, setPdfLoadFail, placeholder, - pdfLoadFail, setSignerPos, setXyPostion, index, @@ -57,165 +54,157 @@ function RenderPdf({ unSignedWidgetId, setIsCheckbox, handleNameModal, + handleTextSettingModal, setTempSignerId, - uniqueId + uniqueId, + setPdfRenderHeight, + isResize, + pdfOriginalWH, + scale }) { + const [isLoadPdf, setIsLoadPdf] = useState(false); + const isMobile = window.innerWidth < 767; - const newWidth = containerWH.width; - const scale = isMobile ? pdfOriginalWidth / newWidth : 1; //check isGuestSigner is present in local if yes than handle login flow header in mobile view const isGuestSigner = localStorage.getItem("isGuestSigner"); // handle signature block width and height according to screen const posWidth = (pos, signYourself) => { + const containerScale = containerWH.width / pdfOriginalWH.width; const defaultWidth = defaultWidthHeight(pos.type).width; const posWidth = pos.Width ? pos.Width : defaultWidth; - let width; if (signYourself) { - width = posWidth; - return width; + return posWidth * scale * containerScale; } else { - if (isMobile) { - if (!pos.isMobile) { - if (pos.IsResize) { - width = posWidth ? posWidth : defaultWidth; - return width; + if (pos.isMobile && pos.scale) { + if (pos.IsResize) { + if (scale > 1) { + return posWidth * pos.scale * containerScale * scale; } else { - width = (posWidth || defaultWidth) / scale; - - return width; + return posWidth * containerScale; } } else { - width = posWidth; - return width; + if (scale > 1) { + return posWidth * pos.scale * containerScale * scale; + } else { + return posWidth * pos.scale * containerScale; + } } } else { - if (pos.isMobile) { - if (pos.IsResize) { - width = posWidth ? posWidth : defaultWidth; - return width; - } else { - width = (posWidth || defaultWidth) * pos.scale; - return width; - } - } else { - width = posWidth ? posWidth : defaultWidth; - return width; - } + return posWidth * scale * containerScale; } } }; const posHeight = (pos, signYourself) => { - let height; - const posHeight = pos.Height; - const defaultHeight = defaultWidthHeight(pos.type).height; + const containerScale = containerWH.width / pdfOriginalWH.width; + const posHeight = pos.Height || defaultWidthHeight(pos.type).height; if (signYourself) { - height = posHeight ? posHeight : defaultHeight; - - return height; + return posHeight * scale * containerScale; } else { - if (isMobile) { - if (!pos.isMobile) { - if (pos.IsResize) { - height = posHeight ? posHeight : defaultHeight; - return height; + if (pos.isMobile && pos.scale) { + if (pos.IsResize) { + if (scale > 1) { + return posHeight * pos.scale * containerScale * scale; } else { - height = (posHeight || defaultHeight) / scale; - - return height; + return posHeight * containerScale; } } else { - height = posHeight ? posHeight : defaultHeight; - return height; + if (scale > 1) { + return posHeight * pos.scale * containerScale * scale; + } else { + return posHeight * pos.scale * containerScale; + } } } else { - if (pos.isMobile) { - if (pos.IsResize) { - height = posHeight ? posHeight : defaultHeight; - return height; - } else { - height = (posHeight || defaultHeight) * pos.scale; - return height; - } - } else { - height = posHeight ? posHeight : defaultHeight; - return height; - } + return posHeight * scale * containerScale; } } }; - const xPos = (pos, signYourself) => { + const containerScale = containerWH.width / pdfOriginalWH.width; const resizePos = pos.xPosition; + if (signYourself) { - return resizePos; + return resizePos * containerScale * scale; } else { //checking both condition mobile and desktop view - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (!pos.isMobile) { - return resizePos / scale; + if (pos.isMobile && pos.scale) { + if (scale > 1) { + return resizePos * pos.scale * containerScale * scale; + } else { + return resizePos * pos.scale * containerScale; } - //pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale - else { - return resizePos * (pos.scale / scale); + } else if (pos.scale === containerScale) { + if (scale > 1) { + return resizePos * pos.scale * scale; + } else { + return resizePos * pos.scale; } } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - - if (pos.isMobile) { - return pos.scale && resizePos * pos.scale; - } - //else placeholder save from desktop(bigscreen) and show in desktop(bigscreen) - else { - return resizePos; + if (pos.scale === containerScale) { + if (scale > 1) { + return resizePos * pos.scale * scale; + } else { + return resizePos * pos.scale; + } + } else { + return resizePos * containerScale; } } } }; const yPos = (pos, signYourself) => { + const containerScale = containerWH.width / pdfOriginalWH.width; const resizePos = pos.yPosition; + if (signYourself) { - return resizePos; + // if (pos.scale === containerScale) { + // if (scale > 1) { + // return resizePos * pos.scale * scale; + // } else { + // return resizePos * pos.scale; + // } + // } else { + return resizePos * containerScale * scale; + // } } else { - //checking both condition mobile and desktop view - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (!pos.isMobile) { - return resizePos / scale; + // checking both condition mobile and desktop view + if (pos.isMobile && pos.scale) { + if (scale > 1) { + return resizePos * pos.scale * containerScale * scale; + } else { + return resizePos * pos.scale * containerScale; } - //pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale - else { - return resizePos * (pos.scale / scale); + } else if (pos.scale === containerScale) { + if (scale > 1) { + return resizePos * pos.scale * scale; + } else { + return resizePos * pos.scale; } } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - - if (pos.isMobile) { - return pos.scale && resizePos * pos.scale; - } - //else placeholder save from desktop(bigscreen) and show in desktop(bigscreen) - else { - return resizePos; - } + return resizePos * containerScale; } } }; + //function for render placeholder block over pdf document - const checkSignedSignes = (data) => { + const CheckSignedSignes = ({ data }) => { let checkSign = []; //condition to handle quick send flow and using normal request sign flow checkSign = signedSigners.filter( (sign) => sign?.Id === data?.Id || sign?.objectId === data?.signerObjId ); - if (data.signerObjId === signerObjectId) { - setCurrentSigner(true); - } + useEffect(() => { + if (data.signerObjId === signerObjectId) { + setCurrentSigner(true); + } + }, [data.signerObjId]); + const handleAllUserName = (Id, Role, type) => { return ( -
+
{ pdfDetails[0].Signers?.find( (signer) => signer.objectId === data.signerObjId @@ -231,7 +220,6 @@ function RenderPdf({ ); }; - return ( checkSign.length === 0 && data.placeHolder.map((placeData, key) => { @@ -253,6 +241,7 @@ function RenderPdf({ setXyPostion={setSignerPos} data={data} setIsResize={setIsResize} + isResize={isResize} isShowBorder={false} signerObjId={signerObjectId} isShowDropdown={true} @@ -271,6 +260,9 @@ function RenderPdf({ setSelectWidgetId={setSelectWidgetId} selectWidgetId={selectWidgetId} setCurrWidgetsDetails={setCurrWidgetsDetails} + scale={scale} + containerWH={containerWH} + pdfOriginalWH={pdfOriginalWH} /> ) @@ -282,6 +274,8 @@ function RenderPdf({ ); }; + //function for render placeholder block over pdf document + const handleUserName = (Id, Role, type) => { if (Id) { const checkSign = signersdata.find((sign) => sign.Id === Id); @@ -316,11 +310,10 @@ function RenderPdf({ ); } }; - return ( <> {successEmail && Email sent successfully!} - {isMobile && scale ? ( + {isMobile ? (
- {pdfLoadFail.status && + {isLoadPdf && (pdfRequest ? signerPos.map((data, key) => { return ( - {checkSignedSignes(data)} + ); }) @@ -391,6 +384,11 @@ function RenderPdf({ handleNameModal={handleNameModal} setTempSignerId={setTempSignerId} uniqueId={uniqueId} + handleTextSettingModal={ + handleTextSettingModal + } + containerWH={containerWH} + pdfOriginalWH={pdfOriginalWH} /> ); @@ -422,7 +420,6 @@ function RenderPdf({ index={index} xyPostion={xyPostion} setXyPostion={setXyPostion} - pdfOriginalWidth={pdfOriginalWidth} containerWH={containerWH} setIsSignPad={setIsSignPad} isShowBorder={true} @@ -441,6 +438,11 @@ function RenderPdf({ setIsCheckbox={setIsCheckbox} setValidateAlert={setValidateAlert} setCurrWidgetsDetails={setCurrWidgetsDetails} + handleTextSettingModal={ + handleTextSettingModal + } + scale={scale} + pdfOriginalWH={pdfOriginalWH} /> ) ); @@ -452,7 +454,9 @@ function RenderPdf({ {/* this component for render pdf document is in middle of the component */}
setPdfLoadFail(true)} + onLoadError={() => { + setPdfLoadFail(true); + }} loading={"Loading Document.."} onLoadSuccess={pageDetails} // ref={pdfRef}' @@ -471,6 +475,10 @@ function RenderPdf({ > {Array.from(new Array(numPages), (el, index) => ( { + setPdfRenderHeight && setPdfRenderHeight(height); + setIsLoadPdf(true); + }} key={index} pageNumber={pageNumber} width={containerWH.width} @@ -490,25 +498,24 @@ function RenderPdf({ style={{ position: "relative", boxShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px", - width: - pdfOriginalWidth > pdfNewWidth ? pdfNewWidth : pdfOriginalWidth, - height: window.innerHeight - 110 + "px" + height: window.innerHeight + "px" }} noScrollY={false} - noScrollX={pdfNewWidth < pdfOriginalWidth ? false : true} + noScrollX={scale === 1 ? true : false} >
- {pdfLoadFail.status && + {isLoadPdf && (pdfRequest - ? signerPos.map((data, key) => { + ? signerPos?.map((data, key) => { return ( - {checkSignedSignes(data)} + ); }) @@ -564,6 +571,12 @@ function RenderPdf({ handleNameModal={handleNameModal} setTempSignerId={setTempSignerId} uniqueId={uniqueId} + handleTextSettingModal={ + handleTextSettingModal + } + scale={scale} + containerWH={containerWH} + pdfOriginalWH={pdfOriginalWH} /> ); @@ -577,53 +590,52 @@ function RenderPdf({ : xyPostion.map((data, ind) => { return ( - {data.pageNumber === pageNumber && - data.pos.map((pos) => { - return ( - pos && ( - - - handleStop(event, dragElement, pos.type) - } - handleSignYourselfImageResize={ - handleSignYourselfImageResize - } - index={index} - xyPostion={xyPostion} - setXyPostion={setXyPostion} - pdfOriginalWidth={pdfOriginalWidth} - containerWH={containerWH} - setIsSignPad={setIsSignPad} - isShowBorder={true} - isSignYourself={true} - xPos={xPos} - yPos={yPos} - posWidth={posWidth} - posHeight={posHeight} - pdfDetails={pdfDetails[0]} - isDragging={isDragging} - setIsInitial={setIsInitial} - setWidgetType={setWidgetType} - setSelectWidgetId={setSelectWidgetId} - selectWidgetId={selectWidgetId} - handleUserName={handleUserName} - setIsCheckbox={setIsCheckbox} - setValidateAlert={setValidateAlert} - setCurrWidgetsDetails={ - setCurrWidgetsDetails - } - /> - - ) - ); - })} + {data.pos.map((pos) => { + return ( + + + handleStop(event, dragElement, pos.type) + } + handleSignYourselfImageResize={ + handleSignYourselfImageResize + } + index={index} + xyPostion={xyPostion} + setXyPostion={setXyPostion} + setIsSignPad={setIsSignPad} + isShowBorder={true} + isSignYourself={true} + xPos={xPos} + yPos={yPos} + posWidth={posWidth} + posHeight={posHeight} + pdfDetails={pdfDetails[0]} + isDragging={isDragging} + setIsInitial={setIsInitial} + setWidgetType={setWidgetType} + setSelectWidgetId={setSelectWidgetId} + selectWidgetId={selectWidgetId} + handleUserName={handleUserName} + setIsCheckbox={setIsCheckbox} + setValidateAlert={setValidateAlert} + setCurrWidgetsDetails={setCurrWidgetsDetails} + handleTextSettingModal={ + handleTextSettingModal + } + scale={scale} + containerWH={containerWH} + pdfOriginalWH={pdfOriginalWH} + /> + + ); + })} ); }))} @@ -655,7 +667,13 @@ function RenderPdf({ > {Array.from(new Array(numPages), (el, index) => ( { + setPdfRenderHeight && setPdfRenderHeight(height); + setIsLoadPdf(true); + }} key={index} + width={containerWH.width} + scale={scale || 1} pageNumber={pageNumber} renderAnnotationLayer={false} renderTextLayer={false} diff --git a/apps/OpenSign/src/components/pdf/Signedby.js b/apps/OpenSign/src/components/pdf/Signedby.js index b5213b200..d3cd4a789 100644 --- a/apps/OpenSign/src/components/pdf/Signedby.js +++ b/apps/OpenSign/src/components/pdf/Signedby.js @@ -13,8 +13,12 @@ function Signedby({ pdfDetails }) {
-
- +
+ {getFirstLetter(pdfDetails.ExtUserPtr.Name)}
diff --git a/apps/OpenSign/src/components/pdf/SignerListComponent.js b/apps/OpenSign/src/components/pdf/SignerListComponent.js new file mode 100644 index 000000000..8d324bf43 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/SignerListComponent.js @@ -0,0 +1,56 @@ +import React from "react"; +import { darkenColor, getFirstLetter } from "../../constant/Utils"; + +function SignerListComponent(props) { + const checkSignerBackColor = (obj) => { + if (obj) { + let data = ""; + if (obj?.Id) { + data = props.signerPos.filter((data) => data.Id === obj.Id); + } else { + data = props.signerPos.filter( + (data) => data.signerObjId === obj.objectId + ); + } + return data && data.length > 0 && data[0].blockColor; + } + }; + const checkUserNameColor = (obj) => { + const getBackColor = checkSignerBackColor(obj); + if (getBackColor) { + const color = darkenColor(getBackColor, 0.4); + return color; + } else { + return "#abd1d0"; + } + }; + + return ( +
+
+ + {getFirstLetter(props?.obj?.Name || props?.obj?.Role)} + +
+
+ {props.obj?.Name || props?.obj?.Role} + + {" "} + {props.obj?.Email || props.obj?.email} + +
+
+ ); +} + +export default SignerListComponent; diff --git a/apps/OpenSign/src/components/pdf/SignerListPlace.js b/apps/OpenSign/src/components/pdf/SignerListPlace.js index 6de0a90e8..559ae856f 100644 --- a/apps/OpenSign/src/components/pdf/SignerListPlace.js +++ b/apps/OpenSign/src/components/pdf/SignerListPlace.js @@ -8,7 +8,7 @@ function SignerListPlace(props) {
{props.title ? props.title : "Recipients"} - + {props?.title === "Roles" && ( <> @@ -17,8 +17,10 @@ function SignerListPlace(props) { -
-

What are template roles?

+
+

+ What are template roles? +

Begin by specifying each role needed for the completion of the document. Think about the parties involved in the @@ -61,8 +63,8 @@ function SignerListPlace(props) {

props.handleAddSigner()} > Add role diff --git a/apps/OpenSign/src/components/pdf/TextFontSetting.js b/apps/OpenSign/src/components/pdf/TextFontSetting.js new file mode 100644 index 000000000..03c2d4ef6 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/TextFontSetting.js @@ -0,0 +1,76 @@ +import React from "react"; +import ModalUi from "../../primitives/ModalUi"; +import { fontColorArr, fontsizeArr } from "../../constant/Utils"; +import { themeColor } from "../../constant/const"; + +function TextFontSetting(props) { + return ( + { + props.setIsTextSetting(false); + }} + > +
+
+ Font size: + +
+ color: + + +
+
+ +
+ +
+
+ ); +} + +export default TextFontSetting; diff --git a/apps/OpenSign/src/components/pdf/WidgetComponent.js b/apps/OpenSign/src/components/pdf/WidgetComponent.js index af6cbddc9..7b6e00e86 100644 --- a/apps/OpenSign/src/components/pdf/WidgetComponent.js +++ b/apps/OpenSign/src/components/pdf/WidgetComponent.js @@ -349,12 +349,13 @@ function WidgetComponent({ data-tut={dataTut} className={`${ isMailSend ? "bg-opacity-50 pointer-events-none" : "" - } hidden md:block w-[180px] h-full bg-base-100`} + } hidden md:block h-full bg-base-100`} >
Fields
-
+ +
state.showHeader); return props.updateWidgets.map((item, ind) => { return ( -
+
{ props.addPositionOfSignature && props.addPositionOfSignature("onclick", item); @@ -26,7 +28,7 @@ function WidgetList(props) { props?.handleMouseLeave(); }} > - {item.ref && getWidgetType(item, props?.marginLeft)} + {item.ref && getWidgetType(item, isHeader)}
); diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index b007e7b0c..7340e4174 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -8,6 +8,8 @@ import { appInfo } from "./appinfo"; import { saveAs } from "file-saver"; import printModule from "print-js"; +export const fontsizeArr = [7, 8, 9, 10, 11, 12, 13, 14, 15, 18]; +export const fontColorArr = ["red", "black", "blue", "yellow"]; export const isMobile = window.innerWidth < 767; export const textInputWidget = "text input"; export const textWidget = "text"; @@ -157,9 +159,7 @@ export const getDrive = async (documentId, skip = 0, limit = 100) => { // `pdfNewWidthFun` function is used to calculate pdf width to render in middle container export const pdfNewWidthFun = (divRef) => { - const clientWidth = divRef.current.offsetWidth; - const pdfWidth = clientWidth - 160 - 200; - //160 is width of left side, 200 is width of right side component + const pdfWidth = divRef.current.offsetWidth; return pdfWidth; }; @@ -199,15 +199,12 @@ export const handleImageResize = ( signerPos, setSignerPos, pageNumber, + containerScale, + scale, signerId, showResize ) => { - // const filterSignerPos = signerPos.filter( - // (data) => data.signerObjId === signerId - // ); - const filterSignerPos = signerPos.filter((data) => data.Id === signerId); - if (filterSignerPos.length > 0) { const getPlaceHolder = filterSignerPos[0].placeHolder; const getPageNumer = getPlaceHolder.filter( @@ -220,8 +217,8 @@ export const handleImageResize = ( if (url.key === key) { return { ...url, - Width: ref.offsetWidth, - Height: ref.offsetHeight, + Width: ref.offsetWidth / (containerScale * scale), + Height: ref.offsetHeight / (containerScale * scale), IsResize: showResize ? true : false }; } @@ -376,17 +373,23 @@ export const addWidgetOptions = (type) => { return {}; } }; -export const getWidgetType = (item) => { +export const getWidgetType = (item, isHeader) => { return ( -
+
{!isMobile && } - + {item.type}
-
+
@@ -493,7 +496,9 @@ export const handleSignYourselfImageResize = ( key, xyPostion, setXyPostion, - index + index, + containerScale, + scale ) => { const getXYdata = xyPostion[index].pos; const getPosData = getXYdata; @@ -501,8 +506,8 @@ export const handleSignYourselfImageResize = ( if (url.key === key) { return { ...url, - Width: ref.offsetWidth, - Height: ref.offsetHeight, + Width: ref.offsetWidth / (scale * containerScale), + Height: ref.offsetHeight / (scale * containerScale), IsResize: true }; } @@ -1005,7 +1010,7 @@ export const addInitialData = (signerPos, setXyPostion, value, userId) => { }; //calculate width and height -export const calculateInitialWidthHeight = (type, widgetData) => { +export const calculateInitialWidthHeight = (widgetData) => { const intialText = widgetData; const span = document.createElement("span"); span.textContent = intialText; @@ -1178,7 +1183,6 @@ export const onImageSelect = (event, setImgWH, setImage) => { setImage({ src: image.src, imgType: imageType }); }; }; - //convert https url to base64 export const fetchImageBase64 = async (imageUrl) => { try { @@ -1227,9 +1231,10 @@ export const changeImageWH = async (base64Image) => { export const multiSignEmbed = async ( pngUrl, pdfDoc, - pdfOriginalWidth, + pdfOriginalWH, signyourself, - containerWH + containerWH, + zoomPercent ) => { for (let item of pngUrl) { const typeExist = item.pos.some((data) => data?.type); @@ -1246,7 +1251,7 @@ export const multiSignEmbed = async ( updateItem = item.pos; } const newWidth = containerWH.width; - const scale = isMobile ? pdfOriginalWidth / newWidth : 1; + const scale = newWidth / pdfOriginalWH.width; const pageNo = item.pageNumber; const imgUrlList = updateItem; const pages = pdfDoc.getPages(); @@ -1293,43 +1298,33 @@ export const multiSignEmbed = async ( } } let scaleWidth, scaleHeight; - scaleWidth = placeholderWidth(position, scale, signyourself); - scaleHeight = placeholderHeight(position, scale, signyourself); - + scaleWidth = placeholderWidth( + position, + scale, + signyourself, + pdfOriginalWH, + zoomPercent + ); + scaleHeight = placeholderHeight( + position, + scale, + signyourself, + pdfOriginalWH.height, + zoomPercent + ); const xPos = (pos) => { const resizePos = pos.xPosition; - - if (signyourself) { - if (isMobile) { - return resizePos * scale; - } else { - return resizePos; - } + if (pos.isMobile && pos.scale) { + const x = resizePos * pos.scale; + return x; } else { - //checking both condition mobile and desktop view - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (pos.isMobile) { - const x = resizePos * (pos.scale / scale); - return x * scale; - } else { - const x = resizePos / scale; - return x * scale; - } - } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - if (pos.isMobile) { - const x = resizePos * pos.scale; - return x; - } else { - return resizePos; - } - } + return resizePos; } }; const yPos = (pos, ind, labelDefaultHeight) => { const resizePos = pos.yPosition; + let newUpdateHeight = labelDefaultHeight ? labelDefaultHeight : scaleHeight; @@ -1340,61 +1335,21 @@ export const multiSignEmbed = async ( ? 10 : newUpdateHeight; const newHeight = ind ? (ind > 0 ? widgetHeight : 0) : widgetHeight; - - if (signyourself) { - if (isMobile) { - if (ind && ind > 0 && position.type === "checkbox") { - return page.getHeight() - resizePos * scale - newHeight; - } else if (!ind && position.type === "checkbox") { - return page.getHeight() - resizePos * scale - 10; - } else { - return page.getHeight() - resizePos * scale - newHeight; - } - // return page.getHeight() - resizePos * scale - scaleHeight; + if (pos.isMobile && pos.scale) { + if (pos.IsResize) { + const y = resizePos * pos.scale; + return page.getHeight() - y - newUpdateHeight; } else { - if (ind && ind > 0 && position.type === "checkbox") { - return page.getHeight() - resizePos - newHeight; - } else if (!ind && position.type === "checkbox") { - return page.getHeight() - resizePos - 10; - } else { - return page.getHeight() - resizePos - newHeight; - } - // return page.getHeight() - resizePos - scaleHeight; + const y = resizePos * pos.scale; + return page.getHeight() - y - newUpdateHeight; } } else { - //checking both condition mobile and desktop view - const y = resizePos / scale; - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (pos.isMobile) { - const y = resizePos * (pos.scale / scale); - return page.getHeight() - y * scale - newUpdateHeight; - } else { - if (pos.IsResize) { - return page.getHeight() - y * scale - newUpdateHeight; - } else { - return page.getHeight() - y * scale - newUpdateHeight; - } - } + if (ind && ind > 0 && position.type === "checkbox") { + return page.getHeight() - resizePos - newHeight; + } else if (position.type === "checkbox") { + return page.getHeight() - resizePos - 10; } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - if (pos.isMobile) { - if (pos.IsResize) { - const y = resizePos * pos.scale; - return page.getHeight() - y - newUpdateHeight; - } else { - const y = resizePos * pos.scale; - return page.getHeight() - y - newUpdateHeight; - } - } else { - if (ind && ind > 0 && position.type === "checkbox") { - return page.getHeight() - resizePos - newHeight; - } else if (position.type === "checkbox") { - return page.getHeight() - resizePos - 10; - } else { - return page.getHeight() - resizePos - newHeight; - } - } + return page.getHeight() - resizePos - newHeight; } } }; @@ -1457,7 +1412,20 @@ export const multiSignEmbed = async ( } } else if (widgetTypeExist) { const font = await pdfDoc.embedFont("Helvetica"); - const fontSize = 12; + const fontSize = parseInt(position?.options?.fontSize) || 12; + const color = position?.options?.fontColor; + let updateColorInRgb; + if (color === "red") { + updateColorInRgb = rgb(1, 0, 0); + } else if (color === "black") { + updateColorInRgb = rgb(0, 0, 0); + } else if (color === "blue") { + updateColorInRgb = rgb(0, 0, 1); + } else if (color === "yellow") { + updateColorInRgb = rgb(0.9, 1, 0); + } else { + updateColorInRgb = rgb(0, 0, 0); + } let textContent; if (position?.options?.response) { textContent = position.options?.response; @@ -1519,7 +1487,7 @@ export const multiSignEmbed = async ( // Set initial y-coordinate for the first line const labelDefaultHeight = defaultWidthHeight(position.type).height; - let y = yPos(position, null, labelDefaultHeight) + 10; + let y = yPos(position, null, labelDefaultHeight); let x = xPos(position); //xPos(position) // Embed each line on the page @@ -1528,7 +1496,7 @@ export const multiSignEmbed = async ( x: x, y, font, - color: rgb(0, 0, 0), + color: updateColorInRgb, size: fontSize }); y -= 18; // Adjust the line height as needed @@ -1613,90 +1581,38 @@ export function urlValidator(url) { return false; } } - -export const placeholderWidth = (pos, scale, signyourself) => { - let width; +//calculate placeholder width to embed in pdf +export const placeholderWidth = (pos) => { const defaultWidth = defaultWidthHeight(pos.type).width; - const posWidth = pos.Width ? pos.Width : defaultWidth; + const posWidth = pos.Width || defaultWidth; - if (signyourself) { - if (isMobile) { - return posWidth * scale; - } else { + //condition to handle old data saved from mobile view to get widthh + if (pos.isMobile && pos.scale) { + if (pos.IsResize) { return posWidth; + } else { + return posWidth * pos.scale; } } else { - if (isMobile) { - if (pos.isMobile) { - width = posWidth ? posWidth * scale : defaultWidth * scale; - return width; - } else { - if (pos.IsResize) { - width = posWidth ? posWidth * scale : defaultWidth * scale; - return width; - } else { - width = posWidth ? posWidth : defaultWidth; - return width; - } - } - } else { - if (pos.isMobile) { - if (pos.IsResize) { - width = posWidth ? posWidth : defaultWidth; - return width; - } else { - width = posWidth ? posWidth * pos.scale : defaultWidth * pos.scale; - - return width; - } - } else { - width = posWidth ? posWidth : defaultWidth; - return width; - } - } + return posWidth; } }; -export const placeholderHeight = (pos, scale, signyourself) => { - let height; + +//calculate placeholder height to embed in pdf +export const placeholderHeight = (pos) => { const posHeight = pos.Height; const defaultHeight = defaultWidthHeight(pos.type).height; - if (signyourself) { - if (isMobile) { - return posHeight ? posHeight * scale : defaultHeight * scale; + const posUpdateHeight = posHeight || defaultHeight; + + //condition to handle old data saved from mobile view to get height + if (pos.isMobile && pos.scale) { + if (pos.IsResize) { + return posUpdateHeight; } else { - return posHeight ? posHeight : defaultHeight; + return posUpdateHeight * pos.scale; } } else { - if (isMobile) { - if (pos.isMobile) { - height = posHeight ? posHeight * scale : defaultHeight * scale; - return height; - } else { - if (pos.IsResize) { - height = posHeight ? posHeight * scale : defaultHeight * scale; - return height; - } else { - height = posHeight ? posHeight : defaultHeight; - - return height; - } - } - } else { - if (pos.isMobile) { - if (pos.IsResize) { - height = posHeight ? posHeight : defaultHeight; - return height; - } else { - height = posHeight - ? posHeight * pos.scale - : defaultHeight * pos.scale; - return height; - } - } else { - height = posHeight ? posHeight : defaultHeight; - return height; - } - } + return posUpdateHeight; } }; @@ -2001,7 +1917,6 @@ export const convertPdfArrayBuffer = async (url) => { return "Error"; } }; - //`handleSendOTP` function is used to send otp on user's email using `SendOTPMailV1` cloud function export const handleSendOTP = async (email) => { try { diff --git a/apps/OpenSign/src/layout/HomeLayout.js b/apps/OpenSign/src/layout/HomeLayout.js index 3bac80c71..2b85e95ae 100644 --- a/apps/OpenSign/src/layout/HomeLayout.js +++ b/apps/OpenSign/src/layout/HomeLayout.js @@ -5,7 +5,7 @@ import Sidebar from "../components/sidebar/Sidebar"; import { useWindowSize } from "../hook/useWindowSize"; import Tour from "reactour"; import axios from "axios"; -import { useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import Parse from "parse"; import ModalUi from "../primitives/ModalUi"; import { useNavigate, useLocation, Outlet } from "react-router-dom"; @@ -13,10 +13,12 @@ import { isEnableSubscription } from "../constant/const"; import { useCookies } from "react-cookie"; import { fetchSubscription } from "../constant/Utils"; import Loader from "../primitives/Loader"; +import { showHeader } from "../redux/reducers/showHeader"; const HomeLayout = () => { const navigate = useNavigate(); const location = useLocation(); + const dispatch = useDispatch(); const { width } = useWindowSize(); const [isOpen, setIsOpen] = useState(true); const arr = useSelector((state) => state.TourSteps); @@ -98,6 +100,7 @@ const HomeLayout = () => { } const showSidebar = () => { setIsOpen((value) => !value); + dispatch(showHeader(!isOpen)); }; useEffect(() => { if (width && width <= 768) { diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 2e8ef6f6b..8a3c6bb7b 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -31,8 +31,7 @@ import { contactBook, handleDownloadPdf, handleToPrint, - handleDownloadCertificate, - darkenColor + handleDownloadCertificate } from "../constant/Utils"; import LoaderWithMsg from "../primitives/LoaderWithMsg"; import HandleError from "../primitives/HandleError"; @@ -42,14 +41,17 @@ import PdfDeclineModal from "../primitives/PdfDeclineModal"; import Title from "../components/Title"; import DefaultSignature from "../components/pdf/DefaultSignature"; import ModalUi from "../primitives/ModalUi"; -import VerifyEmail from "../components/pdf/VerifyEmail"; import TourContentWithBtn from "../primitives/TourContentWithBtn"; import { appInfo } from "../constant/appinfo"; import Loader from "../primitives/Loader"; +import { useSelector } from "react-redux"; +import SignerListComponent from "../components/pdf/SignerListComponent"; +import VerifyEmail from "../components/pdf/VerifyEmail"; +import PdfZoom from "../components/pdf/PdfZoom"; + function useQuery() { return new URLSearchParams(useLocation().search); } - function PdfRequestFiles() { const { docId } = useParams(); const navigate = useNavigate(); @@ -81,11 +83,10 @@ function PdfRequestFiles() { isLoad: true, message: "This might take some time" }); - const [defaultSignImg, setDefaultSignImg] = useState(); const [isDocId, setIsDocId] = useState(false); const [pdfNewWidth, setPdfNewWidth] = useState(); - const [pdfOriginalWidth, setPdfOriginalWidth] = useState(); + const [pdfOriginalWH, setPdfOriginalWH] = useState(); const [signerPos, setSignerPos] = useState([]); const [signerObjectId, setSignerObjectId] = useState(); const [isUiLoading, setIsUiLoading] = useState(false); @@ -94,6 +95,7 @@ function PdfRequestFiles() { const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" }); const [unSignedWidgetId, setUnSignedWidgetId] = useState(""); const [expiredDate, setExpiredDate] = useState(""); + const [isResize, setIsResize] = useState(false); const [signerUserId, setSignerUserId] = useState(); const [isDontShow, setIsDontShow] = useState(false); const [isDownloading, setIsDownloading] = useState(""); @@ -127,6 +129,11 @@ function PdfRequestFiles() { const [isVerifyModal, setIsVerifyModal] = useState(false); const [otp, setOtp] = useState(""); const [contractName, setContractName] = useState(""); + const [pdfRenderHeight, setPdfRenderHeight] = useState(); + const [zoomPercent, setZoomPercent] = useState(0); + const [totalZoomPercent, setTotalZoomPercent] = useState(); + const [scale, setScale] = useState(1); + const isHeader = useSelector((state) => state.showHeader); const divRef = useRef(null); const isMobile = window.innerWidth < 767; const rowLevel = @@ -155,17 +162,23 @@ function PdfRequestFiles() { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { - if (divRef.current) { - const pdfWidth = pdfNewWidthFun(divRef); - setPdfNewWidth(pdfWidth); - setContainerWH({ - width: divRef.current.offsetWidth, - height: divRef.current.offsetHeight - }); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [divRef.current]); + const updateSize = () => { + if (divRef.current) { + const pdfWidth = pdfNewWidthFun(divRef); + setPdfNewWidth(pdfWidth); + setContainerWH({ + width: divRef.current.offsetWidth, + height: divRef.current.offsetHeight + }); + } + }; + // Use setTimeout to wait for the transition to complete + const timer = setTimeout(updateSize, 100); // match the transition duration + + return () => clearTimeout(timer); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [divRef.current, isHeader]); //function to use resend otp for email verification const handleResend = async (e) => { e.preventDefault(); @@ -206,7 +219,6 @@ function PdfRequestFiles() { setOtpLoader(false); } }; - //`handleVerifyBtn` function is used to send otp on user mail const handleVerifyBtn = async () => { setIsVerifyModal(true); @@ -766,10 +778,12 @@ function PdfRequestFiles() { const pdfBytes = await multiSignEmbed( pngUrl, pdfDoc, - pdfOriginalWidth, + pdfOriginalWH, isSignYourSelfFlow, - containerWH + containerWH, + scale ); + // console.log("pdfte", pdfBytes); //get ExistUserPtr object id of user class to get tenantDetails const objectId = pdfDetails?.[0]?.ExtUserPtr?.UserId?.objectId; //get ExistUserPtr email to get userDetails @@ -1001,28 +1015,22 @@ function PdfRequestFiles() { //function for get pdf page details const pageDetails = async (pdf) => { - const load = { - status: true - }; - setPdfLoadFail(load); pdf.getPage(1).then((pdfPage) => { const pageWidth = pdfPage.view[2]; + const pageHeight = pdfPage.view[3]; + setPdfOriginalWH({ width: pageWidth, height: pageHeight }); - setPdfOriginalWidth(pageWidth); + const load = { + status: true + }; + setPdfLoadFail(load); }); }; - //function for change page function changePage(offset) { setPageNumber((prevPageNumber) => prevPageNumber + offset); } - const getFirstLetter = (name) => { - if (name) { - const firstLetter = name.charAt(0); - return firstLetter; - } - }; //function for image upload or update const onImageChange = (event) => { if (event.target.files && event.target.files[0]) { @@ -1131,26 +1139,6 @@ function PdfRequestFiles() { return newState; }); }; - - const checkSignerBackColor = (obj) => { - let data = ""; - if (obj?.Id) { - data = signerPos.filter((data) => data.Id === obj.Id); - } else { - data = signerPos.filter((data) => data.signerObjId === obj.objectId); - } - return data && data.length > 0 && data[0].blockColor; - }; - const checkUserNameColor = (obj) => { - const getBackColor = checkSignerBackColor(obj); - if (getBackColor) { - const color = darkenColor(getBackColor, 0.4); - return color; - } else { - return "#abd1d0"; - } - }; - //function for set decline true on press decline button const declineDoc = async () => { setIsDecline({ isDeclined: false }); @@ -1396,7 +1384,7 @@ function PdfRequestFiles() { {isUiLoading && (
- + This might take some time
@@ -1410,7 +1398,6 @@ function PdfRequestFiles() {
)}
{!requestSignTour && requestSignTourFunction()} {isAlert.alertMessage}

- - -
- )} -
- - {isDownloading === "pdf" && ( -
- -
- )} - setIsDownloading("")} - > -
- {isDownloading === "certificate"}{" "} -

- Your completion certificate is being generated. Please - wait momentarily. -

-

- If the download doesn't start shortly, click the - button again. -

-
-
- {/* this component is used for signature pad modal */} - + - {/* pdf header which contain funish back button */} -
- {containerWH && ( - + {/* this modal is used show this document is already sign */} + { + setIsCompleted((prev) => ({ ...prev, isModal: false })); + }} + reduceWidth={ + !isCompleted?.message && + "md:min-w-[440px] md:max-w-[400px]" + } + > +
+ {isCompleted?.message ? ( +

{isCompleted?.message}

+ ) : ( +
+ + Congratulations! 🎉 This document has been + successfully signed by all participants! + +
+ )} + {!isCompleted?.message && ( +
+ + + +
+ )} +
+
+ {isDownloading === "pdf" && ( +
+ +
+ )} + setIsDownloading("")} + > +
+ {isDownloading === "certificate"}{" "} +

+ Your completion certificate is being generated. Please + wait momentarily. +

+

+ If the download doesn't start shortly, click the + button again. +

+
+
+ {/* this component is used for signature pad modal */} + - )} -
-
-
+ {/* pdf header which contain funish back button */} +
- {signedSigners.length > 0 && ( -
-
- Signed by -
-
- {signedSigners.map((obj, ind) => { - return ( -
-
- - {getFirstLetter(obj?.Name || obj?.Role)} - -
-
- - {obj?.Name || obj?.Role} - - - {obj?.Email || obj?.email} - -
-
- ); - })} -
-
- )} - - {unsignedSigners.length > 0 && ( -
-
- Yet to sign -
-
- {unsignedSigners.map((obj, ind) => { - return ( -
-
- - {getFirstLetter(obj?.Name || obj?.email)} - -
-
- - {obj?.Name || obj?.Role} - - - {obj?.Email || obj?.email} - -
-
-
- ); - })} -
-
- )} - {defaultSignImg && !alreadySign && ( - )}
+ + {/*
*/} +
)} setValidateAlert(false)} + handleClose={() => { + setValidateAlert(false); + }} >

diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.js b/apps/OpenSign/src/pages/PlaceHolderSign.js index 142372f71..0a7493edb 100644 --- a/apps/OpenSign/src/pages/PlaceHolderSign.js +++ b/apps/OpenSign/src/pages/PlaceHolderSign.js @@ -50,6 +50,10 @@ import Upgrade from "../primitives/Upgrade"; import Alert from "../primitives/Alert"; import Loader from "../primitives/Loader"; import { DotLottieReact } from "@lottiefiles/dotlottie-react"; +import { useSelector } from "react-redux"; +import TextFontSetting from "../components/pdf/TextFontSetting"; +import PdfZoom from "../components/pdf/PdfZoom"; + function PlaceHolderSign() { const editorRef = useRef(); const navigate = useNavigate(); @@ -70,6 +74,8 @@ function PlaceHolderSign() { const [isSend, setIsSend] = useState(false); const [copied, setCopied] = useState(false); const [isAddSigner, setIsAddSigner] = useState(false); + const [fontSize, setFontSize] = useState(); + const [fontColor, setFontColor] = useState(); const [isLoading, setIsLoading] = useState({ isLoad: true, message: "This might take some time" @@ -81,7 +87,7 @@ function PlaceHolderSign() { const [checkTourStatus, setCheckTourStatus] = useState(false); const [tourStatus, setTourStatus] = useState([]); const [signerUserId, setSignerUserId] = useState(); - const [pdfOriginalWidth, setPdfOriginalWidth] = useState(); + const [pdfOriginalWH, setPdfOriginalWH] = useState(); const [contractName, setContractName] = useState(""); const [containerWH, setContainerWH] = useState(); const { docId } = useParams(); @@ -97,6 +103,7 @@ function PlaceHolderSign() { const [blockColor, setBlockColor] = useState(""); const [defaultBody, setDefaultBody] = useState(""); const [defaultSubject, setDefaultSubject] = useState(""); + const [isTextSetting, setIsTextSetting] = useState(false); const [pdfLoadFail, setPdfLoadFail] = useState({ status: false, type: "load" @@ -123,6 +130,8 @@ function PlaceHolderSign() { const [requestSubject, setRequestSubject] = useState(""); const [requestBody, setRequestBody] = useState(""); const [pdfArrayBuffer, setPdfArrayBuffer] = useState(""); + const isHeader = useSelector((state) => state.showHeader); + const [pdfRenderHeight, setPdfRenderHeight] = useState(); const [activeMailAdapter, setActiveMailAdapter] = useState(""); const [isAlreadyPlace, setIsAlreadyPlace] = useState({ status: false, @@ -130,6 +139,8 @@ function PlaceHolderSign() { }); const [extUserId, setExtUserId] = useState(""); const [isCustomize, setIsCustomize] = useState(false); + const [zoomPercent, setZoomPercent] = useState(0); + const [scale, setScale] = useState(1); const isMobile = window.innerWidth < 767; const [, drop] = useDrop({ accept: "BOX", @@ -201,16 +212,16 @@ function PlaceHolderSign() { setDefaultBody(defaultRequestBody); setDefaultSubject( - `{{sender_name}} has requested you to sign "{{document_title}}"` + `{{sender_name}} has requested you to sign {{document_title}}` ); } else { setRequestBody(defaultRequestBody); setRequestSubject( - `{{sender_name}} has requested you to sign "{{document_title}}"` + `{{sender_name}} has requested you to sign {{document_title}}` ); setDefaultBody(defaultRequestBody); setDefaultSubject( - `{{sender_name}}has requested you to sign "{{document_title}}"` + `{{sender_name}}has requested you to sign {{document_title}}` ); } } @@ -223,16 +234,25 @@ function PlaceHolderSign() { }; useEffect(() => { - if (divRef.current) { - const pdfWidth = pdfNewWidthFun(divRef); - setPdfNewWidth(pdfWidth); - setContainerWH({ - width: divRef.current.offsetWidth, - height: divRef.current.offsetHeight - }); - } + const updateSize = () => { + if (divRef.current) { + const pdfWidth = pdfNewWidthFun(divRef); + setPdfNewWidth(pdfWidth); + setContainerWH({ + width: divRef.current.offsetWidth, + height: divRef.current.offsetHeight + }); + setScale(1); + setZoomPercent(0); + } + }; + + // Use setTimeout to wait for the transition to complete + const timer = setTimeout(updateSize, 100); // match the transition duration + + return () => clearTimeout(timer); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [divRef.current]); + }, [divRef.current, isHeader]); async function checkIsSubscribed() { const res = await fetchSubscription(); @@ -446,26 +466,34 @@ function PlaceHolderSign() { const posZIndex = zIndex + 1; setZIndex(posZIndex); const signer = signersdata.find((x) => x.Id === uniqueId); - const newWidth = containerWH.width; - const scale = pdfOriginalWidth / newWidth; const key = randomId(); + const containerScale = containerWH.width / pdfOriginalWH.width; let dropData = []; let placeHolder; const dragTypeValue = item?.text ? item.text : monitor.type; + const widgetWidth = defaultWidthHeight(dragTypeValue).width; + const widgetHeight = defaultWidthHeight(dragTypeValue).height; if (item === "onclick") { const dropObj = { //onclick put placeholder center on pdf - xPosition: window.innerWidth / 2 - 150, - yPosition: window.innerHeight / 2 - 60, + xPosition: + (containerWH.width / 2 - widgetWidth / 2) / + (containerScale * scale), + yPosition: + (containerWH.height / 2 - widgetHeight / 2) / + (containerScale * scale), + isStamp: (dragTypeValue === "stamp" || dragTypeValue === "image") && true, key: key, isDrag: false, - scale: scale, - isMobile: isMobile, + scale: containerScale, + // isMobile: isMobile, zIndex: posZIndex, type: dragTypeValue, - options: addWidgetOptions(dragTypeValue) + options: addWidgetOptions(dragTypeValue), + Width: widgetWidth / (containerScale * scale), + Height: widgetHeight / (containerScale * scale) }; dropData.push(dropObj); placeHolder = { @@ -480,17 +508,25 @@ function PlaceHolderSign() { .getBoundingClientRect(); const x = offset.x - containerRect.left; const y = offset.y - containerRect.top; + const getXPosition = signBtnPosition[0] + ? x - signBtnPosition[0].xPos + : x; + const getYPosition = signBtnPosition[0] + ? y - signBtnPosition[0].yPos + : y; const dropObj = { - xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, - yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, + xPosition: getXPosition / (containerScale * scale), + yPosition: getYPosition / (containerScale * scale), isStamp: (dragTypeValue === "stamp" || dragTypeValue === "image") && true, key: key, - scale: scale, - isMobile: isMobile, + scale: containerScale, + // isMobile: isMobile, zIndex: posZIndex, type: dragTypeValue, - options: addWidgetOptions(dragTypeValue) + options: addWidgetOptions(dragTypeValue), + Width: widgetWidth / (containerScale * scale), + Height: widgetHeight / (containerScale * scale) }; dropData.push(dropObj); @@ -600,6 +636,18 @@ function PlaceHolderSign() { setShowDropdown(true); } else if (dragTypeValue === "checkbox") { setIsCheckbox(true); + } else if ( + [ + textInputWidget, + textWidget, + "name", + "company", + "job title", + "email" + ].includes(dragTypeValue) + ) { + setFontSize(12); + setFontColor("black"); } else if (dragTypeValue === radioButtonWidget) { setIsRadio(true); } @@ -613,14 +661,14 @@ function PlaceHolderSign() { //function for get pdf page details const pageDetails = async (pdf) => { - const load = { - status: true - }; - setPdfLoadFail(load); pdf.getPage(1).then((pdfPage) => { const pageWidth = pdfPage.view[2]; - - setPdfOriginalWidth(pageWidth); + const pageHeight = pdfPage.view[3]; + setPdfOriginalWH({ width: pageWidth, height: pageHeight }); + const load = { + status: true + }; + setPdfLoadFail(load); }); }; @@ -636,13 +684,9 @@ function PlaceHolderSign() { const dataNewPlace = addZIndex(signerPos, key, setZIndex); let updateSignPos = [...signerPos]; updateSignPos.splice(0, updateSignPos.length, ...dataNewPlace); - // signerPos.splice(0, signerPos.length, ...dataNewPlace); - const containerRect = document - .getElementById("container") - .getBoundingClientRect(); const signId = signerId ? signerId : uniqueId; //? signerId : signerObjId; const keyValue = key ? key : dragKey; - const ybottom = containerRect.height - dragElement.y; + const containerScale = containerWH.width / pdfOriginalWH.width; if (keyValue >= 0) { let filterSignerPos; @@ -669,10 +713,8 @@ function PlaceHolderSign() { if (url.key === keyValue) { return { ...url, - xPosition: dragElement.x, - yPosition: dragElement.y, - isDrag: true, - yBottom: ybottom + xPosition: dragElement.x / (containerScale * scale), + yPosition: dragElement.y / (containerScale * scale) }; } return url; @@ -806,13 +848,13 @@ function PlaceHolderSign() { ignoreEncryption: true }); - const flag = false; + const isSignYourSelfFlow = false; try { const pdfBytes = await multiSignEmbed( placeholder, pdfDoc, - pdfOriginalWidth, - flag, + pdfOriginalWH, + isSignYourSelfFlow, containerWH ); @@ -1031,7 +1073,12 @@ function PlaceHolderSign() { Copy link - +

@@ -1386,7 +1433,6 @@ function PlaceHolderSign() { } } }; - const handleWidgetdefaultdata = (defaultdata) => { const options = ["email", "number", "text"]; let inputype; @@ -1619,6 +1665,60 @@ function PlaceHolderSign() { setSignerPos(updatePlaceholderUser); setIsMailSend(false); }; + + const handleSaveFontSize = () => { + const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); + if (filterSignerPos.length > 0) { + const getPlaceHolder = filterSignerPos[0].placeHolder; + + const getPageNumer = getPlaceHolder.filter( + (data) => data.pageNumber === pageNumber + ); + + if (getPageNumer.length > 0) { + const getXYdata = getPageNumer[0].pos; + const getPosData = getXYdata; + const addSignPos = getPosData.map((position) => { + if (position.key === signKey) { + return { + ...position, + options: { + ...position.options, + fontSize: fontSize, + fontColor: fontColor + } + }; + } + return position; + }); + + const newUpdateSignPos = getPlaceHolder.map((obj) => { + if (obj.pageNumber === pageNumber) { + return { ...obj, pos: addSignPos }; + } + return obj; + }); + const newUpdateSigner = signerPos.map((obj) => { + if (obj.Id === uniqueId) { + return { ...obj, placeHolder: newUpdateSignPos }; + } + return obj; + }); + setSignerPos(newUpdateSigner); + } + } + setFontSize(); + setFontColor(); + if (currWidgetsDetails.type === textWidget) { + setUniqueId(tempSignerId); + setTempSignerId(""); + } + + handleTextSettingModal(false); + }; + const handleTextSettingModal = (value) => { + setIsTextSetting(value); + }; return ( <> @@ -1629,8 +1729,9 @@ function PlaceHolderSign() { <HandleError handleError={handleError} /> ) : ( <div - className="op-card overflow-hidden flex flex-row justify-between bg-base-300 relative" - ref={divRef} + className=" min-h-screen + op-card overflow-hidden flex flex-row justify-between bg-base-300 relative + " > {isUiLoading && ( <div className="absolute h-[100vh] w-full flex flex-col justify-center items-center z-[999] bg-[#e6f2f2] bg-opacity-80"> @@ -1670,381 +1771,417 @@ function PlaceHolderSign() { setSignBtnPosition={setSignBtnPosition} pageNumber={pageNumber} /> - {/* pdf render view */} - <div - style={{ - marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px", - marginRight: !isMobile && pdfOriginalWidth > 500 && "20px" - }} - > - {/* this modal is used show alert set placeholder for all signers before send mail */} + <div className="min-h-screen w-full md:w-[57%] flex md:mr-4"> + <PdfZoom + setScale={setScale} + scale={scale} + pdfOriginalWH={pdfOriginalWH} + containerWH={containerWH} + setZoomPercent={setZoomPercent} + zoomPercent={zoomPercent} + /> + <div className="min-h-screen w-full md:w-[97%] "> + {/* this modal is used show alert set placeholder for all signers before send mail */} - <ModalUi - isOpen={isSendAlert.alert} - title={ - isSendAlert.mssg === "sure" || isSendAlert.mssg === textWidget - ? "Fields required" - : isSendAlert.mssg === "confirm" && "Send Mail" - } - handleClose={() => setIsSendAlert({})} - showHeaderMessage={isSendAlert.mssg === "confirm"} - > - <div className="max-h-96 overflow-y-scroll scroll-hide p-[20px] text-base-content"> - {isSendAlert.mssg === "sure" ? ( - <span> - Please ensure there's at least one signature widget - added for all recipients. - </span> - ) : isSendAlert.mssg === textWidget ? ( - <p>Please confirm that you have filled the text field.</p> - ) : ( - isSendAlert.mssg === "confirm" && ( - <> - {!isCustomize && ( - <span> - Are you sure you want to send out this document for - signatures? - </span> - )} - {isCustomize && - (!isEnableSubscription || isSubscribe) && ( - <> - <EmailBody - editorRef={editorRef} - requestBody={requestBody} - requestSubject={requestSubject} - handleOnchangeRequest={handleOnchangeRequest} - setRequestSubject={setRequestSubject} - /> - <div - className="flex justify-end items-center gap-1 mt-2 op-link op-link-primary" - onClick={() => { - setRequestBody(defaultBody); - setRequestSubject(defaultSubject); - }} - > - <span>Reset to default</span> - </div> - </> - )} - <div className="flex flex-row md:items-center gap-2 md:gap-6 mt-2"> - <div className="flex flex-row gap-2"> - <button - onClick={() => sendEmailToSigners()} - className="op-btn op-btn-primary font-[500] text-sm shadow" - > - Send - </button> - {isCustomize && ( - <button - onClick={() => setIsCustomize(false)} - className="op-btn op-btn-ghost font-[500] text-sm" - > - Close - </button> - )} - </div> - - {!isCustomize && - (isSubscribe || !isEnableSubscription) && ( - <span - className="op-link op-link-accent text-sm" - onClick={() => setIsCustomize(!isCustomize)} - > - Cutomize Email + <ModalUi + isOpen={isSendAlert.alert} + title={ + isSendAlert.mssg === "sure" || + isSendAlert.mssg === textWidget + ? "Fields required" + : isSendAlert.mssg === "confirm" && "Send Mail" + } + handleClose={() => setIsSendAlert({})} + showHeaderMessage={isSendAlert.mssg === "confirm"} + > + <div className="max-h-96 overflow-y-scroll scroll-hide p-[20px] text-base-content"> + {isSendAlert.mssg === "sure" ? ( + <span> + Please ensure there's at least one signature widget + added for all recipients. + </span> + ) : isSendAlert.mssg === textWidget ? ( + <p>Please confirm that you have filled the text field.</p> + ) : ( + isSendAlert.mssg === "confirm" && ( + <> + <> + {!isCustomize && ( + <span> + Are you sure you want to send out this document + for signatures? </span> )} + {isCustomize && + (!isEnableSubscription || isSubscribe) && ( + <> + <EmailBody + editorRef={editorRef} + requestBody={requestBody} + requestSubject={requestSubject} + handleOnchangeRequest={ + handleOnchangeRequest + } + setRequestSubject={setRequestSubject} + /> + <div + className="flex justify-end items-center gap-1 mt-2 op-link op-link-primary" + onClick={() => { + setRequestBody(defaultBody); + setRequestSubject(defaultSubject); + }} + > + <span>Reset to default</span> + </div> + </> + )} + <div + className={ + "flex flex-row md:items-center gap-2 md:gap-6 mt-2 " + } + > + <div className="flex flex-row gap-2"> + <button + onClick={() => sendEmailToSigners()} + className="op-btn op-btn-primary font-[500] text-sm shadow" + > + Send + </button> + {isCustomize && ( + <button + onClick={() => { + setIsCustomize(false); + }} + className="op-btn op-btn-ghost font-[500] text-sm" + > + Close + </button> + )} + </div> - {!isSubscribe && isEnableSubscription && ( - <div className="mt-2"> - <Upgrade message="Upgrade to customize Email" /> + {!isCustomize && + (isSubscribe || !isEnableSubscription) && ( + <span + className="op-link op-link-accent text-sm" + onClick={() => { + setIsCustomize(!isCustomize); + }} + > + Cutomize Email + </span> + )} + + {!isSubscribe && isEnableSubscription && ( + <div className="mt-2"> + <Upgrade + message="Upgrade to customize Email" + newWindow={true} + /> + </div> + )} </div> - )} + </> + </> + ) + )} + + {isSendAlert.mssg === "confirm" && ( + <> + <div className="flex justify-center items-center mt-3"> + <span className="h-[1px] w-[20%] bg-[#ccc]"></span> + <span className="ml-[5px] mr-[5px]">or</span> + <span className="h-[1px] w-[20%] bg-[#ccc]"></span> </div> + <div className="mt-3 mb-3">{handleShareList()}</div> </> - ) - )} + )} + </div> + </ModalUi> - {isSendAlert.mssg === "confirm" && ( - <> - <div className="flex justify-center items-center mt-3"> - <span className="h-[1px] w-[20%] bg-[#ccc]"></span> - <span className="ml-[5px] mr-[5px]">or</span> - <span className="h-[1px] w-[20%] bg-[#ccc]"></span> + {/* this modal is used show send mail message and after send mail success message */} + <ModalUi + isOpen={isSend} + title={"Mails Sent"} + handleClose={() => { + setIsSend(false); + setSignerPos([]); + }} + > + <div className="h-[100%] p-[20px]"> + {mailStatus === "success" ? ( + <div className="text-center mb-[10px]"> + <DotLottieReact + dotLottieRefCallback={null} + src="https://lottie.host/00a72a09-f2d4-493a-9b2d-2843bf067638/Ic7jJ44wLJ.json" + autoplay + loop={false} + className="w-[120px] h-[120px] mx-auto" + /> + <p> + You have successfully sent mails to all recipients! + </p> + {isCurrUser && ( + <p>Do you want to sign documents right now ?</p> + )} </div> - <div className="mt-3 mb-3">{handleShareList()}</div> - </> - )} - </div> - </ModalUi> - {/* this modal is used show send mail message and after send mail success message */} - <ModalUi - isOpen={isSend} - title={"Mails Sent"} - handleClose={() => { - setIsSend(false); - setSignerPos([]); - }} - > - <div className="h-[100%] p-[20px]"> - {mailStatus === "success" ? ( - <div className="text-center mb-[10px]"> - <DotLottieReact - dotLottieRefCallback={null} - src="https://lottie.host/00a72a09-f2d4-493a-9b2d-2843bf067638/Ic7jJ44wLJ.json" - autoplay - loop={false} - className="w-[120px] h-[120px] mx-auto" - /> - <p>You have successfully sent mails to all recipients!</p> - {isCurrUser && ( - <p>Do you want to sign documents right now ?</p> - )} - </div> - ) : ( - <p>Please setup mail adapter to send mail!</p> - )} - {!mailStatus && ( - <div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div> - )} - {isCurrUser && ( - <button - onClick={() => handleRecipientSign()} - type="button" - className="op-btn op-btn-primary mr-1" - > - Yes - </button> - )} - <button - onClick={() => { - setIsSend(false); - setSignerPos([]); - }} - type="button" - className="op-btn op-btn-ghost" - > - {isCurrUser ? "No" : "Close"} - </button> - </div> - </ModalUi> - <ModalUi - isOpen={isShowEmail} - title={"signers alert"} - handleClose={() => { - setIsShowEmail(false); - }} - > - <div className="h-[100%] p-[20px]"> - <p>Please select signer for add placeholder!</p> - <div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div> - <button - onClick={() => { - setIsShowEmail(false); - }} - type="button" - className="op-btn op-btn-primary" - > - Ok - </button> - </div> - </ModalUi> - <PlaceholderCopy - isPageCopy={isPageCopy} - setIsPageCopy={setIsPageCopy} - xyPostion={signerPos} - setXyPostion={setSignerPos} - allPages={allPages} - pageNumber={pageNumber} - signKey={signKey} - Id={uniqueId} - widgetType={widgetType} - setUniqueId={setUniqueId} - tempSignerId={tempSignerId} - setTempSignerId={setTempSignerId} - /> - <DropdownWidgetOption - type={radioButtonWidget} - title="Radio group" - showDropdown={isRadio} - setShowDropdown={setIsRadio} - handleSaveWidgetsOptions={handleSaveWidgetsOptions} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - handleClose={handleNameModal} - isSubscribe={isSubscribe} - /> - <DropdownWidgetOption - type="checkbox" - title="Checkbox" - showDropdown={isCheckbox} - setShowDropdown={setIsCheckbox} - handleSaveWidgetsOptions={handleSaveWidgetsOptions} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - handleClose={handleNameModal} - isSubscribe={isSubscribe} - /> - <DropdownWidgetOption - type="dropdown" - title="Dropdown options" - showDropdown={showDropdown} - setShowDropdown={setShowDropdown} - handleSaveWidgetsOptions={handleSaveWidgetsOptions} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - handleClose={handleNameModal} - isSubscribe={isSubscribe} - /> + ) : ( + <p>Please setup mail adapter to send mail!</p> + )} + {!mailStatus && ( + <div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div> + )} + {isCurrUser && ( + <button + onClick={() => { + handleRecipientSign(); + }} + type="button" + className="op-btn op-btn-primary mr-1" + > + Yes + </button> + )} - {/* pdf header which contain funish back button */} - <Header - isPlaceholder={true} - pageNumber={pageNumber} - allPages={allPages} - changePage={changePage} - pdfDetails={pdfDetails} - signerPos={signerPos} - signersdata={signersdata} - isMailSend={isMailSend} - alertSendEmail={alertSendEmail} - isShowHeader={true} - currentSigner={true} - dataTut4="reactourFour" - /> - <div data-tut="reactourThird"> - {containerWH && ( - <RenderPdf - pageNumber={pageNumber} - pdfOriginalWidth={pdfOriginalWidth} - pdfNewWidth={pdfNewWidth} - pdfDetails={pdfDetails} - signerPos={signerPos} - successEmail={false} - numPages={numPages} - pageDetails={pageDetails} - placeholder={true} - drop={drop} - handleDeleteSign={handleDeleteSign} - handleTabDrag={handleTabDrag} - handleStop={handleStop} - setPdfLoadFail={setPdfLoadFail} - pdfLoadFail={pdfLoadFail} - setSignerPos={setSignerPos} - containerWH={containerWH} - setIsResize={setIsResize} - setZIndex={setZIndex} - setIsPageCopy={setIsPageCopy} - signersdata={signersdata} - setSignKey={setSignKey} - setSignerObjId={setSignerObjId} - handleLinkUser={handleLinkUser} - setUniqueId={setUniqueId} - isDragging={isDragging} - setShowDropdown={setShowDropdown} - setWidgetType={setWidgetType} - setIsRadio={setIsRadio} - setIsCheckbox={setIsCheckbox} - setCurrWidgetsDetails={setCurrWidgetsDetails} - setSelectWidgetId={setSelectWidgetId} - selectWidgetId={selectWidgetId} - handleNameModal={setIsNameModal} - setTempSignerId={setTempSignerId} - uniqueId={uniqueId} - /> - )} + <button + onClick={() => { + setIsSend(false); + setSignerPos([]); + }} + type="button" + className="op-btn op-btn-ghost" + > + {isCurrUser ? "No" : "Close"} + </button> + </div> + </ModalUi> + <ModalUi + isOpen={isShowEmail} + title={"signers alert"} + handleClose={() => { + setIsShowEmail(false); + }} + > + <div className="h-[100%] p-[20px]"> + <p>Please select signer for add placeholder!</p> + <div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div> + <button + onClick={() => { + setIsShowEmail(false); + }} + type="button" + className="op-btn op-btn-primary" + > + Ok + </button> + </div> + </ModalUi> + <PlaceholderCopy + isPageCopy={isPageCopy} + setIsPageCopy={setIsPageCopy} + xyPostion={signerPos} + setXyPostion={setSignerPos} + allPages={allPages} + pageNumber={pageNumber} + signKey={signKey} + Id={uniqueId} + widgetType={widgetType} + setUniqueId={setUniqueId} + tempSignerId={tempSignerId} + setTempSignerId={setTempSignerId} + /> + <DropdownWidgetOption + type={radioButtonWidget} + title="Radio group" + showDropdown={isRadio} + setShowDropdown={setIsRadio} + handleSaveWidgetsOptions={handleSaveWidgetsOptions} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + handleClose={handleNameModal} + isSubscribe={isSubscribe} + /> + <DropdownWidgetOption + type="checkbox" + title="Checkbox" + showDropdown={isCheckbox} + setShowDropdown={setIsCheckbox} + handleSaveWidgetsOptions={handleSaveWidgetsOptions} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + handleClose={handleNameModal} + isSubscribe={isSubscribe} + /> + <DropdownWidgetOption + type="dropdown" + title="Dropdown options" + showDropdown={showDropdown} + setShowDropdown={setShowDropdown} + handleSaveWidgetsOptions={handleSaveWidgetsOptions} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + handleClose={handleNameModal} + isSubscribe={isSubscribe} + /> + + {/* pdf header which contain funish back button */} + <Header + isPlaceholder={true} + pageNumber={pageNumber} + allPages={allPages} + changePage={changePage} + pdfDetails={pdfDetails} + signerPos={signerPos} + signersdata={signersdata} + isMailSend={isMailSend} + alertSendEmail={alertSendEmail} + isShowHeader={true} + currentSigner={true} + dataTut4="reactourFour" + /> + <div + ref={divRef} + data-tut="reactourSecond" + className="h-[95%] " + > + {containerWH && ( + <RenderPdf + pageNumber={pageNumber} + pdfNewWidth={pdfNewWidth} + pdfDetails={pdfDetails} + signerPos={signerPos} + successEmail={false} + numPages={numPages} + pageDetails={pageDetails} + placeholder={true} + drop={drop} + handleDeleteSign={handleDeleteSign} + handleTabDrag={handleTabDrag} + handleStop={handleStop} + setPdfLoadFail={setPdfLoadFail} + pdfLoadFail={pdfLoadFail} + setSignerPos={setSignerPos} + containerWH={containerWH} + setIsResize={setIsResize} + setZIndex={setZIndex} + setIsPageCopy={setIsPageCopy} + signersdata={signersdata} + setSignKey={setSignKey} + setSignerObjId={setSignerObjId} + handleLinkUser={handleLinkUser} + setUniqueId={setUniqueId} + isDragging={isDragging} + setShowDropdown={setShowDropdown} + setWidgetType={setWidgetType} + setIsRadio={setIsRadio} + setIsCheckbox={setIsCheckbox} + setCurrWidgetsDetails={setCurrWidgetsDetails} + setSelectWidgetId={setSelectWidgetId} + selectWidgetId={selectWidgetId} + handleNameModal={setIsNameModal} + setTempSignerId={setTempSignerId} + uniqueId={uniqueId} + setPdfRenderHeight={setPdfRenderHeight} + pdfRenderHeight={pdfRenderHeight} + handleTextSettingModal={handleTextSettingModal} + pdfOriginalWH={pdfOriginalWH} + setScale={setScale} + scale={scale} + /> + )} + </div> </div> </div> {/* signature button */} - {isMobile ? ( - <div> - <WidgetComponent - dataTut="reactourFirst" - dataTut2="reactourSecond" - pdfUrl={isMailSend} - dragSignature={dragSignature} - signRef={signRef} - handleDivClick={handleDivClick} - handleMouseLeave={handleMouseLeave} - isDragSign={isDragSign} - dragStamp={dragStamp} - dragRef={dragRef} - isDragStamp={isDragStamp} - isSignYourself={false} - addPositionOfSignature={addPositionOfSignature} - signerPos={signerPos} - signersdata={signersdata} - isSelectListId={isSelectListId} - setSignerObjId={setSignerObjId} - setIsSelectId={setIsSelectId} - setContractName={setContractName} - isSigners={true} - setIsShowEmail={setIsShowEmail} - isMailSend={isMailSend} - setSelectedEmail={setSelectedEmail} - selectedEmail={selectedEmail} - setUniqueId={setUniqueId} - setRoleName={setRoleName} - initial={true} - sendInOrder={pdfDetails[0].SendinOrder} - setSignersData={setSignersData} - blockColor={blockColor} - setBlockColor={setBlockColor} - setIsAddSigner={setIsAddSigner} - handleDeleteUser={handleDeleteUser} - /> - </div> - ) : ( - <div> - <div - className="hidden md:block w-[180px] h-full bg-base-100" - aria-disabled - > - <div - style={{ maxHeight: window.innerHeight - 70 + "px" }} - className="overflow-y-auto hide-scrollbar" - > - <SignerListPlace + <div + className={`w-[23%] bg-[#FFFFFF] min-h-screen autoSignScroll hide-scrollbar`} + > + <div className={`max-h-screen`}> + {isMobile ? ( + <div> + <WidgetComponent + dataTut="reactourFirst" + dataTut2="reactourSecond" + pdfUrl={isMailSend} + dragSignature={dragSignature} + signRef={signRef} + handleDivClick={handleDivClick} + handleMouseLeave={handleMouseLeave} + isDragSign={isDragSign} + dragStamp={dragStamp} + dragRef={dragRef} + isDragStamp={isDragStamp} + isSignYourself={false} + addPositionOfSignature={addPositionOfSignature} signerPos={signerPos} signersdata={signersdata} isSelectListId={isSelectListId} setSignerObjId={setSignerObjId} setIsSelectId={setIsSelectId} setContractName={setContractName} + isSigners={true} + setIsShowEmail={setIsShowEmail} + isMailSend={isMailSend} + setSelectedEmail={setSelectedEmail} + selectedEmail={selectedEmail} setUniqueId={setUniqueId} setRoleName={setRoleName} + initial={true} sendInOrder={pdfDetails[0].SendinOrder} setSignersData={setSignersData} blockColor={blockColor} setBlockColor={setBlockColor} - isMailSend={isMailSend} setIsAddSigner={setIsAddSigner} handleDeleteUser={handleDeleteUser} - roleName={roleName} - // handleAddSigner={handleAddSigner} /> - <div data-tut="reactourSecond"> - <WidgetComponent + </div> + ) : ( + <div> + <div + className="hidden md:block w-full h-full bg-base-100" + aria-disabled + > + <SignerListPlace + signerPos={signerPos} + signersdata={signersdata} + isSelectListId={isSelectListId} + setSignerObjId={setSignerObjId} + setIsSelectId={setIsSelectId} + setContractName={setContractName} + setUniqueId={setUniqueId} + setRoleName={setRoleName} + sendInOrder={pdfDetails[0].SendinOrder} + setSignersData={setSignersData} + blockColor={blockColor} + setBlockColor={setBlockColor} isMailSend={isMailSend} - dragSignature={dragSignature} - signRef={signRef} - handleDivClick={handleDivClick} - handleMouseLeave={handleMouseLeave} - isDragSign={isDragSign} - dragStamp={dragStamp} - dragRef={dragRef} - isDragStamp={isDragStamp} - isSignYourself={false} - addPositionOfSignature={addPositionOfSignature} - initial={true} + setIsAddSigner={setIsAddSigner} + handleDeleteUser={handleDeleteUser} + roleName={roleName} + // handleAddSigner={handleAddSigner} /> + <div data-tut="reactourSecond"> + <WidgetComponent + isMailSend={isMailSend} + dragSignature={dragSignature} + signRef={signRef} + handleDivClick={handleDivClick} + handleMouseLeave={handleMouseLeave} + isDragSign={isDragSign} + dragStamp={dragStamp} + dragRef={dragRef} + isDragStamp={isDragStamp} + isSignYourself={false} + addPositionOfSignature={addPositionOfSignature} + initial={true} + /> + </div> </div> </div> - </div> + )} </div> - )} + </div> </div> )} </DndProvider> @@ -2066,6 +2203,17 @@ function PlaceHolderSign() { </button> </div> </ModalUi> + <TextFontSetting + isTextSetting={isTextSetting} + setIsTextSetting={setIsTextSetting} + fontSize={fontSize} + setFontSize={setFontSize} + fontColor={fontColor} + setFontColor={setFontColor} + handleSaveFontSize={handleSaveFontSize} + currWidgetsDetails={currWidgetsDetails} + /> + <LinkUserModal handleAddUser={handleAddUser} isAddUser={isAddUser} diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js index 2dcfe44fe..7308f2a79 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.js +++ b/apps/OpenSign/src/pages/SignyourselfPdf.js @@ -17,7 +17,6 @@ import { contractDocument, embedDocId, multiSignEmbed, - pdfNewWidthFun, onImageSelect, calculateInitialWidthHeight, defaultWidthHeight, @@ -31,6 +30,7 @@ import { getTenantDetails, checkIsSubscribed, convertPdfArrayBuffer, + textInputWidget, fetchImageBase64, changeImageWH, handleSendOTP @@ -46,7 +46,10 @@ import TourContentWithBtn from "../primitives/TourContentWithBtn"; import Title from "../components/Title"; import ModalUi from "../primitives/ModalUi"; import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption"; +import { useSelector } from "react-redux"; +import TextFontSetting from "../components/pdf/TextFontSetting"; import VerifyEmail from "../components/pdf/VerifyEmail"; +import PdfZoom from "../components/pdf/PdfZoom"; import Loader from "../primitives/Loader"; //For signYourself inProgress section signer can add sign and complete doc sign. function SignYourSelf() { @@ -68,10 +71,12 @@ function SignYourSelf() { const signRef = useRef(null); const dragRef = useRef(null); const [dragKey, setDragKey] = useState(); + const [fontSize, setFontSize] = useState(11); + const [fontColor, setFontColor] = useState("black"); const [signKey, setSignKey] = useState(); const [imgWH, setImgWH] = useState({}); const [pdfNewWidth, setPdfNewWidth] = useState(); - const [pdfOriginalWidth, setPdfOriginalWidth] = useState(); + const [pdfOriginalWH, setPdfOriginalWH] = useState(); const [successEmail, setSuccessEmail] = useState(false); const imageRef = useRef(null); const [myInitial, setMyInitial] = useState(""); @@ -97,6 +102,7 @@ function SignYourSelf() { const [showAlreadySignDoc, setShowAlreadySignDoc] = useState({ status: false }); + const [isTextSetting, setIsTextSetting] = useState(false); const [currWidgetsDetails, setCurrWidgetsDetails] = useState({}); const [isCheckbox, setIsCheckbox] = useState(false); const [widgetType, setWidgetType] = useState(""); @@ -114,6 +120,10 @@ function SignYourSelf() { const [isEmailVerified, setIsEmailVerified] = useState(true); const [isVerifyModal, setIsVerifyModal] = useState(false); const [otp, setOtp] = useState(""); + const [pdfRenderHeight, setPdfRenderHeight] = useState(); + const [zoomPercent, setZoomPercent] = useState(0); + const isHeader = useSelector((state) => state.showHeader); + const [scale, setScale] = useState(1); const divRef = useRef(null); const nodeRef = useRef(null); const [, drop] = useDrop({ @@ -123,10 +133,7 @@ function SignYourSelf() { isOver: !!monitor.isOver() }) }); - const isMobile = window.innerWidth < 767; - const pdfRef = useRef(); - const [{ isDragSign }, dragSignature] = useDrag({ type: "BOX", item: { @@ -154,7 +161,6 @@ function SignYourSelf() { return object.pageNumber === pageNumber; }); // rowlevel={JSON.parse(localStorage.getItem("rowlevel"))} - const rowLevel = localStorage.getItem("rowlevel") && JSON.parse(localStorage.getItem("rowlevel")); @@ -182,17 +188,25 @@ function SignYourSelf() { }, []); useEffect(() => { - if (divRef.current) { - const pdfWidth = pdfNewWidthFun(divRef); - setPdfNewWidth(pdfWidth); - setContainerWH({ - width: divRef.current.offsetWidth, - height: divRef.current.offsetHeight - }); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [divRef.current]); + const updateSize = () => { + if (divRef.current) { + const pdfWidth = divRef.current.offsetWidth; + setPdfNewWidth(pdfWidth); + setContainerWH({ + width: divRef.current.offsetWidth, + height: divRef.current.offsetHeight + }); + setScale(1); + setZoomPercent(0); + } + }; + // Use setTimeout to wait for the transition to complete + const timer = setTimeout(updateSize, 100); // match the transition duration + + return () => clearTimeout(timer); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [divRef.current, isHeader]); //function for get document details for perticular signer with signer'object id const getDocumentDetails = async (showComplete) => { let isCompleted; @@ -214,7 +228,6 @@ function SignYourSelf() { } else { setHandleError("Error: Something went wrong!"); } - isCompleted = documentData[0].IsCompleted && documentData[0].IsCompleted; if (isCompleted) { setIsCompleted(true); @@ -437,6 +450,7 @@ function SignYourSelf() { const key = randomId(); let dropData = []; let dropObj = {}; + const pdfRenderWidth = containerWH.width; let filterDropPos = xyPostion.filter( (data) => data.pageNumber === pageNumber ); @@ -447,28 +461,38 @@ function SignYourSelf() { const widgetTypeExist = ["name", "company", "job title", "email"].includes( dragTypeValue ); + // const scale = pdfOriginalWH.width / containerWH.width; + const containerScale = containerWH.width / pdfOriginalWH.width; + if (item === "onclick") { + const getWidth = widgetTypeExist + ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getWidth + : dragTypeValue === "initials" + ? defaultWidthHeight(dragTypeValue).width + : ""; + const getHeight = widgetTypeExist + ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getHeight + : dragTypeValue === "initials" + ? defaultWidthHeight(dragTypeValue).height + : ""; dropObj = { - xPosition: containerWH.width / 2 - widgetWidth / 2, - yPosition: containerWH.height / 2 - widgetHeight / 2, + xPosition: + (containerWH.width / 2 - widgetWidth / 2) / (containerScale * scale), + yPosition: + (containerWH.height / 2 - widgetHeight / 2) / + (containerScale * scale), isDrag: false, isStamp: (dragTypeValue === "stamp" || dragTypeValue === "image") && true, key: key, type: dragTypeValue, yBottom: window.innerHeight / 2 - 60, - - Width: widgetTypeExist - ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getWidth - : dragTypeValue === "initials" - ? defaultWidthHeight(dragTypeValue).width - : "", - Height: widgetTypeExist - ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getHeight - : dragTypeValue === "initials" - ? defaultWidthHeight(dragTypeValue).height - : "", - options: addWidgetOptions(dragTypeValue) + scale: containerScale, + Width: getWidth / (containerScale * scale), + Height: getHeight / (containerScale * scale), + options: addWidgetOptions(dragTypeValue), + pdfRenderHeight: pdfRenderHeight, + pdfRenderWidth: pdfRenderWidth }; dropData.push(dropObj); @@ -481,22 +505,27 @@ function SignYourSelf() { const x = offset.x - containerRect.left; const y = offset.y - containerRect.top; - + const getXPosition = signBtnPosition[0] ? x - signBtnPosition[0].xPos : x; + const getYPosition = signBtnPosition[0] ? y - signBtnPosition[0].yPos : y; + const getWidth = widgetTypeExist + ? calculateInitialWidthHeight(widgetValue).getWidth + : defaultWidthHeight(dragTypeValue).width; + const getHeight = widgetTypeExist + ? calculateInitialWidthHeight(widgetValue).getHeight + : defaultWidthHeight(dragTypeValue).height; dropObj = { - xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, - yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, - // isDrag: false, + xPosition: getXPosition / (containerScale * scale), + yPosition: getYPosition / (containerScale * scale), isStamp: (dragTypeValue === "stamp" || dragTypeValue === "image") && true, key: key, type: dragTypeValue, - Width: widgetTypeExist - ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getWidth - : defaultWidthHeight(dragTypeValue).width, - Height: widgetTypeExist - ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getHeight - : defaultWidthHeight(dragTypeValue).height, - options: addWidgetOptions(dragTypeValue) + Width: getWidth / (containerScale * scale), + Height: getHeight / (containerScale * scale), + options: addWidgetOptions(dragTypeValue), + pdfRenderHeight: pdfRenderHeight, + pdfRenderWidth: pdfRenderWidth, + scale: containerScale }; dropData.push(dropObj); @@ -539,6 +568,18 @@ function SignYourSelf() { setIsInitial(true); } else if (dragTypeValue === "checkbox") { setIsCheckbox(true); + } else if ( + [ + textInputWidget, + textWidget, + "name", + "company", + "job title", + "email" + ].includes(dragTypeValue) + ) { + setFontSize(12); + setFontColor("black"); } setWidgetType(dragTypeValue); setSelectWidgetId(key); @@ -669,9 +710,10 @@ function SignYourSelf() { const pdfBytes = await multiSignEmbed( xyPostion, pdfDoc, - pdfOriginalWidth, + pdfOriginalWH, isSignYourSelfFlow, - containerWH + containerWH, + scale ); // console.log("pdf", pdfBytes); //function for call to embed signature in pdf and get digital signature pdf @@ -786,17 +828,11 @@ function SignYourSelf() { const handleStop = (event, dragElement) => { if (isDragging && dragElement) { event.preventDefault(); - const containerRect = document - .getElementById("container") - .getBoundingClientRect(); - - const ybottom = containerRect.height - dragElement.y; - + const containerScale = containerWH.width / pdfOriginalWH.width; if (dragKey >= 0) { const filterDropPos = xyPostion.filter( (data) => data.pageNumber === pageNumber ); - if (filterDropPos.length > 0) { const getXYdata = xyPostion[index].pos; const getPosData = getXYdata; @@ -804,10 +840,8 @@ function SignYourSelf() { if (url.key === dragKey) { return { ...url, - xPosition: dragElement.x, - yPosition: dragElement.y, - isDrag: true, - yBottom: ybottom + xPosition: dragElement.x / (containerScale * scale), + yPosition: dragElement.y / (containerScale * scale) }; } return url; @@ -836,8 +870,8 @@ function SignYourSelf() { setPdfLoadFail(load); pdf.getPage(1).then((pdfPage) => { const pageWidth = pdfPage.view[2]; - - setPdfOriginalWidth(pageWidth); + const pageHeight = pdfPage.view[3]; + setPdfOriginalWH({ width: pageWidth, height: pageHeight }); }); }; @@ -1083,11 +1117,47 @@ function SignYourSelf() { } } }; - const handleCloseModal = () => { setCurrWidgetsDetails({}); setIsCheckbox(false); }; + const handleTextSettingModal = (value) => { + setIsTextSetting(value); + }; + const handleSaveFontSize = () => { + const getPageNumer = xyPostion.filter( + (data) => data.pageNumber === pageNumber + ); + + if (getPageNumer.length > 0) { + const getXYdata = getPageNumer[0].pos; + const getPosData = getXYdata; + const addSignPos = getPosData.map((position) => { + if (position.key === signKey) { + return { + ...position, + options: { + ...position.options, + fontSize: fontSize || currWidgetsDetails?.options?.fontSize, + fontColor: fontColor || currWidgetsDetails?.options?.fontColor + } + }; + } + return position; + }); + const updateXYposition = xyPostion.map((obj, ind) => { + if (ind === index) { + return { ...obj, pos: addSignPos }; + } + return obj; + }); + setXyPostion(updateXYposition); + setFontSize(); + setFontColor(); + handleTextSettingModal(false); + } + }; + return ( <DndProvider backend={HTML5Backend}> <Title title={"Self Sign"} /> @@ -1100,7 +1170,7 @@ function SignYourSelf() { {isUiLoading && ( <div className="absolute h-[100vh] w-full z-[999] flex flex-col justify-center items-center bg-[#e6f2f2] bg-opacity-80"> <Loader /> - <span className="font-bold text-[13px]"> + <span style={{ fontSize: "13px", fontWeight: "bold" }}> This might take some time </span> </div> @@ -1110,11 +1180,8 @@ function SignYourSelf() { <Confetti width={window.innerWidth} height={window.innerHeight} /> </div> )} - - <div - className="relative op-card overflow-hidden flex flex-col md:flex-row justify-between bg-base-300" - ref={divRef} - > + {/* <div className="min-h-screen relative op-card overflow-hidden flex flex-col md:flex-row justify-between bg-base-300"> */} + <div className="flex min-h-screen flex-row justify-center bg-[#EBEBEB]"> {!isEmailVerified && ( <VerifyEmail isVerifyModal={isVerifyModal} @@ -1149,195 +1216,200 @@ function SignYourSelf() { setPageNumber={setPageNumber} setSignBtnPosition={setSignBtnPosition} pageNumber={pageNumber} + containerWH={containerWH} /> + <div className="min-h-screen w-full md:w-[57%] flex mr-4"> + <PdfZoom + setScale={setScale} + scale={scale} + pdfOriginalWH={pdfOriginalWH} + containerWH={containerWH} + setZoomPercent={setZoomPercent} + zoomPercent={zoomPercent} + /> + <div className="min-h-screen w-full md:w-[95%] "> + <ModalUi + isOpen={isAlert.isShow} + title={isAlert?.header || "Alert"} + handleClose={() => { + setIsAlert({ + isShow: false, + alertMessage: "" + }); + }} + > + <div className="p-[20px] h-full"> + <p>{isAlert.alertMessage}</p> + </div> + </ModalUi> - {/* pdf render view */} - <div - style={{ - marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px", - marginRight: !isMobile && pdfOriginalWidth > 500 && "20px" - }} - > - <ModalUi - isOpen={isAlert.isShow} - title={isAlert?.header || "Alert"} - handleClose={() => { - setIsAlert({ - isShow: false, - alertMessage: "" - }); - }} - > - <div className="p-[20px] h-full"> - <p>{isAlert.alertMessage}</p> + {/* this modal is used show this document is already sign */} + <ModalUi + isOpen={showAlreadySignDoc.status} + title={"Document signed"} + handleClose={() => { + setShowAlreadySignDoc({ status: false }); + }} + > + <div className="p-[20px] h-full"> + <p>{showAlreadySignDoc.mssg}</p> + + <div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div> + <button + className="op-btn op-btn-ghost shadow-md" + onClick={() => setShowAlreadySignDoc({ status: false })} + > + Close + </button> + </div> + </ModalUi> + <DropdownWidgetOption + type="checkbox" + title="Checkbox" + showDropdown={isCheckbox} + setShowDropdown={setIsCheckbox} + handleSaveWidgetsOptions={handleSaveWidgetsOptions} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + isSignYourself={true} + handleClose={handleCloseModal} + /> + <PlaceholderCopy + isPageCopy={isPageCopy} + setIsPageCopy={setIsPageCopy} + xyPostion={xyPostion} + setXyPostion={setXyPostion} + allPages={allPages} + pageNumber={pageNumber} + signKey={signKey} + /> + {/* this is modal of signature pad */} + <SignPad + isSignPad={isSignPad} + isStamp={isStamp} + setIsImageSelect={setIsImageSelect} + setIsSignPad={setIsSignPad} + setImage={setImage} + isImageSelect={isImageSelect} + imageRef={imageRef} + onImageChange={onImageChange} + setSignature={setSignature} + image={image} + onSaveImage={saveImage} + onSaveSign={saveSign} + defaultSign={defaultSignImg} + myInitial={myInitial} + isInitial={isInitial} + setIsInitial={setIsInitial} + setIsStamp={setIsStamp} + widgetType={widgetType} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + /> + {/*render email component to send email after finish signature on document */} + <EmailComponent + isEmail={isEmail} + pdfUrl={pdfUrl} + setIsEmail={setIsEmail} + pdfName={pdfDetails[0] && pdfDetails[0].Name} + setSuccessEmail={setSuccessEmail} + sender={jsonSender} + setIsAlert={setIsAlert} + extUserId={extUserId} + activeMailAdapter={activeMailAdapter} + /> + {/* pdf header which contain funish back button */} + <Header + pageNumber={pageNumber} + allPages={allPages} + changePage={changePage} + pdfUrl={pdfUrl} + embedWidgetsData={embedWidgetsData} + pdfDetails={pdfDetails} + isShowHeader={true} + currentSigner={true} + alreadySign={pdfUrl ? true : false} + isSignYourself={true} + setIsEmail={setIsEmail} + isCompleted={isCompleted} + /> + <div ref={divRef} data-tut="reactourSecond" className="h-[95%]"> + {containerWH?.width && containerWH?.height && ( + <RenderPdf + pageNumber={pageNumber} + pdfOriginalWH={pdfOriginalWH} + pdfNewWidth={pdfNewWidth} + drop={drop} + successEmail={successEmail} + nodeRef={nodeRef} + handleTabDrag={handleTabDrag} + handleStop={handleStop} + isDragging={isDragging} + setIsSignPad={setIsSignPad} + setIsStamp={setIsStamp} + handleDeleteSign={handleDeleteSign} + setSignKey={setSignKey} + pdfDetails={pdfDetails} + setIsDragging={setIsDragging} + xyPostion={xyPostion} + pdfRef={pdfRef} + pdfUrl={pdfUrl} + numPages={numPages} + pageDetails={pageDetails} + setPdfLoadFail={setPdfLoadFail} + pdfLoadFail={pdfLoadFail} + setXyPostion={setXyPostion} + index={index} + containerWH={containerWH} + setIsPageCopy={setIsPageCopy} + setIsInitial={setIsInitial} + setWidgetType={setWidgetType} + setSelectWidgetId={setSelectWidgetId} + selectWidgetId={selectWidgetId} + setIsCheckbox={setIsCheckbox} + setCurrWidgetsDetails={setCurrWidgetsDetails} + setValidateAlert={setValidateAlert} + handleTextSettingModal={handleTextSettingModal} + pdfRenderHeight={pdfRenderHeight} + setPdfRenderHeight={setPdfRenderHeight} + setScale={setScale} + scale={scale} + /> + )} </div> - </ModalUi> - - {/* this modal is used show this document is already sign */} - <ModalUi - isOpen={showAlreadySignDoc.status} - title={"Document signed"} - handleClose={() => { - setShowAlreadySignDoc({ status: false }); - }} - > - <div className="p-[20px] h-full"> - <p>{showAlreadySignDoc.mssg}</p> - <div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div> - <button - className="op-btn op-btn-ghost shadow-md" - onClick={() => setShowAlreadySignDoc({ status: false })} - > - Close - </button> - </div> - </ModalUi> - <DropdownWidgetOption - type="checkbox" - title="Checkbox" - showDropdown={isCheckbox} - setShowDropdown={setIsCheckbox} - handleSaveWidgetsOptions={handleSaveWidgetsOptions} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - isSignYourself={true} - handleClose={handleCloseModal} - /> - <PlaceholderCopy - isPageCopy={isPageCopy} - setIsPageCopy={setIsPageCopy} - xyPostion={xyPostion} - setXyPostion={setXyPostion} - allPages={allPages} - pageNumber={pageNumber} - signKey={signKey} - /> - {/* this is modal of signature pad */} - <SignPad - isSignPad={isSignPad} - isStamp={isStamp} - setIsImageSelect={setIsImageSelect} - setIsSignPad={setIsSignPad} - setImage={setImage} - isImageSelect={isImageSelect} - imageRef={imageRef} - onImageChange={onImageChange} - setSignature={setSignature} - image={image} - onSaveImage={saveImage} - onSaveSign={saveSign} - defaultSign={defaultSignImg} - myInitial={myInitial} - isInitial={isInitial} - setIsInitial={setIsInitial} - setIsStamp={setIsStamp} - widgetType={widgetType} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - /> - {/*render email component to send email after finish signature on document */} - <EmailComponent - isEmail={isEmail} - pdfUrl={pdfUrl} - setIsEmail={setIsEmail} - pdfName={pdfDetails[0] && pdfDetails[0].Name} - setSuccessEmail={setSuccessEmail} - sender={jsonSender} - setIsAlert={setIsAlert} - extUserId={extUserId} - activeMailAdapter={activeMailAdapter} - /> - {/* pdf header which contain funish back button */} - <Header - pageNumber={pageNumber} - allPages={allPages} - changePage={changePage} - pdfUrl={pdfUrl} - embedWidgetsData={embedWidgetsData} - pdfDetails={pdfDetails} - isShowHeader={true} - currentSigner={true} - alreadySign={pdfUrl ? true : false} - isSignYourself={true} - setIsEmail={setIsEmail} - isCompleted={isCompleted} - /> - - <div data-tut="reactourSecond"> - {containerWH && ( - <RenderPdf - pageNumber={pageNumber} - pdfOriginalWidth={pdfOriginalWidth} - pdfNewWidth={pdfNewWidth} - drop={drop} - successEmail={successEmail} - nodeRef={nodeRef} - handleTabDrag={handleTabDrag} - handleStop={handleStop} - isDragging={isDragging} - setIsSignPad={setIsSignPad} - setIsStamp={setIsStamp} - handleDeleteSign={handleDeleteSign} - setSignKey={setSignKey} - pdfDetails={pdfDetails} - setIsDragging={setIsDragging} - xyPostion={xyPostion} - pdfRef={pdfRef} - pdfUrl={pdfUrl} - numPages={numPages} - pageDetails={pageDetails} - setPdfLoadFail={setPdfLoadFail} - pdfLoadFail={pdfLoadFail} - setXyPostion={setXyPostion} - index={index} - containerWH={containerWH} - setIsPageCopy={setIsPageCopy} - setIsInitial={setIsInitial} - setWidgetType={setWidgetType} - setSelectWidgetId={setSelectWidgetId} - selectWidgetId={selectWidgetId} - setIsCheckbox={setIsCheckbox} - setCurrWidgetsDetails={setCurrWidgetsDetails} - setValidateAlert={setValidateAlert} - /> - )} </div> </div> - {/*if document is not completed then render signature and stamp button in the right side */} - {/*else document is completed then render signed by signer name in the right side */} <div - style={{ - maxHeight: window.innerHeight - 70 + "px", - backgroundColor: "white" - }} - className="overflow-y-auto hide-scrollbar" + className={` md:w-[23%] bg-[#FFFFFF] min-h-screen overflow-y-auto hide-scrollbar`} > - {!isCompleted ? ( - <div> - <WidgetComponent - dataTut="reactourFirst" - pdfUrl={pdfUrl} - dragSignature={dragSignature} - signRef={signRef} - handleDivClick={handleDivClick} - handleMouseLeave={handleMouseLeave} - isDragSign={isDragSign} - dragStamp={dragStamp} - dragRef={dragRef} - isDragStamp={isDragStamp} - handleAllDelete={handleAllDelete} - xyPostion={xyPostion} - isSignYourself={true} - addPositionOfSignature={addPositionOfSignature} - isMailSend={false} - /> - </div> - ) : ( - <div> - <Signedby pdfDetails={pdfDetails[0]} /> - </div> - )} + <div className={`max-h-screen`}> + {!isCompleted ? ( + <div> + <WidgetComponent + dataTut="reactourFirst" + pdfUrl={pdfUrl} + dragSignature={dragSignature} + signRef={signRef} + handleDivClick={handleDivClick} + handleMouseLeave={handleMouseLeave} + isDragSign={isDragSign} + dragStamp={dragStamp} + dragRef={dragRef} + isDragStamp={isDragStamp} + handleAllDelete={handleAllDelete} + xyPostion={xyPostion} + isSignYourself={true} + addPositionOfSignature={addPositionOfSignature} + isMailSend={false} + /> + </div> + ) : ( + <div> + <Signedby pdfDetails={pdfDetails[0]} /> + </div> + )} + </div> </div> </div> </div> @@ -1364,6 +1436,16 @@ function SignYourSelf() { </button> </div> </ModalUi> + <TextFontSetting + isTextSetting={isTextSetting} + setIsTextSetting={setIsTextSetting} + fontSize={fontSize} + setFontSize={setFontSize} + fontColor={fontColor} + setFontColor={setFontColor} + handleSaveFontSize={handleSaveFontSize} + currWidgetsDetails={currWidgetsDetails} + /> </DndProvider> ); } diff --git a/apps/OpenSign/src/pages/TemplatePlaceholder.js b/apps/OpenSign/src/pages/TemplatePlaceholder.js index 745ff32f4..d3f9a4592 100644 --- a/apps/OpenSign/src/pages/TemplatePlaceholder.js +++ b/apps/OpenSign/src/pages/TemplatePlaceholder.js @@ -37,8 +37,12 @@ import PlaceholderCopy from "../components/pdf/PlaceholderCopy"; import TourContentWithBtn from "../primitives/TourContentWithBtn"; import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption"; import Parse from "parse"; +import { useSelector } from "react-redux"; +import TextFontSetting from "../components/pdf/TextFontSetting"; +import PdfZoom from "../components/pdf/PdfZoom"; const TemplatePlaceholder = () => { const navigate = useNavigate(); + const isHeader = useSelector((state) => state.showHeader); const { templateId } = useParams(); const [pdfDetails, setPdfDetails] = useState([]); const [isMailSend, setIsMailSend] = useState(false); @@ -66,7 +70,7 @@ const TemplatePlaceholder = () => { const [checkTourStatus, setCheckTourStatus] = useState(false); const [tourStatus, setTourStatus] = useState([]); const [signerUserId, setSignerUserId] = useState(); - const [pdfOriginalWidth, setPdfOriginalWidth] = useState(); + const [pdfOriginalWH, setPdfOriginalWH] = useState(); const [contractName, setContractName] = useState(""); const [containerWH, setContainerWH] = useState(); const signRef = useRef(null); @@ -83,6 +87,8 @@ const TemplatePlaceholder = () => { const [blockColor, setBlockColor] = useState(""); const [selectWidgetId, setSelectWidgetId] = useState(""); const [isNameModal, setIsNameModal] = useState(false); + const [pdfRenderHeight, setPdfRenderHeight] = useState(); + const [isTextSetting, setIsTextSetting] = useState(false); const [pdfLoadFail, setPdfLoadFail] = useState({ status: false, type: "load" @@ -147,6 +153,10 @@ const TemplatePlaceholder = () => { const [isCheckbox, setIsCheckbox] = useState(false); const [widgetName, setWidgetName] = useState(false); const [isAddRole, setIsAddRole] = useState(false); + const [fontSize, setFontSize] = useState(); + const [fontColor, setFontColor] = useState(); + const [zoomPercent, setZoomPercent] = useState(0); + const [scale, setScale] = useState(1); const senderUser = localStorage.getItem( `Parse/${localStorage.getItem("parseAppId")}/currentUser` @@ -162,16 +172,25 @@ const TemplatePlaceholder = () => { }, []); useEffect(() => { - if (divRef.current) { - const pdfWidth = pdfNewWidthFun(divRef); - setPdfNewWidth(pdfWidth); - setContainerWH({ - width: divRef.current.offsetWidth, - height: divRef.current.offsetHeight - }); - } + const updateSize = () => { + if (divRef.current) { + const pdfWidth = pdfNewWidthFun(divRef); + setPdfNewWidth(pdfWidth); + setContainerWH({ + width: divRef.current.offsetWidth, + height: divRef.current.offsetHeight + }); + setScale(1); + setZoomPercent(0); + } + }; + + // Use setTimeout to wait for the transition to complete + const timer = setTimeout(updateSize, 100); // match the transition duration + + return () => clearTimeout(timer); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [divRef.current]); + }, [divRef.current, isHeader]); async function checkIsSubscribed() { const res = await fetchSubscription(); const freeplan = res.plan; @@ -350,29 +369,33 @@ const TemplatePlaceholder = () => { if (signer) { const posZIndex = zIndex + 1; setZIndex(posZIndex); - const newWidth = containerWH.width; - const scale = pdfOriginalWidth / newWidth; + const containerScale = containerWH.width / pdfOriginalWH.width; const key = randomId(); - // let filterSignerPos = signerPos.filter( - // (data) => data.signerObjId === signerObjId - // ); let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); const dragTypeValue = item?.text ? item.text : monitor.type; + const widgetWidth = defaultWidthHeight(dragTypeValue).width; + const widgetHeight = defaultWidthHeight(dragTypeValue).height; let dropData = []; let placeHolder; if (item === "onclick") { const dropObj = { //onclick put placeholder center on pdf - xPosition: window.innerWidth / 2 - 150, - yPosition: window.innerHeight / 2 - 60, + xPosition: + (containerWH.width / 2 - widgetWidth / 2) / + (containerScale * scale), + yPosition: + (containerWH.height / 2 - widgetHeight / 2) / + (containerScale * scale), isStamp: (dragTypeValue === "stamp" || dragTypeValue === "image") && true, key: key, - scale: scale, - isMobile: isMobile, + scale: containerScale, + // isMobile: isMobile, zIndex: posZIndex, type: dragTypeValue, - options: addWidgetOptions(dragTypeValue) + options: addWidgetOptions(dragTypeValue), + Width: widgetWidth / (containerScale * scale), + Height: widgetHeight / (containerScale * scale) }; dropData.push(dropObj); placeHolder = { @@ -387,17 +410,25 @@ const TemplatePlaceholder = () => { .getBoundingClientRect(); const x = offset.x - containerRect.left; const y = offset.y - containerRect.top; + const getXPosition = signBtnPosition[0] + ? x - signBtnPosition[0].xPos + : x; + const getYPosition = signBtnPosition[0] + ? y - signBtnPosition[0].yPos + : y; const dropObj = { - xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, - yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, + xPosition: getXPosition / (containerScale * scale), + yPosition: getYPosition / (containerScale * scale), isStamp: (dragTypeValue === "stamp" || dragTypeValue === "image") && true, key: key, - scale: scale, - isMobile: isMobile, + scale: containerScale, + // isMobile: isMobile, zIndex: posZIndex, type: item.text, - options: addWidgetOptions(dragTypeValue) + options: addWidgetOptions(dragTypeValue), + Width: widgetWidth / (containerScale * scale), + Height: widgetHeight / (containerScale * scale) }; dropData.push(dropObj); @@ -471,6 +502,13 @@ const TemplatePlaceholder = () => { setShowDropdown(true); } else if (dragTypeValue === "checkbox") { setIsCheckbox(true); + } else if ( + [textInputWidget, "name", "company", "job title", "email"].includes( + dragTypeValue + ) + ) { + setFontSize(12); + setFontColor("black"); } else if (dragTypeValue === radioButtonWidget) { setIsRadio(true); } @@ -499,13 +537,14 @@ const TemplatePlaceholder = () => { //function for get pdf page details const pageDetails = async (pdf) => { - const load = { - status: true - }; - setPdfLoadFail(load); pdf.getPage(1).then((pdfPage) => { const pageWidth = pdfPage.view[2]; - setPdfOriginalWidth(pageWidth); + const pageHeight = pdfPage.view[3]; + setPdfOriginalWH({ width: pageWidth, height: pageHeight }); + const load = { + status: true + }; + setPdfLoadFail(load); }); }; //function for save x and y position and show signature tab on that position @@ -520,14 +559,9 @@ const TemplatePlaceholder = () => { const dataNewPlace = addZIndex(signerPos, key, setZIndex); let updateSignPos = [...signerPos]; updateSignPos.splice(0, updateSignPos.length, ...dataNewPlace); - // signerPos.splice(0, signerPos.length, ...dataNewPlace); - const containerRect = document - .getElementById("container") - .getBoundingClientRect(); const signId = signerId; //? signerId : signerObjId; const keyValue = key ? key : dragKey; - const ybottom = containerRect.height - dragElement.y; - + const containerScale = containerWH.width / pdfOriginalWH.width; if (keyValue >= 0) { const filterSignerPos = updateSignPos.filter( (data) => data.Id === signId @@ -548,10 +582,8 @@ const TemplatePlaceholder = () => { if (url.key === keyValue) { return { ...url, - xPosition: dragElement.x, - yPosition: dragElement.y, - isDrag: true, - yBottom: ybottom + xPosition: dragElement.x / (containerScale * scale), + yPosition: dragElement.y / (containerScale * scale) }; } return url; @@ -1202,6 +1234,55 @@ const TemplatePlaceholder = () => { setIsCheckbox(false); }; + const handleSaveFontSize = () => { + const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); + if (filterSignerPos.length > 0) { + const getPlaceHolder = filterSignerPos[0].placeHolder; + + const getPageNumer = getPlaceHolder.filter( + (data) => data.pageNumber === pageNumber + ); + + if (getPageNumer.length > 0) { + const getXYdata = getPageNumer[0].pos; + const getPosData = getXYdata; + const addSignPos = getPosData.map((position) => { + if (position.key === signKey) { + return { + ...position, + options: { + ...position.options, + fontSize: fontSize, + fontColor: fontColor + } + }; + } + return position; + }); + + const newUpdateSignPos = getPlaceHolder.map((obj) => { + if (obj.pageNumber === pageNumber) { + return { ...obj, pos: addSignPos }; + } + return obj; + }); + const newUpdateSigner = signerPos.map((obj) => { + if (obj.Id === uniqueId) { + return { ...obj, placeHolder: newUpdateSignPos }; + } + return obj; + }); + setSignerPos(newUpdateSigner); + } + } + setFontSize(); + setFontColor(); + + handleTextSettingModal(false); + }; + const handleTextSettingModal = (value) => { + setIsTextSetting(value); + }; return ( <div> <Title title={"Template"} /> @@ -1211,10 +1292,7 @@ const TemplatePlaceholder = () => { ) : handleError ? ( <HandleError handleError={handleError} /> ) : ( - <div - className="op-card overflow-hidden flex flex-row justify-between bg-base-300 relative" - ref={divRef} - > + <div className="flex min-h-screen flex-row justify-center op-card overflow-hidden bg-base-300 relative"> {/* this component used for UI interaction and show their functionality */} {!checkTourStatus && ( //this tour component used in your html component where you want to put @@ -1249,185 +1327,201 @@ const TemplatePlaceholder = () => { /> {/* pdf render view */} - <div - style={{ - marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px", - marginRight: !isMobile && pdfOriginalWidth > 500 && "20px" - }} - > - {/* this modal is used show alert set placeholder for all signers before send mail */} - <ModalUi - isOpen={isSendAlert} - title={"Fields required"} - handleClose={() => setIsSendAlert(false)} - > - <div className="h-full p-[20px]"> - <p>Please add at least one signature field for all roles.</p> - </div> - </ModalUi> - <ModalUi - isOpen={!IsReceipent} - title={"Roles"} - handleClose={() => setIsReceipent(true)} - > - <div className="h-full p-[20px] text-center font-medium"> - <p>Please add roles first</p> - </div> - </ModalUi> - {/* this modal is used show send mail message and after send mail success message */} - <ModalUi - isOpen={isCreateDocModal} - title={"Create Document"} - handleClose={() => setIsCreateDocModal(false)} - > - <div className="h-full p-[20px]"> - <p> - Do you want to create a document using the template you just - created ? - </p> - <div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div> - {currentEmail.length > 0 && ( - <> - <button - onClick={() => handleCreateDocModal()} - type="button" - className="op-btn op-btn-primary" - > - Yes - </button> - <button - onClick={() => { - setIsCreateDocModal(false); - }} - type="button" - className="op-btn op-btn-secondary ml-2" - > - No - </button> - </> + <div className="min-h-screen w-full md:w-[57%] flex md:mr-4"> + <PdfZoom + setScale={setScale} + scale={scale} + pdfOriginalWH={pdfOriginalWH} + containerWH={containerWH} + setZoomPercent={setZoomPercent} + zoomPercent={zoomPercent} + /> + <div className="min-h-screen w-full md:w-[97%] "> + {/* this modal is used show alert set placeholder for all signers before send mail */} + <ModalUi + isOpen={isSendAlert} + title={"Fields required"} + handleClose={() => setIsSendAlert(false)} + > + <div className="h-full p-[20px]"> + <p> + Please add at least one signature field for all roles. + </p> + </div> + </ModalUi> + <ModalUi + isOpen={!IsReceipent} + title={"Roles"} + handleClose={() => setIsReceipent(true)} + > + <div className="h-full p-[20px] text-center font-medium"> + <p>Please add roles first</p> + </div> + </ModalUi> + {/* this modal is used show send mail message and after send mail success message */} + <ModalUi + isOpen={isCreateDocModal} + title={"Create Document"} + handleClose={() => setIsCreateDocModal(false)} + > + <div className="h-full p-[20px]"> + <p> + Do you want to create a document using the template you + just created ? + </p> + <div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div> + {currentEmail.length > 0 && ( + <> + <button + onClick={() => { + handleCreateDocModal(); + }} + type="button" + className="op-btn op-btn-primary" + > + Yes + </button> + <button + onClick={() => { + setIsCreateDocModal(false); + }} + type="button" + className="op-btn op-btn-secondary ml-2" + > + No + </button> + </> + )} + </div> + </ModalUi> + {isCreateDoc && <LoaderWithMsg isLoading={isLoading} />} + <ModalUi + isOpen={isShowEmail} + title={"signers alert"} + handleClose={() => { + setIsShowEmail(false); + }} + > + <div className="h-full p-[20px]"> + <p>Please select signer for add placeholder!</p> + <div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div> + <button + onClick={() => { + setIsShowEmail(false); + }} + type="button" + className="op-btn op-btn-primary" + > + Ok + </button> + </div> + </ModalUi> + <DropdownWidgetOption + type={radioButtonWidget} + title="Radio group" + showDropdown={isRadio} + setShowDropdown={setIsRadio} + handleSaveWidgetsOptions={handleSaveWidgetsOptions} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + handleClose={handleNameModal} + isSubscribe={isSubscribe} + /> + <DropdownWidgetOption + type="checkbox" + title="Checkbox" + showDropdown={isCheckbox} + setShowDropdown={setIsCheckbox} + handleSaveWidgetsOptions={handleSaveWidgetsOptions} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + handleClose={handleNameModal} + isSubscribe={isSubscribe} + /> + <DropdownWidgetOption + type="dropdown" + title="Dropdown options" + showDropdown={showDropdown} + setShowDropdown={setShowDropdown} + handleSaveWidgetsOptions={handleSaveWidgetsOptions} + currWidgetsDetails={currWidgetsDetails} + setCurrWidgetsDetails={setCurrWidgetsDetails} + handleClose={handleNameModal} + isSubscribe={isSubscribe} + /> + <PlaceholderCopy + isPageCopy={isPageCopy} + setIsPageCopy={setIsPageCopy} + xyPostion={signerPos} + setXyPostion={setSignerPos} + allPages={allPages} + pageNumber={pageNumber} + signKey={signKey} + // signerObjId={signerObjId} + Id={uniqueId} + /> + {/* pdf header which contain funish back button */} + <Header + completeBtnTitle={"Save"} + isPlaceholder={true} + pageNumber={pageNumber} + allPages={allPages} + changePage={changePage} + pdfDetails={pdfDetails} + signerPos={signerPos} + signersdata={signersdata} + isMailSend={isMailSend} + alertSendEmail={alertSendEmail} + isShowHeader={true} + currentSigner={true} + setIsEditTemplate={handleEditTemplateModal} + dataTut4="reactourFour" + /> + <div ref={divRef} data-tut="reactourThird" className="h-[95%]"> + {containerWH && ( + <RenderPdf + pageNumber={pageNumber} + pdfNewWidth={pdfNewWidth} + pdfDetails={pdfDetails} + signerPos={signerPos} + successEmail={false} + numPages={numPages} + pageDetails={pageDetails} + placeholder={true} + drop={drop} + handleDeleteSign={handleDeleteSign} + handleTabDrag={handleTabDrag} + handleStop={handleStop} + setPdfLoadFail={setPdfLoadFail} + pdfLoadFail={pdfLoadFail} + setSignerPos={setSignerPos} + containerWH={containerWH} + setIsResize={setIsResize} + setZIndex={setZIndex} + handleLinkUser={handleLinkUser} + setUniqueId={setUniqueId} + signersdata={signersdata} + setIsPageCopy={setIsPageCopy} + setSignKey={setSignKey} + setSignerObjId={setSignerObjId} + isDragging={isDragging} + setShowDropdown={setShowDropdown} + setCurrWidgetsDetails={setCurrWidgetsDetails} + setWidgetType={setWidgetType} + setIsRadio={setIsRadio} + setSelectWidgetId={setSelectWidgetId} + selectWidgetId={selectWidgetId} + setIsCheckbox={setIsCheckbox} + handleNameModal={setIsNameModal} + setPdfRenderHeight={setPdfRenderHeight} + pdfRenderHeight={pdfRenderHeight} + handleTextSettingModal={handleTextSettingModal} + pdfOriginalWH={pdfOriginalWH} + setScale={setScale} + scale={scale} + /> )} </div> - </ModalUi> - {isCreateDoc && <LoaderWithMsg isLoading={isLoading} />} - <ModalUi - isOpen={isShowEmail} - title={"signers alert"} - handleClose={() => { - setIsShowEmail(false); - }} - > - <div className="h-full p-[20px]"> - <p>Please select signer for add placeholder!</p> - <div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div> - <button - onClick={() => setIsShowEmail(false)} - type="button" - className="op-btn op-btn-primary" - > - Ok - </button> - </div> - </ModalUi> - <DropdownWidgetOption - type={radioButtonWidget} - title="Radio group" - showDropdown={isRadio} - setShowDropdown={setIsRadio} - handleSaveWidgetsOptions={handleSaveWidgetsOptions} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - handleClose={handleNameModal} - isSubscribe={isSubscribe} - /> - <DropdownWidgetOption - type="checkbox" - title="Checkbox" - showDropdown={isCheckbox} - setShowDropdown={setIsCheckbox} - handleSaveWidgetsOptions={handleSaveWidgetsOptions} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - handleClose={handleNameModal} - isSubscribe={isSubscribe} - /> - <DropdownWidgetOption - type="dropdown" - title="Dropdown options" - showDropdown={showDropdown} - setShowDropdown={setShowDropdown} - handleSaveWidgetsOptions={handleSaveWidgetsOptions} - currWidgetsDetails={currWidgetsDetails} - setCurrWidgetsDetails={setCurrWidgetsDetails} - handleClose={handleNameModal} - isSubscribe={isSubscribe} - /> - <PlaceholderCopy - isPageCopy={isPageCopy} - setIsPageCopy={setIsPageCopy} - xyPostion={signerPos} - setXyPostion={setSignerPos} - allPages={allPages} - pageNumber={pageNumber} - signKey={signKey} - // signerObjId={signerObjId} - Id={uniqueId} - /> - {/* pdf header which contain finish, back button */} - <Header - completeBtnTitle={"Save"} - isPlaceholder={true} - pageNumber={pageNumber} - allPages={allPages} - changePage={changePage} - pdfDetails={pdfDetails} - signerPos={signerPos} - signersdata={signersdata} - isMailSend={isMailSend} - alertSendEmail={alertSendEmail} - isShowHeader={true} - currentSigner={true} - setIsEditTemplate={handleEditTemplateModal} - dataTut4="reactourFour" - /> - <div data-tut="reactourThird"> - {containerWH && ( - <RenderPdf - pageNumber={pageNumber} - pdfOriginalWidth={pdfOriginalWidth} - pdfNewWidth={pdfNewWidth} - pdfDetails={pdfDetails} - signerPos={signerPos} - successEmail={false} - numPages={numPages} - pageDetails={pageDetails} - placeholder={true} - drop={drop} - handleDeleteSign={handleDeleteSign} - handleTabDrag={handleTabDrag} - handleStop={handleStop} - setPdfLoadFail={setPdfLoadFail} - pdfLoadFail={pdfLoadFail} - setSignerPos={setSignerPos} - containerWH={containerWH} - setIsResize={setIsResize} - setZIndex={setZIndex} - handleLinkUser={handleLinkUser} - setUniqueId={setUniqueId} - signersdata={signersdata} - setIsPageCopy={setIsPageCopy} - setSignKey={setSignKey} - setSignerObjId={setSignerObjId} - isDragging={isDragging} - setShowDropdown={setShowDropdown} - setCurrWidgetsDetails={setCurrWidgetsDetails} - setWidgetType={setWidgetType} - setIsRadio={setIsRadio} - setSelectWidgetId={setSelectWidgetId} - selectWidgetId={selectWidgetId} - setIsCheckbox={setIsCheckbox} - handleNameModal={setIsNameModal} - /> - )} </div> </div> {/* signature button */} @@ -1474,50 +1568,47 @@ const TemplatePlaceholder = () => { /> </div> ) : ( - <div> - <div className="hidden md:block w-[180px] h-full bg-base-100"> - <div - style={{ maxHeight: window.innerHeight - 70 + "px" }} - className="overflow-y-auto hide-scrollbar" - > - <SignerListPlace + <div + className={`w-[23%] bg-[#FFFFFF] min-h-screen overflow-y-auto hide-scrollbar`} + > + <div className={`max-h-screen`}> + <SignerListPlace + isMailSend={isMailSend} + signerPos={signerPos} + signersdata={signersdata} + isSelectListId={isSelectListId} + setSignerObjId={setSignerObjId} + setRoleName={setRoleName} + setIsSelectId={setIsSelectId} + setContractName={setContractName} + handleAddSigner={handleAddSigner} + setUniqueId={setUniqueId} + handleDeleteUser={handleDeleteUser} + handleRoleChange={handleRoleChange} + handleOnBlur={handleOnBlur} + title={"Roles"} + sendInOrder={pdfDetails[0]?.SendinOrder} + setSignersData={setSignersData} + blockColor={blockColor} + setBlockColor={setBlockColor} + /> + <div data-tut="reactourSecond"> + <WidgetComponent isMailSend={isMailSend} - signerPos={signerPos} - signersdata={signersdata} - isSelectListId={isSelectListId} - setSignerObjId={setSignerObjId} - setRoleName={setRoleName} - setIsSelectId={setIsSelectId} - setContractName={setContractName} - handleAddSigner={handleAddSigner} - setUniqueId={setUniqueId} - handleDeleteUser={handleDeleteUser} - handleRoleChange={handleRoleChange} - handleOnBlur={handleOnBlur} + dragSignature={dragSignature} + signRef={signRef} + handleDivClick={handleDivClick} + handleMouseLeave={handleMouseLeave} + isDragSign={isDragSign} + dragStamp={dragStamp} + dragRef={dragRef} + isDragStamp={isDragStamp} + isSignYourself={false} + addPositionOfSignature={addPositionOfSignature} title={"Roles"} - sendInOrder={pdfDetails[0]?.SendinOrder} - setSignersData={setSignersData} - blockColor={blockColor} - setBlockColor={setBlockColor} + initial={true} + isTemplateFlow={true} /> - <div data-tut="reactourSecond"> - <WidgetComponent - isMailSend={isMailSend} - dragSignature={dragSignature} - signRef={signRef} - handleDivClick={handleDivClick} - handleMouseLeave={handleMouseLeave} - isDragSign={isDragSign} - dragStamp={dragStamp} - dragRef={dragRef} - isDragStamp={isDragStamp} - isSignYourself={false} - addPositionOfSignature={addPositionOfSignature} - title={"Roles"} - initial={true} - isTemplateFlow={true} - /> - </div> </div> </div> </div> @@ -1562,6 +1653,16 @@ const TemplatePlaceholder = () => { handleData={handleWidgetdefaultdata} isSubscribe={isSubscribe} /> + <TextFontSetting + isTextSetting={isTextSetting} + setIsTextSetting={setIsTextSetting} + fontSize={fontSize} + setFontSize={setFontSize} + fontColor={fontColor} + setFontColor={setFontColor} + handleSaveFontSize={handleSaveFontSize} + currWidgetsDetails={currWidgetsDetails} + /> </div> ); }; diff --git a/apps/OpenSign/src/redux/reducers/index.js b/apps/OpenSign/src/redux/reducers/index.js index d26334516..277fce1af 100644 --- a/apps/OpenSign/src/redux/reducers/index.js +++ b/apps/OpenSign/src/redux/reducers/index.js @@ -2,9 +2,11 @@ import { combineReducers } from "redux"; import infoReducer from "./infoReducer"; import ShowTenant from "./ShowTenant"; import TourStepsReducer from "./TourStepsReducer"; +import showHeader from "./showHeader"; export default combineReducers({ appInfo: infoReducer, TourSteps: TourStepsReducer, - ShowTenant + ShowTenant, + showHeader }); diff --git a/apps/OpenSign/src/redux/reducers/showHeader.js b/apps/OpenSign/src/redux/reducers/showHeader.js new file mode 100644 index 000000000..9a98203f2 --- /dev/null +++ b/apps/OpenSign/src/redux/reducers/showHeader.js @@ -0,0 +1,14 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const showHeaderSlice = createSlice({ + name: "showTenant", + initialState: "", + reducers: { + showHeader: (state, action) => { + return action.payload; + } + } +}); + +export const { showHeader } = showHeaderSlice.actions; +export default showHeaderSlice.reducer; diff --git a/apps/OpenSign/src/redux/store.js b/apps/OpenSign/src/redux/store.js index 981f3e339..f466cfb48 100644 --- a/apps/OpenSign/src/redux/store.js +++ b/apps/OpenSign/src/redux/store.js @@ -7,10 +7,12 @@ import { configureStore } from "@reduxjs/toolkit"; import infoReducer from "./reducers/infoReducer"; import ShowTenant from "./reducers/ShowTenant"; import TourStepsReducer from "./reducers/TourStepsReducer"; +import showHeader from "./reducers/showHeader"; export const store = configureStore({ reducer: { appInfo: infoReducer, TourSteps: TourStepsReducer, - ShowTenant + ShowTenant, + showHeader } }); diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index 15ac8ff1b..e685dc939 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -15,7 +15,6 @@ border-width: 0.2px; } - .react-datepicker__input-container { position: initial !important; } @@ -27,7 +26,6 @@ user-select: none; } - .radioButton { width: 100%; height: 100%; @@ -39,7 +37,6 @@ border-radius: 50px; } - .drodown-input { padding: 5px; width: 100%; @@ -145,7 +142,7 @@ background: white; transition-duration: 0.4s; cursor: all-scroll; - width: 150px; + width: 'auto'; height: 30px; color: black; } @@ -304,9 +301,12 @@ background: white; } -.ScrollbarsCustom-Track { +.ScrollbarsCustom-TrackY { width: 4px !important; } +.ScrollbarsCustom-TrackX { + height: 4px !important; +} .signYourselfBlock { padding: 0px; @@ -434,7 +434,11 @@ overflow: hidden !important; text-overflow: ellipsis; } - +.user{ + white-space: nowrap; + overflow: hidden !important; + text-overflow: ellipsis; +} .disabled { opacity: 0.5; /* Example: reduce opacity to visually indicate disabled state */ @@ -495,16 +499,16 @@ display: flex; flex-direction: row; justify-content: space-between; - background-color: #ebebeb; + /* background-color: #ebebeb; */ position: "relative"; } .signerComponent { /* box-shadow: rgba(17, 12, 46, 0.15) 0px 48px 100px 0px; */ - width: 180px; + /* width: 180px; */ background-color: white; - height: 100%; + } .modalBody { @@ -513,9 +517,10 @@ } .signLayoutContainer1 { - padding: 30px; + padding: 15px; display: flex; - flex-direction: column; + /* flex-direction: column; */ + /* justify-content: start; */ align-items: center; } @@ -822,9 +827,9 @@ option { flex-direction: column; } - .signerComponent { + /* .signerComponent { display: none; - } + } */ .preBtn1 { display: none; @@ -840,6 +845,7 @@ option { #navbar { overflow: hidden; + z-index: 49; } /* Navbar links */