Skip to content

Commit 7eacbed

Browse files
Merge pull request #763 from OpenSignLabs/tour_message_requestsign
feat: add tour messages to request signatures flow
2 parents 3fb96fc + 2e59472 commit 7eacbed

File tree

7 files changed

+210
-28
lines changed

7 files changed

+210
-28
lines changed

apps/OpenSign/src/components/pdf/DefaultSignature.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function DefaultSignature({ defaultSignImg, xyPostion, setDefaultSignAlert }) {
1717
};
1818

1919
return (
20-
<div>
20+
<div data-tut="reactourThird">
2121
<div
2222
style={{
2323
background: themeColor,

apps/OpenSign/src/components/pdf/PdfHeader.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ function Header({
331331
user exist than show finish button else no
332332
*/}
333333
{currentSigner && (
334-
<>
334+
<div className="flex" data-tut="reactourFifth">
335335
{decline && (
336336
<div
337337
onClick={() => handleDeclinePdfAlert()}
@@ -399,7 +399,7 @@ function Header({
399399
</DropdownMenu.Content>
400400
</DropdownMenu.Portal>
401401
</DropdownMenu.Root>
402-
</>
402+
</div>
403403
)}
404404
</div>
405405
)}
@@ -464,8 +464,8 @@ function Header({
464464
{completeBtnTitle
465465
? completeBtnTitle
466466
: isMailSend
467-
? "Sent"
468-
: "Send"}
467+
? "Sent"
468+
: "Send"}
469469
</button>
470470
</div>
471471
</>
@@ -505,7 +505,7 @@ function Header({
505505
</button>
506506
</div>
507507
) : (
508-
<div className="flex">
508+
<div className="flex" data-tut="reactourFifth">
509509
<button
510510
onClick={() => navigate(-1)}
511511
type="button"

apps/OpenSign/src/components/pdf/RenderPdf.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ function RenderPdf({
334334
{successEmail && <Alert type={"success"}>Email sent successfully!</Alert>}
335335
{isMobile && scale ? (
336336
<div
337+
data-tut="reactourForth"
337338
style={{
338339
border: "0.1px solid #ebe8e8",
339340
marginTop: isGuestSigner && "30px"
@@ -517,6 +518,7 @@ function RenderPdf({
517518
noScrollX={pdfNewWidth < pdfOriginalWidth ? false : true}
518519
>
519520
<div
521+
data-tut="reactourForth"
520522
style={{
521523
border: "0.1px solid #ebe8e8",
522524
width: pdfOriginalWidth

apps/OpenSign/src/constant/Utils.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,10 @@ export const contractUsers = async (email) => {
171171
.then((Listdata) => {
172172
const json = Listdata.data;
173173
let data = [];
174-
175174
if (json && json.result) {
176175
data.push(json.result);
177-
return data;
178176
}
177+
return data;
179178
})
180179
.catch((err) => {
181180
console.log("Err ", err);

apps/OpenSign/src/pages/PdfRequestFiles.js

Lines changed: 197 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import {
2828
fetchSubscription,
2929
convertPdfArrayBuffer,
3030
contractUsers,
31-
handleSendOTP
31+
handleSendOTP,
32+
contactBook
3233
} from "../constant/Utils";
3334
import Loader from "../primitives/LoaderWithMsg";
3435
import HandleError from "../primitives/HandleError";
@@ -39,6 +40,7 @@ import Title from "../components/Title";
3940
import DefaultSignature from "../components/pdf/DefaultSignature";
4041
import ModalUi from "../primitives/ModalUi";
4142
import VerifyEmail from "../components/pdf/VerifyEmail";
43+
import TourContentWithBtn from "../primitives/TourContentWithBtn";
4244
function useQuery() {
4345
return new URLSearchParams(useLocation().search);
4446
}
@@ -68,6 +70,8 @@ function PdfRequestFiles() {
6870
const [selectWidgetId, setSelectWidgetId] = useState("");
6971
const [otpLoader, setOtpLoader] = useState(false);
7072
const [isCelebration, setIsCelebration] = useState(false);
73+
const [requestSignTour, setRequestSignTour] = useState(true);
74+
const [tourStatus, setTourStatus] = useState([]);
7175
const [isLoading, setIsLoading] = useState({
7276
isLoad: true,
7377
message: "This might take some time"
@@ -85,6 +89,8 @@ function PdfRequestFiles() {
8589
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
8690
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
8791
const [expiredDate, setExpiredDate] = useState("");
92+
const [signerUserId, setSignerUserId] = useState();
93+
const [isDontShow, setIsDontShow] = useState(false);
8894
const [defaultSignAlert, setDefaultSignAlert] = useState({
8995
isShow: false,
9096
alertMessage: ""
@@ -114,6 +120,7 @@ function PdfRequestFiles() {
114120
const [isEmailVerified, setIsEmailVerified] = useState(true);
115121
const [isVerifyModal, setIsVerifyModal] = useState(false);
116122
const [otp, setOtp] = useState("");
123+
const [contractName, setContractName] = useState("");
117124
const divRef = useRef(null);
118125
const isMobile = window.innerWidth < 767;
119126
const rowLevel =
@@ -439,7 +446,62 @@ function PdfRequestFiles() {
439446
}, 5000);
440447
}
441448
}
442-
449+
//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
450+
//then stop to display tour message
451+
if (
452+
(checkAlreadySign &&
453+
checkAlreadySign[0] &&
454+
checkAlreadySign.length > 0) ||
455+
!currUserId ||
456+
declined ||
457+
currDate > expireUpdateDate
458+
) {
459+
setRequestSignTour(false);
460+
} else {
461+
//else condition to check current user exist in contracts_Users class and check tour message status
462+
//if not then check user exist in contracts_Contactbook class and check tour message status
463+
const currentUser = JSON.parse(JSON.stringify(Parse.User.current()));
464+
const currentUserEmail = currentUser.email;
465+
const res = await contractUsers(currentUserEmail);
466+
if (res === "Error: Something went wrong!") {
467+
setHandleError("Error: Something went wrong!");
468+
} else if (res[0] && res?.length) {
469+
setContractName("_Users");
470+
currUserId = res[0].objectId;
471+
setSignerUserId(currUserId);
472+
const tourstatus = res[0].TourStatus && res[0].TourStatus;
473+
if (tourstatus && tourstatus.length > 0) {
474+
setTourStatus(tourstatus);
475+
const checkTourRequestSign = tourstatus.filter(
476+
(data) => data.requestSign
477+
);
478+
if (checkTourRequestSign && checkTourRequestSign.length > 0) {
479+
setRequestSignTour(checkTourRequestSign[0].requestSign);
480+
}
481+
}
482+
} else if (res?.length === 0) {
483+
const res = await contactBook(currUserId);
484+
if (res === "Error: Something went wrong!") {
485+
setHandleError("Error: Something went wrong!");
486+
} else if (res[0] && res.length) {
487+
setContractName("_Contactbook");
488+
const objectId = res[0].objectId;
489+
setSignerUserId(objectId);
490+
const tourstatus = res[0].TourStatus && res[0].TourStatus;
491+
if (tourstatus && tourstatus.length > 0) {
492+
setTourStatus(tourstatus);
493+
const checkTourRequestSign = tourstatus.filter(
494+
(data) => data.requestSign
495+
);
496+
if (checkTourRequestSign && checkTourRequestSign.length > 0) {
497+
setRequestSignTour(checkTourRequestSign[0].requestSign);
498+
}
499+
}
500+
} else if (res.length === 0) {
501+
setHandleError("Error: User does not exist!");
502+
}
503+
}
504+
}
443505
setIsUiLoading(false);
444506
} else {
445507
alert("No data found!");
@@ -1141,6 +1203,134 @@ function PdfRequestFiles() {
11411203
alertMessage: ""
11421204
});
11431205
};
1206+
const handleDontShow = (isChecked) => {
1207+
setIsDontShow(isChecked);
1208+
};
1209+
//function to close tour and save tour status
1210+
const closeRequestSignTour = async () => {
1211+
setRequestSignTour(false);
1212+
if (isDontShow) {
1213+
let updatedTourStatus = [];
1214+
if (tourStatus.length > 0) {
1215+
updatedTourStatus = [...tourStatus];
1216+
const requestSignIndex = tourStatus.findIndex(
1217+
(obj) => obj["requestSign"] === false || obj["requestSign"] === true
1218+
);
1219+
if (requestSignIndex !== -1) {
1220+
updatedTourStatus[requestSignIndex] = { requestSign: true };
1221+
} else {
1222+
updatedTourStatus.push({ requestSign: true });
1223+
}
1224+
} else {
1225+
updatedTourStatus = [{ requestSign: true }];
1226+
}
1227+
try {
1228+
await axios.put(
1229+
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
1230+
"_appName"
1231+
)}${contractName}/${signerUserId}`,
1232+
{
1233+
TourStatus: updatedTourStatus
1234+
},
1235+
{
1236+
headers: {
1237+
"Content-Type": "application/json",
1238+
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
1239+
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
1240+
}
1241+
}
1242+
);
1243+
} catch (e) {
1244+
console.log("update tour messages error", e);
1245+
}
1246+
}
1247+
};
1248+
const requestSignTourFunction = () => {
1249+
const tourConfig = [
1250+
{
1251+
selector: '[data-tut="reactourFirst"]',
1252+
content: () => (
1253+
<TourContentWithBtn
1254+
message={`List of signers who still need to sign the document .`}
1255+
isChecked={handleDontShow}
1256+
/>
1257+
),
1258+
position: "top",
1259+
style: { fontSize: "13px" }
1260+
},
1261+
{
1262+
selector: '[data-tut="reactourForth"]',
1263+
content: () => (
1264+
<TourContentWithBtn
1265+
message={`Click any of the placeholders appearing on the document to sign. You will then see options to draw your signature, type it, or upload an image .`}
1266+
isChecked={handleDontShow}
1267+
/>
1268+
),
1269+
position: "top",
1270+
style: { fontSize: "13px" }
1271+
},
1272+
{
1273+
selector: '[data-tut="reactourFifth"]',
1274+
content: () => (
1275+
<TourContentWithBtn
1276+
message={`Click the Back, Decline, or Finish buttons to navigate your document. Use the ellipsis menu for additional options, including the Download button .`}
1277+
isChecked={handleDontShow}
1278+
/>
1279+
),
1280+
position: "top",
1281+
style: { fontSize: "13px" }
1282+
}
1283+
];
1284+
const signedByStep = {
1285+
selector: '[data-tut="reactourSecond"]',
1286+
content: () => (
1287+
<TourContentWithBtn
1288+
message={`List of signers who have already signed the document .`}
1289+
isChecked={handleDontShow}
1290+
/>
1291+
),
1292+
position: "top",
1293+
style: { fontSize: "13px" }
1294+
};
1295+
//checking if signed by user component exist then add signed step
1296+
const signedBy =
1297+
signedSigners.length > 0
1298+
? [...tourConfig.slice(0, 0), signedByStep, ...tourConfig.slice(0)]
1299+
: tourConfig;
1300+
1301+
//checking if default signature component exist then add defaultSign step
1302+
const defaultSignStep = {
1303+
selector: '[data-tut="reactourThird"]',
1304+
content: () => (
1305+
<TourContentWithBtn
1306+
message={`You can click "Auto Sign All" to automatically sign at all the locations meant to be signed by you. Make sure that you review the document properly before you click this button .`}
1307+
isChecked={handleDontShow}
1308+
/>
1309+
),
1310+
position: "top",
1311+
style: { fontSize: "13px" }
1312+
};
1313+
//index is handle is signed by exist then 2 else 1 to add tour step
1314+
const index = signedSigners.length > 0 ? 2 : 1;
1315+
const defaultSignTour = defaultSignImg
1316+
? [...signedBy.slice(0, index), defaultSignStep, ...signedBy.slice(index)]
1317+
: signedBy;
1318+
1319+
if (isMobile) {
1320+
tourConfig.shift();
1321+
}
1322+
1323+
return (
1324+
<Tour
1325+
onRequestClose={closeRequestSignTour}
1326+
steps={isMobile ? tourConfig : defaultSignTour}
1327+
isOpen={true}
1328+
closeWithMask={false}
1329+
rounded={5}
1330+
/>
1331+
);
1332+
};
1333+
11441334
return (
11451335
<DndProvider backend={HTML5Backend}>
11461336
<Title title={"Request Sign"} />
@@ -1209,6 +1399,7 @@ function PdfRequestFiles() {
12091399
}}
12101400
ref={divRef}
12111401
>
1402+
{requestSignTour && requestSignTourFunction()}
12121403
<ModalUi
12131404
headerColor={"#dc3545"}
12141405
isOpen={isAlert.isShow}
@@ -1496,7 +1687,7 @@ function PdfRequestFiles() {
14961687
className="autoSignScroll"
14971688
>
14981689
{signedSigners.length > 0 && (
1499-
<>
1690+
<div data-tut="reactourSecond">
15001691
<div
15011692
style={{ background: themeColor }}
15021693
className="signedStyle"
@@ -1556,11 +1747,11 @@ function PdfRequestFiles() {
15561747
);
15571748
})}
15581749
</div>
1559-
</>
1750+
</div>
15601751
)}
15611752

15621753
{unsignedSigners.length > 0 && (
1563-
<>
1754+
<div data-tut="reactourFirst">
15641755
<div
15651756
style={{
15661757
background: themeColor,
@@ -1626,7 +1817,7 @@ function PdfRequestFiles() {
16261817
);
16271818
})}
16281819
</div>
1629-
</>
1820+
</div>
16301821
)}
16311822
{defaultSignImg && !alreadySign && (
16321823
<DefaultSignature

apps/OpenSign/src/pages/PlaceHolderSign.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,10 +1804,7 @@ function PlaceHolderSign() {
18041804

18051805
{!isSubscribe && isEnableSubscription && (
18061806
<div className="mt-2">
1807-
<Upgrade
1808-
message="Upgrade to customize Email"
1809-
newWindow={true}
1810-
/>
1807+
<Upgrade message="Upgrade to customize Email" />
18111808
</div>
18121809
)}
18131810
</div>

apps/OpenSign/src/primitives/Upgrade.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
import React from "react";
2-
import { useNavigate } from "react-router-dom";
32
import { openInNewTab } from "../constant/Utils";
43

5-
function Upgrade({ message, newWindow }) {
6-
const navigation = useNavigate();
7-
4+
function Upgrade({ message }) {
85
return (
96
<sup>
107
<span
118
onClick={() => {
12-
if (newWindow) {
13-
const url = window.location.origin + "/subscription";
14-
openInNewTab(url);
15-
} else {
16-
navigation("/subscription");
17-
}
9+
const url = window.location.origin + "/subscription";
10+
openInNewTab(url);
1811
}}
1912
className="text-blue-800 text-sm cursor-pointer underline"
2013
>

0 commit comments

Comments
 (0)