feat: optimize design for high-resolution monitors

This commit is contained in:
RaktimaNXG
2024-06-17 21:07:25 +05:30
parent d1d0f40b00
commit 08387fc406
24 changed files with 2234 additions and 1705 deletions
@@ -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=[]
<span className=" hidden md:flex flex-col gap-1 text-center md:w-[5%] mt-[50px] 2xl:mt-[63px]">
<span
className="bg-gray-50 px-[4px] 2xl:px-[15px] 2xl:py-[10px] cursor-pointer"
onClick={onClickZoomIn}
title="Zoom in"
>
<i className="fa-solid fa-magnifying-glass-plus text-gray-500 2xl:text-[30px]"></i>
</span>
<span
className="bg-gray-50 px-[4px] 2xl:px-[15px] 2xl:py-[10px] cursor-pointer "
onClick={handleReset}
title="Reset"
>
<i className="fa-solid fa-arrows-rotate text-gray-500 2xl:text-[30px]"></i>
</span>
<span
className="bg-gray-50 px-[4px] 2xl:px-[15px] 2xl:py-[10px]"
onClick={onClickZoomOut}
style={{
cursor: props.zoomPercent > 0 ? "pointer" : "default"
}}
title="Zoom out"
>
<i className="fa-solid fa-magnifying-glass-minus text-gray-500 2xl:text-[30px]"></i>
</span>
</span>
);
}
export default PdfZoom;
+59 -22
View File
@@ -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 ? (
<i
onClick={(e) => {
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)) && (
<i
onClick={(e) => {
@@ -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"
}}
></i>
)
)}
@@ -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 ? (
<div
// className="sm:inline-block md:inline-block lg:hidden "
style={{
left: props.xPos(props.pos, props.isSignYourself),
top: props.yPos(props.pos, props.isSignYourself),
@@ -689,8 +726,6 @@ function Placeholder(props) {
props.pos.type === "checkbox"
? "auto"
: props.posWidth(props.pos, props.isSignYourself),
// "auto", //props.posWidth(props.pos, props.isSignYourself),
// height: props.posHeight(props.pos, props.isSignYourself),
height:
props.pos.type === radioButtonWidget ||
props.pos.type === "checkbox"
@@ -723,6 +758,7 @@ function Placeholder(props) {
setStartDate={setStartDate}
startDate={startDate}
handleSaveDate={handleSaveDate}
xPos={props.xPos}
/>
</div>
) : (
@@ -749,6 +785,7 @@ function Placeholder(props) {
setStartDate={setStartDate}
startDate={startDate}
handleSaveDate={handleSaveDate}
xPos={props.xPos}
/>
</>
)}
@@ -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 (
@@ -145,32 +145,32 @@ function PlaceholderType(props) {
ref={ref}
>
{value}
<i className="fa-regular fa-calendar ml-[5px]"></i>
<i className="fa-regular fa-calendar ml-[5px]"></i>
</div>
));
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)} */}
</div>
);
case "stamp":
+3 -3
View File
@@ -20,9 +20,9 @@ function PrevNext({ pageNumber, allPages, changePage }) {
<span className="block lg:hidden">
<i className="fa fa-backward" aria-hidden="true"></i>
</span>
<span className="lg:block hidden">Prev</span>
<span className="lg:block hidden 2xl:text-[30px]">Prev</span>
</button>
<span className="text-xs text-base-content font-medium mx-2">
<span className="text-xs text-base-content font-medium mx-2 2xl:text-[30px]">
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
</span>
<button
@@ -33,7 +33,7 @@ function PrevNext({ pageNumber, allPages, changePage }) {
<span className="block lg:hidden">
<i className="fa fa-forward" aria-hidden="true"></i>
</span>
<span className="lg:block hidden">Next</span>
<span className="lg:block hidden 2xl:text-[30px]">Next</span>
</button>
</div>
);
@@ -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) => {
</div>
<div
className={`${
obj?.Name ? "flex-col" : "flex-row"
obj.Name ? "flex-col" : "flex-row"
} flex items-center`}
>
{obj.Name ? (
@@ -175,7 +173,7 @@ const RecipientList = (props) => {
{isEdit?.[obj.Id] && props.handleRoleChange ? (
<input
ref={inputRef}
className="bg-transparent p-[3px"
className="bg-transparent p-[3px]"
value={obj.Role}
onChange={(e) => props.handleRoleChange(e, obj.Id)}
onBlur={() => {
@@ -190,7 +188,9 @@ const RecipientList = (props) => {
}}
/>
) : (
<span className="p-[3px]">{obj.Role}</span>
<span className="text-[13px] 2xl:text-[25px]">
{obj.Role}
</span>
)}
</span>
)}
@@ -251,7 +251,7 @@ const RecipientList = (props) => {
: "text-base-content"
} cursor-pointer ml-[5px]`}
>
<i className="fa-regular fa-trash-can"></i>
<i className="fa-regular fa-trash-can 2xl:text-[30px]"></i>
</div>
)}
<hr />
@@ -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 (
<div>
<div className=" hidden md:flex flex-row bg-base-100 h-full">
<div className="w-[140px]">
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
Pages
</div>
<div>
<RSC
id="RSC-Example"
style={{
width: "135px",
height: window.innerHeight - 130 + "px"
return (
<div
ref={pageContainer}
className="hidden min-h-screen w-[20%] bg-base-100 h-full md:block"
>
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
Pages
</div>
<div
className={`flex h-[90%] flex-col items-center m-2
autoSignScroll hide-scrollbar max-h-[100vh] `}
>
<Document
loading={"Loading Document.."}
onLoadSuccess={onDocumentLoad}
file={signPdfUrl}
>
{Array.from(new Array(allPages), (el, index) => (
<div
key={index}
className={`${
pageNumber - 1 === index ? "border-[red]" : "border-[#878787]"
} border-2 m-[10px] flex justify-center items-center relative`}
onClick={() => {
setPageNumber(index + 1);
if (setSignBtnPosition) {
setSignBtnPosition([]);
}
}}
>
<Document
loading={"Loading Document.."}
onLoadSuccess={onDocumentLoad}
file={signPdfUrl}
>
{Array.from(new Array(allPages), (el, index) => (
<div
key={index}
className={`${
pageNumber - 1 === index
? "border-[red]"
: "border-[#878787]"
} border-2 w-[100px] m-[10px] flex justify-center items-center relative`}
onClick={() => {
setPageNumber(index + 1);
if (setSignBtnPosition) {
setSignBtnPosition([]);
}
}}
>
{signerPos && addSignatureBookmark(index)}
{signerPos && addSignatureBookmark(index)}
<div className="relative z-[1] overflow-hidden">
<Page
key={`page_${index + 1}`}
pageNumber={index + 1}
width={100}
height={100}
scale={1}
renderAnnotationLayer={false}
renderTextLayer={false}
/>
</div>
</div>
))}
</Document>
</RSC>
</div>
<hr />
</div>
<div className="relative z-[1] overflow-hidden">
<Page
key={`page_${index + 1}`}
pageNumber={index + 1}
width={pageWidth - 60}
scale={1}
renderAnnotationLayer={false}
renderTextLayer={false}
/>
</div>
</div>
))}
</Document>
</div>
</div>
);
+181 -163
View File
@@ -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 (
<React.Fragment>
<div className="text-black text-[8px] font-medium">
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
{
pdfDetails[0].Signers?.find(
(signer) => signer.objectId === data.signerObjId
@@ -231,7 +220,6 @@ function RenderPdf({
</React.Fragment>
);
};
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}
/>
</React.Fragment>
)
@@ -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 && <Alert type={"success"}>Email sent successfully!</Alert>}
{isMobile && scale ? (
{isMobile ? (
<div
data-tut="reactourForth"
style={{
@@ -330,12 +323,12 @@ function RenderPdf({
ref={drop}
id="container"
>
{pdfLoadFail.status &&
{isLoadPdf &&
(pdfRequest
? signerPos.map((data, key) => {
return (
<React.Fragment key={key}>
{checkSignedSignes(data)}
<CheckSignedSignes data={data} />
</React.Fragment>
);
})
@@ -391,6 +384,11 @@ function RenderPdf({
handleNameModal={handleNameModal}
setTempSignerId={setTempSignerId}
uniqueId={uniqueId}
handleTextSettingModal={
handleTextSettingModal
}
containerWH={containerWH}
pdfOriginalWH={pdfOriginalWH}
/>
</React.Fragment>
);
@@ -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 */}
<div className="flex items-center justify-center">
<Document
onLoadError={() => 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) => (
<Page
onLoadSuccess={({ height }) => {
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}
>
<div
data-tut="reactourForth"
style={{ border: "0.1px solid #ebe8e8", width: pdfOriginalWidth }}
style={{
width: containerWH.width * scale
}}
ref={drop}
id="container"
>
{pdfLoadFail.status &&
{isLoadPdf &&
(pdfRequest
? signerPos.map((data, key) => {
? signerPos?.map((data, key) => {
return (
<React.Fragment key={key}>
{checkSignedSignes(data)}
<CheckSignedSignes data={data} />
</React.Fragment>
);
})
@@ -564,6 +571,12 @@ function RenderPdf({
handleNameModal={handleNameModal}
setTempSignerId={setTempSignerId}
uniqueId={uniqueId}
handleTextSettingModal={
handleTextSettingModal
}
scale={scale}
containerWH={containerWH}
pdfOriginalWH={pdfOriginalWH}
/>
</React.Fragment>
);
@@ -577,53 +590,52 @@ function RenderPdf({
: xyPostion.map((data, ind) => {
return (
<React.Fragment key={ind}>
{data.pageNumber === pageNumber &&
data.pos.map((pos) => {
return (
pos && (
<React.Fragment key={pos.key}>
<Placeholder
pos={pos}
setIsPageCopy={setIsPageCopy}
setSignKey={setSignKey}
handleDeleteSign={handleDeleteSign}
setIsStamp={setIsStamp}
handleTabDrag={handleTabDrag}
handleStop={(event, dragElement) =>
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
}
/>
</React.Fragment>
)
);
})}
{data.pos.map((pos) => {
return (
<React.Fragment key={pos.key}>
<Placeholder
pos={pos}
setIsPageCopy={setIsPageCopy}
setSignKey={setSignKey}
handleDeleteSign={handleDeleteSign}
setIsStamp={setIsStamp}
handleTabDrag={handleTabDrag}
handleStop={(event, dragElement) =>
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}
/>
</React.Fragment>
);
})}
</React.Fragment>
);
}))}
@@ -655,7 +667,13 @@ function RenderPdf({
>
{Array.from(new Array(numPages), (el, index) => (
<Page
onLoadSuccess={({ height }) => {
setPdfRenderHeight && setPdfRenderHeight(height);
setIsLoadPdf(true);
}}
key={index}
width={containerWH.width}
scale={scale || 1}
pageNumber={pageNumber}
renderAnnotationLayer={false}
renderTextLayer={false}
+6 -2
View File
@@ -13,8 +13,12 @@ function Signedby({ pdfDetails }) {
</div>
<div className="mt-[2px] bg-base-100">
<div className="bg-[#93a3db] rounded-xl mx-1 flex flex-row items-center py-[10px]">
<div className="bg-[#576081] flex w-[30px] h-[30px] rounded-full justify-center items-center mx-1">
<span className="text-[12px] text-center font-bold text-white uppercase">
<div
className=" bg-[#abd1d0] w-[15px] h-[15px] 2xl:w-[30px] 2xl:h-[30px] flex rounded-full ring-[1px] ring-offset-1 justify-center items-center
mr-[0px] mt-[7px] 2xl:mt-[12px]
"
>
<span className="text-[12px] text-center font-bold text-white 2xl:text-[20px] uppercase">
{getFirstLetter(pdfDetails.ExtUserPtr.Name)}
</span>
</div>
@@ -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 (
<div
className="rounded-xl mx-1 flex flex-row items-center py-[10px] mt-1"
style={{
background: checkSignerBackColor(props.obj)
}}
>
<div
style={{
background: checkUserNameColor(props.obj)
}}
className="flex w-[30px] h-[30px] rounded-full justify-center items-center mx-1"
>
<span className="text-[12px] text-center font-bold text-black uppercase">
{getFirstLetter(props?.obj?.Name || props?.obj?.Role)}
</span>
</div>
<div className="flex flex-col">
<span className="userName">{props.obj?.Name || props?.obj?.Role}</span>
<span className="useEmail">
{" "}
{props.obj?.Email || props.obj?.email}
</span>
</div>
</div>
);
}
export default SignerListComponent;
@@ -8,7 +8,7 @@ function SignerListPlace(props) {
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
<span>
{props.title ? props.title : "Recipients"}
<span className="text-xs mt-1 ml-0.5">
<span className="absolute text-xs z-[30] mt-1 ml-0.5">
{props?.title === "Roles" && (
<>
<a data-tooltip-id="my-tooltip">
@@ -17,8 +17,10 @@ function SignerListPlace(props) {
</sup>
</a>
<Tooltip id="my-tooltip" className="z-[100]">
<div className="max-w-[450px]">
<p className="font-bold">What are template roles?</p>
<div className="max-w-[450px] 2xl:max-w-[500px] 2xl:text-[20px] p-[1px]">
<p className="font-bold pb-[1px]">
What are template roles?
</p>
<p>
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) {
<div
role="button"
data-tut="reactourAddbtn"
className="op-btn op-btn-accent op-btn-outline w-full mt-[14px]"
disabled={props?.isMailSend ? true : false}
className="op-btn op-btn-accent op-btn-outline w-full mt-[14px]"
onClick={() => props.handleAddSigner()}
>
<i className="fa-solid fa-plus"></i> Add role
@@ -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 (
<ModalUi
headerColor={"#dc3545"}
isOpen={props.isTextSetting}
title={"Text field"}
handleClose={() => {
props.setIsTextSetting(false);
}}
>
<div style={{ height: "100%", padding: 20 }}>
<div className="flex items-center gap-4">
<span>Font size: </span>
<select
className="border-[1px] border-gray-300 px-[5px]"
value={
props.fontSize || props.currWidgetsDetails?.options?.fontSize
}
onChange={(e) => props.setFontSize(e.target.value)}
>
{fontsizeArr.map((size, ind) => {
return (
<option style={{ fontSize: "13px" }} value={size} key={ind}>
{size}
</option>
);
})}
</select>
<div className="flex flex-row gap-1">
<span>color: </span>
<select
value={
props.fontColor || props.currWidgetsDetails?.options?.fontColor
}
onChange={(e) => props.setFontColor(e.target.value)}
className="border-[1px] border-gray-300 px-[2px] ml-[10px] "
>
{fontColorArr.map((color, ind) => {
return (
<option value={color} key={ind}>
{color}
</option>
);
})}
</select>
<span
style={{
background:
props.fontColor ||
props.currWidgetsDetails?.options?.fontColor
}}
className="w-5 h-[19px]"
></span>
</div>
</div>
<div className="h-[1px] bg-[#9f9f9f] w-full mt-[15px] mb-[15px]"></div>
<button
onClick={() => props.handleSaveFontSize()}
style={{ background: themeColor }}
type="button"
className="finishBtn "
>
save
</button>
</div>
</ModalUi>
);
}
export default TextFontSetting;
@@ -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`}
>
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
<span>Fields</span>
</div>
<div className="flex flex-col items-center my-3">
<div className="p-[15px] flex flex-col pt-4 2xl:m-5">
<WidgetList
updateWidgets={updateWidgets}
handleDivClick={handleDivClick}
@@ -1,12 +1,14 @@
import React from "react";
import { getWidgetType } from "../../constant/Utils";
import { useSelector } from "react-redux";
function WidgetList(props) {
const isHeader = useSelector((state) => state.showHeader);
return props.updateWidgets.map((item, ind) => {
return (
<div key={ind} className="mb-[5px]">
<div className="2xl:p-3 mb-[5px]" key={ind}>
<div
className="select-none"
className="select-none mx-[2px] md:mx-0 cursor-all-scroll"
onClick={() => {
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)}
</div>
</div>
);
+93 -178
View File
@@ -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 (
<div className="op-btn op-btn-primary op-btn-outline op-btn-sm focus:outline-none outline outline-[1.5px] w-fit md:w-[150px] ml-[6px] md:ml-0 p-0 overflow-hidden">
<div className="op-btn w-[100%] op-btn-primary op-btn-outline op-btn-sm focus:outline-none outline outline-[1.5px] ml-[6px] md:ml-0 p-0 overflow-hidden">
<div className="w-full h-full flex md:justify-between items-center">
<div className="flex justify-start items-center text-[13px] ml-1">
{!isMobile && <i className="fa-sharp fa-solid fa-grip-vertical"></i>}
<span className="text-center text-[15px] ml-[5px] font-semibold">
<span
className={`${
isHeader && "md:hidden lg:inline-block"
} md:inline-block text-center text-[15px] ml-[5px] font-semibold`}
>
{item.type}
</span>
</div>
<div className="text-[20px] op-btn op-btn-primary rounded-none w-[40px] h-full flex justify-center items-center">
<div
className={` text-[20px] op-btn op-btn-primary rounded-none w-[40px] h-full flex justify-center items-center`}
>
<i className={item.icon}></i>
</div>
</div>
@@ -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 {
+4 -1
View File
@@ -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) {
+320 -330
View File
@@ -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 && (
<div className="absolute h-[100vh] w-full flex flex-col justify-center items-center z-[999] bg-[#e6f2f2] bg-opacity-80">
<Loader />
<span className="text-[13px] font-bold">
<span style={{ fontSize: "13px", fontWeight: "bold" }}>
This might take some time
</span>
</div>
@@ -1410,7 +1398,6 @@ function PdfRequestFiles() {
</div>
)}
<div
className="relative op-card overflow-hidden flex flex-col md:flex-row justify-between bg-base-300"
style={{
pointerEvents:
isExpired ||
@@ -1418,7 +1405,9 @@ function PdfRequestFiles() {
? "none"
: "auto"
}}
ref={divRef}
className=" min-h-screen
relative op-card overflow-hidden flex flex-col md:flex-row justify-between bg-base-300
"
>
{!requestSignTour && requestSignTourFunction()}
<ModalUi
@@ -1435,9 +1424,12 @@ function PdfRequestFiles() {
<p>{isAlert.alertMessage}</p>
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
<button
onClick={() =>
setIsAlert({ isShow: false, alertMessage: "" })
}
onClick={() => {
setIsAlert({
isShow: false,
alertMessage: ""
});
}}
type="button"
className="op-btn op-btn-primary"
>
@@ -1495,9 +1487,12 @@ function PdfRequestFiles() {
<ModalUi
isOpen={defaultSignAlert.isShow}
title={"Auto sign"}
handleClose={() =>
setDefaultSignAlert({ isShow: false, alertMessage: "" })
}
handleClose={() => {
setDefaultSignAlert({
isShow: false,
alertMessage: ""
});
}}
>
<div className="h-full p-[20px]">
<p>{defaultSignAlert.alertMessage}</p>
@@ -1512,12 +1507,12 @@ function PdfRequestFiles() {
Yes
</button>
<button
onClick={() =>
onClick={() => {
setDefaultSignAlert({
isShow: false,
alertMessage: ""
})
}
});
}}
type="button"
className="op-btn op-btn-secondary"
>
@@ -1526,9 +1521,12 @@ function PdfRequestFiles() {
</>
) : (
<button
onClick={() =>
setIsAlert({ isShow: false, alertMessage: "" })
}
onClick={() => {
setIsAlert({
isShow: false,
alertMessage: ""
});
}}
type="button"
className="op-btn op-btn-primary"
>
@@ -1550,289 +1548,281 @@ function PdfRequestFiles() {
setPageNumber={setPageNumber}
pageNumber={pageNumber}
/>
{/* pdf render view */}
<div
style={{
marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px",
marginRight: !isMobile && pdfOriginalWidth > 500 && "20px"
}}
>
{/* this modal is used show this document is already sign */}
<ModalUi
isOpen={isCompleted.isModal}
title={"Document signed"}
handleClose={() => {
setIsCompleted((prev) => ({ ...prev, isModal: false }));
}}
reduceWidth={
!isCompleted?.message &&
"md:min-w-[440px] md:max-w-[400px]"
}
>
<div className="h-full p-[20px] text-base-content">
{isCompleted?.message ? (
<p>{isCompleted?.message}</p>
) : (
<div className="px-[15px]">
<span>
Congratulations! 🎉 This document has been
successfully signed by all participants!
</span>
</div>
)}
{!isCompleted?.message && (
<div className="flex mt-4 gap-1 px-[15px]">
<button
type="button"
onClick={() =>
handleDownloadCertificate(
pdfDetails,
setIsDownloading
)
}
className="font-[500] text-[13px] mr-[5px] op-btn op-btn-secondary"
>
<i
className="fa-solid fa-award"
aria-hidden="true"
></i>
<span className="hidden lg:block">Certificate</span>
</button>
<button
onClick={(e) =>
handleToPrint(e, pdfUrl, setIsDownloading)
}
type="button"
className="font-[500] text-[13px] mr-[5px] op-btn op-btn-neutral"
>
<i className="fa fa-print" aria-hidden="true"></i>
<span className="hidden lg:block">Print</span>
</button>
<button
type="button"
className="font-[500] text-[13px] mr-[5px] op-btn op-btn-primary"
onClick={() =>
handleDownloadPdf(
pdfDetails,
pdfUrl,
setIsDownloading
)
}
>
<i
className="fa fa-download"
aria-hidden="true"
></i>
<span className="hidden lg:block">Download</span>
</button>
</div>
)}
</div>
</ModalUi>
{isDownloading === "pdf" && (
<div className="fixed z-[1000] inset-0 flex justify-center items-center bg-black bg-opacity-30">
<Loader />
</div>
)}
<ModalUi
isOpen={isDownloading === "certificate"}
title={
isDownloading === "certificate"
? "Generating certificate"
: "PDF Download"
}
handleClose={() => setIsDownloading("")}
>
<div className="p-3 md:p-5 text-[13px] md:text-base text-center">
{isDownloading === "certificate"}{" "}
<p>
Your completion certificate is being generated. Please
wait momentarily.
</p>
<p>
If the download doesn&apos;t start shortly, click the
button again.
</p>
</div>
</ModalUi>
{/* this component is used for signature pad modal */}
<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}
currWidgetsDetails={currWidgetsDetails}
setCurrWidgetsDetails={setCurrWidgetsDetails}
<div className="min-h-screen w-full md:w-[57%] md:flex md:mr-4">
<PdfZoom
setScale={setScale}
scale={scale}
pdfOriginalWH={pdfOriginalWH}
containerWH={containerWH}
setZoomPercent={setZoomPercent}
zoomPercent={zoomPercent}
/>
{/* pdf header which contain funish back button */}
<Header
isPdfRequestFiles={true}
pageNumber={pageNumber}
allPages={allPages}
changePage={changePage}
pdfDetails={pdfDetails}
signerPos={signerPos}
isSigned={isSigned}
isCompleted={isCompleted.isCertificate}
embedWidgetsData={embedWidgetsData}
isShowHeader={true}
setIsDecline={setIsDecline}
decline={true}
currentSigner={currentSigner}
pdfUrl={pdfUrl}
alreadySign={alreadySign}
/>
{containerWH && (
<RenderPdf
pageNumber={pageNumber}
pdfOriginalWidth={pdfOriginalWidth}
pdfNewWidth={pdfNewWidth}
<div className="min-h-screen w-full md:w-[97%] ">
{/* this modal is used show this document is already sign */}
<ModalUi
isOpen={isCompleted.isModal}
title={"Document signed"}
handleClose={() => {
setIsCompleted((prev) => ({ ...prev, isModal: false }));
}}
reduceWidth={
!isCompleted?.message &&
"md:min-w-[440px] md:max-w-[400px]"
}
>
<div className="h-full p-[20px] text-base-content">
{isCompleted?.message ? (
<p>{isCompleted?.message}</p>
) : (
<div className="px-[15px]">
<span>
Congratulations! 🎉 This document has been
successfully signed by all participants!
</span>
</div>
)}
{!isCompleted?.message && (
<div className="flex mt-4 gap-1 px-[15px]">
<button
type="button"
onClick={() =>
handleDownloadCertificate(
pdfDetails,
setIsDownloading
)
}
className="font-[500] text-[13px] mr-[5px] op-btn op-btn-secondary"
>
<i
className="fa-solid fa-award"
aria-hidden="true"
></i>
<span className="hidden lg:block">
Certificate
</span>
</button>
<button
onClick={(e) =>
handleToPrint(e, pdfUrl, setIsDownloading)
}
type="button"
className="font-[500] text-[13px] mr-[5px] op-btn op-btn-neutral"
>
<i className="fa fa-print" aria-hidden="true"></i>
<span className="hidden lg:block">Print</span>
</button>
<button
type="button"
className="font-[500] text-[13px] mr-[5px] op-btn op-btn-primary"
onClick={() =>
handleDownloadPdf(
pdfDetails,
pdfUrl,
setIsDownloading
)
}
>
<i
className="fa fa-download"
aria-hidden="true"
></i>
<span className="hidden lg:block">Download</span>
</button>
</div>
)}
</div>
</ModalUi>
{isDownloading === "pdf" && (
<div className="fixed z-[1000] inset-0 flex justify-center items-center bg-black bg-opacity-30">
<Loader />
</div>
)}
<ModalUi
isOpen={isDownloading === "certificate"}
title={
isDownloading === "certificate"
? "Generating certificate"
: "PDF Download"
}
handleClose={() => setIsDownloading("")}
>
<div className="p-3 md:p-5 text-[13px] md:text-base text-center">
{isDownloading === "certificate"}{" "}
<p>
Your completion certificate is being generated. Please
wait momentarily.
</p>
<p>
If the download doesn&apos;t start shortly, click the
button again.
</p>
</div>
</ModalUi>
{/* this component is used for signature pad modal */}
<SignPad
isSignPad={isSignPad}
isStamp={isStamp}
setIsImageSelect={setIsImageSelect}
setIsSignPad={setIsSignPad}
setIsStamp={setIsStamp}
setSignKey={setSignKey}
pdfDetails={pdfDetails}
signerPos={signerPos}
successEmail={false}
pdfUrl={pdfUrl}
numPages={numPages}
pageDetails={pageDetails}
pdfRequest={true}
signerObjectId={signerObjectId}
signedSigners={signedSigners}
setCurrentSigner={setCurrentSigner}
setPdfLoadFail={setPdfLoadFail}
pdfLoadFail={pdfLoadFail}
setSignerPos={setSignerPos}
containerWH={containerWH}
setImage={setImage}
isImageSelect={isImageSelect}
imageRef={imageRef}
onImageChange={onImageChange}
setSignature={setSignature}
image={image}
onSaveImage={saveImage}
onSaveSign={saveSign}
defaultSign={defaultSignImg}
myInitial={myInitial}
isInitial={isInitial}
setIsInitial={setIsInitial}
setValidateAlert={setValidateAlert}
unSignedWidgetId={unSignedWidgetId}
setSelectWidgetId={setSelectWidgetId}
selectWidgetId={selectWidgetId}
setIsStamp={setIsStamp}
currWidgetsDetails={currWidgetsDetails}
setCurrWidgetsDetails={setCurrWidgetsDetails}
/>
)}
</div>
<div>
<div className="hidden md:block w-[180px] h-full bg-base-100">
{/* pdf header which contain funish back button */}
<Header
isPdfRequestFiles={true}
pageNumber={pageNumber}
allPages={allPages}
changePage={changePage}
pdfDetails={pdfDetails}
signerPos={signerPos}
isSigned={isSigned}
isCompleted={isCompleted.isCertificate}
embedWidgetsData={embedWidgetsData}
isShowHeader={true}
setIsDecline={setIsDecline}
decline={true}
currentSigner={currentSigner}
pdfUrl={pdfUrl}
alreadySign={alreadySign}
totalZoomPercent={totalZoomPercent}
setTotalZoomPercent={setTotalZoomPercent}
setScale={setScale}
scale={scale}
pdfOriginalWH={pdfOriginalWH}
containerWH={containerWH}
setZoomPercent={setZoomPercent}
zoomPercent={zoomPercent}
/>
<div
style={{ maxHeight: window.innerHeight - 70 + "px" }}
className="overflow-y-auto hide-scrollbar"
ref={divRef}
data-tut="reactourSecond"
className="h-[95%] 2xl:mt-[6px] mt-[3px]"
>
{signedSigners.length > 0 && (
<div data-tut="reactourSecond">
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
Signed by
</div>
<div className="mt-[2px]">
{signedSigners.map((obj, ind) => {
return (
<div
className="rounded-xl mx-1 flex flex-row items-center py-[10px] mt-1"
style={{
background: checkSignerBackColor(obj)
}}
key={ind}
>
<div
className="flex w-[30px] h-[30px] rounded-full justify-center items-center mx-1"
style={{
background: checkUserNameColor(obj)
}}
>
<span className="text-[12px] text-center font-bold text-white uppercase">
{getFirstLetter(obj?.Name || obj?.Role)}
</span>
</div>
<div className="flex flex-col">
<span className="userName">
{obj?.Name || obj?.Role}
</span>
<span className="useEmail">
{obj?.Email || obj?.email}
</span>
</div>
</div>
);
})}
</div>
</div>
)}
{unsignedSigners.length > 0 && (
<div data-tut="reactourFirst">
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
Yet to sign
</div>
<div className="mt-[5px]">
{unsignedSigners.map((obj, ind) => {
return (
<div
className="rounded-xl mx-1 flex flex-row items-center py-[10px] mt-1"
style={{
background: checkSignerBackColor(obj)
}}
key={ind}
>
<div
className="flex w-[30px] h-[30px] rounded-full justify-center items-center mx-1"
style={{
background: checkUserNameColor(obj)
}}
>
<span className="text-[12px] text-center font-bold text-black uppercase">
{getFirstLetter(obj?.Name || obj?.email)}
</span>
</div>
<div className="flex flex-col">
<span className="userName">
{obj?.Name || obj?.Role}
</span>
<span className="useEmail">
{obj?.Email || obj?.email}
</span>
</div>
<hr />
</div>
);
})}
</div>
</div>
)}
{defaultSignImg && !alreadySign && (
<DefaultSignature
defaultSignImg={defaultSignImg}
setDefaultSignImg={setDefaultSignImg}
userObjectId={signerObjectId}
setIsLoading={setIsLoading}
xyPostion={signerPos}
setDefaultSignAlert={setDefaultSignAlert}
{containerWH && (
<RenderPdf
pageNumber={pageNumber}
pdfOriginalWH={pdfOriginalWH}
pdfNewWidth={pdfNewWidth}
setIsSignPad={setIsSignPad}
setIsStamp={setIsStamp}
setSignKey={setSignKey}
pdfDetails={pdfDetails}
signerPos={signerPos}
successEmail={false}
pdfUrl={pdfUrl}
numPages={numPages}
pageDetails={pageDetails}
pdfRequest={true}
signerObjectId={signerObjectId}
signedSigners={signedSigners}
setCurrentSigner={setCurrentSigner}
setPdfLoadFail={setPdfLoadFail}
pdfLoadFail={pdfLoadFail}
setSignerPos={setSignerPos}
containerWH={containerWH}
setIsInitial={setIsInitial}
setValidateAlert={setValidateAlert}
unSignedWidgetId={unSignedWidgetId}
setSelectWidgetId={setSelectWidgetId}
selectWidgetId={selectWidgetId}
setCurrWidgetsDetails={setCurrWidgetsDetails}
divRef={divRef}
setPdfRenderHeight={setPdfRenderHeight}
pdfRenderHeight={pdfRenderHeight}
setIsResize={setIsResize}
isResize={isResize}
setTotalZoomPercent={setTotalZoomPercent}
setScale={setScale}
scale={scale}
/>
)}
</div>
</div>
</div>
{/* <div className="signerComponent"> */}
<div
className={`w-[23%] bg-[#FFFFFF] min-h-screen overflow-y-auto hide-scrollbar hidden md:inline-block`}
>
<div className={`max-h-screen`}>
{signedSigners.length > 0 && (
<>
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
<span> Signed by</span>
</div>
<div className="mt-[2px]">
{signedSigners.map((obj, ind) => {
return (
<div key={ind}>
<SignerListComponent
ind={ind}
obj={obj}
isMenu={isHeader}
signerPos={signerPos}
/>
</div>
);
})}
</div>
</>
)}
{unsignedSigners.length > 0 && (
<>
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
<span>Yet to sign</span>
</div>
<div className="mt-[5px]">
{unsignedSigners.map((obj, ind) => {
return (
<div key={ind}>
<SignerListComponent
ind={ind}
obj={obj}
isMenu={isHeader}
signerPos={signerPos}
/>
</div>
);
})}
</div>
</>
)}
{defaultSignImg && !alreadySign && currentSigner && (
<DefaultSignature
defaultSignImg={defaultSignImg}
setDefaultSignImg={setDefaultSignImg}
userObjectId={signerObjectId}
setIsLoading={setIsLoading}
xyPostion={signerPos}
setDefaultSignAlert={setDefaultSignAlert}
/>
)}
</div>
</div>
</div>
</div>
)}
<ModalUi
isOpen={validateAlert}
title={"Validation alert"}
handleClose={() => setValidateAlert(false)}
handleClose={() => {
setValidateAlert(false);
}}
>
<div className="h-[100%] p-[20px]">
<p>
File diff suppressed because it is too large Load Diff
+327 -245
View File
@@ -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>
);
}
+363 -262
View File
@@ -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>
);
};
+3 -1
View File
@@ -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
});
@@ -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;
+3 -1
View File
@@ -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
}
});
+19 -13
View File
@@ -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 */