mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-17 21:25:54 +02:00
1653 lines
56 KiB
JavaScript
1653 lines
56 KiB
JavaScript
import React, { useState, useRef, useEffect } from "react";
|
|
import axios from "axios";
|
|
import Parse from "parse";
|
|
import "../css/./signature.css";
|
|
import { PDFDocument } from "pdf-lib";
|
|
import { themeColor } from "../utils/ThemeColor/backColor";
|
|
import { DndProvider } from "react-dnd";
|
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
|
import { useDrag, useDrop } from "react-dnd";
|
|
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
|
import FieldsComponent from "./component/fieldsComponent";
|
|
import Tour from "reactour";
|
|
import loader from "../assests/loader2.gif";
|
|
import { useLocation, useParams } from "react-router-dom";
|
|
import Loader from "./component/loader";
|
|
import HandleError from "./component/HandleError";
|
|
import Nodata from "./component/Nodata";
|
|
import SignerListPlace from "./component/signerListPlace";
|
|
import Header from "./component/header";
|
|
import {
|
|
pdfNewWidthFun,
|
|
contractDocument,
|
|
contractUsers,
|
|
getHostUrl,
|
|
addZIndex,
|
|
randomId,
|
|
defaultWidthHeight,
|
|
multiSignEmbed,
|
|
addWidgetOptions
|
|
} from "../utils/Utils";
|
|
import RenderPdf from "./component/renderPdf";
|
|
import { useNavigate } from "react-router-dom";
|
|
import PlaceholderCopy from "./component/PlaceholderCopy";
|
|
import LinkUserModal from "./component/LinkUserModal";
|
|
import Title from "./component/Title";
|
|
import TourContentWithBtn from "../premitives/TourContentWithBtn";
|
|
import ModalUi from "../premitives/ModalUi";
|
|
import DropdownWidgetOption from "../Component/WidgetComponent/dropdownWidgetOption";
|
|
import InputValidation from "./WidgetComponent/inputValidation";
|
|
|
|
function PlaceHolderSign() {
|
|
const navigate = useNavigate();
|
|
const { state } = useLocation();
|
|
const [pdfDetails, setPdfDetails] = useState([]);
|
|
const [isMailSend, setIsMailSend] = useState(false);
|
|
const [allPages, setAllPages] = useState(null);
|
|
const numPages = 1;
|
|
const [pageNumber, setPageNumber] = useState(1);
|
|
const [signBtnPosition, setSignBtnPosition] = useState([]);
|
|
const [xySignature, setXYSignature] = useState({});
|
|
const [dragKey, setDragKey] = useState();
|
|
const [signersdata, setSignersData] = useState();
|
|
const [signerObjId, setSignerObjId] = useState();
|
|
const [signerPos, setSignerPos] = useState([]);
|
|
const [isSelectListId, setIsSelectId] = useState();
|
|
const [isSendAlert, setIsSendAlert] = useState({});
|
|
const [isSend, setIsSend] = useState(false);
|
|
const [isLoading, setIsLoading] = useState({
|
|
isLoad: true,
|
|
message: "This might take some time"
|
|
});
|
|
const [handleError, setHandleError] = useState();
|
|
const [currentId, setCurrentId] = useState("");
|
|
const [pdfNewWidth, setPdfNewWidth] = useState();
|
|
const [placeholderTour, setPlaceholderTour] = useState(true);
|
|
const [checkTourStatus, setCheckTourStatus] = useState(false);
|
|
const [tourStatus, setTourStatus] = useState([]);
|
|
const [signerUserId, setSignerUserId] = useState();
|
|
const [noData, setNoData] = useState(false);
|
|
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
|
const [contractName, setContractName] = useState("");
|
|
const [containerWH, setContainerWH] = useState();
|
|
const { docId } = useParams();
|
|
const signRef = useRef(null);
|
|
const dragRef = useRef(null);
|
|
const divRef = useRef(null);
|
|
const [isShowEmail, setIsShowEmail] = useState(false);
|
|
const [selectedEmail, setSelectedEmail] = useState(false);
|
|
const [isResize, setIsResize] = useState(false);
|
|
const [zIndex, setZIndex] = useState(1);
|
|
const [signKey, setSignKey] = useState();
|
|
const [pdfLoadFail, setPdfLoadFail] = useState({
|
|
status: false,
|
|
type: "load"
|
|
});
|
|
const [isPageCopy, setIsPageCopy] = useState(false);
|
|
const [uniqueId, setUniqueId] = useState("");
|
|
const [roleName, setRoleName] = useState("");
|
|
const [isAddUser, setIsAddUser] = useState({});
|
|
const [signerExistModal, setSignerExistModal] = useState(false);
|
|
const [isDontShow, setIsDontShow] = useState(false);
|
|
const [isDragging, setIsDragging] = useState(false);
|
|
const [showDropdown, setShowDropdown] = useState(false);
|
|
const [isValidate, setIsValidate] = useState(false);
|
|
const [textValidate, setTextValidate] = useState("");
|
|
const [widgetType, setWidgetType] = useState("");
|
|
const [isUiLoading, setIsUiLoading] = useState(false);
|
|
const [isRadio, setIsRadio] = useState(false);
|
|
const [currWidgetsDetails, setCurrWidgetsDetails] = useState([]);
|
|
const [selectWidgetId, setSelectWidgetId] = useState("");
|
|
const [isCheckbox, setIsCheckbox] = useState(false);
|
|
const [hint, setHint] = useState("");
|
|
const color = [
|
|
"#93a3db",
|
|
"#e6c3db",
|
|
"#c0e3bc",
|
|
"#bce3db",
|
|
"#b8ccdb",
|
|
"#ceb8db",
|
|
"#ffccff",
|
|
"#99ffcc",
|
|
"#cc99ff",
|
|
"#ffcc99",
|
|
"#66ccff",
|
|
"#ffffcc"
|
|
];
|
|
|
|
const isMobile = window.innerWidth < 767;
|
|
const [{ isOver }, drop] = useDrop({
|
|
accept: "BOX",
|
|
drop: (item, monitor) => addPositionOfSignature(item, monitor),
|
|
collect: (monitor) => ({
|
|
isOver: !!monitor.isOver()
|
|
})
|
|
});
|
|
|
|
const [{ isDragSign }, dragSignature] = useDrag({
|
|
type: "BOX",
|
|
item: {
|
|
type: "BOX",
|
|
id: 1,
|
|
text: "signature"
|
|
},
|
|
|
|
collect: (monitor) => ({
|
|
isDragSign: !!monitor.isDragging()
|
|
})
|
|
});
|
|
const [{ isDragStamp }, dragStamp] = useDrag({
|
|
type: "BOX",
|
|
item: {
|
|
type: "BOX",
|
|
id: 2,
|
|
text: "stamp"
|
|
},
|
|
|
|
collect: (monitor) => ({
|
|
isDragStamp: !!monitor.isDragging()
|
|
})
|
|
});
|
|
|
|
const rowLevel =
|
|
localStorage.getItem("rowlevel") &&
|
|
JSON.parse(localStorage.getItem("rowlevel"));
|
|
const objectId =
|
|
rowLevel && rowLevel.id
|
|
? rowLevel.id
|
|
: rowLevel?.objectId && rowLevel.objectId;
|
|
|
|
const documentId = docId ? docId : objectId && objectId;
|
|
const senderUser =
|
|
localStorage.getItem(
|
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
|
) &&
|
|
localStorage.getItem(
|
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
|
);
|
|
const jsonSender = JSON.parse(senderUser);
|
|
|
|
useEffect(() => {
|
|
if (documentId) {
|
|
getDocumentDetails();
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (divRef.current) {
|
|
const pdfWidth = pdfNewWidthFun(divRef);
|
|
setPdfNewWidth(pdfWidth);
|
|
setContainerWH({
|
|
width: divRef.current.offsetWidth,
|
|
height: divRef.current.offsetHeight
|
|
});
|
|
}
|
|
}, [divRef.current]);
|
|
|
|
//function for get document details
|
|
const getDocumentDetails = async () => {
|
|
//getting document details
|
|
const documentData = await contractDocument(documentId);
|
|
if (documentData && documentData.length > 0) {
|
|
// const alreadyPlaceholder =
|
|
// documentData[0].Placeholders && documentData[0].Placeholders;
|
|
// if (alreadyPlaceholder && alreadyPlaceholder.length > 0) {
|
|
// setIsAlreadyPlace(true);
|
|
// }
|
|
// setSignersData(documentData[0]);
|
|
// setIsSelectId(0);
|
|
// setSignerObjId(documentData[0].Signers[0].objectId);
|
|
// setContractName(documentData[0].Signers[0].className);
|
|
setPdfDetails(documentData);
|
|
|
|
if (documentData[0].Signers && documentData[0].Signers.length > 0) {
|
|
const currEmail = documentData[0].ExtUserPtr.Email;
|
|
setCurrentId(currEmail);
|
|
setSignerObjId(documentData[0].Signers[0].objectId);
|
|
setContractName(documentData[0].Signers[0].className);
|
|
setIsSelectId(0);
|
|
if (
|
|
documentData[0].Placeholders &&
|
|
documentData[0].Placeholders.length > 0
|
|
) {
|
|
setSignerPos(documentData[0].Placeholders);
|
|
let signers = [...documentData[0].Signers];
|
|
let updatedSigners = documentData[0].Placeholders.map((x) => {
|
|
let matchingSigner = signers.find(
|
|
(y) => x.signerObjId && x.signerObjId === y.objectId
|
|
);
|
|
|
|
if (matchingSigner) {
|
|
return {
|
|
...matchingSigner,
|
|
Role: x.Role ? x.Role : matchingSigner.Role,
|
|
Id: x.Id,
|
|
blockColor: x.blockColor
|
|
};
|
|
} else {
|
|
return {
|
|
Role: x.Role,
|
|
Id: x.Id,
|
|
blockColor: x.blockColor
|
|
};
|
|
}
|
|
});
|
|
setSignersData(updatedSigners);
|
|
setUniqueId(updatedSigners[0].Id);
|
|
} else {
|
|
const updatedSigners = documentData[0].Signers.map((x, index) => ({
|
|
...x,
|
|
Id: randomId(),
|
|
Role: "User " + (index + 1)
|
|
}));
|
|
setSignersData(updatedSigners);
|
|
setUniqueId(updatedSigners[0].Id);
|
|
}
|
|
} else {
|
|
setRoleName("User 1");
|
|
if (
|
|
documentData[0].Placeholders &&
|
|
documentData[0].Placeholders.length > 0
|
|
) {
|
|
let updatedSigners = documentData[0].Placeholders.map((x) => {
|
|
return {
|
|
Role: x.Role,
|
|
Id: x.Id,
|
|
blockColor: x.blockColor
|
|
};
|
|
});
|
|
|
|
setSignerPos(documentData[0].Placeholders);
|
|
setSignersData(updatedSigners);
|
|
setIsSelectId(0);
|
|
setUniqueId(updatedSigners[0].Id);
|
|
}
|
|
}
|
|
} else if (
|
|
documentData === "Error: Something went wrong!" ||
|
|
(documentData.result && documentData.result.error)
|
|
) {
|
|
const loadObj = {
|
|
isLoad: false
|
|
};
|
|
setHandleError("Error: Something went wrong!");
|
|
setIsLoading(loadObj);
|
|
} else {
|
|
setNoData(true);
|
|
|
|
const loadObj = {
|
|
isLoad: false
|
|
};
|
|
setIsLoading(loadObj);
|
|
}
|
|
const res = await contractUsers(jsonSender.email);
|
|
if (res[0] && res.length) {
|
|
setSignerUserId(res[0].objectId);
|
|
const tourstatus = res[0].TourStatus && res[0].TourStatus;
|
|
if (tourstatus && tourstatus.length > 0) {
|
|
setTourStatus(tourstatus);
|
|
const checkTourRecipients = tourstatus.filter(
|
|
(data) => data.placeholder
|
|
);
|
|
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
|
setCheckTourStatus(checkTourRecipients[0].placeholder);
|
|
}
|
|
}
|
|
const loadObj = {
|
|
isLoad: false
|
|
};
|
|
setIsLoading(loadObj);
|
|
} else if (res === "Error: Something went wrong!") {
|
|
const loadObj = {
|
|
isLoad: false
|
|
};
|
|
setHandleError("Error: Something went wrong!");
|
|
setIsLoading(loadObj);
|
|
} else if (res.length === 0) {
|
|
setNoData(true);
|
|
|
|
const loadObj = {
|
|
isLoad: false
|
|
};
|
|
setIsLoading(loadObj);
|
|
}
|
|
};
|
|
|
|
//function for setting position after drop signature button over pdf
|
|
const addPositionOfSignature = (item, monitor) => {
|
|
getSignerPos(item, monitor);
|
|
};
|
|
|
|
const getSignerPos = (item, monitor) => {
|
|
// setSignerObjId("");
|
|
// setContractName("");
|
|
if (uniqueId) {
|
|
const posZIndex = zIndex + 1;
|
|
setZIndex(posZIndex);
|
|
const signer = signersdata.find((x) => x.Id === uniqueId);
|
|
const newWidth = containerWH.width;
|
|
const scale = pdfOriginalWidth / newWidth;
|
|
const key = randomId();
|
|
let dropData = [];
|
|
let placeHolder;
|
|
const dragTypeValue = item?.text ? item.text : monitor.type;
|
|
|
|
if (item === "onclick") {
|
|
const dropObj = {
|
|
//onclick put placeholder center on pdf
|
|
xPosition: window.innerWidth / 2 - 150,
|
|
yPosition: window.innerHeight / 2 - 60,
|
|
isStamp:
|
|
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
|
|
key: key,
|
|
isDrag: false,
|
|
scale: scale,
|
|
isMobile: isMobile,
|
|
zIndex: posZIndex,
|
|
type: dragTypeValue,
|
|
options: addWidgetOptions(dragTypeValue)
|
|
};
|
|
dropData.push(dropObj);
|
|
placeHolder = {
|
|
pageNumber: pageNumber,
|
|
pos: dropData
|
|
};
|
|
} else {
|
|
const offset = monitor.getClientOffset();
|
|
//adding and updating drop position in array when user drop signature button in div
|
|
const containerRect = document
|
|
.getElementById("container")
|
|
.getBoundingClientRect();
|
|
const x = offset.x - containerRect.left;
|
|
const y = offset.y - containerRect.top;
|
|
const dropObj = {
|
|
xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x,
|
|
yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y,
|
|
isStamp:
|
|
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
|
|
key: key,
|
|
scale: scale,
|
|
isMobile: isMobile,
|
|
zIndex: posZIndex,
|
|
type: dragTypeValue,
|
|
options: addWidgetOptions(dragTypeValue)
|
|
};
|
|
|
|
dropData.push(dropObj);
|
|
placeHolder = {
|
|
pageNumber: pageNumber,
|
|
pos: dropData
|
|
};
|
|
}
|
|
|
|
setSelectWidgetId(key);
|
|
if (signer) {
|
|
let filterSignerPos;
|
|
if (dragTypeValue === "label") {
|
|
filterSignerPos = signerPos.filter((data) => data.Role === "prefill");
|
|
} else {
|
|
filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
|
}
|
|
|
|
const { blockColor, Role } = signer;
|
|
|
|
//adding placholder in existing signer pos array (placaholder)
|
|
if (filterSignerPos.length > 0) {
|
|
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
|
const updatePlace = getPlaceHolder.filter(
|
|
(data) => data.pageNumber !== pageNumber
|
|
);
|
|
const getPageNumer = getPlaceHolder.filter(
|
|
(data) => data.pageNumber === pageNumber
|
|
);
|
|
|
|
//add entry of position for same signer on multiple page
|
|
if (getPageNumer.length > 0) {
|
|
const getPos = getPageNumer[0].pos;
|
|
const newSignPos = getPos.concat(dropData);
|
|
let xyPos = {
|
|
pageNumber: pageNumber,
|
|
pos: newSignPos
|
|
};
|
|
updatePlace.push(xyPos);
|
|
let updatesignerPos;
|
|
if (dragTypeValue === "label") {
|
|
updatesignerPos = signerPos.map((x) =>
|
|
x.Role === "prefill" ? { ...x, placeHolder: updatePlace } : x
|
|
);
|
|
} else {
|
|
updatesignerPos = signerPos.map((x) =>
|
|
x.Id === uniqueId ? { ...x, placeHolder: updatePlace } : x
|
|
);
|
|
}
|
|
|
|
setSignerPos(updatesignerPos);
|
|
} else {
|
|
let updatesignerPos;
|
|
if (dragTypeValue === "label") {
|
|
updatesignerPos = signerPos.map((x) =>
|
|
x.Role === "prefill"
|
|
? { ...x, placeHolder: [...x.placeHolder, placeHolder] }
|
|
: x
|
|
);
|
|
} else {
|
|
updatesignerPos = signerPos.map((x) =>
|
|
x.Id === uniqueId
|
|
? { ...x, placeHolder: [...x.placeHolder, placeHolder] }
|
|
: x
|
|
);
|
|
}
|
|
setSignerPos(updatesignerPos);
|
|
}
|
|
} else {
|
|
//adding new placeholder for selected signer in pos array (placeholder)
|
|
// const signerData = signerPos;
|
|
let placeHolderPos;
|
|
if (dragTypeValue === "label") {
|
|
placeHolderPos = {
|
|
signerPtr: {},
|
|
signerObjId: "",
|
|
blockColor: "#f58f8c",
|
|
placeHolder: [placeHolder],
|
|
Role: "prefill",
|
|
Id: key
|
|
};
|
|
} else {
|
|
if (contractName) {
|
|
placeHolderPos = {
|
|
signerPtr: {
|
|
__type: "Pointer",
|
|
className: `${contractName}`,
|
|
objectId: signerObjId
|
|
},
|
|
signerObjId: signerObjId,
|
|
blockColor: blockColor ? blockColor : color[isSelectListId],
|
|
placeHolder: [placeHolder],
|
|
Role: Role ? Role : roleName,
|
|
Id: uniqueId
|
|
};
|
|
} else {
|
|
placeHolderPos = {
|
|
signerPtr: {},
|
|
signerObjId: "",
|
|
blockColor: blockColor ? blockColor : color[isSelectListId],
|
|
placeHolder: [placeHolder],
|
|
Role: Role ? Role : roleName,
|
|
Id: uniqueId
|
|
};
|
|
}
|
|
}
|
|
setSignerPos((prev) => [...prev, placeHolderPos]);
|
|
}
|
|
if (dragTypeValue === "dropdown") {
|
|
setShowDropdown(true);
|
|
} else if (dragTypeValue === "checkbox") {
|
|
setIsCheckbox(true);
|
|
} else if (dragTypeValue === "radio") {
|
|
setIsRadio(true);
|
|
}
|
|
setWidgetType(dragTypeValue);
|
|
setSignKey(key);
|
|
}
|
|
}
|
|
};
|
|
|
|
//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);
|
|
});
|
|
};
|
|
|
|
//function for save x and y position and show signature tab on that position
|
|
const handleTabDrag = (key, signerId) => {
|
|
setDragKey(key);
|
|
setIsDragging(true);
|
|
};
|
|
|
|
//function for set and update x and y postion after drag and drop signature tab
|
|
const handleStop = (event, dragElement, signerId, key) => {
|
|
if (!isResize && isDragging) {
|
|
const dataNewPlace = addZIndex(signerPos, key, setZIndex);
|
|
let updateSignPos = [...signerPos];
|
|
updateSignPos.splice(0, updateSignPos.length, ...dataNewPlace);
|
|
// signerPos.splice(0, signerPos.length, ...dataNewPlace);
|
|
const containerRect = document
|
|
.getElementById("container")
|
|
.getBoundingClientRect();
|
|
const signId = signerId ? signerId : uniqueId; //? signerId : signerObjId;
|
|
const keyValue = key ? key : dragKey;
|
|
const ybottom = containerRect.height - dragElement.y;
|
|
|
|
if (keyValue >= 0) {
|
|
let filterSignerPos;
|
|
if (signId) {
|
|
filterSignerPos = updateSignPos.filter((data) => data.Id === signId);
|
|
} else {
|
|
filterSignerPos = updateSignPos.filter(
|
|
(data) => data.Role === "prefill"
|
|
);
|
|
}
|
|
|
|
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((url, ind) => {
|
|
if (url.key === keyValue) {
|
|
return {
|
|
...url,
|
|
xPosition: dragElement.x,
|
|
yPosition: dragElement.y,
|
|
isDrag: true,
|
|
yBottom: ybottom
|
|
};
|
|
}
|
|
return url;
|
|
});
|
|
|
|
const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
|
|
if (obj.pageNumber === pageNumber) {
|
|
return { ...obj, pos: addSignPos };
|
|
}
|
|
return obj;
|
|
});
|
|
const newUpdateSigner = updateSignPos.map((obj, ind) => {
|
|
if (signId) {
|
|
if (obj.Id === signId) {
|
|
return { ...obj, placeHolder: newUpdateSignPos };
|
|
}
|
|
} else {
|
|
if (obj.Role === "prefill") {
|
|
return { ...obj, placeHolder: newUpdateSignPos };
|
|
}
|
|
}
|
|
|
|
return obj;
|
|
});
|
|
|
|
setSignerPos(newUpdateSigner);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
setTimeout(() => {
|
|
setIsDragging(false);
|
|
}, 200);
|
|
};
|
|
|
|
//function for delete signature block
|
|
const handleDeleteSign = (key, Id) => {
|
|
const updateData = [];
|
|
const filterSignerPos = signerPos.filter((data) => data.Id === Id);
|
|
|
|
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.filter(
|
|
(data, ind) => data.key !== key
|
|
);
|
|
|
|
if (getXYdata.length > 0) {
|
|
updateData.push(getXYdata);
|
|
const newUpdatePos = getPlaceHolder.map((obj, ind) => {
|
|
if (obj.pageNumber === pageNumber) {
|
|
return { ...obj, pos: updateData[0] };
|
|
}
|
|
return obj;
|
|
});
|
|
|
|
const newUpdateSigner = signerPos.map((obj, ind) => {
|
|
if (obj.Id === Id) {
|
|
return { ...obj, placeHolder: newUpdatePos };
|
|
}
|
|
return obj;
|
|
});
|
|
setSignerPos(newUpdateSigner);
|
|
} else {
|
|
const updateFilter = signerPos.filter((data) => data.Id !== Id);
|
|
const getRemainPage = filterSignerPos[0].placeHolder.filter(
|
|
(data) => data.pageNumber !== pageNumber
|
|
);
|
|
|
|
if (getRemainPage && getRemainPage.length > 0) {
|
|
const newUpdatePos = filterSignerPos.map((obj, ind) => {
|
|
if (obj.Id === Id) {
|
|
return { ...obj, placeHolder: getRemainPage };
|
|
}
|
|
return obj;
|
|
});
|
|
let signerupdate = [];
|
|
signerupdate = signerPos.filter((data) => data.Id !== Id);
|
|
signerupdate.push(newUpdatePos[0]);
|
|
|
|
setSignerPos(signerupdate);
|
|
} else {
|
|
setSignerPos(updateFilter);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//function for change page
|
|
function changePage(offset) {
|
|
setSignBtnPosition([]);
|
|
setPageNumber((prevPageNumber) => prevPageNumber + offset);
|
|
}
|
|
|
|
//function for capture position on hover signature button
|
|
const handleDivClick = (e) => {
|
|
const divRect = e.currentTarget.getBoundingClientRect();
|
|
const mouseX = e.clientX - divRect.left;
|
|
const mouseY = e.clientY - divRect.top;
|
|
|
|
const xyPosition = {
|
|
xPos: mouseX,
|
|
yPos: mouseY
|
|
};
|
|
|
|
setXYSignature(xyPosition);
|
|
};
|
|
|
|
//function for capture position of x and y on hover signature button last position
|
|
const handleMouseLeave = (e) => {
|
|
setSignBtnPosition([xySignature]);
|
|
};
|
|
|
|
function sanitizeFileName(fileName) {
|
|
// Remove spaces and invalid characters
|
|
return fileName.replace(/[^a-zA-Z0-9._-]/g, "");
|
|
}
|
|
//embed prefill label widget data
|
|
const embedPrefilllData = async () => {
|
|
const prefillExist = signerPos.filter((data) => data.Role === "prefill");
|
|
if (prefillExist && prefillExist.length > 0) {
|
|
const placeholder = prefillExist[0].placeHolder;
|
|
const pdfUrl = pdfDetails[0].URL;
|
|
const existingPdfBytes = await fetch(pdfUrl).then((res) =>
|
|
res.arrayBuffer()
|
|
);
|
|
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
|
ignoreEncryption: true
|
|
});
|
|
|
|
const flag = false;
|
|
try {
|
|
const pdfBytes = await multiSignEmbed(
|
|
placeholder,
|
|
pdfDoc,
|
|
pdfOriginalWidth,
|
|
flag,
|
|
containerWH
|
|
);
|
|
|
|
const parseBaseUrl = localStorage.getItem("baseUrl");
|
|
const parseAppId = localStorage.getItem("parseAppId");
|
|
Parse.initialize(parseAppId);
|
|
Parse.serverURL = parseBaseUrl;
|
|
Parse.initialize(parseAppId);
|
|
const fileName = sanitizeFileName(pdfDetails[0].Name) + ".pdf";
|
|
const pdfFile = new Parse.File(fileName, { base64: pdfBytes });
|
|
|
|
// Save the Parse File if needed
|
|
const pdfData = await pdfFile.save();
|
|
const pdfUrl = pdfData.url();
|
|
return pdfUrl;
|
|
} catch (e) {
|
|
console.log("error", e);
|
|
}
|
|
} else {
|
|
return pdfDetails[0].URL;
|
|
}
|
|
};
|
|
|
|
const alertSendEmail = async () => {
|
|
const filterPrefill = signerPos.filter((data) => data.Role !== "prefill");
|
|
if (filterPrefill.length === signersdata.length) {
|
|
const IsSignerNotExist = filterPrefill?.some((x) => !x.signerObjId);
|
|
if (IsSignerNotExist) {
|
|
setSignerExistModal(true);
|
|
} else {
|
|
const alert = {
|
|
mssg: "confirm",
|
|
alert: true
|
|
};
|
|
setIsSendAlert(alert);
|
|
}
|
|
} else {
|
|
const alert = {
|
|
mssg: "sure",
|
|
alert: true
|
|
};
|
|
setIsSendAlert(alert);
|
|
}
|
|
};
|
|
|
|
const sendEmailToSigners = async () => {
|
|
setIsUiLoading(true);
|
|
const pdfUrl = await embedPrefilllData();
|
|
setIsSendAlert({});
|
|
let sendMail;
|
|
const expireDate = pdfDetails?.[0].ExpiryDate.iso;
|
|
const newDate = new Date(expireDate);
|
|
const localExpireDate = newDate.toLocaleDateString("en-US", {
|
|
day: "numeric",
|
|
month: "long",
|
|
year: "numeric"
|
|
});
|
|
let sender = pdfDetails?.[0].ExtUserPtr.Email;
|
|
const signerMail = signersdata;
|
|
|
|
for (let i = 0; i < signerMail.length; i++) {
|
|
try {
|
|
const imgPng =
|
|
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
|
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3/`;
|
|
const headers = {
|
|
"Content-Type": "application/json",
|
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
sessionToken: localStorage.getItem("accesstoken")
|
|
};
|
|
const serverUrl = localStorage.getItem("baseUrl");
|
|
const newServer = serverUrl.replaceAll("/", "%2F");
|
|
const objectId = signerMail[i].objectId;
|
|
const serverParams = `${newServer}&${localStorage.getItem(
|
|
"parseAppId"
|
|
)}&${localStorage.getItem("_appName")}`;
|
|
|
|
const hostUrl = window.location.origin + "/loadmf/signmicroapp";
|
|
let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}/${serverParams}`;
|
|
const openSignUrl = "https://www.opensignlabs.com/";
|
|
const orgName = pdfDetails[0]?.ExtUserPtr.Company
|
|
? pdfDetails[0].ExtUserPtr.Company
|
|
: "";
|
|
const themeBGcolor = themeColor();
|
|
let params = {
|
|
recipient: signerMail[i].Email,
|
|
subject: `${pdfDetails?.[0].ExtUserPtr.Name} has requested you to sign ${pdfDetails?.[0].Name}`,
|
|
from: sender,
|
|
|
|
html:
|
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> </head> <body> <div style='background-color: #f5f5f5; padding: 20px'=> <div style=' box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background: white;padding-bottom: 20px;'> <div style='padding:10px 10px 0 10px'><img src=" +
|
|
imgPng +
|
|
" height='50' style='padding: 20px,width:170px,height:40px' /></div> <div style=' padding: 2px;font-family: system-ui;background-color:" +
|
|
themeBGcolor +
|
|
";'><p style='font-size: 20px;font-weight: 400;color: white;padding-left: 20px;' > Digital Signature Request</p></div><div><p style='padding: 20px;font-family: system-ui;font-size: 14px; margin-bottom: 10px;'> " +
|
|
pdfDetails?.[0].ExtUserPtr.Name +
|
|
" has requested you to review and sign <strong> " +
|
|
pdfDetails?.[0].Name +
|
|
"</strong>.</p><div style='padding: 5px 0px 5px 25px;display: flex;flex-direction: row;justify-content: space-around;'><table> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Sender</td> <td> </td> <td style='color:#626363;font-weight:bold'>" +
|
|
sender +
|
|
"</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Organization</td> <td> </td><td style='color:#626363;font-weight:bold'> " +
|
|
orgName +
|
|
"</td></tr> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Expire on</td><td> </td> <td style='color:#626363;font-weight:bold'>" +
|
|
localExpireDate +
|
|
"</td></tr><tr> <td></td> <td> </td></tr></table> </div> <div style='margin-left:70px'><a href=" +
|
|
signPdf +
|
|
"> <button style='padding: 12px 12px 12px 12px;background-color: #d46b0f;color: white; border: 0px;box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px,rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;font-weight:bold;margin-top:30px'>Sign here</button></a> </div> <div style='display: flex; justify-content: center;margin-top: 10px;'> </div></div></div><div><p> This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender " +
|
|
sender +
|
|
" directly.If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ <a href= " +
|
|
openSignUrl +
|
|
" target=_blank>here</a>.</p> </div></div></body> </html>"
|
|
};
|
|
sendMail = await axios.post(url, params, { headers: headers });
|
|
} catch (error) {
|
|
console.log("error", error);
|
|
}
|
|
}
|
|
|
|
if (sendMail.data.result.status === "success") {
|
|
const signers = signersdata?.map((x) => {
|
|
return {
|
|
__type: "Pointer",
|
|
className: "contracts_Contactbook",
|
|
objectId: x.objectId
|
|
};
|
|
});
|
|
const addExtraDays = pdfDetails[0]?.TimeToCompleteDays
|
|
? pdfDetails[0].TimeToCompleteDays
|
|
: 15;
|
|
const currentUser = signersdata.find((x) => x.Email === currentId);
|
|
setCurrentId(currentUser?.objectId);
|
|
let updateExpiryDate, data;
|
|
updateExpiryDate = new Date();
|
|
updateExpiryDate.setDate(updateExpiryDate.getDate() + addExtraDays);
|
|
const filterPrefill = signerPos.filter((data) => data.Role !== "prefill");
|
|
|
|
try {
|
|
if (updateExpiryDate) {
|
|
data = {
|
|
Placeholders: filterPrefill,
|
|
SignedUrl: pdfUrl,
|
|
Signers: signers,
|
|
ExpiryDate: {
|
|
iso: updateExpiryDate,
|
|
__type: "Date"
|
|
}
|
|
};
|
|
} else {
|
|
data = {
|
|
Placeholders: filterPrefill,
|
|
SignedUrl: pdfUrl,
|
|
Signers: signers
|
|
};
|
|
}
|
|
|
|
await axios
|
|
.put(
|
|
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
|
"_appName"
|
|
)}_Document/${documentId}`,
|
|
data,
|
|
{
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
}
|
|
}
|
|
)
|
|
.then((result) => {
|
|
setIsSend(true);
|
|
setIsMailSend(true);
|
|
setIsUiLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.log("axois err ", err);
|
|
});
|
|
} catch (e) {
|
|
console.log("error", e);
|
|
}
|
|
}
|
|
};
|
|
const handleDontShow = (isChecked) => {
|
|
setIsDontShow(isChecked);
|
|
};
|
|
//here you can add your messages in content and selector is key of particular steps
|
|
|
|
const tourConfig = [
|
|
{
|
|
selector: '[data-tut="reactourFirst"]',
|
|
content: () => (
|
|
<TourContentWithBtn
|
|
message={`Select a recipient from this list to add a place-holder where he is supposed to sign.The placeholder will appear in the same colour as the recipient name once you drop it on the document.`}
|
|
isChecked={handleDontShow}
|
|
/>
|
|
),
|
|
position: "top",
|
|
style: { fontSize: "13px" }
|
|
},
|
|
{
|
|
selector: '[data-tut="reactourSecond"]',
|
|
content: () => (
|
|
<TourContentWithBtn
|
|
message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`}
|
|
isChecked={handleDontShow}
|
|
/>
|
|
),
|
|
position: "top",
|
|
style: { fontSize: "13px" }
|
|
},
|
|
{
|
|
selector: '[data-tut="reactourThird"]',
|
|
content: () => (
|
|
<TourContentWithBtn
|
|
message={`The PDF content area already displays the template's existing placeholders. For your convenience, these placeholders will match the color of the recipient's name, making them easily identifiable.`}
|
|
isChecked={handleDontShow}
|
|
/>
|
|
),
|
|
position: "top",
|
|
style: { fontSize: "13px" }
|
|
},
|
|
{
|
|
selector: '[data-tut="reactourLinkUser"]',
|
|
content: () => (
|
|
<TourContentWithBtn
|
|
message={`Use this icon to assign a new signer or change the existing one for the placeholder.`}
|
|
isChecked={handleDontShow}
|
|
/>
|
|
),
|
|
position: "top",
|
|
style: { fontSize: "13px" }
|
|
},
|
|
{
|
|
selector: '[data-tut="reactourFour"]',
|
|
content: () => (
|
|
<TourContentWithBtn
|
|
message={`Clicking "Send" button will share the document with all the recipients.It will also send out emails to everyone on the recipients list.`}
|
|
isChecked={handleDontShow}
|
|
/>
|
|
),
|
|
position: "top",
|
|
style: { fontSize: "13px" }
|
|
}
|
|
];
|
|
|
|
const handleSaveWidgetsOptions = (
|
|
dropdownName,
|
|
dropdownOptions,
|
|
minCount,
|
|
maxCount,
|
|
isReadOnly,
|
|
addOption,
|
|
deleteOption
|
|
) => {
|
|
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) {
|
|
if (widgetType === "radio") {
|
|
if (addOption) {
|
|
return {
|
|
...position,
|
|
Height: position.Height
|
|
? position.Height + 15
|
|
: defaultWidthHeight(widgetType).height + 15
|
|
};
|
|
} else if (deleteOption) {
|
|
return {
|
|
...position,
|
|
Height: position.Height
|
|
? position.Height - 15
|
|
: defaultWidthHeight(widgetType).height - 15
|
|
};
|
|
} else {
|
|
return {
|
|
...position,
|
|
options: {
|
|
...position.options,
|
|
name: dropdownName,
|
|
values: dropdownOptions
|
|
}
|
|
};
|
|
}
|
|
} else if (widgetType === "checkbox") {
|
|
if (addOption) {
|
|
return {
|
|
...position,
|
|
Height: position.Height
|
|
? position.Height + 15
|
|
: defaultWidthHeight(widgetType).height + 15
|
|
};
|
|
} else if (deleteOption) {
|
|
return {
|
|
...position,
|
|
Height: position.Height
|
|
? position.Height - 15
|
|
: defaultWidthHeight(widgetType).height - 15
|
|
};
|
|
} else {
|
|
return {
|
|
...position,
|
|
options: {
|
|
...position.options,
|
|
name: dropdownName,
|
|
values: dropdownOptions,
|
|
validation: {
|
|
minRequiredCount: minCount,
|
|
maxRequiredCount: maxCount
|
|
},
|
|
isReadOnly: isReadOnly
|
|
}
|
|
};
|
|
}
|
|
} else {
|
|
return {
|
|
...position,
|
|
options: {
|
|
...position.options,
|
|
name: dropdownName,
|
|
values: dropdownOptions
|
|
}
|
|
};
|
|
}
|
|
}
|
|
return position;
|
|
});
|
|
|
|
const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
|
|
if (obj.pageNumber === pageNumber) {
|
|
return { ...obj, pos: addSignPos };
|
|
}
|
|
return obj;
|
|
});
|
|
const newUpdateSigner = signerPos.map((obj, ind) => {
|
|
if (obj.Id === uniqueId) {
|
|
return { ...obj, placeHolder: newUpdateSignPos };
|
|
}
|
|
return obj;
|
|
});
|
|
|
|
setSignerPos(newUpdateSigner);
|
|
}
|
|
}
|
|
};
|
|
|
|
//function for update TourStatus
|
|
const closeTour = async () => {
|
|
setPlaceholderTour(false);
|
|
if (isDontShow) {
|
|
const extUserClass = localStorage.getItem("extended_class");
|
|
let updatedTourStatus = [];
|
|
if (tourStatus.length > 0) {
|
|
updatedTourStatus = [...tourStatus];
|
|
const placeholderIndex = tourStatus.findIndex(
|
|
(obj) => obj["placeholder"] === false || obj["placeholder"] === true
|
|
);
|
|
if (placeholderIndex !== -1) {
|
|
updatedTourStatus[placeholderIndex] = { placeholder: true };
|
|
} else {
|
|
updatedTourStatus.push({ placeholder: true });
|
|
}
|
|
} else {
|
|
updatedTourStatus = [{ placeholder: true }];
|
|
}
|
|
await axios
|
|
.put(
|
|
`${localStorage.getItem(
|
|
"baseUrl"
|
|
)}classes/${extUserClass}/${signerUserId}`,
|
|
{
|
|
TourStatus: updatedTourStatus
|
|
},
|
|
{
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
sessionToken: localStorage.getItem("accesstoken")
|
|
}
|
|
}
|
|
)
|
|
.then((Listdata) => {
|
|
// const json = Listdata.data;
|
|
// const res = json.results;
|
|
})
|
|
.catch((err) => {
|
|
console.log("axois err ", err);
|
|
});
|
|
}
|
|
};
|
|
const handleRecipientSign = () => {
|
|
const hostUrl = getHostUrl();
|
|
navigate(`${hostUrl}recipientSignPdf/${documentId}/${currentId}`);
|
|
};
|
|
|
|
const handleLinkUser = (id) => {
|
|
setIsAddUser({ [id]: true });
|
|
};
|
|
const handleAddUser = (data) => {
|
|
if (data && data.objectId) {
|
|
const signerPtr = {
|
|
__type: "Pointer",
|
|
className: "contracts_Contactbook",
|
|
objectId: data.objectId
|
|
};
|
|
const updatePlaceHolder = signerPos.map((x) => {
|
|
if (x.Id === uniqueId) {
|
|
return { ...x, signerPtr: signerPtr, signerObjId: data.objectId };
|
|
}
|
|
return { ...x };
|
|
});
|
|
|
|
setSignerPos(updatePlaceHolder);
|
|
|
|
const updateSigner = signersdata.map((x) => {
|
|
if (x.Id === uniqueId) {
|
|
return { ...x, ...data, className: "contracts_Contactbook" };
|
|
}
|
|
return { ...x };
|
|
});
|
|
if (updateSigner && updateSigner.length > 0) {
|
|
const currEmail = pdfDetails[0].ExtUserPtr.Email;
|
|
const getCurrentUserDeatils = updateSigner.filter(
|
|
(x) => x.Email === currEmail
|
|
);
|
|
if (getCurrentUserDeatils && getCurrentUserDeatils.length > 0) {
|
|
setCurrentId(getCurrentUserDeatils[0].Email);
|
|
}
|
|
}
|
|
|
|
setSignersData(updateSigner);
|
|
const index = signersdata.findIndex((x) => x.Id === uniqueId);
|
|
setIsSelectId(index);
|
|
}
|
|
};
|
|
|
|
const closePopup = () => {
|
|
setIsAddUser({});
|
|
};
|
|
|
|
//function for base on condition to add checkbox widget status and input text validation in signerPos array
|
|
const handleApplyWidgetsStatus = (textValidate) => {
|
|
const options = ["email", "number", "text"];
|
|
const regexType = options.includes(textValidate);
|
|
let regularExpression = textValidate;
|
|
|
|
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, ind) => {
|
|
if (position.key === signKey) {
|
|
return {
|
|
...position,
|
|
options: {
|
|
...position.options,
|
|
hint: hint,
|
|
validation: {
|
|
type: regexType ? regularExpression : "regex",
|
|
pattern: !regexType ? regularExpression : ""
|
|
}
|
|
}
|
|
};
|
|
}
|
|
return position;
|
|
});
|
|
|
|
const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
|
|
if (obj.pageNumber === pageNumber) {
|
|
return { ...obj, pos: addSignPos };
|
|
}
|
|
return obj;
|
|
});
|
|
const newUpdateSigner = signerPos.map((obj, ind) => {
|
|
if (obj.Id === uniqueId) {
|
|
return { ...obj, placeHolder: newUpdateSignPos };
|
|
}
|
|
return obj;
|
|
});
|
|
|
|
setSignerPos(newUpdateSigner);
|
|
setTextValidate("");
|
|
}
|
|
}
|
|
};
|
|
const handleValidateInput = (e) => {
|
|
handleApplyWidgetsStatus(textValidate);
|
|
setIsValidate(false);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Title title={state?.title ? state.title : "New Document"} />
|
|
<DndProvider backend={HTML5Backend}>
|
|
{isLoading.isLoad ? (
|
|
<Loader isLoading={isLoading} />
|
|
) : handleError ? (
|
|
<HandleError handleError={handleError} />
|
|
) : noData ? (
|
|
<Nodata />
|
|
) : (
|
|
<div className="signatureContainer" ref={divRef}>
|
|
{isUiLoading && (
|
|
<div
|
|
style={{
|
|
position: "absolute",
|
|
height: "100vh",
|
|
width: "100%",
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
flexDirection: "column",
|
|
alignItems: "center",
|
|
zIndex: "999",
|
|
backgroundColor: "#e6f2f2",
|
|
opacity: 0.8
|
|
}}
|
|
>
|
|
<img
|
|
alt="no img"
|
|
src={loader}
|
|
style={{ width: "100px", height: "100px" }}
|
|
/>
|
|
<span style={{ fontSize: "13px", fontWeight: "bold" }}>
|
|
This might take some time
|
|
</span>
|
|
</div>
|
|
)}
|
|
{/* this component used for UI interaction and show their functionality */}
|
|
{!checkTourStatus && (
|
|
//this tour component used in your html component where you want to put
|
|
//onRequestClose function to close tour
|
|
//steps is defined what will be your messages and style also
|
|
//isOpen is takes boolean value to open
|
|
<Tour
|
|
onRequestClose={closeTour}
|
|
steps={tourConfig}
|
|
isOpen={placeholderTour}
|
|
rounded={5}
|
|
closeWithMask={false}
|
|
/>
|
|
)}
|
|
{/* this component used to render all pdf pages in left side */}
|
|
<RenderAllPdfPage
|
|
signPdfUrl={pdfDetails[0].URL}
|
|
allPages={allPages}
|
|
setAllPages={setAllPages}
|
|
setPageNumber={setPageNumber}
|
|
setSignBtnPosition={setSignBtnPosition}
|
|
pageNumber={pageNumber}
|
|
/>
|
|
|
|
{/* pdf render view */}
|
|
<div
|
|
style={{
|
|
marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px",
|
|
marginRight: !isMobile && pdfOriginalWidth > 500 && "20px"
|
|
}}
|
|
>
|
|
{/* this modal is used show alert set placeholder for all signers before send mail */}
|
|
|
|
<ModalUi
|
|
headerColor={
|
|
isSendAlert.mssg === "sure"
|
|
? "#dc3545"
|
|
: isSendAlert.mssg === "confirm" && themeColor()
|
|
}
|
|
isOpen={isSendAlert.alert}
|
|
title={
|
|
isSendAlert.mssg === "sure"
|
|
? "Fields required"
|
|
: isSendAlert.mssg === "confirm" && "Send Mail"
|
|
}
|
|
handleClose={() => setIsSendAlert({})}
|
|
>
|
|
<div style={{ height: "100%", padding: 20 }}>
|
|
{isSendAlert.mssg === "sure" ? (
|
|
<p>Please add field for all recipients.</p>
|
|
) : (
|
|
isSendAlert.mssg === "confirm" && (
|
|
<p>
|
|
Are you sure you want to send out this document for
|
|
signatures?
|
|
</p>
|
|
)
|
|
)}
|
|
<div
|
|
style={{
|
|
height: "1px",
|
|
backgroundColor: "#9f9f9f",
|
|
width: "100%",
|
|
marginTop: "15px",
|
|
marginBottom: "15px"
|
|
}}
|
|
></div>
|
|
|
|
{isSendAlert.mssg === "confirm" && (
|
|
<button
|
|
onClick={() => sendEmailToSigners()}
|
|
style={{
|
|
background: themeColor()
|
|
}}
|
|
type="button"
|
|
className="finishBtn"
|
|
>
|
|
Yes
|
|
</button>
|
|
)}
|
|
<button
|
|
onClick={() => setIsSendAlert({})}
|
|
type="button"
|
|
className="finishBtn cancelBtn"
|
|
>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</ModalUi>
|
|
|
|
{/* this modal is used show send mail message and after send mail success message */}
|
|
<ModalUi
|
|
isOpen={isSend}
|
|
title={"Mails Sent"}
|
|
handleClose={() => {
|
|
setIsSend(false);
|
|
setSignerPos([]);
|
|
}}
|
|
>
|
|
<div style={{ height: "100%", padding: 20 }}>
|
|
<p>You have successfully sent mails to all recipients!</p>
|
|
{currentId && (
|
|
<p>Do you want to sign documents right now ?</p>
|
|
)}
|
|
<div
|
|
style={{
|
|
height: "1px",
|
|
backgroundColor: "#9f9f9f",
|
|
width: "100%",
|
|
marginTop: "15px",
|
|
marginBottom: "15px"
|
|
}}
|
|
></div>
|
|
{currentId ? (
|
|
<>
|
|
<button
|
|
onClick={() => {
|
|
handleRecipientSign();
|
|
}}
|
|
style={{
|
|
background: themeColor(),
|
|
color: "white"
|
|
}}
|
|
type="button"
|
|
className="finishBtn"
|
|
>
|
|
Yes
|
|
</button>
|
|
<button
|
|
onClick={() => {
|
|
setIsSend(false);
|
|
setSignerPos([]);
|
|
}}
|
|
type="button"
|
|
className="finishBtn cancelBtn"
|
|
>
|
|
No
|
|
</button>
|
|
</>
|
|
) : (
|
|
<button
|
|
onClick={() => {
|
|
setIsSend(false);
|
|
setSignerPos([]);
|
|
}}
|
|
type="button"
|
|
className="finishBtn cancelBtn"
|
|
>
|
|
Close
|
|
</button>
|
|
)}
|
|
</div>
|
|
</ModalUi>
|
|
|
|
{/* <ModalComponent isShow={isAlreadyPlace} type={"alreadyPlace"} /> */}
|
|
<ModalUi
|
|
headerColor={"#dc3545"}
|
|
isOpen={isShowEmail}
|
|
title={"signersAlert"}
|
|
handleClose={() => {
|
|
setIsShowEmail(false);
|
|
}}
|
|
>
|
|
<div style={{ height: "100%", padding: 20 }}>
|
|
<p>Please select signer for add placeholder!</p>
|
|
|
|
<div
|
|
style={{
|
|
height: "1px",
|
|
backgroundColor: "#9f9f9f",
|
|
width: "100%",
|
|
marginTop: "15px",
|
|
marginBottom: "15px"
|
|
}}
|
|
></div>
|
|
<button
|
|
onClick={() => {
|
|
setIsShowEmail(false);
|
|
}}
|
|
type="button"
|
|
className="finishBtn cancelBtn"
|
|
>
|
|
Ok
|
|
</button>
|
|
</div>
|
|
</ModalUi>
|
|
<InputValidation
|
|
setIsValidate={setIsValidate}
|
|
handleValidateInput={handleValidateInput}
|
|
isValidate={isValidate}
|
|
hint={hint}
|
|
setHint={setHint}
|
|
setTextValidate={setTextValidate}
|
|
textValidate={textValidate}
|
|
/>
|
|
<PlaceholderCopy
|
|
isPageCopy={isPageCopy}
|
|
setIsPageCopy={setIsPageCopy}
|
|
xyPostion={signerPos}
|
|
setXyPostion={setSignerPos}
|
|
allPages={allPages}
|
|
pageNumber={pageNumber}
|
|
signKey={signKey}
|
|
// signerObjId={signerObjId}
|
|
Id={uniqueId}
|
|
/>
|
|
<DropdownWidgetOption
|
|
type="radio"
|
|
title="Radio group"
|
|
showDropdown={isRadio}
|
|
setShowDropdown={setIsRadio}
|
|
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
|
|
currWidgetsDetails={currWidgetsDetails}
|
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
|
/>
|
|
<DropdownWidgetOption
|
|
type="checkbox"
|
|
title="Checkbox"
|
|
showDropdown={isCheckbox}
|
|
setShowDropdown={setIsCheckbox}
|
|
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
|
|
currWidgetsDetails={currWidgetsDetails}
|
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
|
/>
|
|
<DropdownWidgetOption
|
|
type="dropdown"
|
|
title="Dropdown options"
|
|
showDropdown={showDropdown}
|
|
setShowDropdown={setShowDropdown}
|
|
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
|
|
currWidgetsDetails={currWidgetsDetails}
|
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
|
/>
|
|
{/* pdf header which contain funish back button */}
|
|
<Header
|
|
isPlaceholder={true}
|
|
pageNumber={pageNumber}
|
|
allPages={allPages}
|
|
changePage={changePage}
|
|
pdfDetails={pdfDetails}
|
|
signerPos={signerPos}
|
|
signersdata={signersdata}
|
|
isMailSend={isMailSend}
|
|
alertSendEmail={alertSendEmail}
|
|
isShowHeader={true}
|
|
currentSigner={true}
|
|
dataTut4="reactourFour"
|
|
/>
|
|
<div data-tut="reactourThird">
|
|
{containerWH && (
|
|
<RenderPdf
|
|
pageNumber={pageNumber}
|
|
pdfOriginalWidth={pdfOriginalWidth}
|
|
pdfNewWidth={pdfNewWidth}
|
|
pdfDetails={pdfDetails}
|
|
signerPos={signerPos}
|
|
successEmail={false}
|
|
numPages={numPages}
|
|
pageDetails={pageDetails}
|
|
placeholder={true}
|
|
drop={drop}
|
|
handleDeleteSign={handleDeleteSign}
|
|
handleTabDrag={handleTabDrag}
|
|
handleStop={handleStop}
|
|
setPdfLoadFail={setPdfLoadFail}
|
|
pdfLoadFail={pdfLoadFail}
|
|
setSignerPos={setSignerPos}
|
|
containerWH={containerWH}
|
|
setIsResize={setIsResize}
|
|
setZIndex={setZIndex}
|
|
setIsPageCopy={setIsPageCopy}
|
|
signersdata={signersdata}
|
|
setSignKey={setSignKey}
|
|
setSignerObjId={setSignerObjId}
|
|
handleLinkUser={handleLinkUser}
|
|
setUniqueId={setUniqueId}
|
|
isDragging={isDragging}
|
|
setShowDropdown={setShowDropdown}
|
|
setIsValidate={setIsValidate}
|
|
setWidgetType={setWidgetType}
|
|
setIsRadio={setIsRadio}
|
|
setIsCheckbox={setIsCheckbox}
|
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
|
setSelectWidgetId={setSelectWidgetId}
|
|
selectWidgetId={selectWidgetId}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* signature button */}
|
|
{isMobile ? (
|
|
<div>
|
|
<FieldsComponent
|
|
dataTut="reactourFirst"
|
|
dataTut2="reactourSecond"
|
|
pdfUrl={isMailSend}
|
|
dragSignature={dragSignature}
|
|
signRef={signRef}
|
|
handleDivClick={handleDivClick}
|
|
handleMouseLeave={handleMouseLeave}
|
|
isDragSign={isDragSign}
|
|
themeColor={themeColor}
|
|
dragStamp={dragStamp}
|
|
dragRef={dragRef}
|
|
isDragStamp={isDragStamp}
|
|
isSignYourself={false}
|
|
addPositionOfSignature={addPositionOfSignature}
|
|
signerPos={signerPos}
|
|
signersdata={signersdata}
|
|
isSelectListId={isSelectListId}
|
|
setSignerObjId={setSignerObjId}
|
|
setIsSelectId={setIsSelectId}
|
|
setContractName={setContractName}
|
|
isSigners={true}
|
|
setIsShowEmail={setIsShowEmail}
|
|
isMailSend={isMailSend}
|
|
setSelectedEmail={setSelectedEmail}
|
|
selectedEmail={selectedEmail}
|
|
setUniqueId={setUniqueId}
|
|
setRoleName={setRoleName}
|
|
initial={true}
|
|
/>
|
|
</div>
|
|
) : (
|
|
<div>
|
|
<div className="signerComponent">
|
|
<div
|
|
style={{ maxHeight: window.innerHeight - 70 + "px" }}
|
|
className="autoSignScroll"
|
|
>
|
|
<SignerListPlace
|
|
signerPos={signerPos}
|
|
signersdata={signersdata}
|
|
isSelectListId={isSelectListId}
|
|
setSignerObjId={setSignerObjId}
|
|
setIsSelectId={setIsSelectId}
|
|
setContractName={setContractName}
|
|
setUniqueId={setUniqueId}
|
|
setRoleName={setRoleName}
|
|
// handleAddSigner={handleAddSigner}
|
|
/>
|
|
<div data-tut="reactourSecond">
|
|
<FieldsComponent
|
|
pdfUrl={isMailSend}
|
|
dragSignature={dragSignature}
|
|
signRef={signRef}
|
|
handleDivClick={handleDivClick}
|
|
handleMouseLeave={handleMouseLeave}
|
|
isDragSign={isDragSign}
|
|
themeColor={themeColor}
|
|
dragStamp={dragStamp}
|
|
dragRef={dragRef}
|
|
isDragStamp={isDragStamp}
|
|
isSignYourself={false}
|
|
addPositionOfSignature={addPositionOfSignature}
|
|
initial={true}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</DndProvider>
|
|
<div>
|
|
<ModalUi
|
|
headerColor={"#dc3545"}
|
|
isOpen={signerExistModal}
|
|
title={"Users required"}
|
|
handleClose={() => {
|
|
setSignerExistModal(false);
|
|
}}
|
|
>
|
|
<div style={{ height: "100%", padding: 20 }}>
|
|
<p>Please assign signers to all placeholders</p>
|
|
|
|
<div
|
|
style={{
|
|
height: "1px",
|
|
backgroundColor: "#9f9f9f",
|
|
width: "100%",
|
|
marginTop: "15px",
|
|
marginBottom: "15px"
|
|
}}
|
|
></div>
|
|
<button
|
|
onClick={() => setSignerExistModal(false)}
|
|
type="button"
|
|
className="finishBtn cancelBtn"
|
|
>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</ModalUi>
|
|
|
|
<LinkUserModal
|
|
handleAddUser={handleAddUser}
|
|
isAddUser={isAddUser}
|
|
uniqueId={uniqueId}
|
|
closePopup={closePopup}
|
|
/>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default PlaceHolderSign;
|