mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-29 04:54:56 +02:00
implement share button option to share recipient's sign url after finishing a doc creation using request signature flow
This commit is contained in:
Generated
+10
@@ -43,6 +43,7 @@
|
|||||||
"react-select": "^5.8.0",
|
"react-select": "^5.8.0",
|
||||||
"react-signature-canvas": "^1.0.6",
|
"react-signature-canvas": "^1.0.6",
|
||||||
"react-tooltip": "^5.26.3",
|
"react-tooltip": "^5.26.3",
|
||||||
|
"react-web-share": "^2.0.2",
|
||||||
"reactour": "^1.19.2",
|
"reactour": "^1.19.2",
|
||||||
"redux": "^5.0.1",
|
"redux": "^5.0.1",
|
||||||
"redux-thunk": "^3.1.0",
|
"redux-thunk": "^3.1.0",
|
||||||
@@ -20225,6 +20226,15 @@
|
|||||||
"react-dom": ">=16.6.0"
|
"react-dom": ">=16.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-web-share": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-web-share/-/react-web-share-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-bGm1TJc6xtC0MhAnYFsrzT4En7l2oAdLTgCK7nk7b4xGTg3L5gOldiPrmYQ8a/dEXNydgekvOj/tfjduIlIRVA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16 || ^17 || ^18",
|
||||||
|
"react-dom": "^16 || ^17 || ^18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reactour": {
|
"node_modules/reactour": {
|
||||||
"version": "1.19.2",
|
"version": "1.19.2",
|
||||||
"resolved": "https://registry.npmjs.org/reactour/-/reactour-1.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/reactour/-/reactour-1.19.2.tgz",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
"react-select": "^5.8.0",
|
"react-select": "^5.8.0",
|
||||||
"react-signature-canvas": "^1.0.6",
|
"react-signature-canvas": "^1.0.6",
|
||||||
"react-tooltip": "^5.26.3",
|
"react-tooltip": "^5.26.3",
|
||||||
|
"react-web-share": "^2.0.2",
|
||||||
"reactour": "^1.19.2",
|
"reactour": "^1.19.2",
|
||||||
"redux": "^5.0.1",
|
"redux": "^5.0.1",
|
||||||
"redux-thunk": "^3.1.0",
|
"redux-thunk": "^3.1.0",
|
||||||
|
|||||||
@@ -1862,3 +1862,18 @@ export function replaceMailVaribles(subject, body, variables) {
|
|||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const copytoData = (text) => {
|
||||||
|
// navigator.clipboard.writeText(text);
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
navigator.clipboard.writeText(text);
|
||||||
|
} else {
|
||||||
|
// Fallback for browsers that don't support navigator.clipboard
|
||||||
|
const textArea = document.createElement("textarea");
|
||||||
|
textArea.value = text;
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.select();
|
||||||
|
document.execCommand("copy");
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import { isEnableSubscription, rejectBtn, submitBtn } from "../constant/const";
|
import { isEnableSubscription, rejectBtn, submitBtn } from "../constant/const";
|
||||||
import { checkIsSubscribed, openInNewTab } from "../constant/Utils";
|
import { checkIsSubscribed, copytoData, openInNewTab } from "../constant/Utils";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
||||||
import Tooltip from "../primitives/Tooltip";
|
import Tooltip from "../primitives/Tooltip";
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ function GenerateToken() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const copytoclipboard = (text) => {
|
const copytoclipboard = (text) => {
|
||||||
navigator.clipboard.writeText(text);
|
copytoData(text);
|
||||||
setCopied(true);
|
setCopied(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setCopied(false);
|
setCopied(false);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ function Login() {
|
|||||||
Destination: ""
|
Destination: ""
|
||||||
});
|
});
|
||||||
const [isModal, setIsModal] = useState(false);
|
const [isModal, setIsModal] = useState(false);
|
||||||
const [image, setImage] = useState(appInfo?.applogo);
|
const [image, setImage] = useState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("accesstoken")) {
|
if (localStorage.getItem("accesstoken")) {
|
||||||
@@ -65,6 +65,8 @@ function Login() {
|
|||||||
} else {
|
} else {
|
||||||
setImage(appInfo?.applogo || undefined);
|
setImage(appInfo?.applogo || undefined);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setImage(appInfo?.applogo || undefined);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
|
|||||||
@@ -385,354 +385,351 @@ function PdfRequestFiles() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkSendInOrder = () => {
|
// const checkSendInOrder = () => {
|
||||||
if (sendInOrder) {
|
// if (sendInOrder) {
|
||||||
const index = pdfDetails?.[0].Signers.findIndex(
|
// const index = pdfDetails?.[0].Signers.findIndex(
|
||||||
(x) => x.Email === jsonSender.email
|
// (x) => x.Email === jsonSender.email
|
||||||
);
|
// );
|
||||||
const newIndex = index - 1;
|
// const newIndex = index - 1;
|
||||||
if (newIndex !== -1) {
|
// if (newIndex !== -1) {
|
||||||
const user = pdfDetails?.[0].Signers[newIndex];
|
// const user = pdfDetails?.[0].Signers[newIndex];
|
||||||
const isPrevUserSigned =
|
// const isPrevUserSigned =
|
||||||
pdfDetails?.[0].AuditTrail &&
|
// pdfDetails?.[0].AuditTrail &&
|
||||||
pdfDetails?.[0].AuditTrail.some(
|
// pdfDetails?.[0].AuditTrail.some(
|
||||||
(x) =>
|
// (x) =>
|
||||||
x.UserPtr.objectId === user.objectId && x.Activity === "Signed"
|
// x.UserPtr.objectId === user.objectId && x.Activity === "Signed"
|
||||||
);
|
// );
|
||||||
if (isPrevUserSigned) {
|
// if (isPrevUserSigned) {
|
||||||
return true;
|
// return true;
|
||||||
} else {
|
// } else {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
//function for embed signature or image url in pdf
|
//function for embed signature or image url in pdf
|
||||||
async function embedWidgetsData() {
|
async function embedWidgetsData() {
|
||||||
const validateSigning = checkSendInOrder();
|
// const validateSigning = checkSendInOrder();
|
||||||
if (validateSigning) {
|
// if (validateSigning) {
|
||||||
const checkUser = signerPos.filter(
|
const checkUser = signerPos.filter(
|
||||||
(data) => data.signerObjId === signerObjectId
|
(data) => data.signerObjId === signerObjectId
|
||||||
);
|
);
|
||||||
if (checkUser && checkUser.length > 0) {
|
if (checkUser && checkUser.length > 0) {
|
||||||
let checkboxExist,
|
let checkboxExist,
|
||||||
requiredRadio,
|
requiredRadio,
|
||||||
showAlert = false,
|
showAlert = false,
|
||||||
widgetKey,
|
widgetKey,
|
||||||
radioExist,
|
radioExist,
|
||||||
requiredCheckbox;
|
requiredCheckbox;
|
||||||
|
|
||||||
for (let i = 0; i < checkUser[0].placeHolder.length; i++) {
|
for (let i = 0; i < checkUser[0].placeHolder.length; i++) {
|
||||||
for (let j = 0; j < checkUser[0].placeHolder[i].pos.length; j++) {
|
for (let j = 0; j < checkUser[0].placeHolder[i].pos.length; j++) {
|
||||||
checkboxExist =
|
checkboxExist =
|
||||||
checkUser[0].placeHolder[i].pos[j].type === "checkbox";
|
checkUser[0].placeHolder[i].pos[j].type === "checkbox";
|
||||||
radioExist =
|
radioExist =
|
||||||
checkUser[0].placeHolder[i].pos[j].type === radioButtonWidget;
|
checkUser[0].placeHolder[i].pos[j].type === radioButtonWidget;
|
||||||
if (checkboxExist) {
|
if (checkboxExist) {
|
||||||
requiredCheckbox = checkUser[0].placeHolder[i].pos.filter(
|
requiredCheckbox = checkUser[0].placeHolder[i].pos.filter(
|
||||||
(position) =>
|
(position) =>
|
||||||
!position.options?.isReadOnly && position.type === "checkbox"
|
!position.options?.isReadOnly && position.type === "checkbox"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (requiredCheckbox && requiredCheckbox.length > 0) {
|
if (requiredCheckbox && requiredCheckbox.length > 0) {
|
||||||
for (let i = 0; i < requiredCheckbox.length; i++) {
|
for (let i = 0; i < requiredCheckbox.length; i++) {
|
||||||
const minCount =
|
const minCount =
|
||||||
requiredCheckbox[i].options?.validation?.minRequiredCount;
|
requiredCheckbox[i].options?.validation?.minRequiredCount;
|
||||||
const parseMin = minCount && parseInt(minCount);
|
const parseMin = minCount && parseInt(minCount);
|
||||||
const maxCount =
|
const maxCount =
|
||||||
requiredCheckbox[i].options?.validation?.maxRequiredCount;
|
requiredCheckbox[i].options?.validation?.maxRequiredCount;
|
||||||
const parseMax = maxCount && parseInt(maxCount);
|
const parseMax = maxCount && parseInt(maxCount);
|
||||||
const response =
|
const response = requiredCheckbox[i].options?.response?.length;
|
||||||
requiredCheckbox[i].options?.response?.length;
|
const defaultValue =
|
||||||
const defaultValue =
|
requiredCheckbox[i].options?.defaultValue?.length;
|
||||||
requiredCheckbox[i].options?.defaultValue?.length;
|
if (parseMin === 0 && parseMax === 0) {
|
||||||
if (parseMin === 0 && parseMax === 0) {
|
if (!showAlert) {
|
||||||
if (!showAlert) {
|
showAlert = false;
|
||||||
showAlert = false;
|
setminRequiredCount(null);
|
||||||
setminRequiredCount(null);
|
}
|
||||||
}
|
} else if (parseMin === 0 && parseMax > 0) {
|
||||||
} else if (parseMin === 0 && parseMax > 0) {
|
if (!showAlert) {
|
||||||
if (!showAlert) {
|
showAlert = false;
|
||||||
showAlert = false;
|
setminRequiredCount(null);
|
||||||
setminRequiredCount(null);
|
}
|
||||||
}
|
} else if (!response) {
|
||||||
} else if (!response) {
|
if (!defaultValue) {
|
||||||
if (!defaultValue) {
|
|
||||||
if (!showAlert) {
|
|
||||||
showAlert = true;
|
|
||||||
widgetKey = requiredCheckbox[i].key;
|
|
||||||
setminRequiredCount(parseMin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (parseMin > 0 && parseMin > response) {
|
|
||||||
if (!showAlert) {
|
if (!showAlert) {
|
||||||
showAlert = true;
|
showAlert = true;
|
||||||
widgetKey = requiredCheckbox[i].key;
|
widgetKey = requiredCheckbox[i].key;
|
||||||
setminRequiredCount(parseMin);
|
setminRequiredCount(parseMin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (parseMin > 0 && parseMin > response) {
|
||||||
|
if (!showAlert) {
|
||||||
|
showAlert = true;
|
||||||
|
widgetKey = requiredCheckbox[i].key;
|
||||||
|
setminRequiredCount(parseMin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (radioExist) {
|
}
|
||||||
requiredRadio = checkUser[0].placeHolder[i].pos.filter(
|
} else if (radioExist) {
|
||||||
(position) =>
|
requiredRadio = checkUser[0].placeHolder[i].pos.filter(
|
||||||
!position.options?.isReadOnly &&
|
(position) =>
|
||||||
position.type === radioButtonWidget
|
!position.options?.isReadOnly &&
|
||||||
);
|
position.type === radioButtonWidget
|
||||||
if (requiredRadio && requiredRadio?.length > 0) {
|
);
|
||||||
let checkSigned;
|
if (requiredRadio && requiredRadio?.length > 0) {
|
||||||
for (let i = 0; i < requiredRadio?.length; i++) {
|
let checkSigned;
|
||||||
checkSigned = requiredRadio[i]?.options.response;
|
for (let i = 0; i < requiredRadio?.length; i++) {
|
||||||
if (!checkSigned) {
|
checkSigned = requiredRadio[i]?.options.response;
|
||||||
let checkDefaultSigned =
|
if (!checkSigned) {
|
||||||
requiredRadio[i]?.options.defaultValue;
|
let checkDefaultSigned =
|
||||||
|
requiredRadio[i]?.options.defaultValue;
|
||||||
|
if (!checkDefaultSigned) {
|
||||||
|
if (!showAlert) {
|
||||||
|
showAlert = true;
|
||||||
|
widgetKey = requiredRadio[i].key;
|
||||||
|
setminRequiredCount(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const requiredWidgets = checkUser[0].placeHolder[i].pos.filter(
|
||||||
|
(position) =>
|
||||||
|
position.options?.status === "required" &&
|
||||||
|
position.type !== radioButtonWidget &&
|
||||||
|
position.type !== "checkbox"
|
||||||
|
);
|
||||||
|
if (requiredWidgets && requiredWidgets?.length > 0) {
|
||||||
|
let checkSigned;
|
||||||
|
for (let i = 0; i < requiredWidgets?.length; i++) {
|
||||||
|
checkSigned = requiredWidgets[i]?.options?.response;
|
||||||
|
if (!checkSigned) {
|
||||||
|
const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl;
|
||||||
|
|
||||||
|
let checkDefaultSigned =
|
||||||
|
requiredWidgets[i]?.options?.defaultValue;
|
||||||
|
if (!checkSignUrl) {
|
||||||
if (!checkDefaultSigned) {
|
if (!checkDefaultSigned) {
|
||||||
if (!showAlert) {
|
if (!showAlert) {
|
||||||
showAlert = true;
|
showAlert = true;
|
||||||
widgetKey = requiredRadio[i].key;
|
widgetKey = requiredWidgets[i].key;
|
||||||
setminRequiredCount(null);
|
setminRequiredCount(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
const requiredWidgets = checkUser[0].placeHolder[i].pos.filter(
|
|
||||||
(position) =>
|
|
||||||
position.options?.status === "required" &&
|
|
||||||
position.type !== radioButtonWidget &&
|
|
||||||
position.type !== "checkbox"
|
|
||||||
);
|
|
||||||
if (requiredWidgets && requiredWidgets?.length > 0) {
|
|
||||||
let checkSigned;
|
|
||||||
for (let i = 0; i < requiredWidgets?.length; i++) {
|
|
||||||
checkSigned = requiredWidgets[i]?.options?.response;
|
|
||||||
if (!checkSigned) {
|
|
||||||
const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl;
|
|
||||||
|
|
||||||
let checkDefaultSigned =
|
|
||||||
requiredWidgets[i]?.options?.defaultValue;
|
|
||||||
if (!checkSignUrl) {
|
|
||||||
if (!checkDefaultSigned) {
|
|
||||||
if (!showAlert) {
|
|
||||||
showAlert = true;
|
|
||||||
widgetKey = requiredWidgets[i].key;
|
|
||||||
setminRequiredCount(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (checkboxExist && requiredCheckbox && showAlert) {
|
if (checkboxExist && requiredCheckbox && showAlert) {
|
||||||
setUnSignedWidgetId(widgetKey);
|
setUnSignedWidgetId(widgetKey);
|
||||||
setWidgetsTour(true);
|
setWidgetsTour(true);
|
||||||
} else if (radioExist && showAlert) {
|
} else if (radioExist && showAlert) {
|
||||||
setUnSignedWidgetId(widgetKey);
|
setUnSignedWidgetId(widgetKey);
|
||||||
setWidgetsTour(true);
|
setWidgetsTour(true);
|
||||||
} else if (showAlert) {
|
} else if (showAlert) {
|
||||||
setUnSignedWidgetId(widgetKey);
|
setUnSignedWidgetId(widgetKey);
|
||||||
setWidgetsTour(true);
|
setWidgetsTour(true);
|
||||||
} else {
|
} else {
|
||||||
setIsUiLoading(true);
|
setIsUiLoading(true);
|
||||||
const pngUrl = checkUser[0].placeHolder;
|
const pngUrl = checkUser[0].placeHolder;
|
||||||
// Load a PDFDocument from the existing PDF bytes
|
// Load a PDFDocument from the existing PDF bytes
|
||||||
const existingPdfBytes = await fetch(pdfUrl).then((res) =>
|
const existingPdfBytes = await fetch(pdfUrl).then((res) =>
|
||||||
res.arrayBuffer()
|
res.arrayBuffer()
|
||||||
);
|
);
|
||||||
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
||||||
ignoreEncryption: true
|
ignoreEncryption: true
|
||||||
});
|
});
|
||||||
const flag = false;
|
const flag = false;
|
||||||
const extUserPtr = pdfDetails[0].ExtUserPtr;
|
const extUserPtr = pdfDetails[0].ExtUserPtr;
|
||||||
const HeaderDocId = extUserPtr?.HeaderDocId;
|
const HeaderDocId = extUserPtr?.HeaderDocId;
|
||||||
//embed document's object id to all pages in pdf document
|
//embed document's object id to all pages in pdf document
|
||||||
if (!HeaderDocId) {
|
if (!HeaderDocId) {
|
||||||
if (!isDocId) {
|
if (!isDocId) {
|
||||||
await embedDocId(pdfDoc, documentId, allPages);
|
await embedDocId(pdfDoc, documentId, allPages);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//embed multi signature in pdf
|
}
|
||||||
const pdfBytes = await multiSignEmbed(
|
//embed multi signature in pdf
|
||||||
pngUrl,
|
const pdfBytes = await multiSignEmbed(
|
||||||
pdfDoc,
|
pngUrl,
|
||||||
pdfOriginalWidth,
|
pdfDoc,
|
||||||
flag,
|
pdfOriginalWidth,
|
||||||
containerWH
|
flag,
|
||||||
|
containerWH
|
||||||
|
);
|
||||||
|
//get ExistUserPtr object id of user class to get tenantDetails
|
||||||
|
const objectId = pdfDetails?.[0]?.ExtUserPtr?.UserId?.objectId;
|
||||||
|
//function for call to embed signature in pdf and get digital signature pdf
|
||||||
|
try {
|
||||||
|
const res = await signPdfFun(
|
||||||
|
pdfBytes,
|
||||||
|
documentId,
|
||||||
|
signerObjectId,
|
||||||
|
setIsAlert,
|
||||||
|
objectId,
|
||||||
|
isSubscribed
|
||||||
);
|
);
|
||||||
//get ExistUserPtr object id of user class to get tenantDetails
|
if (res && res.status === "success") {
|
||||||
const objectId = pdfDetails?.[0]?.ExtUserPtr?.UserId?.objectId;
|
setPdfUrl(res.data);
|
||||||
//function for call to embed signature in pdf and get digital signature pdf
|
setIsSigned(true);
|
||||||
try {
|
setSignedSigners([]);
|
||||||
const res = await signPdfFun(
|
setUnSignedSigners([]);
|
||||||
pdfBytes,
|
getDocumentDetails();
|
||||||
documentId,
|
if (sendInOrder) {
|
||||||
signerObjectId,
|
const index = pdfDetails?.[0].Signers.findIndex(
|
||||||
setIsAlert,
|
(x) => x.Email === jsonSender.email
|
||||||
objectId,
|
);
|
||||||
isSubscribed
|
const requestBody = pdfDetails?.[0]?.RequestBody;
|
||||||
);
|
const requestSubject = pdfDetails?.[0]?.RequestSubject;
|
||||||
if (res && res.status === "success") {
|
|
||||||
setPdfUrl(res.data);
|
|
||||||
setIsSigned(true);
|
|
||||||
setSignedSigners([]);
|
|
||||||
setUnSignedSigners([]);
|
|
||||||
getDocumentDetails();
|
|
||||||
if (sendInOrder) {
|
|
||||||
const index = pdfDetails?.[0].Signers.findIndex(
|
|
||||||
(x) => x.Email === jsonSender.email
|
|
||||||
);
|
|
||||||
const requestBody = pdfDetails?.[0]?.RequestBody;
|
|
||||||
const requestSubject = pdfDetails?.[0]?.RequestSubject;
|
|
||||||
|
|
||||||
const newIndex = index + 1;
|
const newIndex = index + 1;
|
||||||
const user = pdfDetails?.[0].Signers[newIndex];
|
const user = pdfDetails?.[0].Signers[newIndex];
|
||||||
if (user) {
|
if (user) {
|
||||||
const expireDate = pdfDetails?.[0].ExpiryDate.iso;
|
const expireDate = pdfDetails?.[0].ExpiryDate.iso;
|
||||||
const newDate = new Date(expireDate);
|
const newDate = new Date(expireDate);
|
||||||
const localExpireDate = newDate.toLocaleDateString("en-US", {
|
const localExpireDate = newDate.toLocaleDateString("en-US", {
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric"
|
year: "numeric"
|
||||||
});
|
});
|
||||||
let senderEmail = pdfDetails?.[0].ExtUserPtr.Email;
|
let senderEmail = pdfDetails?.[0].ExtUserPtr.Email;
|
||||||
let senderPhone = pdfDetails?.[0]?.ExtUserPtr?.Phone;
|
let senderPhone = pdfDetails?.[0]?.ExtUserPtr?.Phone;
|
||||||
const senderName = `${pdfDetails?.[0].ExtUserPtr.Name}`;
|
const senderName = `${pdfDetails?.[0].ExtUserPtr.Name}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const imgPng =
|
const imgPng =
|
||||||
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
||||||
let url = `${localStorage.getItem(
|
let url = `${localStorage.getItem(
|
||||||
"baseUrl"
|
"baseUrl"
|
||||||
)}functions/sendmailv3/`;
|
)}functions/sendmailv3/`;
|
||||||
const headers = {
|
const headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-Parse-Application-Id":
|
"X-Parse-Application-Id":
|
||||||
localStorage.getItem("parseAppId"),
|
localStorage.getItem("parseAppId"),
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const serverUrl = localStorage.getItem("baseUrl");
|
||||||
|
const newServer = serverUrl.replaceAll("/", "%2F");
|
||||||
|
const objectId = user.objectId;
|
||||||
|
const serverParams = `${newServer}&${localStorage.getItem(
|
||||||
|
"parseAppId"
|
||||||
|
)}&${localStorage.getItem("_appName")}`;
|
||||||
|
const hostUrl = window.location.origin;
|
||||||
|
let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${user.Email}/${objectId}/${serverParams}`;
|
||||||
|
const openSignUrl = "https://www.opensignlabs.com/contact-us";
|
||||||
|
const orgName = pdfDetails[0]?.ExtUserPtr.Company
|
||||||
|
? pdfDetails[0].ExtUserPtr.Company
|
||||||
|
: "";
|
||||||
|
const themeBGcolor = themeColor;
|
||||||
|
let replaceVar;
|
||||||
|
if (
|
||||||
|
requestBody &&
|
||||||
|
requestSubject &&
|
||||||
|
(!isEnableSubscription || isSubscribed)
|
||||||
|
) {
|
||||||
|
const replacedRequestBody = requestBody.replace(/"/g, "'");
|
||||||
|
const htmlReqBody =
|
||||||
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body>" +
|
||||||
|
replacedRequestBody +
|
||||||
|
"</body> </html>";
|
||||||
|
|
||||||
|
const variables = {
|
||||||
|
document_title: pdfDetails?.[0].Name,
|
||||||
|
sender_name: senderName,
|
||||||
|
sender_mail: senderEmail,
|
||||||
|
sender_phone: senderPhone,
|
||||||
|
receiver_name: user.Name,
|
||||||
|
receiver_email: user.Email,
|
||||||
|
receiver_phone: user.Phone,
|
||||||
|
expiry_date: localExpireDate,
|
||||||
|
company_name: orgName,
|
||||||
|
signing_url: `<a href=${signPdf}>Sign here</a>`
|
||||||
};
|
};
|
||||||
const serverUrl = localStorage.getItem("baseUrl");
|
replaceVar = replaceMailVaribles(
|
||||||
const newServer = serverUrl.replaceAll("/", "%2F");
|
requestSubject,
|
||||||
const objectId = user.objectId;
|
htmlReqBody,
|
||||||
const serverParams = `${newServer}&${localStorage.getItem(
|
variables
|
||||||
"parseAppId"
|
);
|
||||||
)}&${localStorage.getItem("_appName")}`;
|
|
||||||
const hostUrl = window.location.origin;
|
|
||||||
let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${user.Email}/${objectId}/${serverParams}`;
|
|
||||||
const openSignUrl =
|
|
||||||
"https://www.opensignlabs.com/contact-us";
|
|
||||||
const orgName = pdfDetails[0]?.ExtUserPtr.Company
|
|
||||||
? pdfDetails[0].ExtUserPtr.Company
|
|
||||||
: "";
|
|
||||||
const themeBGcolor = themeColor;
|
|
||||||
let replaceVar;
|
|
||||||
if (
|
|
||||||
requestBody &&
|
|
||||||
requestSubject &&
|
|
||||||
(!isEnableSubscription || isSubscribed)
|
|
||||||
) {
|
|
||||||
const replacedRequestBody = requestBody.replace(
|
|
||||||
/"/g,
|
|
||||||
"'"
|
|
||||||
);
|
|
||||||
const htmlReqBody =
|
|
||||||
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body>" +
|
|
||||||
replacedRequestBody +
|
|
||||||
"</body> </html>";
|
|
||||||
|
|
||||||
const variables = {
|
|
||||||
document_title: pdfDetails?.[0].Name,
|
|
||||||
sender_name: senderName,
|
|
||||||
sender_mail: senderEmail,
|
|
||||||
sender_phone: senderPhone,
|
|
||||||
receiver_name: user.Name,
|
|
||||||
receiver_email: user.Email,
|
|
||||||
receiver_phone: user.Phone,
|
|
||||||
expiry_date: localExpireDate,
|
|
||||||
company_name: orgName,
|
|
||||||
signing_url: `<a href=${signPdf}>Sign here</a>`
|
|
||||||
};
|
|
||||||
replaceVar = replaceMailVaribles(
|
|
||||||
requestSubject,
|
|
||||||
htmlReqBody,
|
|
||||||
variables
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let params = {
|
|
||||||
extUserId: extUserId,
|
|
||||||
recipient: user.Email,
|
|
||||||
subject: requestSubject
|
|
||||||
? replaceVar?.subject
|
|
||||||
: `${pdfDetails?.[0].ExtUserPtr.Name} has requested you to sign ${pdfDetails?.[0].Name}`,
|
|
||||||
from: senderEmail,
|
|
||||||
html: requestBody
|
|
||||||
? replaceVar?.body
|
|
||||||
: "<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'>" +
|
|
||||||
senderEmail +
|
|
||||||
"</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'>Expires 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 " +
|
|
||||||
senderEmail +
|
|
||||||
" 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>"
|
|
||||||
};
|
|
||||||
await axios.post(url, params, {
|
|
||||||
headers: headers
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log("error", error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
extUserId: extUserId,
|
||||||
|
recipient: user.Email,
|
||||||
|
subject: requestSubject
|
||||||
|
? replaceVar?.subject
|
||||||
|
: `${pdfDetails?.[0].ExtUserPtr.Name} has requested you to sign ${pdfDetails?.[0].Name}`,
|
||||||
|
from: senderEmail,
|
||||||
|
html: requestBody
|
||||||
|
? replaceVar?.body
|
||||||
|
: "<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'>" +
|
||||||
|
senderEmail +
|
||||||
|
"</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'>Expires 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 " +
|
||||||
|
senderEmail +
|
||||||
|
" 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>"
|
||||||
|
};
|
||||||
|
await axios.post(url, params, {
|
||||||
|
headers: headers
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("error", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} else {
|
||||||
setIsAlert({
|
setIsAlert({
|
||||||
isShow: true,
|
isShow: true,
|
||||||
alertMessage: "something went wrong"
|
alertMessage: "something went wrong"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: "something went wrong"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
setIsSignPad(false);
|
|
||||||
} else {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
setIsSignPad(false);
|
||||||
} else {
|
} else {
|
||||||
setIsAlert({
|
setIsAlert({
|
||||||
isShow: true,
|
isShow: true,
|
||||||
alertMessage:
|
alertMessage: "something went wrong"
|
||||||
"Please wait for your turn to sign this document, as it has been set up by the creator to be signed in a specific order; you'll be notified when it's your turn."
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// setIsAlert({
|
||||||
|
// isShow: true,
|
||||||
|
// alertMessage:
|
||||||
|
// "Please wait for your turn to sign this document, as it has been set up by the creator to be signed in a specific order; you'll be notified when it's your turn."
|
||||||
|
// });
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
//function for update TourStatus
|
//function for update TourStatus
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import Loader from "../primitives/LoaderWithMsg";
|
|||||||
import HandleError from "../primitives/HandleError";
|
import HandleError from "../primitives/HandleError";
|
||||||
import SignerListPlace from "../components/pdf/SignerListPlace";
|
import SignerListPlace from "../components/pdf/SignerListPlace";
|
||||||
import Header from "../components/pdf/PdfHeader";
|
import Header from "../components/pdf/PdfHeader";
|
||||||
|
import { RWebShare } from "react-web-share";
|
||||||
import {
|
import {
|
||||||
pdfNewWidthFun,
|
pdfNewWidthFun,
|
||||||
contractDocument,
|
contractDocument,
|
||||||
@@ -30,7 +31,8 @@ import {
|
|||||||
radioButtonWidget,
|
radioButtonWidget,
|
||||||
color,
|
color,
|
||||||
getTenantDetails,
|
getTenantDetails,
|
||||||
replaceMailVaribles
|
replaceMailVaribles,
|
||||||
|
copytoData
|
||||||
} from "../constant/Utils";
|
} from "../constant/Utils";
|
||||||
import RenderPdf from "../components/pdf/RenderPdf";
|
import RenderPdf from "../components/pdf/RenderPdf";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@@ -44,6 +46,7 @@ import WidgetNameModal from "../components/pdf/WidgetNameModal";
|
|||||||
import { SaveFileSize } from "../constant/saveFileSize";
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
import { EmailBody } from "../components/pdf/EmailBody";
|
import { EmailBody } from "../components/pdf/EmailBody";
|
||||||
import Upgrade from "../primitives/Upgrade";
|
import Upgrade from "../primitives/Upgrade";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
|
||||||
function PlaceHolderSign() {
|
function PlaceHolderSign() {
|
||||||
const editorRef = useRef();
|
const editorRef = useRef();
|
||||||
@@ -63,6 +66,7 @@ function PlaceHolderSign() {
|
|||||||
const [isSelectListId, setIsSelectId] = useState();
|
const [isSelectListId, setIsSelectId] = useState();
|
||||||
const [isSendAlert, setIsSendAlert] = useState({});
|
const [isSendAlert, setIsSendAlert] = useState({});
|
||||||
const [isSend, setIsSend] = useState(false);
|
const [isSend, setIsSend] = useState(false);
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState({
|
const [isLoading, setIsLoading] = useState({
|
||||||
isLoad: true,
|
isLoad: true,
|
||||||
message: "This might take some time"
|
message: "This might take some time"
|
||||||
@@ -857,6 +861,7 @@ function PlaceHolderSign() {
|
|||||||
mssg: "confirm",
|
mssg: "confirm",
|
||||||
alert: true
|
alert: true
|
||||||
};
|
};
|
||||||
|
saveDocumentDetails();
|
||||||
setIsSendAlert(alert);
|
setIsSendAlert(alert);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -868,10 +873,146 @@ function PlaceHolderSign() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//function to use save placeholder details in contracts_document
|
||||||
|
const saveDocumentDetails = async () => {
|
||||||
|
let signerMail = signersdata.slice();
|
||||||
|
if (pdfDetails?.[0]?.SendinOrder && pdfDetails?.[0]?.SendinOrder === true) {
|
||||||
|
signerMail.splice(1);
|
||||||
|
}
|
||||||
|
const pdfUrl = await embedPrefilllData();
|
||||||
|
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);
|
||||||
|
if (pdfDetails?.[0]?.SendinOrder && pdfDetails?.[0]?.SendinOrder === true) {
|
||||||
|
const currentUserMail = Parse.User.current()?.getEmail();
|
||||||
|
const isCurrentUser = signerMail?.[0]?.Email === currentUserMail;
|
||||||
|
setIsCurrUser(isCurrentUser);
|
||||||
|
} else {
|
||||||
|
setIsCurrUser(currentUser?.objectId ? true : false);
|
||||||
|
}
|
||||||
|
let updateExpiryDate, data;
|
||||||
|
updateExpiryDate = new Date();
|
||||||
|
updateExpiryDate.setDate(updateExpiryDate.getDate() + addExtraDays);
|
||||||
|
//filter label widgets after add label widgets data on pdf
|
||||||
|
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(() => {
|
||||||
|
setIsMailSend(true);
|
||||||
|
setSignerPos([]);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log("axois err ", err);
|
||||||
|
alert("something went wrong");
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log("error", e);
|
||||||
|
alert("something went wrong");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const copytoclipboard = (text) => {
|
||||||
|
copytoData(text);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCopied(false);
|
||||||
|
}, 1500); // Reset copied state after 1.5 seconds
|
||||||
|
};
|
||||||
|
//function show signer list and share link to share signUrl
|
||||||
|
const handleShareList = () => {
|
||||||
|
const shareLinkList = [];
|
||||||
|
let signerMail = signersdata.slice();
|
||||||
|
if (pdfDetails?.[0]?.SendinOrder && pdfDetails?.[0]?.SendinOrder === true) {
|
||||||
|
signerMail.splice(1);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < signerMail.length; i++) {
|
||||||
|
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;
|
||||||
|
let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}/${serverParams}`;
|
||||||
|
shareLinkList.push({ signerEmail: signerMail[i].Email, url: signPdf });
|
||||||
|
}
|
||||||
|
return shareLinkList.map((data, ind) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col md:flex-row justify-between mb-1"
|
||||||
|
key={ind}
|
||||||
|
>
|
||||||
|
{copied && <Alert type="success">Copied</Alert>}
|
||||||
|
<span>{data.signerEmail}</span>
|
||||||
|
<div className=" ">
|
||||||
|
<span
|
||||||
|
className="mr-3 underline text-blue-700 cursor-pointer "
|
||||||
|
onClick={() => copytoclipboard(data.url)}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-link "></i> copy link
|
||||||
|
</span>
|
||||||
|
<RWebShare
|
||||||
|
data={{
|
||||||
|
// text: "Like humans, flamingos make friends for life",
|
||||||
|
url: data.url,
|
||||||
|
title: "Sign url"
|
||||||
|
}}
|
||||||
|
// onClick={() => console.log("shared successfully!")}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa-solid fa-share-from-square cursor-pointer "
|
||||||
|
style={{ color: themeColor }}
|
||||||
|
></i>
|
||||||
|
</RWebShare>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
const sendEmailToSigners = async () => {
|
const sendEmailToSigners = async () => {
|
||||||
let htmlReqBody;
|
let htmlReqBody;
|
||||||
setIsUiLoading(true);
|
setIsUiLoading(true);
|
||||||
const pdfUrl = await embedPrefilllData();
|
|
||||||
setIsSendAlert({});
|
setIsSendAlert({});
|
||||||
let sendMail;
|
let sendMail;
|
||||||
const expireDate = pdfDetails?.[0].ExpiryDate.iso;
|
const expireDate = pdfDetails?.[0].ExpiryDate.iso;
|
||||||
@@ -987,170 +1128,62 @@ function PlaceHolderSign() {
|
|||||||
}
|
}
|
||||||
if (sendMail.data.result.status === "success") {
|
if (sendMail.data.result.status === "success") {
|
||||||
setMailStatus("success");
|
setMailStatus("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);
|
|
||||||
if (
|
if (
|
||||||
pdfDetails?.[0]?.SendinOrder &&
|
requestBody &&
|
||||||
pdfDetails?.[0]?.SendinOrder === true
|
requestSubject &&
|
||||||
|
isCustomize &&
|
||||||
|
(isSubscribe || !isEnableSubscription)
|
||||||
) {
|
) {
|
||||||
const currentUserMail = Parse.User.current()?.getEmail();
|
try {
|
||||||
const isCurrentUser = signerMail?.[0]?.Email === currentUserMail;
|
const data = {
|
||||||
setIsCurrUser(isCurrentUser);
|
RequestBody: htmlReqBody,
|
||||||
} else {
|
RequestSubject: requestSubject
|
||||||
setIsCurrUser(currentUser?.objectId ? true : false);
|
};
|
||||||
}
|
|
||||||
let updateExpiryDate, data;
|
|
||||||
updateExpiryDate = new Date();
|
|
||||||
updateExpiryDate.setDate(updateExpiryDate.getDate() + addExtraDays);
|
|
||||||
//filter label widgets after add label widgets data on pdf
|
|
||||||
const filterPrefill = signerPos.filter((data) => data.Role !== "prefill");
|
|
||||||
|
|
||||||
try {
|
await axios
|
||||||
if (updateExpiryDate) {
|
.put(
|
||||||
if (isCustomize) {
|
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||||
data = {
|
"_appName"
|
||||||
RequestBody: htmlReqBody,
|
)}_Document/${documentId}`,
|
||||||
RequestSubject: requestSubject,
|
data,
|
||||||
Placeholders: filterPrefill,
|
{
|
||||||
SignedUrl: pdfUrl,
|
headers: {
|
||||||
Signers: signers,
|
"Content-Type": "application/json",
|
||||||
ExpiryDate: {
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
iso: updateExpiryDate,
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
__type: "Date"
|
}
|
||||||
}
|
}
|
||||||
};
|
)
|
||||||
} else {
|
.then(() => {
|
||||||
data = {
|
setIsSend(true);
|
||||||
Placeholders: filterPrefill,
|
setIsMailSend(true);
|
||||||
SignedUrl: pdfUrl,
|
const loadObj = {
|
||||||
Signers: signers,
|
isLoad: false
|
||||||
ExpiryDate: {
|
};
|
||||||
iso: updateExpiryDate,
|
setIsLoading(loadObj);
|
||||||
__type: "Date"
|
setIsUiLoading(false);
|
||||||
}
|
})
|
||||||
};
|
.catch((err) => {
|
||||||
}
|
console.log("axois err ", err);
|
||||||
} else {
|
});
|
||||||
if (isCustomize) {
|
} catch (e) {
|
||||||
data = {
|
console.log("error", e);
|
||||||
RequestBody: htmlReqBody,
|
|
||||||
RequestSubject: requestSubject,
|
|
||||||
Placeholders: filterPrefill,
|
|
||||||
SignedUrl: pdfUrl,
|
|
||||||
Signers: signers
|
|
||||||
};
|
|
||||||
} 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(() => {
|
|
||||||
setIsSend(true);
|
|
||||||
setIsMailSend(true);
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
setIsUiLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("axois err ", err);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.log("error", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setIsSend(true);
|
||||||
|
setIsMailSend(true);
|
||||||
|
const loadObj = {
|
||||||
|
isLoad: false
|
||||||
|
};
|
||||||
|
setIsLoading(loadObj);
|
||||||
|
setIsUiLoading(false);
|
||||||
} else {
|
} else {
|
||||||
setMailStatus("failed");
|
setMailStatus("failed");
|
||||||
const signers = signersdata?.map((x) => {
|
setIsSend(true);
|
||||||
return {
|
setIsMailSend(true);
|
||||||
__type: "Pointer",
|
setIsUiLoading(false);
|
||||||
className: "contracts_Contactbook",
|
|
||||||
objectId: x.objectId
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const addExtraDays = pdfDetails[0]?.TimeToCompleteDays
|
|
||||||
? pdfDetails[0].TimeToCompleteDays
|
|
||||||
: 15;
|
|
||||||
const currentUser = signersdata.find((x) => x.Email === currentId);
|
|
||||||
setIsCurrUser(currentUser?.objectId ? true : false);
|
|
||||||
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(() => {
|
|
||||||
setIsSend(true);
|
|
||||||
setIsMailSend(true);
|
|
||||||
setIsUiLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("axois err ", err);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.log("error", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleDontShow = (isChecked) => {
|
const handleDontShow = (isChecked) => {
|
||||||
@@ -1615,92 +1648,112 @@ function PlaceHolderSign() {
|
|||||||
) : (
|
) : (
|
||||||
isSendAlert.mssg === "confirm" && (
|
isSendAlert.mssg === "confirm" && (
|
||||||
<>
|
<>
|
||||||
<p>
|
|
||||||
Are you sure you want to send out this document for
|
|
||||||
signatures?
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<>
|
<>
|
||||||
|
{!isCustomize && (
|
||||||
|
<span>
|
||||||
|
Are you sure you want to send out this document
|
||||||
|
for signatures?
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{isCustomize &&
|
||||||
|
(!isEnableSubscription || isSubscribe) && (
|
||||||
|
<>
|
||||||
|
<EmailBody
|
||||||
|
editorRef={editorRef}
|
||||||
|
requestBody={requestBody}
|
||||||
|
requestSubject={requestSubject}
|
||||||
|
handleOnchangeRequest={handleOnchangeRequest}
|
||||||
|
setRequestSubject={setRequestSubject}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
"flex justify-end items-center gap-1 mt-2 underline text-blue-700 focus:outline-none cursor-pointer "
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
setRequestBody(defaultBody);
|
||||||
|
setRequestSubject(defaultSubject);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>Reset to default</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
"flex mt-4 items-center gap-1 mt-2 underline text-blue-700 focus:outline-none "
|
"flex flex-col md:flex-row md:items-center md:gap-6 mt-2 "
|
||||||
}
|
}
|
||||||
onClick={() => {
|
|
||||||
isSubscribe ||
|
|
||||||
(!isEnableSubscription &&
|
|
||||||
setIsCustomize(!isCustomize));
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<span
|
<div className="flex flex-row gap-2">
|
||||||
className={
|
<button
|
||||||
isSubscribe || !isEnableSubscription
|
onClick={() => sendEmailToSigners()}
|
||||||
? "cursor-pointer"
|
className=" shadow rounded-[2px] py-[3px] px-[25px] font-[500] text-sm "
|
||||||
: "opacity-30 select-none"
|
style={{
|
||||||
}
|
background: themeColor,
|
||||||
>
|
color: "white"
|
||||||
Cutomize Email
|
}}
|
||||||
</span>
|
>
|
||||||
|
Send
|
||||||
|
</button>
|
||||||
|
{isCustomize && (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setIsCustomize(false);
|
||||||
|
}}
|
||||||
|
className=" shadow rounded-[2px] py-[3px] px-[25px] font-[500] text-sm border-[0.1px] border-gray-300"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!isCustomize && (
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
isSubscribe || !isEnableSubscription
|
||||||
|
? "cursor-pointer underline text-blue-700 focus:outline-none"
|
||||||
|
: "opacity-30 select-none underline text-blue-700 focus:outline-none"
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
isSubscribe ||
|
||||||
|
(!isEnableSubscription &&
|
||||||
|
setIsCustomize(!isCustomize));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cutomize Email
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
{!isSubscribe && isEnableSubscription && (
|
{!isSubscribe && isEnableSubscription && (
|
||||||
<Upgrade message="Upgrade to customize Email" />
|
<Upgrade message="Upgrade to customize Email" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
{isCustomize &&
|
|
||||||
(!isEnableSubscription || isSubscribe) && (
|
|
||||||
<>
|
|
||||||
<EmailBody
|
|
||||||
editorRef={editorRef}
|
|
||||||
requestBody={requestBody}
|
|
||||||
requestSubject={requestSubject}
|
|
||||||
handleOnchangeRequest={handleOnchangeRequest}
|
|
||||||
setRequestSubject={setRequestSubject}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
"flex justify-end items-center gap-1 mt-2 underline text-blue-700 focus:outline-none cursor-pointer "
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
setRequestBody(defaultBody);
|
|
||||||
setRequestSubject(defaultSubject);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>Reset to default</span>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
|
|
||||||
{isSendAlert.mssg === "confirm" && (
|
{isSendAlert.mssg === "confirm" && (
|
||||||
<button
|
<>
|
||||||
onClick={() => sendEmailToSigners()}
|
<div className="flex justify-center items-center mt-4">
|
||||||
style={{ background: themeColor }}
|
<span
|
||||||
type="button"
|
style={{
|
||||||
className="finishBtn"
|
height: 1,
|
||||||
>
|
width: "20%",
|
||||||
Send
|
backgroundColor: "#ccc"
|
||||||
</button>
|
}}
|
||||||
|
></span>
|
||||||
|
<span className="ml-[5px] mr-[5px]">or</span>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
height: 1,
|
||||||
|
width: "20%",
|
||||||
|
backgroundColor: "#ccc"
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 mb-3">{handleShareList()}</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<button
|
|
||||||
onClick={() => setIsSendAlert({})}
|
|
||||||
type="button"
|
|
||||||
className="finishBtn cancelBtn"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
|
|
||||||
@@ -1746,6 +1799,7 @@ function PlaceHolderSign() {
|
|||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsSend(false);
|
setIsSend(false);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const Signup = () => {
|
|||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
const [company, setCompany] = useState("");
|
const [company, setCompany] = useState("");
|
||||||
const [jobTitle, setJobTitle] = useState("");
|
const [jobTitle, setJobTitle] = useState("");
|
||||||
const [image, setImage] = useState(appInfo?.applogo);
|
const [image, setImage] = useState();
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
loading: false,
|
loading: false,
|
||||||
alertType: "success",
|
alertType: "success",
|
||||||
@@ -482,6 +482,8 @@ const Signup = () => {
|
|||||||
} else {
|
} else {
|
||||||
setImage(appInfo?.applogo || undefined);
|
setImage(appInfo?.applogo || undefined);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setImage(appInfo?.applogo || undefined);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user