import React, { useState, useRef, useEffect } from "react"; import axios from "axios"; import "../css/./signature.css"; import Modal from "react-bootstrap/Modal"; import sign from "../assests/sign3.png"; import stamp from "../assests/stamp2.png"; 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 { 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 } from "../utils/Utils"; import RenderPdf from "./component/renderPdf"; import ModalComponent from "./component/modalComponent"; import { useNavigate } from "react-router-dom"; function PlaceHolderSign() { const navigate = useNavigate(); 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 [currentEmail, setCurrentEmail] = 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 [isAlreadyPlace, setIsAlreadyPlace] = useState(false); const [pdfLoadFail, setPdfLoadFail] = useState({ status: false, type: "load" }); 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: "drag me" }, collect: (monitor) => ({ isDragSign: !!monitor.isDragging() }) }); const [{ isDragStamp }, dragStamp] = useDrag({ type: "BOX", item: { type: "BOX", id: 2, text: "drag me" }, collect: (monitor) => ({ isDragStamp: !!monitor.isDragging() }) }); const [{ isDragSignatureSS }, dragSignatureSS] = useDrag({ type: "BOX", item: { type: "BOX", id: 3, text: "drag me" }, collect: (monitor) => ({ isDragSignatureSS: !!monitor.isDragging() }) }); const [{ isDragStampSS }, dragStampSS] = useDrag({ type: "BOX", item: { type: "BOX", id: 4, text: "drag me" }, collect: (monitor) => ({ isDragStampSS: !!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); } setPdfDetails(documentData); const currEmail = documentData[0].ExtUserPtr.Email; const filterCurrEmail = documentData[0].Signers.filter( (data) => data.Email === currEmail ); setCurrentEmail(filterCurrEmail); setSignersData(documentData[0]); setSignerObjId(documentData[0].Signers[0].objectId); setContractName(documentData[0].Signers[0].className); setIsSelectId(0); } 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) => { if (isMobile) { if (selectedEmail) { getSignerPos(item, monitor); } else { setIsShowEmail(true); } } else { getSignerPos(item, monitor); } }; const getSignerPos = (item, monitor) => { const newWidth = containerWH.width; const scale = pdfOriginalWidth / newWidth; const key = Math.floor(1000 + Math.random() * 9000); let filterSignerPos = signerPos.filter( (data) => data.signerObjId === signerObjId ); let dropData = []; let xyPosArr = []; let xyPos = {}; if (item === "onclick") { const dropObj = { xPosition: window.innerWidth / 2 - 100, yPosition: window.innerHeight / 2 - 60, isStamp: monitor, key: key, isDrag: false, scale: scale, isMobile: isMobile, yBottom: window.innerHeight / 2 - 60 }; dropData.push(dropObj); xyPos = { pageNumber: pageNumber, pos: dropData }; xyPosArr.push(xyPos); } else if (item.type === "BOX") { 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 ybottom = containerRect.bottom - offset.y; const dropObj = { xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, isStamp: isDragStamp || isDragStampSS ? true : false, key: key, isDrag: false, firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, yBottom: ybottom, scale: scale, isMobile: isMobile }; dropData.push(dropObj); xyPos = { pageNumber: pageNumber, pos: dropData }; xyPosArr.push(xyPos); } //add signers objId first inseretion if (filterSignerPos.length > 0) { const colorIndex = signerPos .map((e) => e.signerObjId) .indexOf(signerObjId); 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 placeHolderPos = { blockColor: color[isSelectListId], signerObjId: signerObjId, placeHolder: updatePlace, signerPtr: { __type: "Pointer", className: `${contractName}`, objectId: signerObjId } }; signerPos.splice(colorIndex, 1, placeHolderPos); } else { const newSignPoss = getPlaceHolder.concat(xyPosArr[0]); let placeHolderPos = { blockColor: color[isSelectListId], signerObjId: signerObjId, placeHolder: newSignPoss, signerPtr: { __type: "Pointer", className: `${contractName}`, objectId: signerObjId } }; signerPos.splice(colorIndex, 1, placeHolderPos); } } else { let placeHolderPos = { signerPtr: { __type: "Pointer", className: `${contractName}`, objectId: signerObjId }, signerObjId: signerObjId, blockColor: color[isSelectListId], placeHolder: xyPosArr }; setSignerPos((prev) => [...prev, placeHolderPos]); } }; //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); setSignerObjId(signerId); }; //function for set and update x and y postion after drag and drop signature tab const handleStop = (event, dragElement, signerId, key) => { if (!isResize) { const containerRect = document .getElementById("container") .getBoundingClientRect(); const signId = signerId ? signerId : signerObjId; const keyValue = key ? key : dragKey; const ybottom = containerRect.height - dragElement.y; if (keyValue >= 0) { const filterSignerPos = signerPos.filter( (data) => data.signerObjId === signId ); 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 = signerPos.map((obj, ind) => { if (obj.signerObjId === signId) { return { ...obj, placeHolder: newUpdateSignPos }; } return obj; }); setSignerPos(newUpdateSigner); } } } } }; //function for delete signature block const handleDeleteSign = (key, signerId) => { const updateData = []; const filterSignerPos = signerPos.filter( (data) => data.signerObjId === signerId ); 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.signerObjId === signerId) { return { ...obj, placeHolder: newUpdatePos }; } return obj; }); setSignerPos(newUpdateSigner); } else { const updateFilter = signerPos.filter( (data) => data.signerObjId !== signerId ); const getRemainPage = filterSignerPos[0].placeHolder.filter( (data) => data.pageNumber !== pageNumber ); if (getRemainPage && getRemainPage.length > 0) { const newUpdatePos = filterSignerPos.map((obj, ind) => { if (obj.signerObjId === signerId) { return { ...obj, placeHolder: getRemainPage }; } return obj; }); let signerupdate = []; signerupdate = signerPos.filter( (data) => data.signerObjId !== signerId ); 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]); }; const alertSendEmail = async () => { if (signerPos.length === signersdata.Signers.length) { const alert = { mssg: "confirm", alert: true }; setIsSendAlert(alert); } else { const alert = { mssg: "sure", alert: true }; setIsSendAlert(alert); } }; const sendEmailToSigners = async () => { const loadObj = { isLoad: true, message: "This might take some time" }; setIsLoading(loadObj); setIsSendAlert({}); let sendMail; const expireDate = signersdata.ExpiryDate.iso; const newDate = new Date(expireDate); const localExpireDate = newDate.toLocaleDateString("en-US", { day: "numeric", month: "long", year: "numeric" }); let sender = signersdata.ExtUserPtr.Email; const signerMail = signersdata.Signers; 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/${signersdata.objectId}/${signerMail[i].Email}/${objectId}/${serverParams}`; const themeBGcolor = themeColor(); let params = { recipient: signerMail[i].Email, subject: `${signersdata.ExtUserPtr.Name} has requested you to sign ${signersdata.Name}`, from: sender, html: "
Digital Signature Request
This is an automated email from Open Sign. 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 Open Sign here.
Please Add field for all recipients.
) : ( isSendAlert.mssg === "confirm" && (Are you sure you want to send out this document for signatures?
) )}You have successfully sent mails to all recipients!
{currentEmail.length > 0 && (Do you want to sign documents right now ?
)}