Skip to content

Commit d99fecd

Browse files
feat: add download, certificate & print buttons on the document completion popup
1 parent 32c75d1 commit d99fecd

File tree

4 files changed

+236
-168
lines changed

4 files changed

+236
-168
lines changed

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

Lines changed: 29 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import React, { useState } from "react";
22
import PrevNext from "./PrevNext";
3-
import printModule from "print-js";
4-
import { getBase64FromUrl } from "../../constant/Utils";
5-
import { saveAs } from "file-saver";
3+
import {
4+
handleDownloadCertificate,
5+
handleDownloadPdf,
6+
handleToPrint
7+
} from "../../constant/Utils";
68
import "../../styles/signature.css";
79
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
810
import { useNavigate } from "react-router-dom";
911
import { themeColor } from "../../constant/const";
10-
import axios from "axios";
1112
import ModalUi from "../../primitives/ModalUi";
12-
import { appInfo } from "../../constant/appinfo";
1313

1414
function Header({
1515
isPdfRequestFiles,
@@ -59,123 +59,6 @@ function Header({
5959
setIsDecline(currentDecline);
6060
};
6161

62-
//function for print digital sign pdf
63-
const handleToPrint = async (event) => {
64-
event.preventDefault();
65-
66-
try {
67-
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
68-
const axiosRes = await axios.post(
69-
`${appInfo.baseUrl}/functions/getsignedurl`,
70-
{ url: pdfUrl },
71-
{
72-
headers: {
73-
"content-type": "Application/json",
74-
"X-Parse-Application-Id": appInfo.appId,
75-
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
76-
}
77-
}
78-
);
79-
const url = axiosRes.data.result;
80-
const pdf = await getBase64FromUrl(url);
81-
const isAndroidDevice = navigator.userAgent.match(/Android/i);
82-
const isAppleDevice =
83-
(/iPad|iPhone|iPod/.test(navigator.platform) ||
84-
(navigator.platform === "MacIntel" &&
85-
navigator.maxTouchPoints > 1)) &&
86-
!window.MSStream;
87-
if (isAndroidDevice || isAppleDevice) {
88-
const byteArray = Uint8Array.from(
89-
atob(pdf)
90-
.split("")
91-
.map((char) => char.charCodeAt(0))
92-
);
93-
const blob = new Blob([byteArray], { type: "application/pdf" });
94-
const blobUrl = URL.createObjectURL(blob);
95-
window.open(blobUrl, "_blank");
96-
} else {
97-
printModule({ printable: pdf, type: "pdf", base64: true });
98-
}
99-
} catch (err) {
100-
console.log("err in getsignedurl", err);
101-
alert("something went wrong, please try again later.");
102-
}
103-
};
104-
105-
//handle download signed pdf
106-
const handleDownloadPdf = async () => {
107-
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
108-
try {
109-
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
110-
const axiosRes = await axios.post(
111-
`${appInfo.baseUrl}/functions/getsignedurl`,
112-
{ url: pdfUrl },
113-
{
114-
headers: {
115-
"content-type": "Application/json",
116-
"X-Parse-Application-Id": appInfo.appId,
117-
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
118-
}
119-
}
120-
);
121-
const url = axiosRes.data.result;
122-
saveAs(url, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
123-
} catch (err) {
124-
console.log("err in getsignedurl", err);
125-
alert("something went wrong, please try again later.");
126-
}
127-
};
128-
129-
const sanitizeFileName = (pdfName) => {
130-
// Replace spaces with underscore
131-
return pdfName.replace(/ /g, "_");
132-
};
133-
134-
//handle download signed pdf
135-
const handleDownloadCertificate = async () => {
136-
if (pdfDetails?.length > 0 && pdfDetails[0]?.CertificateUrl) {
137-
try {
138-
await fetch(pdfDetails[0] && pdfDetails[0]?.CertificateUrl);
139-
const certificateUrl = pdfDetails[0] && pdfDetails[0]?.CertificateUrl;
140-
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
141-
} catch (err) {
142-
console.log("err in download in certificate", err);
143-
}
144-
} else {
145-
setIsCertificate(true);
146-
try {
147-
const data = {
148-
docId: pdfDetails[0]?.objectId
149-
};
150-
const docDetails = await axios.post(
151-
`${localStorage.getItem("baseUrl")}functions/getDocument`,
152-
data,
153-
{
154-
headers: {
155-
"Content-Type": "application/json",
156-
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
157-
sessionToken: localStorage.getItem("accesstoken")
158-
}
159-
}
160-
);
161-
if (docDetails.data && docDetails.data.result) {
162-
const doc = docDetails.data.result;
163-
if (doc?.CertificateUrl) {
164-
await fetch(doc?.CertificateUrl);
165-
const certificateUrl = doc?.CertificateUrl;
166-
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
167-
setIsCertificate(false);
168-
} else {
169-
setIsCertificate(true);
170-
}
171-
}
172-
} catch (err) {
173-
console.log("err in download in certificate", err);
174-
alert("something went wrong, please try again later.");
175-
}
176-
}
177-
};
178-
17962
return (
18063
<div style={{ padding: "5px 0px 5px 0px" }} className="mobileHead">
18164
{isMobile && isShowHeader ? (
@@ -248,7 +131,7 @@ function Header({
248131
>
249132
<DropdownMenu.Item
250133
className="DropdownMenuItem"
251-
onClick={() => handleDownloadPdf()}
134+
onClick={() => handleDownloadPdf(pdfDetails, pdfUrl)}
252135
>
253136
<div
254137
style={{
@@ -267,7 +150,12 @@ function Header({
267150
{isCompleted && (
268151
<DropdownMenu.Item
269152
className="DropdownMenuItem"
270-
onClick={() => handleDownloadCertificate()}
153+
onClick={() =>
154+
handleDownloadCertificate(
155+
pdfDetails,
156+
setIsCertificate
157+
)
158+
}
271159
>
272160
<div
273161
style={{
@@ -306,7 +194,7 @@ function Header({
306194
)}
307195
<DropdownMenu.Item
308196
className="DropdownMenuItem"
309-
onClick={handleToPrint}
197+
onClick={(e) => handleToPrint(e, pdfUrl)}
310198
>
311199
<div
312200
style={{
@@ -388,7 +276,9 @@ function Header({
388276
>
389277
<DropdownMenu.Item
390278
className="flex flex-row justify-center items-center text-[13px] focus:outline-none cursor-pointer"
391-
onClick={() => handleDownloadPdf()}
279+
onClick={() =>
280+
handleDownloadPdf(pdfDetails, pdfUrl)
281+
}
392282
>
393283
<i
394284
className="fa fa-arrow-down mr-[5px]"
@@ -475,7 +365,9 @@ function Header({
475365
{isCompleted && (
476366
<button
477367
type="button"
478-
onClick={() => handleDownloadCertificate()}
368+
onClick={() =>
369+
handleDownloadCertificate(pdfDetails, setIsCertificate)
370+
}
479371
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#08bc66]"
480372
>
481373
<i
@@ -487,7 +379,7 @@ function Header({
487379
)}
488380

489381
<button
490-
onClick={handleToPrint}
382+
onClick={(e) => handleToPrint(e, pdfUrl)}
491383
type="button"
492384
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#188ae2]"
493385
>
@@ -498,7 +390,7 @@ function Header({
498390
<button
499391
type="button"
500392
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#f14343]"
501-
onClick={() => handleDownloadPdf()}
393+
onClick={() => handleDownloadPdf(pdfDetails, pdfUrl)}
502394
>
503395
<i className="fa fa-download py-[3px]" aria-hidden="true"></i>
504396
<span className="hidden lg:block ml-1">Download</span>
@@ -547,7 +439,9 @@ function Header({
547439
>
548440
<DropdownMenu.Item
549441
className="flex flex-row justify-center items-center text-[13px] focus:outline-none cursor-pointer"
550-
onClick={() => handleDownloadPdf()}
442+
onClick={() =>
443+
handleDownloadPdf(pdfDetails, pdfUrl)
444+
}
551445
>
552446
<i
553447
className="fa fa-arrow-down mr-[5px]"
@@ -567,7 +461,9 @@ function Header({
567461
{isCompleted && (
568462
<button
569463
type="button"
570-
onClick={() => handleDownloadCertificate()}
464+
onClick={() =>
465+
handleDownloadCertificate(pdfDetails, setIsCertificate)
466+
}
571467
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#08bc66]"
572468
>
573469
<i
@@ -578,7 +474,7 @@ function Header({
578474
</button>
579475
)}
580476
<button
581-
onClick={handleToPrint}
477+
onClick={(e) => handleToPrint(e, pdfUrl)}
582478
type="button"
583479
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#188ae2]"
584480
>
@@ -588,7 +484,7 @@ function Header({
588484
<button
589485
type="button"
590486
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#f14343]"
591-
onClick={() => handleDownloadPdf()}
487+
onClick={() => handleDownloadPdf(pdfDetails, pdfUrl)}
592488
>
593489
<i className="fa fa-download py-[3px]" aria-hidden="true"></i>
594490
<span className="hidden lg:block ml-1">Download</span>

apps/OpenSign/src/constant/Utils.js

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import { isEnableSubscription, themeColor } from "./const";
44
import React from "react";
55
import { rgb } from "pdf-lib";
66
import Parse from "parse";
7+
import { appInfo } from "./appinfo";
8+
import { saveAs } from "file-saver";
9+
import printModule from "print-js";
710

811
export const isMobile = window.innerWidth < 767;
912
export const textInputWidget = "text input";
@@ -1350,8 +1353,8 @@ export const multiSignEmbed = async (
13501353
position.type === radioButtonWidget
13511354
? 10
13521355
: position.type === "checkbox"
1353-
? 10
1354-
: newUpdateHeight;
1356+
? 10
1357+
: newUpdateHeight;
13551358
const newHeight = ind ? (ind > 0 ? widgetHeight : 0) : widgetHeight;
13561359

13571360
if (signyourself) {
@@ -2029,3 +2032,121 @@ export const handleSendOTP = async (email) => {
20292032
alert(error.message);
20302033
}
20312034
};
2035+
2036+
//handle download signed pdf
2037+
export const handleDownloadPdf = async (pdfDetails, pdfUrl) => {
2038+
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
2039+
try {
2040+
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
2041+
const axiosRes = await axios.post(
2042+
`${appInfo.baseUrl}/functions/getsignedurl`,
2043+
{ url: pdfUrl },
2044+
{
2045+
headers: {
2046+
"content-type": "Application/json",
2047+
"X-Parse-Application-Id": appInfo.appId,
2048+
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
2049+
}
2050+
}
2051+
);
2052+
const url = axiosRes.data.result;
2053+
saveAs(url, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
2054+
} catch (err) {
2055+
console.log("err in getsignedurl", err);
2056+
alert("something went wrong, please try again later.");
2057+
}
2058+
};
2059+
2060+
export const sanitizeFileName = (pdfName) => {
2061+
// Replace spaces with underscore
2062+
return pdfName.replace(/ /g, "_");
2063+
};
2064+
//function for print digital sign pdf
2065+
export const handleToPrint = async (event, pdfUrl) => {
2066+
event.preventDefault();
2067+
2068+
try {
2069+
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
2070+
const axiosRes = await axios.post(
2071+
`${appInfo.baseUrl}/functions/getsignedurl`,
2072+
{ url: pdfUrl },
2073+
{
2074+
headers: {
2075+
"content-type": "Application/json",
2076+
"X-Parse-Application-Id": appInfo.appId,
2077+
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
2078+
}
2079+
}
2080+
);
2081+
const url = axiosRes.data.result;
2082+
const pdf = await getBase64FromUrl(url);
2083+
const isAndroidDevice = navigator.userAgent.match(/Android/i);
2084+
const isAppleDevice =
2085+
(/iPad|iPhone|iPod/.test(navigator.platform) ||
2086+
(navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)) &&
2087+
!window.MSStream;
2088+
if (isAndroidDevice || isAppleDevice) {
2089+
const byteArray = Uint8Array.from(
2090+
atob(pdf)
2091+
.split("")
2092+
.map((char) => char.charCodeAt(0))
2093+
);
2094+
const blob = new Blob([byteArray], { type: "application/pdf" });
2095+
const blobUrl = URL.createObjectURL(blob);
2096+
window.open(blobUrl, "_blank");
2097+
} else {
2098+
printModule({ printable: pdf, type: "pdf", base64: true });
2099+
}
2100+
} catch (err) {
2101+
console.log("err in getsignedurl", err);
2102+
alert("something went wrong, please try again later.");
2103+
}
2104+
};
2105+
2106+
//handle download signed pdf
2107+
export const handleDownloadCertificate = async (
2108+
pdfDetails,
2109+
setIsCertificate
2110+
) => {
2111+
if (pdfDetails?.length > 0 && pdfDetails[0]?.CertificateUrl) {
2112+
try {
2113+
await fetch(pdfDetails[0] && pdfDetails[0]?.CertificateUrl);
2114+
const certificateUrl = pdfDetails[0] && pdfDetails[0]?.CertificateUrl;
2115+
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
2116+
} catch (err) {
2117+
console.log("err in download in certificate", err);
2118+
}
2119+
} else {
2120+
setIsCertificate(true);
2121+
try {
2122+
const data = {
2123+
docId: pdfDetails[0]?.objectId
2124+
};
2125+
const docDetails = await axios.post(
2126+
`${localStorage.getItem("baseUrl")}functions/getDocument`,
2127+
data,
2128+
{
2129+
headers: {
2130+
"Content-Type": "application/json",
2131+
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
2132+
sessionToken: localStorage.getItem("accesstoken")
2133+
}
2134+
}
2135+
);
2136+
if (docDetails.data && docDetails.data.result) {
2137+
const doc = docDetails.data.result;
2138+
if (doc?.CertificateUrl) {
2139+
await fetch(doc?.CertificateUrl);
2140+
const certificateUrl = doc?.CertificateUrl;
2141+
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
2142+
setIsCertificate(false);
2143+
} else {
2144+
setIsCertificate(true);
2145+
}
2146+
}
2147+
} catch (err) {
2148+
console.log("err in download in certificate", err);
2149+
alert("something went wrong, please try again later.");
2150+
}
2151+
}
2152+
};

0 commit comments

Comments
 (0)