diff --git a/apps/OpenSign/public/locales/en/translation.json b/apps/OpenSign/public/locales/en/translation.json
index af4497936..11417711a 100644
--- a/apps/OpenSign/public/locales/en/translation.json
+++ b/apps/OpenSign/public/locales/en/translation.json
@@ -303,7 +303,9 @@
"otp-verification":"OTP verification",
"enter-otp":"Enter OTP",
"verify":"Verify",
+ "verify-email-1":"Verify email",
"resend":"Resend",
+ "contact-details":"Contact Details",
"verify-email":"Please verify your email !",
"send-otp":" Send OTP",
"otp-placeholder":"Enter OTP received over email",
@@ -567,6 +569,9 @@
"placeholder-sign-4":"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.",
"placeholder-sign-5":"Clicking 'Send' will save the document. In the next step you can customize the emails to be sent out to the recipients or copy the signing links and share those with the recipients yourself.",
"report-1":"Click the 'Add' button to create a new template. Templates are reusable documents designed to quickly generate new documents with the same structure and varying signers. For example, an HR template for onboarding could have predefined roles like ‘HR Manager’ and ‘New Employee’. Each time you use the template, you can assign the ‘New Employee’ role to different incoming staff members, while the ‘HR Manager’ role remains constant, facilitating a seamless onboarding process for each recruit. ",
+ "redirect":"Click the 'Use' button to create a new document from an existing template.",
+ "bulksend":"To quickly create and send multiple documents using an existing template, click the 'Quick Send' button.",
+ "option": "This menu reveals more options such as Edit & Delete. Use the 'Edit' button to add signer roles, modify fields, and update your template. Changes will apply to all future documents created from this template but won’t affect existing documents.Use the Delete button you can delete template. ",
"signyour-self-1":"Select and drag your preferred widgets onto the PDF to customize your document before signing. Choose the perfect spots for each modification to tailor the document to your needs.",
"signyour-self-2":"Drag and drop anywhere in this area. You can resize and move it later.",
"template-placeholder-1":"Clicking 'Add role' button will allow you to add various signer roles. You can attach users to each role in subsequent steps.",
@@ -580,11 +585,13 @@
"Recent signature requests": "This is a list of documents that are waiting for your signature.",
"Recently sent for signatures":"This is a list of documents you've sent to other parties for signature.",
"Drafts":"This are documents you have started but have not finalized for sending."
-
-
-
-
- }
+ },
+ "enter-email-plaholder":"Add an email address and hit enter",
+ "success-email-alert":"Email sent successfully!",
+ "expired-doc-title":"Expired Document",
+ "expired-on-mssg" :"This document expired on {{expiredDate}} and is no longer available to sign.",
+ "signature-validate-alert":"Please confirm that you have selected at least {{minRequiredCount}} checkboxes.",
+ "signature-validate-alert-2" :"Ensure this field is accurately filled and meets all requirements."
diff --git a/apps/OpenSign/public/locales/fr/translation.json b/apps/OpenSign/public/locales/fr/translation.json
index 9ba28201c..c79e0f9bc 100644
--- a/apps/OpenSign/public/locales/fr/translation.json
+++ b/apps/OpenSign/public/locales/fr/translation.json
@@ -114,7 +114,7 @@
"Users":"Utilisateurs"
},
"report-heading":{
- "Sr.No":"Numéro du document",
+ "Sr.No":"Numéro",
"Title":"Titre",
"Email":"E-mail",
"Phone":"Téléphone",
@@ -128,7 +128,7 @@
"Active":"Actif",
"Role":"Rôle",
"Team":"Équipe",
- "Name":"Nom et Prénom",
+ "Name":"Nom",
"Status":"Statut",
"created-date":"Date de création",
"Type":"Saisir"
@@ -302,7 +302,9 @@
"otp-verification":"Vérification OTP",
"enter-otp":"Entrez OTP",
"verify":"Vérifier",
+ "verify-email-1":"Vérifier l'e-mail",
"resend":"Renvoyer",
+ "contact-details" :"Coordonnées",
"verify-email":"Veuillez vérifier votre email!",
"send-otp":"envoyer un code à usage unique",
"otp-placeholder":"Saisissez l'OTP reçu par e-mail",
@@ -566,6 +568,9 @@
"placeholder-sign-4":"La zone de contenu PDF affiche déjà les espaces réservés existants du modèle. Pour votre commodité, ces espaces réservés correspondront à la couleur du nom du destinataire, ce qui les rendra facilement identifiables.",
"placeholder-sign-5":"Cliquer sur 'Envoyer' enregistrera le document. À l'étape suivante, vous pourrez personnaliser les e-mails à envoyer aux destinataires ou copier les liens de signature et les partager vous-même avec les destinataires.",
"report-1":"Cliquez sur le bouton 'Ajouter' pour créer un nouveau modèle. Les modèles sont des documents réutilisables conçus pour générer rapidement de nouveaux documents avec la même structure et différents signataires. Par exemple, un modèle RH pour l'intégration peut avoir des rôles prédéfinis tels que 'Responsable RH' et ' Nouvel employé'. Chaque fois que vous utilisez le modèle, vous pouvez attribuer le rôle 'Nouvel employé' à différents membres du personnel entrants, tandis que le rôle 'Responsable RH' reste constant, facilitant ainsi un processus d'intégration fluide pour chaque recrue",
+ "redirect":"Cliquez sur le bouton 'Utiliser' pour créer un nouveau document à partir d'un modèle existant.",
+ "bulksend":"Pour créer et envoyer rapidement plusieurs documents à l'aide d'un modèle existant, cliquez sur le bouton 'Envoi rapide'.",
+ "option": "Ce menu révèle plus d'options telles que Modifier et Supprimer. Utilisez le bouton « Modifier » pour ajouter des rôles de signataire, modifier les champs et mettre à jour votre modèle. Les modifications s'appliqueront à tous les futurs documents créés à partir de ce modèle mais n'affecteront pas les documents existants. Utilisez le bouton Supprimer, vous pouvez supprimer le modèle ",
"signyour-self-1": "Sélectionnez et faites glisser vos widgets préférés sur le PDF pour personnaliser votre document avant de le signer. Choisissez les endroits parfaits pour chaque modification afin d'adapter le document à vos besoins.",
"signyour-self-2":"Faites glisser et déposer n'importe où dans cette zone. Vous pourrez la redimensionner et la déplacer plus tard.",
"template-placeholder-1":"Cliquer sur le bouton 'Ajouter un rôle' vous permettra d'ajouter différents rôles de signataire. Vous pourrez attacher des utilisateurs à chaque rôle dans les étapes suivantes.",
@@ -579,8 +584,13 @@
"Recent signature requests": "Voici une liste de documents qui attendent votre signature.",
"Recently sent for signatures":"Il s'agit d'une liste de documents que vous avez envoyés à d'autres parties pour signature.",
"Drafts":"Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi."
-
- }
+ },
+ "enter-email-plaholder":"Ajoutez une adresse email et appuyez sur Entrée",
+ "success-email-alert" :"E-mail envoyé avec succès!",
+ "expired-doc-title" :"Document expiré",
+ "expired-on-mssg" :"Ce document a expiré le {{expiredDate}} et n'est plus disponible pour signature.",
+ "signature-validate-alert":"Veuillez confirmer que vous avez coché au moins {{minRequiredCount}} cases.",
+ "signature-validate-alert-2" :"Assurez-vous que ce champ est rempli avec précision et répond à toutes les exigences."
diff --git a/apps/OpenSign/src/components/AddSigner.js b/apps/OpenSign/src/components/AddSigner.js
index 8f4eb528d..24e73de24 100644
--- a/apps/OpenSign/src/components/AddSigner.js
+++ b/apps/OpenSign/src/components/AddSigner.js
@@ -247,7 +247,9 @@ const AddSigner = (props) => {
type="email"
id="email"
value={email}
- onChange={(e) => setEmail(e.target.value?.toLowerCase())}
+ onChange={(e) =>
+ setEmail(e.target.value?.toLowerCase?.replace(/\s/g, ""))
+ }
required
onInvalid={(e) => e.target.setCustomValidity(t("input-required"))}
onInput={(e) => e.target.setCustomValidity("")}
diff --git a/apps/OpenSign/src/components/AddUser.js b/apps/OpenSign/src/components/AddUser.js
index 4eee75af4..2bdd3f5f5 100644
--- a/apps/OpenSign/src/components/AddUser.js
+++ b/apps/OpenSign/src/components/AddUser.js
@@ -240,8 +240,15 @@ const AddUser = (props) => {
props.closePopup();
}
};
- const handleChange = (e) => {
- setFormdata((prev) => ({ ...prev, [e.target.name]: e.target.value }));
+ const handleChange = (event) => {
+ let { name, value } = event.target;
+ if (name === "email") {
+ value = value?.toLowerCase()?.replace(/\s/g, "");
+ }
+ setFormdata((prev) => ({
+ ...prev,
+ [name]: value
+ }));
};
const copytoclipboard = (text) => {
diff --git a/apps/OpenSign/src/components/pdf/EmailComponent.js b/apps/OpenSign/src/components/pdf/EmailComponent.js
index a41f82cbb..948f58994 100644
--- a/apps/OpenSign/src/components/pdf/EmailComponent.js
+++ b/apps/OpenSign/src/components/pdf/EmailComponent.js
@@ -1,9 +1,7 @@
import React, { useState } from "react";
-import { saveAs } from "file-saver";
import axios from "axios";
-import { getBase64FromUrl } from "../../constant/Utils";
+import { handleDownloadPdf, handleToPrint } from "../../constant/Utils";
import { themeColor, emailRegex } from "../../constant/const";
-import printModule from "print-js";
import Loader from "../../primitives/Loader";
import ModalUi from "../../primitives/ModalUi";
import { useTranslation } from "react-i18next";
@@ -13,7 +11,7 @@ function EmailComponent({
pdfUrl,
setIsEmail,
setSuccessEmail,
- pdfName,
+ pdfDetails,
sender,
setIsAlert,
extUserId,
@@ -24,10 +22,12 @@ function EmailComponent({
const [emailValue, setEmailValue] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [emailErr, setEmailErr] = useState(false);
+ const [isDownloading, setIsDownloading] = useState("");
+ const isAndroid = /Android/i.test(navigator.userAgent);
//function for send email
const sendEmail = async () => {
+ const pdfName = pdfDetails[0]?.Name;
setIsLoading(true);
-
let sendMail;
for (let i = 0; i < emailList.length; i++) {
try {
@@ -113,7 +113,7 @@ function EmailComponent({
};
//function for get email value
const handleEmailValue = (e) => {
- const value = e.target.value;
+ const value = e.target.value?.toLowerCase()?.replace(/\s/g, "");
setEmailErr(false);
setEmailValue(value);
};
@@ -140,43 +140,6 @@ function EmailComponent({
}
}
};
-
- // function for print signed pdf
- const handleToPrint = async (event) => {
- event.preventDefault();
-
- const pdf = await getBase64FromUrl(pdfUrl);
- const isAndroidDevice = navigator.userAgent.match(/Android/i);
- const isAppleDevice =
- (/iPad|iPhone|iPod/.test(navigator.platform) ||
- (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)) &&
- !window.MSStream;
- if (isAndroidDevice || isAppleDevice) {
- const byteArray = Uint8Array.from(
- atob(pdf)
- .split("")
- .map((char) => char.charCodeAt(0))
- );
- const blob = new Blob([byteArray], { type: "application/pdf" });
- const blobUrl = URL.createObjectURL(blob);
- window.open(blobUrl, "_blank");
- } else {
- printModule({ printable: pdf, type: "pdf", base64: true });
- }
- };
-
- //handle download signed pdf
- const handleDownloadPdf = () => {
- saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
- };
-
- const sanitizeFileName = (pdfName) => {
- // Replace spaces with underscore
- return pdfName.replace(/ /g, "_");
- };
-
- const isAndroid = /Android/i.test(navigator.userAgent);
-
return (
{/* isEmail */}
@@ -190,6 +153,11 @@ function EmailComponent({
)}
+ {isDownloading === "pdf" && (
+
+
+
+ )}
{t("successfully-signed")}
@@ -197,7 +165,7 @@ function EmailComponent({
{!isAndroid && (
handleToPrint(e, pdfUrl, setIsDownloading)}
className="op-btn op-btn-neutral op-btn-sm text-[15px]"
>
@@ -206,7 +174,9 @@ function EmailComponent({
)}
handleDownloadPdf()}
+ onClick={() =>
+ handleDownloadPdf(pdfDetails, pdfUrl, setIsDownloading)
+ }
>
{t("download")}
@@ -263,7 +233,7 @@ function EmailComponent({
className="p-[10px] pb-[20px] rounded w-full text-[15px] outline-none bg-transparent border-[1.5px] op-border-primary"
onChange={handleEmailValue}
onKeyDown={handleEnterPress}
- placeholder="Add an email address and hit enter"
+ placeholder={t("enter-email-plaholder")}
onBlur={() => emailValue && handleEnterPress("add")}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
diff --git a/apps/OpenSign/src/components/pdf/RenderPdf.js b/apps/OpenSign/src/components/pdf/RenderPdf.js
index 6250ad32f..4e1fe3fe2 100644
--- a/apps/OpenSign/src/components/pdf/RenderPdf.js
+++ b/apps/OpenSign/src/components/pdf/RenderPdf.js
@@ -9,6 +9,7 @@ import {
} from "../../constant/Utils";
import Placeholder from "./Placeholder";
import Alert from "../../primitives/Alert";
+import { useTranslation } from "react-i18next";
function RenderPdf({
pageNumber,
@@ -24,7 +25,6 @@ function RenderPdf({
setSignKey,
pdfDetails,
xyPostion,
- pdfUrl,
pageDetails,
pdfRequest,
signerObjectId,
@@ -63,6 +63,7 @@ function RenderPdf({
ispublicTemplate,
handleUserDetails
}) {
+ const { t } = useTranslation();
const isMobile = window.innerWidth < 767;
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
const isGuestSigner = localStorage.getItem("isGuestSigner");
@@ -249,7 +250,9 @@ function RenderPdf({
};
return (
<>
- {successEmail && Email sent successfully! }
+ {successEmail && (
+ {t("success-email-alert")}
+ )}
{isMobile ? (
{
setPdfLoad(false);
}}
- loading={"Loading Document.."}
+ loading={t("loading-doc")}
onLoadSuccess={pageDetails}
// ref={pdfRef}'
onClick={() => {
@@ -402,13 +405,7 @@ function RenderPdf({
setSelectWidgetId("");
}
}}
- file={
- pdfUrl
- ? pdfUrl
- : pdfDetails[0] && pdfDetails[0].SignedUrl
- ? pdfDetails[0].SignedUrl
- : pdfDetails[0].URL
- }
+ file={pdfDetails[0]?.SignedUrl || pdfDetails[0]?.URL}
>
{
setPdfLoad(false);
}}
- loading={"Loading Document.."}
+ loading={t("loading-doc")}
onLoadSuccess={pageDetails}
onClick={() => {
if (setSelectWidgetId) {
@@ -589,13 +586,7 @@ function RenderPdf({
}
}}
// ref={pdfRef}
- file={
- pdfUrl
- ? pdfUrl
- : pdfDetails[0] && pdfDetails[0].SignedUrl
- ? pdfDetails[0].SignedUrl
- : pdfDetails[0].URL
- }
+ file={pdfDetails[0]?.SignedUrl || pdfDetails[0].URL}
>
{
return 20;
};
-export async function getBase64FromUrl(url) {
+export async function getBase64FromUrl(url, autosign) {
const data = await fetch(url);
const blob = await data.blob();
return new Promise((resolve) => {
@@ -447,8 +447,12 @@ export async function getBase64FromUrl(url) {
reader.readAsDataURL(blob);
reader.onloadend = function () {
const pdfBase = this.result;
- const suffixbase64 = pdfBase.split(",").pop();
- resolve(suffixbase64);
+ if (autosign) {
+ resolve(pdfBase);
+ } else {
+ const suffixbase64 = pdfBase.split(",").pop();
+ resolve(suffixbase64);
+ }
};
});
}
@@ -2230,3 +2234,38 @@ export const saveLanguageInLocal = (i18n) => {
const detectedLanguage = i18n.language || "en";
localStorage.setItem("i18nextLng", detectedLanguage);
};
+//function to get default signatur eof current user from `contracts_Signature` class
+export const getDefaultSignature = async (objectId) => {
+ try {
+ const query = new Parse.Query("contracts_Signature");
+ query.equalTo("UserId", {
+ __type: "Pointer",
+ className: "_User",
+ objectId: objectId
+ });
+
+ const result = await query.first();
+ if (result) {
+ const res = JSON.parse(JSON.stringify(result));
+ const defaultSignature = res?.ImageURL
+ ? await getBase64FromUrl(res?.ImageURL, true)
+ : "";
+ const defaultInitial = res?.Initials
+ ? await getBase64FromUrl(res?.Initials, true)
+ : "";
+
+ return {
+ status: "success",
+ res: {
+ defaultSignature: defaultSignature,
+ defaultInitial: defaultInitial
+ }
+ };
+ }
+ } catch (err) {
+ console.log("Error: error in fetch data in contracts_Signature", err);
+ return {
+ status: "error"
+ };
+ }
+};
diff --git a/apps/OpenSign/src/constant/const.js b/apps/OpenSign/src/constant/const.js
index 4ac828514..f5a7babe8 100644
--- a/apps/OpenSign/src/constant/const.js
+++ b/apps/OpenSign/src/constant/const.js
@@ -11,3 +11,7 @@ export const isEnableSubscription =
: false;
export const isStaging =
window.location.origin === "https://staging-app.opensignlabs.com";
+export const isPublicProduction =
+ window.location.origin === "https://opensign.me";
+export const isPublicStaging =
+ window.location.origin === "https://staging.opensign.me";
diff --git a/apps/OpenSign/src/i18n.js b/apps/OpenSign/src/i18n.js
index e82bfc4ce..3d9e3adfd 100644
--- a/apps/OpenSign/src/i18n.js
+++ b/apps/OpenSign/src/i18n.js
@@ -2,12 +2,23 @@ import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import Backend from "i18next-http-backend";
import LanguageDetector from "i18next-browser-languagedetector";
+import { isPublicProduction, isPublicStaging } from "./constant/const";
+
+//handle path to support language on public profile
+const backendPath = isPublicStaging
+ ? "https://staging-app.opensignlabs.com/locales/{{lng}}/{{ns}}.json"
+ : isPublicProduction
+ ? "https://app.opensignlabs.com/locales/{{lng}}/{{ns}}.json"
+ : "/locales/{{lng}}/{{ns}}.json";
i18n
.use(Backend)
.use(LanguageDetector) // Use LanguageDetector directly without creating an instance
.use(initReactI18next)
.init({
+ backend: {
+ loadPath: backendPath
+ },
fallbackLng: "en", // Fallback to English if no other language is detected
detection: {
// Specifies the default language to fall back to if the detected language is not available.
@@ -15,6 +26,8 @@ i18n
// Defines where the detected language should be cached.
caches: ["localStorage"]
},
+ ns: ["translation"], // default namespace
+ defaultNS: "translation", // default namespace
//Enables debug mode, which outputs detailed logs to the console about the translation process.
debug: false,
interpolation: {
diff --git a/apps/OpenSign/src/json/ReportJson.js b/apps/OpenSign/src/json/ReportJson.js
index 626c6cb61..f09d72279 100644
--- a/apps/OpenSign/src/json/ReportJson.js
+++ b/apps/OpenSign/src/json/ReportJson.js
@@ -10,7 +10,7 @@ export default function reportJson(id) {
"Owner",
"Signers"
];
- const contactbook = ["Sr.No", "Title", "Email", "Phone"];
+ const contactbook = ["Sr.No", "Name", "Email", "Phone"];
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"];
switch (id) {
@@ -325,9 +325,7 @@ export default function reportJson(id) {
btnIcon: "fa-light fa-plus",
redirectUrl: "placeHolderSign",
action: "redirect",
- selector: "reactourSecond",
- message:
- "Click the 'Use' button to create a new document from an existing template. "
+ selector: "reactourSecond"
},
{
btnId: "1631",
@@ -337,9 +335,7 @@ export default function reportJson(id) {
btnIcon: "fa-light fa-envelope",
redirectUrl: "",
action: "bulksend",
- selector: "tourbulksend",
- message:
- "To quickly create and send multiple documents using an existing template, click the 'Quick Send' button."
+ selector: "tourbulksend"
},
{
btnId: "2234",
@@ -349,8 +345,6 @@ export default function reportJson(id) {
btnIcon: "fa-light fa-ellipsis-vertical fa-lg",
action: "option",
selector: "reactourThird",
- message:
- "This menu reveals more options such as Edit & Delete. Use the 'Edit' button to add signer roles, modify fields, and update your template. Changes will apply to all future documents created from this template but won’t affect existing documents.Use the Delete button you can delete template. ",
subaction: [
{
btnId: "2434",
diff --git a/apps/OpenSign/src/layout/HomeLayout.js b/apps/OpenSign/src/layout/HomeLayout.js
index a9cb67e5e..7c7fca29c 100644
--- a/apps/OpenSign/src/layout/HomeLayout.js
+++ b/apps/OpenSign/src/layout/HomeLayout.js
@@ -38,6 +38,7 @@ const HomeLayout = () => {
useEffect(() => {
const language = localStorage.getItem("i18nextLng");
i18n.changeLanguage(language);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
diff --git a/apps/OpenSign/src/pages/AddAdmin.js b/apps/OpenSign/src/pages/AddAdmin.js
index 82c5da286..5214109b4 100644
--- a/apps/OpenSign/src/pages/AddAdmin.js
+++ b/apps/OpenSign/src/pages/AddAdmin.js
@@ -310,7 +310,11 @@ const AddAdmin = () => {
type="email"
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
value={email}
- onChange={(e) => setEmail(e.target.value?.toLowerCase())}
+ onChange={(e) =>
+ setEmail(
+ e.target.value?.toLowerCase()?.replace(/\s/g, "")
+ )
+ }
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
diff --git a/apps/OpenSign/src/pages/ForgetPassword.js b/apps/OpenSign/src/pages/ForgetPassword.js
index 0bab81f53..5591df965 100644
--- a/apps/OpenSign/src/pages/ForgetPassword.js
+++ b/apps/OpenSign/src/pages/ForgetPassword.js
@@ -24,7 +24,10 @@ function ForgotPassword() {
const [image, setImage] = useState();
const handleChange = (event) => {
- const { name, value } = event.target;
+ let { name, value } = event.target;
+ if (name === "email") {
+ value = value?.toLowerCase()?.replace(/\s/g, "");
+ }
setState({ ...state, [name]: value });
};
diff --git a/apps/OpenSign/src/pages/Login.js b/apps/OpenSign/src/pages/Login.js
index 43f085a19..04a0887d5 100644
--- a/apps/OpenSign/src/pages/Login.js
+++ b/apps/OpenSign/src/pages/Login.js
@@ -74,7 +74,10 @@ function Login() {
dispatch(fetchAppInfo());
};
const handleChange = (event) => {
- const { name, value } = event.target;
+ let { name, value } = event.target;
+ if (name === "email") {
+ value = value?.toLowerCase()?.replace(/\s/g, "");
+ }
setState({ ...state, [name]: value });
};
diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js
index 1e77ff05a..f72b098f5 100644
--- a/apps/OpenSign/src/pages/PdfRequestFiles.js
+++ b/apps/OpenSign/src/pages/PdfRequestFiles.js
@@ -30,7 +30,8 @@ import {
contactBook,
handleDownloadPdf,
handleToPrint,
- handleDownloadCertificate
+ handleDownloadCertificate,
+ getDefaultSignature
} from "../constant/Utils";
import LoaderWithMsg from "../primitives/LoaderWithMsg";
import HandleError from "../primitives/HandleError";
@@ -340,243 +341,232 @@ function PdfRequestFiles(props) {
};
//function for get document details for perticular signer with signer'object id
const getDocumentDetails = async (docId, isNextUser) => {
- const senderUser = localStorage.getItem(
- `Parse/${localStorage.getItem("parseAppId")}/currentUser`
- );
- const jsonSender = JSON.parse(senderUser);
- let currUserId;
- //getting document details
- const documentData = await contractDocument(documentId || docId);
- if (documentData && documentData.length > 0) {
- setExtUserId(documentData[0]?.ExtUserPtr?.objectId);
- const isCompleted =
- documentData[0].IsCompleted && documentData[0].IsCompleted;
- const expireDate = documentData[0].ExpiryDate.iso;
- const declined = documentData[0].IsDeclined && documentData[0].IsDeclined;
- const expireUpdateDate = new Date(expireDate).getTime();
- const currDate = new Date().getTime();
- const getSigners = documentData[0].Signers;
- const getCurrentSigner =
- getSigners &&
- getSigners.filter(
- (data) => data.UserId.objectId === jsonSender?.objectId
- );
+ try {
+ const senderUser = localStorage.getItem(
+ `Parse/${localStorage.getItem("parseAppId")}/currentUser`
+ );
+ const jsonSender = JSON.parse(senderUser);
+ let currUserId;
+ //getting document details
+ const documentData = await contractDocument(documentId || docId);
+ if (documentData && documentData.length > 0) {
+ setExtUserId(documentData[0]?.ExtUserPtr?.objectId);
+ const isCompleted =
+ documentData[0].IsCompleted && documentData[0].IsCompleted;
+ const expireDate = documentData[0].ExpiryDate.iso;
+ const declined =
+ documentData[0].IsDeclined && documentData[0].IsDeclined;
+ const expireUpdateDate = new Date(expireDate).getTime();
+ const currDate = new Date().getTime();
+ const getSigners = documentData[0].Signers;
+ const getCurrentSigner =
+ getSigners &&
+ getSigners.filter(
+ (data) => data.UserId.objectId === jsonSender?.objectId
+ );
- currUserId = getCurrentSigner[0] ? getCurrentSigner[0].objectId : "";
- if (isEnableSubscription) {
- await checkIsSubscribed(
- documentData[0]?.ExtUserPtr?.objectId,
- currUserId
- );
- }
- if (currUserId) {
- setSignerObjectId(currUserId);
- }
- if (documentData[0].SignedUrl) {
- setPdfUrl(documentData[0].SignedUrl);
- } else {
- setPdfUrl(documentData[0].URL);
- }
- if (isCompleted) {
- setIsSigned(true);
- const data = {
- isCertificate: true,
- isModal: true
- };
- setAlreadySign(true);
- setIsCompleted(data);
- setIsCelebration(true);
- setTimeout(() => {
- setIsCelebration(false);
- }, 5000);
- } else if (declined) {
- const currentDecline = {
- currnt: "another",
- isDeclined: true
- };
- setIsDecline(currentDecline);
- } else if (currDate > expireUpdateDate) {
- const expireDateFormat = moment(new Date(expireDate)).format(
- "MMM DD, YYYY"
- );
- setIsExpired(true);
- setExpiredDate(expireDateFormat);
- } // Check if the current signer is not a last signer and handle the complete message.
- else if (isNextUser) {
- setIsCelebration(true);
- setTimeout(() => {
- setIsCelebration(false);
- }, 5000);
- setIsCompleted({
- isModal: true,
- message: t("document-signed-alert-1")
- });
- } else {
+ currUserId = getCurrentSigner[0] ? getCurrentSigner[0].objectId : "";
+ if (isEnableSubscription) {
+ await checkIsSubscribed(
+ documentData[0]?.ExtUserPtr?.objectId,
+ currUserId
+ );
+ }
if (currUserId) {
- const checkCurrentUser = documentData[0].Placeholders.find(
- (data) => data?.signerObjId === currUserId
- );
- if (checkCurrentUser) {
- setCurrentSigner(true);
- }
+ setSignerObjectId(currUserId);
}
- }
- const audittrailData =
- documentData[0].AuditTrail &&
- documentData[0].AuditTrail.length > 0 &&
- documentData[0].AuditTrail.filter((data) => data.Activity === "Signed");
-
- const checkAlreadySign =
- documentData[0].AuditTrail &&
- documentData[0].AuditTrail.length > 0 &&
- documentData[0].AuditTrail.filter(
- (data) =>
- data.UserPtr.objectId === currUserId && data.Activity === "Signed"
- );
- if (
- checkAlreadySign &&
- checkAlreadySign[0] &&
- checkAlreadySign.length > 0
- ) {
- setAlreadySign(true);
- } else {
- const obj = documentData?.[0];
- setSendInOrder(obj?.SendinOrder || false);
- if (
- obj &&
- obj.Signers &&
- obj.Signers.length > 0 &&
- obj.Placeholders &&
- obj.Placeholders.length > 0
- ) {
- const params = {
- event: "viewed",
- contactId: currUserId,
- body: {
- objectId: documentData?.[0].objectId,
- file: documentData?.[0]?.SignedUrl || documentData?.[0]?.URL,
- name: documentData?.[0].Name,
- note: documentData?.[0].Note || "",
- description: documentData?.[0].Description || "",
- signers: documentData?.[0].Signers?.map((x) => ({
- name: x?.Name,
- email: x?.Email,
- phone: x?.Phone
- })),
- viewedBy: jsonSender.email,
- viewedAt: new Date(),
- createdAt: documentData?.[0].createdAt
- }
- };
-
- try {
- await axios.post(
- `${localStorage.getItem("baseUrl")}functions/callwebhook`,
- params,
- {
- headers: {
- "Content-Type": "application/json",
- "X-Parse-Application-Id": localStorage.getItem("parseAppId"),
- sessiontoken: localStorage.getItem("accesstoken")
- }
- }
- );
- } catch (err) {
- console.log("Err ", err);
- }
- }
- }
-
- let signers = [];
- let unSignedSigner = [];
-
- const placeholdersOrSigners = [];
- for (const placeholder of documentData[0].Placeholders) {
- //`emailExist` variable to handle condition for quick send flow and show unsigned signers list
- const signerIdExist = placeholder?.signerObjId;
- if (signerIdExist) {
- const getSignerData = documentData[0].Signers.find(
- (data) => data.objectId === placeholder?.signerObjId
- );
- placeholdersOrSigners.push(getSignerData);
+ if (documentData[0].SignedUrl) {
+ setPdfUrl(documentData[0].SignedUrl);
} else {
- placeholdersOrSigners.push(placeholder);
+ setPdfUrl(documentData[0].URL);
}
- }
- //condition to check already signed document by someone
- if (audittrailData && audittrailData.length > 0) {
- setIsDocId(true);
-
- for (const item of placeholdersOrSigners) {
- const checkEmail = item?.email;
- //if email exist then compare user signed by using email else signers objectId
- const emailOrId = checkEmail ? item.email : item.objectId;
- //`isSignedSignature` variable to handle break loop whenever it get true
- let isSignedSignature = false;
- //checking the signer who signed the document by using audit trail details.
- //and save signedSigners and unsignedSigners details
- for (const doc of audittrailData) {
- const signedExist = checkEmail
- ? doc?.UserPtr.Email
- : doc?.UserPtr.objectId;
-
- if (emailOrId === signedExist) {
- signers.push({ ...item });
- isSignedSignature = true;
- break;
+ if (isCompleted) {
+ setIsSigned(true);
+ const data = {
+ isCertificate: true,
+ isModal: true
+ };
+ setAlreadySign(true);
+ setIsCompleted(data);
+ setIsCelebration(true);
+ setTimeout(() => {
+ setIsCelebration(false);
+ }, 5000);
+ } else if (declined) {
+ const currentDecline = {
+ currnt: "another",
+ isDeclined: true
+ };
+ setIsDecline(currentDecline);
+ } else if (currDate > expireUpdateDate) {
+ const expireDateFormat = moment(new Date(expireDate)).format(
+ "MMM DD, YYYY"
+ );
+ setIsExpired(true);
+ setExpiredDate(expireDateFormat);
+ } // Check if the current signer is not a last signer and handle the complete message.
+ else if (isNextUser) {
+ setIsCelebration(true);
+ setTimeout(() => {
+ setIsCelebration(false);
+ }, 5000);
+ setIsCompleted({
+ isModal: true,
+ message: t("document-signed-alert-1")
+ });
+ } else {
+ if (currUserId) {
+ const checkCurrentUser = documentData[0].Placeholders.find(
+ (data) => data?.signerObjId === currUserId
+ );
+ if (checkCurrentUser) {
+ setCurrentSigner(true);
}
}
- if (!isSignedSignature) {
- unSignedSigner.push({ ...item });
+ }
+ const audittrailData =
+ documentData[0].AuditTrail &&
+ documentData[0].AuditTrail.length > 0 &&
+ documentData[0].AuditTrail.filter(
+ (data) => data.Activity === "Signed"
+ );
+
+ const checkAlreadySign =
+ documentData[0].AuditTrail &&
+ documentData[0].AuditTrail.length > 0 &&
+ documentData[0].AuditTrail.filter(
+ (data) =>
+ data.UserPtr.objectId === currUserId && data.Activity === "Signed"
+ );
+ if (
+ checkAlreadySign &&
+ checkAlreadySign[0] &&
+ checkAlreadySign.length > 0
+ ) {
+ setAlreadySign(true);
+ } else {
+ const obj = documentData?.[0];
+ setSendInOrder(obj?.SendinOrder || false);
+ if (
+ obj &&
+ obj.Signers &&
+ obj.Signers.length > 0 &&
+ obj.Placeholders &&
+ obj.Placeholders.length > 0
+ ) {
+ const params = {
+ event: "viewed",
+ contactId: currUserId,
+ body: {
+ objectId: documentData?.[0].objectId,
+ file: documentData?.[0]?.SignedUrl || documentData?.[0]?.URL,
+ name: documentData?.[0].Name,
+ note: documentData?.[0].Note || "",
+ description: documentData?.[0].Description || "",
+ signers: documentData?.[0].Signers?.map((x) => ({
+ name: x?.Name,
+ email: x?.Email,
+ phone: x?.Phone
+ })),
+ viewedBy: jsonSender.email,
+ viewedAt: new Date(),
+ createdAt: documentData?.[0].createdAt
+ }
+ };
+
+ try {
+ await axios.post(
+ `${localStorage.getItem("baseUrl")}functions/callwebhook`,
+ params,
+ {
+ headers: {
+ "Content-Type": "application/json",
+ "X-Parse-Application-Id":
+ localStorage.getItem("parseAppId"),
+ sessiontoken: localStorage.getItem("accesstoken")
+ }
+ }
+ );
+ } catch (err) {
+ console.log("Err ", err);
+ }
}
}
- setSignedSigners(signers);
- setUnSignedSigners(unSignedSigner);
- setSignerPos(documentData[0].Placeholders);
- } else {
- //else condition is show there are no details in audit trail then direct push all signers details
- //in unsignedsigners array
- setUnSignedSigners(placeholdersOrSigners);
- setSignerPos(documentData[0].Placeholders);
- }
- setPdfDetails(documentData);
- //checking if condition current user already sign or owner does not exist as a signer or document has been declined by someone or document has been expired
- //then stop to display tour message
- if (
- (checkAlreadySign &&
- checkAlreadySign[0] &&
- checkAlreadySign.length > 0) ||
- !currUserId ||
- declined ||
- currDate > expireUpdateDate
- ) {
- setRequestSignTour(true);
- } else {
- //else condition to check current user exist in contracts_Users class and check tour message status
- //if not then check user exist in contracts_Contactbook class and check tour message statu
- const res = await contractUsers();
- if (res === "Error: Something went wrong!") {
- setHandleError(t("something-went-wrong-mssg"));
- } else if (res[0] && res?.length) {
- setContractName("_Users");
- currUserId = res[0].objectId;
- setSignerUserId(currUserId);
- const tourData = res[0].TourStatus && res[0].TourStatus;
- if (tourData && tourData.length > 0) {
- const checkTourRequest = tourData.filter(
- (data) => data?.requestSign
+
+ let signers = [];
+ let unSignedSigner = [];
+
+ const placeholdersOrSigners = [];
+ for (const placeholder of documentData[0].Placeholders) {
+ //`emailExist` variable to handle condition for quick send flow and show unsigned signers list
+ const signerIdExist = placeholder?.signerObjId;
+ if (signerIdExist) {
+ const getSignerData = documentData[0].Signers.find(
+ (data) => data.objectId === placeholder?.signerObjId
);
- setTourStatus(tourData);
- setRequestSignTour(checkTourRequest[0]?.requestSign || false);
+ placeholdersOrSigners.push(getSignerData);
+ } else {
+ placeholdersOrSigners.push(placeholder);
}
- } else if (res?.length === 0) {
- const res = await contactBook(currUserId);
+ }
+ //condition to check already signed document by someone
+ if (audittrailData && audittrailData.length > 0) {
+ setIsDocId(true);
+
+ for (const item of placeholdersOrSigners) {
+ const checkEmail = item?.email;
+ //if email exist then compare user signed by using email else signers objectId
+ const emailOrId = checkEmail ? item.email : item.objectId;
+ //`isSignedSignature` variable to handle break loop whenever it get true
+ let isSignedSignature = false;
+ //checking the signer who signed the document by using audit trail details.
+ //and save signedSigners and unsignedSigners details
+ for (const doc of audittrailData) {
+ const signedExist = checkEmail
+ ? doc?.UserPtr.Email
+ : doc?.UserPtr.objectId;
+
+ if (emailOrId === signedExist) {
+ signers.push({ ...item });
+ isSignedSignature = true;
+ break;
+ }
+ }
+ if (!isSignedSignature) {
+ unSignedSigner.push({ ...item });
+ }
+ }
+ setSignedSigners(signers);
+ setUnSignedSigners(unSignedSigner);
+ setSignerPos(documentData[0].Placeholders);
+ } else {
+ //else condition is show there are no details in audit trail then direct push all signers details
+ //in unsignedsigners array
+ setUnSignedSigners(placeholdersOrSigners);
+ setSignerPos(documentData[0].Placeholders);
+ }
+ setPdfDetails(documentData);
+ //checking if condition current user already sign or owner does not exist as a signer or document has been declined by someone or document has been expired
+ //then stop to display tour message
+ if (
+ (checkAlreadySign &&
+ checkAlreadySign[0] &&
+ checkAlreadySign.length > 0) ||
+ !currUserId ||
+ declined ||
+ currDate > expireUpdateDate
+ ) {
+ setRequestSignTour(true);
+ } else {
+ //else condition to check current user exist in contracts_Users class and check tour message status
+ //if not then check user exist in contracts_Contactbook class and check tour message statu
+ const res = await contractUsers();
if (res === "Error: Something went wrong!") {
setHandleError(t("something-went-wrong-mssg"));
- } else if (res[0] && res.length) {
- setContractName("_Contactbook");
- const objectId = res[0].objectId;
- setSignerUserId(objectId);
+ } else if (res[0] && res?.length) {
+ setContractName("_Users");
+ currUserId = res[0].objectId;
+ setSignerUserId(currUserId);
const tourData = res[0].TourStatus && res[0].TourStatus;
if (tourData && tourData.length > 0) {
const checkTourRequest = tourData.filter(
@@ -585,64 +575,63 @@ function PdfRequestFiles(props) {
setTourStatus(tourData);
setRequestSignTour(checkTourRequest[0]?.requestSign || false);
}
- } else if (res.length === 0) {
- setHandleError(t("user-not-exist"));
+ } else if (res?.length === 0) {
+ const res = await contactBook(currUserId);
+ if (res === "Error: Something went wrong!") {
+ setHandleError(t("something-went-wrong-mssg"));
+ } else if (res[0] && res.length) {
+ setContractName("_Contactbook");
+ const objectId = res[0].objectId;
+ setSignerUserId(objectId);
+ const tourData = res[0].TourStatus && res[0].TourStatus;
+ if (tourData && tourData.length > 0) {
+ const checkTourRequest = tourData.filter(
+ (data) => data?.requestSign
+ );
+ setTourStatus(tourData);
+ setRequestSignTour(checkTourRequest[0]?.requestSign || false);
+ }
+ } else if (res.length === 0) {
+ setHandleError(t("user-not-exist"));
+ }
}
}
- }
- setIsUiLoading(false);
- } else if (
- documentData === "Error: Something went wrong!" ||
- (documentData.result && documentData.result.error)
- ) {
- setHandleError(t("something-went-wrong-mssg"));
- setIsLoading({
- isLoad: false
- });
- console.log("err in getDocument cloud function ");
- } else {
- setHandleError(t("no-data"));
- setIsUiLoading({
- isLoad: false
- });
- }
- await axios
- .get(
- `${localStorage.getItem(
- "baseUrl"
- )}classes/contracts_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${
- jsonSender?.objectId
- }"}}`,
- {
- headers: {
- "Content-Type": "application/json",
- "X-Parse-Application-Id": localStorage.getItem("parseAppId"),
- "X-Parse-Session-Token": localStorage.getItem("accesstoken")
- }
- }
- )
- .then((Listdata) => {
- const json = Listdata.data;
- const res = json.results;
-
- if (res[0] && res.length > 0) {
- setDefaultSignImg(res[0].ImageURL);
- setMyInitial(res[0]?.Initials);
- }
-
- const loadObj = {
- isLoad: false
- };
- setIsLoading(loadObj);
- })
- .catch((err) => {
- console.log("Err in contracts_Signature class", err);
+ setIsUiLoading(false);
+ } else if (
+ documentData === "Error: Something went wrong!" ||
+ (documentData.result && documentData.result.error)
+ ) {
setHandleError(t("something-went-wrong-mssg"));
setIsLoading({
isLoad: false
});
+ console.log("err in getDocument cloud function ");
+ } else {
+ setHandleError(t("no-data"));
+ setIsUiLoading({
+ isLoad: false
+ });
+ }
+ //function to get default signatur eof current user from `contracts_Signature` class
+ const defaultSignRes = await getDefaultSignature(jsonSender.objectId);
+ if (defaultSignRes?.status === "success") {
+ setDefaultSignImg(defaultSignRes?.res?.defaultSignature);
+ setMyInitial(defaultSignRes?.res?.defaultInitial);
+ } else if (defaultSignRes?.status === "error") {
+ setHandleError("Error: Something went wrong!");
+ }
+ setIsLoading({
+ isLoad: false
});
+ } catch (err) {
+ console.log("Error: error in getDocumentDetails", err);
+ setHandleError("Error: Something went wrong!");
+ setIsLoading({
+ isLoad: false
+ });
+ }
};
+
//function for embed signature or image url in pdf
async function embedWidgetsData() {
//for emailVerified data checking first in localstorage
@@ -1089,8 +1078,8 @@ function PdfRequestFiles(props) {
{
selector: '[data-tut="IsSigned"]',
content: minRequiredCount
- ? `Please confirm that you have selected at least ${minRequiredCount} checkboxes.`
- : "Ensure this field is accurately filled and meets all requirements.",
+ ? t("signature-validate-alert", { minRequiredCount })
+ : t("signature-validate-alert-2"),
position: "top",
style: { fontSize: "13px" }
}
@@ -1484,7 +1473,11 @@ function PdfRequestFiles(props) {
};
const handleInputChange = (e) => {
- setContact((prev) => ({ ...prev, [e.target.name]: e.target.value }));
+ let { name, value } = e.target;
+ if (name === "email") {
+ value = value?.toLowerCase()?.replace(/\s/g, "");
+ }
+ setContact({ ...contact, [name]: value });
};
const SendOtp = async () => {
@@ -1690,8 +1683,8 @@ function PdfRequestFiles(props) {
{/* this modal is used for show expired alert */}
{!isEmailVerified && (
{
handleCloseOtp();
}}
@@ -1723,7 +1716,7 @@ function PdfRequestFiles(props) {
type="number"
name="otp"
className="grow"
- placeholder="Enter Verification Code"
+ placeholder={t("otp-placeholder")}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
@@ -1743,13 +1736,13 @@ function PdfRequestFiles(props) {
handleCloseOtp();
}}
>
- Cancel
+ {t("cancel")}
- {loading ? "Loading..." : "Verify"}
+ {loading ? t("loading") : t("verify")}
@@ -1772,7 +1765,7 @@ function PdfRequestFiles(props) {
name="name"
value={contact.name}
onChange={handleInputChange}
- placeholder="name"
+ placeholder={t("name")}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
@@ -1792,12 +1785,12 @@ function PdfRequestFiles(props) {
e.target.setCustomValidity(t("input-required"))
}
@@ -1822,7 +1815,7 @@ function PdfRequestFiles(props) {
type="text"
name="phone"
className="grow"
- placeholder="phone"
+ placeholder={t("phone")}
disabled={loading}
/>
@@ -1835,13 +1828,13 @@ function PdfRequestFiles(props) {
handleCloseOtp();
}}
>
- Close
+ {t("close")}
- {loading ? "Loading..." : "Submit"}
+ {loading ? t("loading") : t("submit")}
@@ -2164,7 +2157,6 @@ function PdfRequestFiles(props) {
{defaultSignImg && !alreadySign && currentSigner && (
Hi {{receiver_name}},We hope this email finds you well. {{sender_name}} has requested you to review and sign {{document_title}}.
Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.
{{signing_url}}
If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.
Thanks
Team OpenSign™
`;
+ const defaultSubject = `{{sender_name}} has requested you to sign {{document_title}}`;
+ setDefaultBody(defaultRequestBody);
+ setDefaultSubject(defaultSubject);
const tenantDetails = await getTenantDetails(user?.objectId);
if (tenantDetails && tenantDetails === "user does not exist!") {
alert(t("user-not-exist"));
} else if (tenantDetails) {
- const defaultRequestBody = `Hi {{receiver_name}},
We hope this email finds you well. {{sender_name}} has requested you to review and sign {{document_title}}.
Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.
{{signing_url}}
If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.
Thanks
Team OpenSign™
`;
if (tenantDetails?.RequestBody) {
setRequestBody(tenantDetails?.RequestBody);
setRequestSubject(tenantDetails?.RequestSubject);
-
- setDefaultBody(defaultRequestBody);
- setDefaultSubject(
- `{{sender_name}} has requested you to sign {{document_title}}`
- );
} else {
setRequestBody(defaultRequestBody);
- setRequestSubject(
- `{{sender_name}} has requested you to sign {{document_title}}`
- );
- setDefaultBody(defaultRequestBody);
- setDefaultSubject(
- `{{sender_name}}has requested you to sign {{document_title}}`
- );
+ setRequestSubject(defaultSubject);
}
}
} catch (e) {
@@ -222,6 +214,7 @@ function PlaceHolderSign() {
}
};
+ console.log("default body", defaultBody);
useEffect(() => {
const updateSize = () => {
if (divRef.current) {
@@ -1772,8 +1765,10 @@ function PlaceHolderSign() {
<>
diff --git a/apps/OpenSign/src/pages/Report.js b/apps/OpenSign/src/pages/Report.js
index c6a8451d0..4a28898bc 100644
--- a/apps/OpenSign/src/pages/Report.js
+++ b/apps/OpenSign/src/pages/Report.js
@@ -100,7 +100,7 @@ const Report = () => {
selector: `[data-tut="${data?.selector}"]`,
content: () => (
),
diff --git a/apps/OpenSign/src/pages/Signup.js b/apps/OpenSign/src/pages/Signup.js
index e5fb83431..ce59b885f 100644
--- a/apps/OpenSign/src/pages/Signup.js
+++ b/apps/OpenSign/src/pages/Signup.js
@@ -365,7 +365,9 @@ const Signup = () => {
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
value={email}
onChange={(e) =>
- setEmail(e.target.value?.toLowerCase())
+ setEmail(
+ e.target.value?.toLowerCase()?.replace(/\s/g, "")
+ )
}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js
index c3155a123..b44c4afcd 100644
--- a/apps/OpenSign/src/pages/SignyourselfPdf.js
+++ b/apps/OpenSign/src/pages/SignyourselfPdf.js
@@ -33,7 +33,8 @@ import {
fetchImageBase64,
changeImageWH,
handleSendOTP,
- getContainerScale
+ getContainerScale,
+ getDefaultSignature
} from "../constant/Utils";
import { useParams } from "react-router-dom";
import Tour from "reactour";
@@ -207,131 +208,90 @@ function SignYourSelf() {
}, [divRef.current, isHeader]);
//function for get document details for perticular signer with signer'object id
const getDocumentDetails = async (showComplete) => {
- let isCompleted;
- //getting document details
- const documentData = await contractDocument(documentId);
+ try {
+ let isCompleted;
+ //getting document details
+ const documentData = await contractDocument(documentId);
- if (documentData && documentData.length > 0) {
- setPdfDetails(documentData);
- setExtUserId(documentData[0]?.ExtUserPtr?.objectId);
- const url = documentData[0] && documentData[0]?.URL;
- if (url) {
- //convert document url in array buffer format to use embed widgets in pdf using pdf-lib
- const arrayBuffer = await convertPdfArrayBuffer(url);
- if (arrayBuffer === "Error") {
+ if (documentData && documentData.length > 0) {
+ setPdfDetails(documentData);
+ setExtUserId(documentData[0]?.ExtUserPtr?.objectId);
+ const url = documentData[0] && documentData[0]?.URL;
+ if (url) {
+ //convert document url in array buffer format to use embed widgets in pdf using pdf-lib
+ const arrayBuffer = await convertPdfArrayBuffer(url);
+ if (arrayBuffer === "Error") {
+ setHandleError(t("something-went-wrong-mssg"));
+ } else {
+ setPdfArrayBuffer(arrayBuffer);
+ }
+ } else {
setHandleError(t("something-went-wrong-mssg"));
- } else {
- setPdfArrayBuffer(arrayBuffer);
}
- } else {
- setHandleError(t("something-went-wrong-mssg"));
- }
- isCompleted = documentData[0].IsCompleted && documentData[0].IsCompleted;
- if (isCompleted) {
- setIsCelebration(true);
- setTimeout(() => {
- setIsCelebration(false);
- }, 5000);
- setIsCompleted(true);
- setPdfUrl(documentData[0].SignedUrl);
- const alreadySign = {
- status: true,
- mssg: t("document-signed-alert")
- };
- if (showComplete) {
- setShowAlreadySignDoc(alreadySign);
- } else {
- setIsUiLoading(false);
- setIsSignPad(false);
- setIsEmail(true);
- setXyPostion([]);
- setSignBtnPosition([]);
- }
- }
- } else if (
- documentData === "Error: Something went wrong!" ||
- (documentData.result && documentData.result.error)
- ) {
- const loadObj = {
- isLoad: false
- };
- setHandleError(t("something-went-wrong-mssg"));
- setIsLoading(loadObj);
- } else {
- setHandleError(t("no-data-avaliable"));
- const loadObj = {
- isLoad: false
- };
- setIsLoading(loadObj);
- }
- await axios
- .get(
- `${localStorage.getItem(
- "baseUrl"
- )}classes/contracts_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${
- jsonSender.objectId
- }"}}`,
- {
- headers: {
- "Content-Type": "application/json",
- "X-Parse-Application-Id": localStorage.getItem("parseAppId"),
- "X-Parse-Session-Token": localStorage.getItem("accesstoken")
+ isCompleted =
+ documentData[0].IsCompleted && documentData[0].IsCompleted;
+ if (isCompleted) {
+ setIsCelebration(true);
+ setTimeout(() => {
+ setIsCelebration(false);
+ }, 5000);
+ setIsCompleted(true);
+ setPdfUrl(documentData[0].SignedUrl);
+ const alreadySign = {
+ status: true,
+ mssg: t("document-signed-alert")
+ };
+ if (showComplete) {
+ setShowAlreadySignDoc(alreadySign);
+ } else {
+ setIsUiLoading(false);
+ setIsSignPad(false);
+ setIsEmail(true);
+ setXyPostion([]);
+ setSignBtnPosition([]);
}
}
- )
- .then((Listdata) => {
- const json = Listdata.data;
- const res = json.results;
- if (res[0] && res.length > 0) {
- setDefaultSignImg(res[0].ImageURL);
- setMyInitial(res[0]?.Initials);
- }
- })
- .catch((err) => {
- console.log("Err ", err);
+ } else if (
+ documentData === "Error: Something went wrong!" ||
+ (documentData.result && documentData.result.error)
+ ) {
const loadObj = {
isLoad: false
};
setHandleError(t("something-went-wrong-mssg"));
setIsLoading(loadObj);
- });
- const contractUsersRes = await contractUsers();
- if (contractUsersRes === "Error: Something went wrong!") {
- const loadObj = {
- isLoad: false
- };
- setHandleError(t("something-went-wrong-mssg"));
- setIsLoading(loadObj);
- } else if (contractUsersRes[0] && contractUsersRes.length > 0) {
- setActiveMailAdapter(contractUsersRes[0]?.active_mail_adapter);
- setContractName("_Users");
- setSignerUserId(contractUsersRes[0].objectId);
- const tourstatuss =
- contractUsersRes[0].TourStatus && contractUsersRes[0].TourStatus;
- if (tourstatuss && tourstatuss.length > 0 && !isCompleted) {
- setTourStatus(tourstatuss);
- const checkTourRecipients = tourstatuss.filter(
- (data) => data.signyourself
- );
- if (checkTourRecipients && checkTourRecipients.length > 0) {
- setCheckTourStatus(checkTourRecipients[0].signyourself);
- }
} else {
- setCheckTourStatus(true);
+ setHandleError(t("no-data-avaliable"));
+ const loadObj = {
+ isLoad: false
+ };
+ setIsLoading(loadObj);
}
- const loadObj = {
- isLoad: false
- };
- setIsLoading(loadObj);
- } else if (contractUsersRes.length === 0) {
- const contractContactBook = await contactBook(jsonSender.objectId);
- if (contractContactBook && contractContactBook.length > 0) {
- setContractName("_Contactbook");
- setSignerUserId(contractContactBook[0].objectId);
+ //function to get default signatur eof current user from `contracts_Signature` class
+ const defaultSignRes = await getDefaultSignature(jsonSender.objectId);
+ console.log("defaultSignRes", defaultSignRes);
+ if (defaultSignRes?.status === "success") {
+ setDefaultSignImg(defaultSignRes?.res?.defaultSignature);
+ setMyInitial(defaultSignRes?.res?.defaultInitial);
+ } else if (defaultSignRes?.status === "error") {
+ setHandleError("Error: Something went wrong!");
+ setIsLoading({
+ isLoad: false
+ });
+ }
+ const contractUsersRes = await contractUsers();
+ if (contractUsersRes === "Error: Something went wrong!") {
+ const loadObj = {
+ isLoad: false
+ };
+ setHandleError(t("something-went-wrong-mssg"));
+ setIsLoading(loadObj);
+ } else if (contractUsersRes[0] && contractUsersRes.length > 0) {
+ setActiveMailAdapter(contractUsersRes[0]?.active_mail_adapter);
+ setContractName("_Users");
+ setSignerUserId(contractUsersRes[0].objectId);
const tourstatuss =
- contractContactBook[0].TourStatus &&
- contractContactBook[0].TourStatus;
-
+ contractUsersRes[0].TourStatus && contractUsersRes[0].TourStatus;
if (tourstatuss && tourstatuss.length > 0 && !isCompleted) {
setTourStatus(tourstatuss);
const checkTourRecipients = tourstatuss.filter(
@@ -343,13 +303,44 @@ function SignYourSelf() {
} else {
setCheckTourStatus(true);
}
- } else {
- setHandleError(t("no-data-avaliable"));
+ const loadObj = {
+ isLoad: false
+ };
+ setIsLoading(loadObj);
+ } else if (contractUsersRes.length === 0) {
+ const contractContactBook = await contactBook(jsonSender.objectId);
+ if (contractContactBook && contractContactBook.length > 0) {
+ setContractName("_Contactbook");
+ setSignerUserId(contractContactBook[0].objectId);
+ const tourstatuss =
+ contractContactBook[0].TourStatus &&
+ contractContactBook[0].TourStatus;
+
+ if (tourstatuss && tourstatuss.length > 0 && !isCompleted) {
+ setTourStatus(tourstatuss);
+ const checkTourRecipients = tourstatuss.filter(
+ (data) => data.signyourself
+ );
+ if (checkTourRecipients && checkTourRecipients.length > 0) {
+ setCheckTourStatus(checkTourRecipients[0].signyourself);
+ }
+ } else {
+ setCheckTourStatus(true);
+ }
+ } else {
+ setHandleError(t("no-data-avaliable"));
+ }
+ const loadObj = {
+ isLoad: false
+ };
+ setIsLoading(loadObj);
}
- const loadObj = {
+ } catch (err) {
+ console.log("Error: error in getDocumentDetails", err);
+ setHandleError("Error: Something went wrong!");
+ setIsLoading({
isLoad: false
- };
- setIsLoading(loadObj);
+ });
}
};
const getWidgetValue = (type) => {
@@ -1313,7 +1304,7 @@ function SignYourSelf() {
isEmail={isEmail}
pdfUrl={pdfUrl}
setIsEmail={setIsEmail}
- pdfName={pdfDetails[0] && pdfDetails[0].Name}
+ pdfDetails={pdfDetails}
setSuccessEmail={setSuccessEmail}
sender={jsonSender}
setIsAlert={setIsAlert}
diff --git a/apps/OpenSign/src/pages/TeamList.js b/apps/OpenSign/src/pages/TeamList.js
index 65e7359e6..d4b4eb063 100644
--- a/apps/OpenSign/src/pages/TeamList.js
+++ b/apps/OpenSign/src/pages/TeamList.js
@@ -97,6 +97,7 @@ const TeamList = () => {
const pageNumbers = getPaginationRange();
useEffect(() => {
fetchTeamList();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
async function fetchTeamList() {
try {
diff --git a/apps/OpenSign/src/pages/UpdateExistUserAdmin.js b/apps/OpenSign/src/pages/UpdateExistUserAdmin.js
index 50b104c99..dac0a6fe5 100644
--- a/apps/OpenSign/src/pages/UpdateExistUserAdmin.js
+++ b/apps/OpenSign/src/pages/UpdateExistUserAdmin.js
@@ -119,7 +119,9 @@ const UpdateExistUserAdmin = () => {
onChange={(e) =>
setFormdata((prev) => ({
...prev,
- email: e.target.value?.toLowerCase()
+ email: e.target.value
+ ?.toLowerCase()
+ ?.replace(/\s/g, "")
}))
}
onInvalid={(e) =>
diff --git a/apps/OpenSign/src/pages/UserList.js b/apps/OpenSign/src/pages/UserList.js
index 3d07febe1..9d38d154c 100644
--- a/apps/OpenSign/src/pages/UserList.js
+++ b/apps/OpenSign/src/pages/UserList.js
@@ -85,6 +85,7 @@ const UserList = () => {
const pageNumbers = getPaginationRange();
useEffect(() => {
fetchUserList();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
async function fetchUserList() {
try {
diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js
index 1c383d840..df42f0e0b 100644
--- a/apps/OpenSign/src/pages/UserProfile.js
+++ b/apps/OpenSign/src/pages/UserProfile.js
@@ -7,7 +7,7 @@ import Title from "../components/Title";
import sanitizeFileName from "../primitives/sanitizeFileName";
import axios from "axios";
import Tooltip from "../primitives/Tooltip";
-import { isEnableSubscription } from "../constant/const";
+import { isEnableSubscription, isStaging } from "../constant/const";
import {
checkIsSubscribed,
checkIsSubscribedTeam,
@@ -57,6 +57,7 @@ function UserProfile() {
useEffect(() => {
getUserDetail();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const getUserDetail = async () => {
@@ -475,7 +476,9 @@ function UserProfile() {
/>
-
opensign.me/
+
+ {isStaging ? "staging.opensign.me/" : " opensign.me/"}
+
{editmode ? (
{
type="email"
id="email"
value={email}
- onChange={(e) => setEmail(e.target.value?.toLowerCase())}
+ onChange={(e) =>
+ setEmail(e.target.value?.toLowerCase()?.replace(/\s/g, ""))
+ }
onInvalid={(e) => e.target.setCustomValidity(t("input-required"))}
onInput={(e) => e.target.setCustomValidity("")}
required
diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js
index ac17cb183..8991c800d 100644
--- a/apps/OpenSign/src/primitives/GetReportDisplay.js
+++ b/apps/OpenSign/src/primitives/GetReportDisplay.js
@@ -4,7 +4,7 @@ import { useLocation, useNavigate } from "react-router-dom";
import axios from "axios";
import ModalUi from "./ModalUi";
import AddSigner from "../components/AddSigner";
-import { isEnableSubscription } from "../constant/const";
+import { isEnableSubscription, isStaging } from "../constant/const";
import Alert from "./Alert";
import Tooltip from "./Tooltip";
import { RWebShare } from "react-web-share";
@@ -990,9 +990,16 @@ const ReportTable = (props) => {
}
};
+ const publicUrl = () => {
+ const subDomain = isStaging
+ ? `https://staging.opensign.me/`
+ : `https://opensign.me/`;
+ const url = `${subDomain}${publicUserName}`;
+ return url;
+ };
// function to copy public profile links
const copytoProfileLink = () => {
- const url = `https://opensign.me/${publicUserName}`;
+ const url = publicUrl();
copytoData(url);
setIsAlert(true);
setAlertMsg({
@@ -1198,7 +1205,8 @@ const ReportTable = (props) => {
)}
{props.heading.includes("Folder") && (
- {item?.Folder?.Name || t("OpenSign™ Drive")}
+ {item?.Folder?.Name ||
+ t("sidebar.OpenSign™ Drive")}
)}
@@ -1325,7 +1333,9 @@ const ReportTable = (props) => {
copytoProfileLink()}
className="underline underline-offset-2 w-[150px] md:w-[350px] whitespace-nowrap overflow-hidden text-ellipsis cursor-pointer"
- >{`https://opensign.me/${publicUserName}`}
+ >
+ {publicUrl()}
+
) : (
diff --git a/apps/OpenSign/src/primitives/ValidateRoute.js b/apps/OpenSign/src/primitives/ValidateRoute.js
index 23caa01ca..e0af692b6 100644
--- a/apps/OpenSign/src/primitives/ValidateRoute.js
+++ b/apps/OpenSign/src/primitives/ValidateRoute.js
@@ -23,6 +23,7 @@ const ValidateRoute = () => {
}
}
})();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const handlelogout = async () => {
let appdata = localStorage.getItem("userSettings");
diff --git a/apps/OpenSign/src/script/PublicTemplate.js b/apps/OpenSign/src/script/PublicTemplate.js
index 3ef08df4c..b512e2670 100644
--- a/apps/OpenSign/src/script/PublicTemplate.js
+++ b/apps/OpenSign/src/script/PublicTemplate.js
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useEffect, useState } from "react";
import Parse from "parse";
import ReactDOM from "react-dom/client";
import PdfRequestFiles from "../pages/PdfRequestFiles";
@@ -6,6 +6,8 @@ import { pdfjs } from "react-pdf";
import { Provider } from "react-redux";
import { store } from "../redux/store";
import "../index.css";
+import "../i18n";
+import { isPublicStaging } from "../constant/const";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.mjs`;
// Wrapper component to manage props
@@ -13,15 +15,22 @@ const PublicScriptFileWrapper = ({ initialProps }) => {
const [props, setProps] = useState(initialProps);
// Make the setProps function globally accessible
- window.updatePublicTemplateProps = setProps;
+ useEffect(() => {
+ window.updatePublicTemplateProps = setProps;
+
+ return () => {
+ window.updatePublicTemplateProps = undefined;
+ };
+ }, []);
return ;
};
-const appId = "legadranaxn";
-// "opensign";
-const serverUrl = "https://app.opensignlabs.com/api/app";
-// "https://staging-app.opensignlabs.com/api/app";
+const appId = isPublicStaging ? "opensign" : "legadranaxn";
+const serverUrl = isPublicStaging
+ ? "https://staging-app.opensignlabs.com/api/app"
+ : "https://app.opensignlabs.com/api/app";
+
localStorage.setItem("baseUrl", `${serverUrl}/`);
localStorage.setItem("parseAppId", appId);
Parse.initialize(appId);
@@ -38,9 +47,8 @@ document.head.appendChild(link);
//add the Tailwind CSS file
const tailwindCssLink = document.createElement("link");
tailwindCssLink.href =
- "https://app.opensignlabs.com/static/js/public-template.bundle.css"; // css bundle file
-// "https://staging-app.opensignlabs.com/static/js/public-template.bundle.css"; // css bundle file
-tailwindCssLink.rel = "stylesheet";
+ // "https://app.opensignlabs.com/static/js/public-template.bundle.css"; // css bundle file
+ tailwindCssLink.rel = "stylesheet";
document.head.appendChild(tailwindCssLink);
// Create a root and render the wrapper component with initial props
const root = ReactDOM.createRoot(document.getElementById("script-component"));
diff --git a/apps/OpenSign/webpack.config.js b/apps/OpenSign/webpack.config.js
index 54967737e..f4c76810f 100644
--- a/apps/OpenSign/webpack.config.js
+++ b/apps/OpenSign/webpack.config.js
@@ -50,7 +50,7 @@ module.exports = {
]
},
resolve: {
- extensions: [".js", ".jsx"]
+ extensions: [".js", ".jsx", ".json"]
},
plugins: [
new Dotenv(),
diff --git a/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js b/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js
index a33d04bc0..9233981ec 100644
--- a/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js
+++ b/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js
@@ -21,12 +21,11 @@ async function GetPublicTemplate(request) {
templatQuery.equalTo('IsPublic', true);
templatQuery.notEqualTo('IsArchive', true);
const getTemplate = await templatQuery.find({ useMasterKey: true });
-
const extcls = new Parse.Query('contracts_Users');
- extcls.equalTo('email', user.get('email'));
+ extcls.equalTo('Email', user.get('email'));
const res = await extcls.first({ useMasterKey: true });
if (res) {
- const _res = JSON.parse(JSON.stringify(_res));
+ const _res = JSON.parse(JSON.stringify(res));
return {
template: getTemplate,
user: user,