mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-31 04:09:46 +02:00
add SignDocument microfrontend
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import React from "react";
|
||||
import stamp from "../../assests/stamp2.png";
|
||||
import sign from "../../assests/sign3.png";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
|
||||
function DragElement({ type, id }) {
|
||||
const selectedId = id;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{selectedId === 3 ? (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="sign img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "23px",
|
||||
background: themeColor(),
|
||||
}}
|
||||
src={sign}
|
||||
/>
|
||||
<span style={{ color: themeColor(), fontSize: "12px" }}>
|
||||
Signature
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="stamp img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "23px",
|
||||
background: themeColor(),
|
||||
}}
|
||||
src={stamp}
|
||||
/>
|
||||
<span style={{ color: themeColor(), fontSize: "12px" }}>Stamp</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DragElement;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
function HandleError({ handleError }) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: "20px", color: "gray" }}>{handleError}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default HandleError;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
function Nodata() {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "50vh",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontWeight: "bold" }}>No Data Found!</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Nodata;
|
||||
@@ -0,0 +1,122 @@
|
||||
import React, { useEffect } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
function DefaultSignature({
|
||||
themeColor,
|
||||
defaultSignImg,
|
||||
setShowAlreadySignDoc,
|
||||
setDefaultSignImg,
|
||||
userObjectId,
|
||||
setIsLoading,
|
||||
xyPostion,
|
||||
}) {
|
||||
useEffect(() => {
|
||||
getDefaultSignature(userObjectId);
|
||||
}, []);
|
||||
|
||||
//function for fetch default sigature added bu users
|
||||
const getDefaultSignature = async (userObjectId) => {
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${userObjectId}"}}`,
|
||||
{
|
||||
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);
|
||||
}
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
})
|
||||
.catch((err) => {
|
||||
// this.setState({ loading: false });
|
||||
console.log("axois err ", err);
|
||||
});
|
||||
};
|
||||
|
||||
const confirmToaddDefaultSign = () => {
|
||||
if (xyPostion.length > 0) {
|
||||
const alreadySign = {
|
||||
status: true,
|
||||
mssg: "Are you sure you want to sign at requested locations?",
|
||||
sure: true,
|
||||
};
|
||||
setShowAlreadySignDoc(alreadySign);
|
||||
} else {
|
||||
alert("please select position!");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="signerComponent">
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
color: "white",
|
||||
padding: "5px",
|
||||
fontFamily: "sans-serif",
|
||||
}}
|
||||
>
|
||||
Signature
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
marginTop: "10px",
|
||||
fontWeight: "600",
|
||||
}}
|
||||
>
|
||||
{defaultSignImg ? (
|
||||
<>
|
||||
<p>Your Signature</p>
|
||||
<div className="defaultSignBox">
|
||||
<img
|
||||
alt="default img"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={defaultSignImg}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
style={{
|
||||
background: themeColor(),
|
||||
color: "white",
|
||||
marginTop: "20px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn finishnHover"
|
||||
onClick={() => confirmToaddDefaultSign()}
|
||||
>
|
||||
Auto Sign All
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<div style={{ margin: "10px" }}>
|
||||
<span>You didn't add your default signature yet!</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DefaultSignature;
|
||||
@@ -0,0 +1,385 @@
|
||||
import React, { useState } from "react";
|
||||
import { saveAs } from "file-saver";
|
||||
import celebration from "../../assests/newCeleb.gif";
|
||||
import close from "../../assests/close.png";
|
||||
import Modal from "react-bootstrap/Modal";
|
||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
||||
import axios from "axios";
|
||||
import { getBase64FromUrl } from "../../utils/Utils";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import printModule from "print-js";
|
||||
import loader from "../../assests/loader2.gif";
|
||||
|
||||
function EmailComponent({
|
||||
isEmail,
|
||||
pdfUrl,
|
||||
isCeleb,
|
||||
setIsEmail,
|
||||
setSuccessEmail,
|
||||
signObjId,
|
||||
pdfName,
|
||||
sender,
|
||||
}) {
|
||||
const [emailCount, setEmailCount] = useState([]);
|
||||
const [emailValue, setEmailValue] = useState();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
//function for send email
|
||||
const sendEmail = async () => {
|
||||
setIsLoading(true);
|
||||
let sendMail, recipent;
|
||||
for (let i = 0; i < emailCount.length; i++) {
|
||||
// await axios
|
||||
// .get(
|
||||
// `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem("_appName")}_Contactbook?where={"Email":"${emailCount[i]}"}`,
|
||||
// {
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// "X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
// sessionToken: localStorage.getItem("accesstoken"),
|
||||
// },
|
||||
// }
|
||||
// )
|
||||
// .then((Listdata) => {
|
||||
// const json = Listdata.data;
|
||||
// if (json.results[0]) {
|
||||
// recipent = json.results[0];
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log("axois err ", err);
|
||||
// });
|
||||
try {
|
||||
console.log("recipients", recipent);
|
||||
const imgPng =
|
||||
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
||||
// "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png";
|
||||
|
||||
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3/`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessionToken: localStorage.getItem("accesstoken"),
|
||||
};
|
||||
// const serverUrl = localStorage.getItem("baseUrl");
|
||||
// const newServer = serverUrl.replaceAll("/", "%2F");
|
||||
|
||||
// const serverParams = `${newServer}&${localStorage.getItem(
|
||||
// "parseAppId"
|
||||
// )}&${localStorage.getItem("_appName")}`;
|
||||
// let pdfUrlWeb = `<span><a href=https://qik-ai-org.github.io/Sign-MicroappV2/#/login/${signObjId}/${recipent.Email}/${serverParams} style='cursor: pointer;'> ${pdfName}</a><span>`;
|
||||
const themeBGcolor = themeColor();
|
||||
let params = {
|
||||
pdfName: pdfName,
|
||||
url: pdfUrl,
|
||||
recipient: emailCount[i],
|
||||
subject: `${sender.name} has signed the doc - ${pdfName}`,
|
||||
from: sender.email,
|
||||
html:
|
||||
"<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-color:white;'> <div><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',> Document Copy</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>A copy of the document " +
|
||||
pdfName +
|
||||
" Standard is attached to this email. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from Open Sign. For any queries regarding this email, please contact the sender " +
|
||||
sender.email +
|
||||
" directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>",
|
||||
//"html":"<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-color: white;padding-bottom: 20px;'> <div><img src="+imgPng +" height='50' style='padding: 20px' /></div> <div style=' padding: 2px;font-family: system-ui;background-color: #47a3ad;'><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;'> " + recipent.Name + " has requested you to review and sign" +pdfName+"</p><div style='padding: 5px 0px 5px 25px;display: flex;flex-direction: row;justify-content: space-around;'><span>Sender</span><span>" + recipent.Email + " </span></div><div style='display: flex; justify-content: center;margin-top: 10px;'><button style='padding: 8px 15px 8px 15px;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;'>Sign here</button></div></div></div><div><p> This is an automated email from Open Sign. For any queries regarding this email, please contact the sender " + recipent.Email + " directly.If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p> </div></div></body> </html>"
|
||||
};
|
||||
sendMail = await axios.post(url, params, { headers: headers });
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
setIsLoading(false);
|
||||
alert("Something went wrong!");
|
||||
}
|
||||
}
|
||||
|
||||
if (sendMail.data.result.status === "success") {
|
||||
setIsEmail(false);
|
||||
setSuccessEmail(true);
|
||||
setTimeout(() => {
|
||||
setSuccessEmail(false);
|
||||
}, 3000);
|
||||
setIsLoading(false);
|
||||
} else if (sendMail.data.result.status === "error") {
|
||||
setIsLoading(false);
|
||||
alert("Something went wrong!");
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
alert("Something went wrong!");
|
||||
}
|
||||
};
|
||||
//function for remove email
|
||||
const removeChip = (index) => {
|
||||
const updateEmailCount = emailCount.filter((data, key) => key !== index);
|
||||
setEmailCount(updateEmailCount);
|
||||
};
|
||||
//function for get email value
|
||||
const handleEmailValue = (e) => {
|
||||
const value = e.target.value;
|
||||
setEmailValue(value);
|
||||
};
|
||||
|
||||
//function for save email in array after press enter
|
||||
const handleEnterPress = (e) => {
|
||||
if (e.key === "Enter" && emailValue) {
|
||||
setEmailCount((prev) => [...prev, emailValue]);
|
||||
setEmailValue("");
|
||||
} else if (e === "add" && emailValue) {
|
||||
setEmailCount((prev) => [...prev, emailValue]);
|
||||
setEmailValue("");
|
||||
}
|
||||
};
|
||||
|
||||
// function for print signed pdf
|
||||
const handleToPrint = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const base64 = await getBase64FromUrl(pdfUrl);
|
||||
printModule({ printable: base64, type: "pdf", base64: true });
|
||||
|
||||
// window.print('https://nxgcreator.s3.ap-south-1.amazonaws.com/exported_file_32_2023-08-22T04%3A59%3A13.432Z.pdf',);
|
||||
};
|
||||
|
||||
//handle download signed pdf
|
||||
const handleDownloadPdf = () => {
|
||||
saveAs(pdfUrl, `${pdfName}_signed_by_opensign.qik.ai.pdf`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* isEmail */}
|
||||
<Modal show={isEmail}>
|
||||
{isLoading && (
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
zIndex: "20",
|
||||
backgroundColor: "#e6f2f2",
|
||||
opacity: 0.8,
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="no img"
|
||||
src={loader}
|
||||
style={{ width: "70px", height: "70px" }}
|
||||
/>
|
||||
<span style={{ fontSize: "12px", fontWeight: "bold" }}>
|
||||
This might take some time
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ModalHeader style={{ background: themeColor() }}>
|
||||
<span style={{ color: "white" }}>Email Documents</span>
|
||||
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
<div></div>
|
||||
<button
|
||||
onClick={handleToPrint}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
className="btn btn-primary btn-sm"
|
||||
>
|
||||
<i
|
||||
class="fa fa-print"
|
||||
style={{
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
color: "white",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Print
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="btn btn-danger btn-sm"
|
||||
onClick={() => handleDownloadPdf()}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-download"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
</ModalHeader>
|
||||
|
||||
<Modal.Body>
|
||||
{isCeleb && (
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
marginLeft: "50px",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="print img"
|
||||
width={300}
|
||||
height={250}
|
||||
// style={styles.gifCeleb}
|
||||
src={celebration}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<p
|
||||
style={{
|
||||
fontFamily: "system-ui",
|
||||
verticalAlign: "baseline",
|
||||
fontWeight: "500",
|
||||
color: "#403f3e",
|
||||
fontSize: "15px",
|
||||
}}
|
||||
>
|
||||
Recipients added here will get a copy of the signed document.
|
||||
</p>
|
||||
{emailCount.length > 0 ? (
|
||||
<>
|
||||
<div className="addEmail">
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
width: "450px",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
{emailCount.map((data, ind) => {
|
||||
return (
|
||||
<div className="emailChip" key={ind}>
|
||||
<span
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "13px",
|
||||
marginRight: "20px",
|
||||
}}
|
||||
>
|
||||
{data}
|
||||
</span>
|
||||
|
||||
<img
|
||||
alt="print img"
|
||||
onClick={() => removeChip(ind)}
|
||||
src={close}
|
||||
width={10}
|
||||
height={10}
|
||||
style={{ fontWeight: "600" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{emailCount.length <= 9 && (
|
||||
<input
|
||||
type="text"
|
||||
value={emailValue}
|
||||
className="addEmailInput"
|
||||
onChange={handleEmailValue}
|
||||
onKeyDown={handleEnterPress}
|
||||
required
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
value={emailValue}
|
||||
className="emailInput"
|
||||
onChange={handleEmailValue}
|
||||
onKeyDown={handleEnterPress}
|
||||
placeholder="Add the email addresses"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<span
|
||||
style={{
|
||||
cursor: emailValue && "pointer",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (emailValue) {
|
||||
handleEnterPress("add");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<i
|
||||
style={{
|
||||
backgroundColor: themeColor(),
|
||||
padding: "2px 10px",
|
||||
marginTop: "10px",
|
||||
color: "white",
|
||||
}}
|
||||
class="fa fa-plus"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</span>
|
||||
|
||||
<div
|
||||
style={{
|
||||
background: "#e3e2e1",
|
||||
marginTop: "30px",
|
||||
padding: "5px",
|
||||
borderRadius: "3px",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontWeight: "700" }}>Note:</span>
|
||||
<span style={{ fontSize: "15px" }}>
|
||||
{" "}
|
||||
You can only send to ten recipients at a time.
|
||||
</span>
|
||||
</div>
|
||||
</Modal.Body>
|
||||
|
||||
<Modal.Footer>
|
||||
<button
|
||||
style={{
|
||||
color: "black",
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn"
|
||||
onClick={() => setIsEmail(false)}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<button
|
||||
disabled={emailCount.length === 0 && true}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
color: "white",
|
||||
}}
|
||||
type="button"
|
||||
className={emailCount.length === 0 ? "defaultBtn" : "finishBtn"}
|
||||
onClick={() => sendEmail()}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EmailComponent;
|
||||
@@ -0,0 +1,366 @@
|
||||
import React, { useState } from "react";
|
||||
import * as Select from "@radix-ui/react-select";
|
||||
import classnames from "classnames";
|
||||
function FieldsComponent({
|
||||
pdfUrl,
|
||||
sign,
|
||||
stamp,
|
||||
dragSignature,
|
||||
signRef,
|
||||
handleDivClick,
|
||||
handleMouseLeave,
|
||||
isDragSign,
|
||||
themeColor,
|
||||
dragStamp,
|
||||
dragRef,
|
||||
isDragStamp,
|
||||
dragSignatureSS,
|
||||
dragStampSS,
|
||||
isDragSignatureSS,
|
||||
isSignYourself,
|
||||
addPositionOfSignature,
|
||||
signerPos,
|
||||
signersdata,
|
||||
isSelectListId,
|
||||
setSignerObjId,
|
||||
setIsSelectId,
|
||||
setContractName,
|
||||
isSigners,
|
||||
}) {
|
||||
const signStyle = pdfUrl ? "disableSign" : "signatureBtn";
|
||||
|
||||
const isMobile = window.innerWidth < 712;
|
||||
const [isShowSort, setIsShowSort] = useState(false);
|
||||
const [selectedEmail, setSelectedEmail] = useState("");
|
||||
const SelectItem = React.forwardRef(
|
||||
({ children, className, ...props }, forwardedRef) => {
|
||||
return (
|
||||
<Select.Item
|
||||
className={classnames("SelectItem", className)}
|
||||
{...props}
|
||||
ref={forwardedRef}
|
||||
>
|
||||
<Select.ItemText>{children}</Select.ItemText>
|
||||
<Select.ItemIndicator className="SelectItemIndicator"></Select.ItemIndicator>
|
||||
</Select.Item>
|
||||
);
|
||||
}
|
||||
);
|
||||
console.log("sign",isSignYourself)
|
||||
return (
|
||||
<>
|
||||
<div className="signerComponent">
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
|
||||
padding: "5px",
|
||||
}}
|
||||
>
|
||||
<span className="signedStyle">Fields</span>
|
||||
</div>
|
||||
|
||||
<div className="signLayoutContainer1">
|
||||
{pdfUrl ? (
|
||||
<>
|
||||
<button className={signStyle} disabled={true}>
|
||||
<span
|
||||
style={{
|
||||
fontWeight: "400",
|
||||
fontSize: "15px",
|
||||
padding: "3px 20px 0px 20px",
|
||||
color: "#bfbfbf",
|
||||
}}
|
||||
>
|
||||
Signature
|
||||
</span>
|
||||
|
||||
<img
|
||||
alt="sign img"
|
||||
style={{
|
||||
width: "30px",
|
||||
height: "28px",
|
||||
background: "#d3edeb",
|
||||
}}
|
||||
src={sign}
|
||||
/>
|
||||
</button>
|
||||
<button className={signStyle} disabled={true}>
|
||||
<span
|
||||
style={{
|
||||
fontWeight: "400",
|
||||
fontSize: "15px",
|
||||
padding: "3px 0px 0px 35px",
|
||||
color: "#bfbfbf",
|
||||
}}
|
||||
>
|
||||
Stamp
|
||||
</span>
|
||||
|
||||
<img
|
||||
alt="stamp img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "28px",
|
||||
background: "#d3edeb",
|
||||
}}
|
||||
src={stamp}
|
||||
/>
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
ref={(element) => {
|
||||
dragSignature(element);
|
||||
if (element) {
|
||||
signRef.current = element;
|
||||
// const height = signRef && signRef.current.offsetHeight;
|
||||
// const width = signRef && signRef.current.offsetWidth;
|
||||
}
|
||||
}}
|
||||
className={signStyle}
|
||||
onMouseMove={handleDivClick}
|
||||
onMouseDown={handleMouseLeave}
|
||||
style={{
|
||||
opacity: isDragSign ? 0.5 : 1,
|
||||
boxShadow:
|
||||
"0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontWeight: "400",
|
||||
fontSize: "15px",
|
||||
padding: "3px 20px 0px 20px",
|
||||
color: "black",
|
||||
}}
|
||||
>
|
||||
Signature
|
||||
</span>
|
||||
<img
|
||||
alt="sign img"
|
||||
style={{
|
||||
width: "30px",
|
||||
height: "28px",
|
||||
background: themeColor(),
|
||||
}}
|
||||
src={sign}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
ref={(element) => {
|
||||
dragStamp(element);
|
||||
dragRef.current = element;
|
||||
if (isDragStamp) {
|
||||
// setIsStamp(true);
|
||||
}
|
||||
}}
|
||||
className={!pdfUrl ? signStyle : "disableSign"}
|
||||
disabled={pdfUrl && true}
|
||||
onMouseMove={handleDivClick}
|
||||
onMouseDown={handleMouseLeave}
|
||||
style={{
|
||||
opacity: isDragStamp ? 0.5 : 1,
|
||||
boxShadow:
|
||||
"0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontWeight: "400",
|
||||
fontSize: "15px",
|
||||
padding: "3px 0px 0px 35px",
|
||||
color: !pdfUrl ? "black" : "#bfbfbf",
|
||||
}}
|
||||
>
|
||||
Stamp
|
||||
</span>
|
||||
|
||||
<img
|
||||
alt="stamp img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "28px",
|
||||
background: themeColor(),
|
||||
}}
|
||||
src={stamp}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{isMobile && isSignYourself && (
|
||||
<div
|
||||
id="navbar"
|
||||
className="stickyfooter"
|
||||
style={{ width: window.innerWidth + "px" }}
|
||||
>
|
||||
{isSigners && (
|
||||
<div
|
||||
style={{
|
||||
background: "#887abf",
|
||||
padding: "10px 20px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: "18px", fontWeight: "500" }}>
|
||||
Signer :
|
||||
</span>
|
||||
|
||||
<Select.Root onValueChange={(e) => console.log("value", e)}>
|
||||
<Select.Trigger
|
||||
onValueChange={(e) => console.log("value", e)}
|
||||
className="SelectTrigger"
|
||||
aria-label="Food"
|
||||
>
|
||||
<Select.Value placeholder="Select signer" />
|
||||
<Select.Icon className="SelectIcon">
|
||||
<i
|
||||
style={{
|
||||
marginTop: "5px",
|
||||
marginLeft: "5px",
|
||||
color: "#3b15d1",
|
||||
fontSize: "20px",
|
||||
}}
|
||||
class="fa fa-angle-down"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</Select.Icon>
|
||||
</Select.Trigger>
|
||||
<Select.Portal>
|
||||
<Select.Content
|
||||
className="SelectContent"
|
||||
style={{ zIndex: "5000" }}
|
||||
>
|
||||
<Select.ScrollUpButton className="SelectScrollButton">
|
||||
<i
|
||||
style={{
|
||||
marginTop: "5px",
|
||||
marginLeft: "5px",
|
||||
color: "#3b15d1",
|
||||
fontSize: "20px",
|
||||
}}
|
||||
class="fa fa-angle-down"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</Select.ScrollUpButton>
|
||||
<Select.Viewport className="SelectViewport">
|
||||
<Select.Group>
|
||||
{signersdata.Signers.map((obj, ind) => {
|
||||
return (
|
||||
<SelectItem key={ind} value={selectedEmail}>
|
||||
{" "}
|
||||
{obj.Email}
|
||||
</SelectItem>
|
||||
);
|
||||
})}
|
||||
</Select.Group>
|
||||
</Select.Viewport>
|
||||
<Select.ScrollDownButton className="SelectScrollButton">
|
||||
<i
|
||||
style={{
|
||||
marginTop: "5px",
|
||||
marginLeft: "5px",
|
||||
color: "#3b15d1",
|
||||
fontSize: "20px",
|
||||
}}
|
||||
class="fa fa-angle-down"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</Select.ScrollDownButton>
|
||||
</Select.Content>
|
||||
</Select.Portal>
|
||||
</Select.Root>
|
||||
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="signLayoutContainer2"
|
||||
style={{ backgroundColor: themeColor() }}
|
||||
>
|
||||
<div
|
||||
onClick={() => addPositionOfSignature("onclick", false)}
|
||||
ref={(element) => {
|
||||
dragSignatureSS(element);
|
||||
if (element) {
|
||||
signRef.current = element;
|
||||
// const height = signRef && signRef.current.offsetHeight;
|
||||
// const width = signRef && signRef.current.offsetWidth;
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none",
|
||||
opacity: isDragSignatureSS ? 0.5 : 1,
|
||||
backgroundImage: `url(${sign})`,
|
||||
backgroundSize: "70% 70%",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "center center",
|
||||
paddingBottom: "2.2rem",
|
||||
}}
|
||||
>
|
||||
{/* <img
|
||||
alt="sign img"
|
||||
style={{
|
||||
width: "30px",
|
||||
height: "30px",
|
||||
background: themeColor(),
|
||||
}}
|
||||
src={sign}
|
||||
/> */}
|
||||
<span
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "12px",
|
||||
position: "relative",
|
||||
top: "2.6rem",
|
||||
}}
|
||||
>
|
||||
Signature
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => addPositionOfSignature("onclick", true)}
|
||||
ref={(element) => {
|
||||
dragStampSS(element);
|
||||
dragRef.current = element;
|
||||
}}
|
||||
onMouseMove={handleDivClick}
|
||||
onMouseDown={handleMouseLeave}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none",
|
||||
backgroundImage: `url(${stamp})`,
|
||||
backgroundSize: "32px 33px",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "center center",
|
||||
paddingBottom: "2.2rem",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "12px",
|
||||
position: "relative",
|
||||
top: "2.6rem",
|
||||
}}
|
||||
>
|
||||
Stamp
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default FieldsComponent;
|
||||
@@ -0,0 +1,660 @@
|
||||
import React from "react";
|
||||
import PrevNext from "./prevNext";
|
||||
import { PDFDownloadLink } from "@react-pdf/renderer";
|
||||
import Certificate from "../Certificate/Certificate";
|
||||
import printModule from "print-js";
|
||||
import { getBase64FromUrl } from "../../utils/Utils";
|
||||
import { saveAs } from "file-saver";
|
||||
import "../../css/signature.css";
|
||||
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
|
||||
function Header({
|
||||
isPdfRequestFiles,
|
||||
isPlaceholder,
|
||||
recipient,
|
||||
setIsDecline,
|
||||
pageNumber,
|
||||
isAlreadySign,
|
||||
allPages,
|
||||
changePage,
|
||||
pdfUrl,
|
||||
documentStatus,
|
||||
embedImages,
|
||||
pdfDetails,
|
||||
signerPos,
|
||||
signersdata,
|
||||
isMailSend,
|
||||
alertSendEmail,
|
||||
isSigned,
|
||||
isCompleted,
|
||||
isShowHeader,
|
||||
decline,
|
||||
currentSigner,
|
||||
}) {
|
||||
const isMobile = window.innerWidth < 712;
|
||||
const navigate = useNavigate();
|
||||
|
||||
//for go to previous page
|
||||
function previousPage() {
|
||||
changePage(-1);
|
||||
}
|
||||
//for go to next page
|
||||
function nextPage() {
|
||||
changePage(1);
|
||||
}
|
||||
//function for show decline alert
|
||||
const handleDeclinePdfAlert = async () => {
|
||||
const currentDecline = {
|
||||
currnt: "Sure",
|
||||
isDeclined: true,
|
||||
};
|
||||
setIsDecline(currentDecline);
|
||||
};
|
||||
|
||||
//function for print digital sign pdf
|
||||
const handleToPrint = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const pdf = await getBase64FromUrl(pdfUrl);
|
||||
|
||||
printModule({ printable: pdf, type: "pdf", base64: true });
|
||||
};
|
||||
|
||||
//handle download signed pdf
|
||||
const handleDownloadPdf = () => {
|
||||
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
|
||||
|
||||
saveAs(pdfUrl, `${pdfName}_signed_by_opensign.qik.ai.pdf`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{ paddingBottom: "5px", paddingTop: "5px" }}
|
||||
className="mobileHead"
|
||||
>
|
||||
<div className="signatureHeader headerBtn">
|
||||
<PrevNext
|
||||
pageNumber={pageNumber}
|
||||
allPages={allPages}
|
||||
changePage={changePage}
|
||||
/>
|
||||
|
||||
{recipient ? (
|
||||
pdfUrl || isAlreadySign.mssg ? (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
{pdfDetails[0] && pdfDetails.length > 0 && (
|
||||
// <Certificate
|
||||
// pdfData={completePdfData}
|
||||
// />
|
||||
<PDFDownloadLink
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<i
|
||||
class="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
)}
|
||||
<button
|
||||
onClick={handleToPrint}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
className="defaultBtn printBtn"
|
||||
>
|
||||
<i
|
||||
class="fa fa-print"
|
||||
style={{
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
color: "white",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Print
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
className="defaultBtn downloadBtn"
|
||||
onClick={() => handleDownloadPdf()}
|
||||
>
|
||||
<i
|
||||
className="fa fa-download"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
<button
|
||||
style={{
|
||||
background: "#de4337",
|
||||
}}
|
||||
className="finishBtn hoverCss"
|
||||
onClick={() => {
|
||||
handleDeclinePdfAlert();
|
||||
}}
|
||||
>
|
||||
Decline
|
||||
</button>
|
||||
|
||||
<button
|
||||
data-tut="reactourThird"
|
||||
style={{
|
||||
background: !pdfUrl ? "#188ae2" : "#d3edeb",
|
||||
}}
|
||||
className="finishBtn sendHover"
|
||||
onClick={() => {
|
||||
if (!pdfUrl) {
|
||||
embedImages();
|
||||
}
|
||||
}}
|
||||
>
|
||||
Finish
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
) : pdfUrl || (documentStatus && documentStatus.isCompleted) ? (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
<PDFDownloadLink
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
className="defaultBtn certificateBtn"
|
||||
>
|
||||
<i
|
||||
class="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
<button
|
||||
onClick={handleToPrint}
|
||||
type="button"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
className="defaultBtn printBtn"
|
||||
>
|
||||
<i
|
||||
class="fa fa-print"
|
||||
style={{
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
color: "white",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Print
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn downloadBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
onClick={() => handleDownloadPdf()}
|
||||
>
|
||||
<i
|
||||
className="fa fa-download"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
) : isPlaceholder ? (
|
||||
<>
|
||||
{!isMailSend &&
|
||||
signersdata.Signers &&
|
||||
signersdata.Signers.length !== signerPos.length && (
|
||||
<div>
|
||||
{signerPos.length === 0 ? (
|
||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
||||
Add all {signersdata.Signers.length - signerPos.length}{" "}
|
||||
recipients signature
|
||||
</span>
|
||||
) : (
|
||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
||||
Add {signersdata.Signers.length - signerPos.length} more
|
||||
recipients signature
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
navigate(-1);
|
||||
}}
|
||||
type="button"
|
||||
className="defaultBtn backBtn"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
|
||||
<button
|
||||
data-tut="reactourFour"
|
||||
style={{
|
||||
background: !isMailSend ? "#188ae2" : "#d3edeb",
|
||||
}}
|
||||
onClick={() => {
|
||||
alertSendEmail();
|
||||
}}
|
||||
className="finishBtn sendHover"
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
) : isPdfRequestFiles ? (
|
||||
isSigned ? (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
{isCompleted.isCertificate && (
|
||||
<PDFDownloadLink
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<i
|
||||
class="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
)}
|
||||
<button
|
||||
onClick={handleToPrint}
|
||||
type="button"
|
||||
className="defaultBtn printBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<i
|
||||
class="fa fa-print"
|
||||
style={{
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
color: "white",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Print
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn downloadBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
onClick={() => handleDownloadPdf()}
|
||||
>
|
||||
<i
|
||||
className="fa fa-download"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
navigate(-1);
|
||||
}}
|
||||
type="button"
|
||||
className="defaultBtn backBtn"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
{currentSigner && (
|
||||
<>
|
||||
<button
|
||||
style={{
|
||||
background: "#de4337",
|
||||
}}
|
||||
className="finishBtn hoverCss"
|
||||
onClick={() => {
|
||||
handleDeclinePdfAlert();
|
||||
}}
|
||||
>
|
||||
Decline
|
||||
</button>
|
||||
<button
|
||||
style={{
|
||||
background: "#188ae2",
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn sendHover"
|
||||
onClick={() => {
|
||||
embedImages();
|
||||
}}
|
||||
>
|
||||
Finish
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
navigate(-1);
|
||||
}}
|
||||
type="button"
|
||||
className="defaultBtn backBtn"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
|
||||
<button
|
||||
style={{
|
||||
background: "#188ae2",
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn sendHover"
|
||||
onClick={() => {
|
||||
if (!pdfUrl) {
|
||||
embedImages();
|
||||
}
|
||||
}}
|
||||
>
|
||||
Finish
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{isMobile && isShowHeader && (
|
||||
<div
|
||||
id="navbar"
|
||||
className="stickyHead"
|
||||
style={{ width: window.innerWidth - 30 + "px" }}
|
||||
>
|
||||
<div className="preBtn2">
|
||||
<div
|
||||
onClick={() => {
|
||||
navigate(-1);
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-arrow-left"
|
||||
aria-hidden="true"
|
||||
style={{ color: themeColor(), cursor: "pointer" }}
|
||||
></i>
|
||||
</div>
|
||||
<div>
|
||||
<i
|
||||
onClick={() => {
|
||||
if (pageNumber > 1) {
|
||||
previousPage();
|
||||
}
|
||||
}}
|
||||
className="fa fa-backward"
|
||||
style={{ color: "gray", cursor: "pointer" }}
|
||||
></i>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "13px",
|
||||
fontWeight: "600",
|
||||
marginLeft: "10px",
|
||||
marginRight: "10px",
|
||||
}}
|
||||
>
|
||||
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
|
||||
</span>
|
||||
<i
|
||||
onClick={() => {
|
||||
if (pageNumber < allPages) {
|
||||
nextPage();
|
||||
}
|
||||
}}
|
||||
className="fa fa-forward"
|
||||
style={{ color: "gray", cursor: "pointer" }}
|
||||
></i>
|
||||
</div>
|
||||
{pdfUrl ? (
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<div
|
||||
// onClick={() => handleDownloadPdf()}
|
||||
style={{
|
||||
color: themeColor(),
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px",
|
||||
}}
|
||||
>
|
||||
<i class="fa fa-ellipsis-v" aria-hidden="true"></i>
|
||||
</div>
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content
|
||||
className="DropdownMenuContent"
|
||||
sideOffset={5}
|
||||
>
|
||||
<DropdownMenu.Item
|
||||
className="DropdownMenuItem"
|
||||
onClick={() => handleDownloadPdf()}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<i class="fa fa-arrow-down" aria-hidden="true" style={{marginRight:"2px"}}></i>
|
||||
Download
|
||||
</div>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="DropdownMenuItem">
|
||||
<PDFDownloadLink
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
<>
|
||||
{console.log("error",error)}
|
||||
{loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<i
|
||||
class="fa fa-certificate"
|
||||
style={{
|
||||
fontSize: "15px",
|
||||
marginRight: "3px",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Root>
|
||||
) : (
|
||||
<div style={{ display: "flex", justifyContent: "space-around" }}>
|
||||
{/* current signer is checking user send request and check status of pdf sign than if current
|
||||
user exist than show finish button else no
|
||||
*/}
|
||||
{currentSigner && (
|
||||
<>
|
||||
{decline && (
|
||||
<div
|
||||
onClick={() => {
|
||||
handleDeclinePdfAlert();
|
||||
}}
|
||||
style={{
|
||||
color: "red",
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px",
|
||||
marginRight: "10px",
|
||||
}}
|
||||
>
|
||||
Decline
|
||||
</div>
|
||||
)}
|
||||
{isPlaceholder ?(
|
||||
<div
|
||||
onClick={() => {
|
||||
alertSendEmail();
|
||||
}}
|
||||
style={{
|
||||
color: themeColor(),
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px",
|
||||
}}
|
||||
>
|
||||
Send
|
||||
</div>
|
||||
):(
|
||||
<div
|
||||
onClick={() => {
|
||||
if (!pdfUrl) {
|
||||
embedImages();
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
color: themeColor(),
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px",
|
||||
}}
|
||||
>
|
||||
Finish
|
||||
</div>
|
||||
)}
|
||||
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react'
|
||||
import loader from "../../assests/loader2.gif";
|
||||
|
||||
|
||||
function Loader({isLoading}) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="no img"
|
||||
src={loader}
|
||||
style={{ width: "80px", height: "80px" }}
|
||||
/>
|
||||
<span style={{ fontSize: "13px", color: "gray" }}>
|
||||
{isLoading.message}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Loader
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
import Modal from "react-bootstrap/Modal";
|
||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
||||
|
||||
function ModalComponent({ isShow, type }) {
|
||||
return (
|
||||
<Modal show={isShow}>
|
||||
<ModalHeader className="bg-danger" style={{ color: "white" }}>
|
||||
{type === "pdfFail" ? (
|
||||
<span>Failed to load pdf!</span>
|
||||
) : (
|
||||
<span>Document Expired!</span>
|
||||
)}
|
||||
</ModalHeader>
|
||||
|
||||
<Modal.Body>
|
||||
{type === "pdfFail" ? (
|
||||
<p>Something went wrong failed to load pdf file!</p>
|
||||
) : (
|
||||
<p>This Document is no longer available.</p>
|
||||
)}
|
||||
|
||||
</Modal.Body>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalComponent;
|
||||
@@ -0,0 +1,58 @@
|
||||
import React from "react";
|
||||
|
||||
function PrevNext({ pageNumber, allPages, changePage }) {
|
||||
//for go to previous page
|
||||
function previousPage() {
|
||||
changePage(-1);
|
||||
}
|
||||
//for go to next page
|
||||
function nextPage() {
|
||||
changePage(1);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="preBtn1">
|
||||
<button
|
||||
style={{
|
||||
padding: "3px 20px ",
|
||||
fontSize: "10px",
|
||||
background: "#d3edeb",
|
||||
fontWeight: "600",
|
||||
|
||||
border: "0px",
|
||||
marginRight: "5px",
|
||||
}}
|
||||
disabled={pageNumber <= 1}
|
||||
onClick={previousPage}
|
||||
>
|
||||
Prev
|
||||
</button>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "13px",
|
||||
fontWeight: "600",
|
||||
}}
|
||||
>
|
||||
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
|
||||
</span>
|
||||
<button
|
||||
style={{
|
||||
padding: "3px 20px ",
|
||||
fontSize: "10px",
|
||||
background: "#d3edeb",
|
||||
fontWeight: "600",
|
||||
marginLeft: "5px",
|
||||
border: "0px",
|
||||
}}
|
||||
disabled={pageNumber >= allPages}
|
||||
onClick={nextPage}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PrevNext;
|
||||
@@ -0,0 +1,96 @@
|
||||
import React from "react";
|
||||
import RSC from "react-scrollbars-custom";
|
||||
import { Document, Page, pdfjs } from "react-pdf";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
|
||||
function RenderAllPdfPage({
|
||||
pdfUrl,
|
||||
signPdfUrl,
|
||||
allPages,
|
||||
setAllPages,
|
||||
setPageNumber,
|
||||
setSignBtnPosition,
|
||||
}) {
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
|
||||
|
||||
//set all number of pages after load pdf
|
||||
function onDocumentLoad({ numPages }) {
|
||||
setAllPages(numPages);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="showPages">
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
boxShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px",
|
||||
backgroundColor: "white",
|
||||
height:"100%"
|
||||
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "140px" }}>
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
// color:"white"
|
||||
}}
|
||||
className="signedStyle"
|
||||
>
|
||||
Pages
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<RSC id="RSC-Example" style={{width:"135px",height:window.innerHeight-130+'px'}} >
|
||||
<Document
|
||||
onLoadSuccess={onDocumentLoad}
|
||||
file={pdfUrl ? pdfUrl : signPdfUrl}
|
||||
// file="https://api.printnode.com/static/test/pdf/multipage.pdf"
|
||||
>
|
||||
{Array.from(new Array(allPages), (el, index) => (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
width: "100px",
|
||||
border: "2px solid #878787",
|
||||
// padding: "5px",
|
||||
margin: "10px",
|
||||
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
contain: "content",
|
||||
}}
|
||||
onClick={() => {
|
||||
setPageNumber(index + 1);
|
||||
if (setSignBtnPosition) {
|
||||
setSignBtnPosition([]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Page
|
||||
key={`page_${index + 1}`}
|
||||
pageNumber={index + 1}
|
||||
width={100}
|
||||
height={100}
|
||||
scale={1}
|
||||
renderAnnotationLayer={false}
|
||||
renderTextLayer={false}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Document>
|
||||
</RSC>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default RenderAllPdfPage;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,476 @@
|
||||
import React from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import SignatureCanvas from "react-signature-canvas";
|
||||
import redPen from "../../assests/redPen.png";
|
||||
import bluePen from "../../assests/bluePen.png";
|
||||
import blackPen from "../../assests/blackPen.png";
|
||||
import Modal from "react-bootstrap/Modal";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import { useEffect } from "react";
|
||||
|
||||
function SignPad({
|
||||
isSignPad,
|
||||
isStamp,
|
||||
setIsImageSelect,
|
||||
onSaveSign,
|
||||
setIsSignPad,
|
||||
setImage,
|
||||
isImageSelect,
|
||||
imageRef,
|
||||
onImageChange,
|
||||
|
||||
onSaveImage,
|
||||
image,
|
||||
defaultSign,
|
||||
setSignature,
|
||||
}) {
|
||||
const [penColor, setPenColor] = useState("blue");
|
||||
const allColor = [bluePen, redPen, blackPen];
|
||||
const canvasRef = useRef(null);
|
||||
const [isDefaultSign, setIsDefaultSign] = useState(false);
|
||||
const [isTab, setIsTab] = useState("signature");
|
||||
const [isSignImg, setIsSignImg] = useState("");
|
||||
//function for clear signature
|
||||
const handleClear = () => {
|
||||
if (canvasRef.current) {
|
||||
canvasRef.current.clear();
|
||||
}
|
||||
|
||||
setIsSignImg("");
|
||||
};
|
||||
//function for set signature url
|
||||
const handleSignatureChange = (dataURL) => {
|
||||
// canvasRef.current.backgroundColor = 'rgb(165, 26, 26)'
|
||||
setSignature(canvasRef.current.toDataURL());
|
||||
setIsSignImg(canvasRef.current.toDataURL());
|
||||
};
|
||||
|
||||
//save button component
|
||||
const SaveBtn = () => {
|
||||
// console.log("isSign",isSignImg,image)
|
||||
|
||||
return (
|
||||
<div>
|
||||
{!isStamp && !isImageSelect && (
|
||||
<button
|
||||
style={{
|
||||
color: "black",
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn saveBtn"
|
||||
onClick={() => handleClear()}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!image) {
|
||||
if (isDefaultSign) {
|
||||
setIsSignImg("");
|
||||
onSaveSign(isDefaultSign);
|
||||
} else {
|
||||
setIsSignImg("");
|
||||
onSaveSign();
|
||||
}
|
||||
|
||||
setPenColor("blue");
|
||||
} else {
|
||||
setIsSignImg("");
|
||||
onSaveImage();
|
||||
}
|
||||
setIsSignPad(false);
|
||||
|
||||
setIsImageSelect(false);
|
||||
setIsDefaultSign(false);
|
||||
setImage();
|
||||
setIsTab("signature");
|
||||
}}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
color: "white",
|
||||
}}
|
||||
disabled={isSignImg || image || isDefaultSign ? false : true}
|
||||
type="button"
|
||||
className={
|
||||
isSignImg || image ? "finishBtn saveBtn" : "disabledFinish saveBtn"
|
||||
}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Load the default signature after the component mounts
|
||||
if (canvasRef.current) {
|
||||
canvasRef.current.fromDataURL(isSignImg);
|
||||
}
|
||||
}, [isTab]);
|
||||
return (
|
||||
<div>
|
||||
{/*isSignPad */}
|
||||
<Modal show={isSignPad}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
background: "white",
|
||||
borderBottom: "1.6px solid #ebe6e6",
|
||||
marginTop: "15px",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-around",
|
||||
alignItems: "end",
|
||||
gap: 10,
|
||||
|
||||
// background: themeColor(),
|
||||
}}
|
||||
>
|
||||
{isStamp ? (
|
||||
<span style={{ color: themeColor() }} className="signTab">
|
||||
Upload Image
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
<div>
|
||||
<span
|
||||
onClick={() => {
|
||||
setIsDefaultSign(false);
|
||||
setIsImageSelect(false);
|
||||
setIsTab("signature");
|
||||
setImage();
|
||||
}}
|
||||
style={{
|
||||
color: isTab === "signature" ? themeColor() : "#515252",
|
||||
|
||||
marginLeft: "2px",
|
||||
}}
|
||||
className="signTab"
|
||||
>
|
||||
Signature
|
||||
</span>
|
||||
|
||||
<div
|
||||
style={{
|
||||
border:
|
||||
isTab === "signature"
|
||||
? "1.5px solid #108783"
|
||||
: "1.5px solid #ffffff",
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
onClick={() => {
|
||||
setIsDefaultSign(false);
|
||||
setIsImageSelect(true);
|
||||
setIsTab("uploadImage");
|
||||
}}
|
||||
style={{
|
||||
color: isTab === "uploadImage" ? themeColor() : "#515252",
|
||||
}}
|
||||
className="signTab"
|
||||
>
|
||||
Upload Image
|
||||
</span>
|
||||
<div
|
||||
style={{
|
||||
border:
|
||||
isTab === "uploadImage"
|
||||
? "1.5px solid #108783"
|
||||
: "1.5px solid #ffffff",
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
|
||||
{defaultSign && (
|
||||
<div>
|
||||
<span
|
||||
onClick={() => {
|
||||
setIsDefaultSign(true);
|
||||
setIsImageSelect(true);
|
||||
setIsTab("mysignature");
|
||||
setImage();
|
||||
}}
|
||||
style={{
|
||||
color:
|
||||
isTab === "mysignature" ? themeColor() : "#515252",
|
||||
}}
|
||||
className="signTab"
|
||||
>
|
||||
My Signature
|
||||
</span>
|
||||
<div
|
||||
style={{
|
||||
border:
|
||||
isTab === "mysignature"
|
||||
? "1.5px solid #108783"
|
||||
: "1.5px solid #ffffff",
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
style={{
|
||||
border: "0px",
|
||||
background: "none",
|
||||
paddingLeft: "7px",
|
||||
paddingRight: "7px",
|
||||
marginRight: "5px",
|
||||
}}
|
||||
onClick={() => {
|
||||
setPenColor("blue");
|
||||
setIsSignPad(false);
|
||||
|
||||
setIsImageSelect(false);
|
||||
setIsDefaultSign(false);
|
||||
setImage();
|
||||
setIsTab("signature");
|
||||
}}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* signature modal */}
|
||||
<Modal.Body className="modalBody">
|
||||
{isDefaultSign ? (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 6,
|
||||
cursor: "pointer",
|
||||
// background:'rgb(255, 255, 255)'
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
>
|
||||
<img
|
||||
alt="stamp img"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
background: "rgb(255, 255, 255)",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={defaultSign}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
<SaveBtn />
|
||||
</div>
|
||||
</>
|
||||
) : isImageSelect || isStamp ? (
|
||||
!image ? (
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 6,
|
||||
cursor: "pointer",
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
onClick={() => imageRef.current.click()}
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
onChange={onImageChange}
|
||||
className="filetype"
|
||||
accept="image/*"
|
||||
ref={imageRef}
|
||||
hidden
|
||||
// style={{ display: "none" }}
|
||||
/>
|
||||
<i className="fas fa-cloud-upload-alt uploadImgLogo"></i>
|
||||
<div className="uploadImg">Upload</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
// position: "relative",
|
||||
|
||||
border: "1px solid black",
|
||||
marginBottom: 6,
|
||||
// justifyContent:"center"
|
||||
overflow: "hidden",
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
>
|
||||
<img
|
||||
alt="print img"
|
||||
ref={imageRef}
|
||||
// alt="preview image"
|
||||
src={image.src}
|
||||
style={{
|
||||
//overflow:"hidden",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
<SaveBtn />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<>
|
||||
{/* {isSignImg ? (
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
|
||||
border: "2px solid #888",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
>
|
||||
<img
|
||||
alt="preview image"
|
||||
src={isSignImg}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : ( */}
|
||||
<SignatureCanvas
|
||||
ref={canvasRef}
|
||||
penColor={penColor}
|
||||
canvasProps={{
|
||||
// width: "460px",
|
||||
// height: "184px",
|
||||
// width:"280px",
|
||||
// height:"112px",
|
||||
className: "signatureCanvas",
|
||||
}}
|
||||
backgroundColor="rgb(255, 255, 255)"
|
||||
onEnd={() =>
|
||||
handleSignatureChange(canvasRef.current.toDataURL())
|
||||
}
|
||||
dotSize={1}
|
||||
/>
|
||||
{/* )} */}
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
marginTop:"4px"
|
||||
}}
|
||||
>
|
||||
<div style={{display:"flex",flexDirection:"row"}}>
|
||||
{allColor.map((data, key) => {
|
||||
return (
|
||||
<img
|
||||
key={key}
|
||||
alt="pen img"
|
||||
style={{
|
||||
border: "none",
|
||||
margin: "5px",
|
||||
borderBottom:
|
||||
key === 0 && penColor === "blue"
|
||||
? "2px solid blue"
|
||||
: key === 1 && penColor === "red"
|
||||
? "2px solid red"
|
||||
: key === 2 && penColor === "black"
|
||||
? "2px solid black"
|
||||
: "2px solid white",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (key === 0) {
|
||||
setPenColor("blue");
|
||||
} else if (key === 1) {
|
||||
setPenColor("red");
|
||||
} else if (key === 2) {
|
||||
setPenColor("black");
|
||||
}
|
||||
}}
|
||||
src={data}
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
// </button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<SaveBtn />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Modal.Body>
|
||||
|
||||
{/* <Modal.Footer>
|
||||
{!isStamp && !isImageSelect && (
|
||||
<button
|
||||
style={{
|
||||
color: "black",
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn"
|
||||
onClick={() => handleClear()}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!image) {
|
||||
if (isDefaultSign) {
|
||||
onSaveSign(isDefaultSign);
|
||||
} else {
|
||||
onSaveSign();
|
||||
}
|
||||
|
||||
setPenColor("blue");
|
||||
} else {
|
||||
onSaveImage();
|
||||
}
|
||||
setIsSignPad(false);
|
||||
|
||||
setIsImageSelect(false);
|
||||
setIsDefaultSign(false);
|
||||
setImage();
|
||||
}}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
color: "white",
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</Modal.Footer> */}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SignPad;
|
||||
@@ -0,0 +1,68 @@
|
||||
import React from "react";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import "../../css/signature.css";
|
||||
function Signedby({ pdfDetails }) {
|
||||
const getFirstLetter = (name) => {
|
||||
const firstLetter = name.charAt(0);
|
||||
return firstLetter;
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<div className="signerComponent">
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
// color:"white"
|
||||
}}
|
||||
className="signedStyle"
|
||||
>
|
||||
Signed By
|
||||
</div>
|
||||
<div style={{ marginTop: "2px" }}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
padding: "10px",
|
||||
|
||||
background: "#93a3db",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="signerStyle"
|
||||
style={{
|
||||
background: "#abd1d0",
|
||||
width: 20,
|
||||
height: 20,
|
||||
display: "flex",
|
||||
borderRadius: 30 / 2,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginRight: "20px",
|
||||
marginTop: "5px",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "8px",
|
||||
textAlign: "center",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{" "}
|
||||
{getFirstLetter(pdfDetails.ExtUserPtr.Name)}
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
<span className="userName">{pdfDetails.ExtUserPtr.Name}</span>
|
||||
<span className="useEmail">{pdfDetails.ExtUserPtr.Email}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
export default Signedby;
|
||||
@@ -0,0 +1,163 @@
|
||||
import React, { useState } from "react";
|
||||
import check from "../../assests/checkBox.png";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
|
||||
function SignerListPlace({
|
||||
signerPos,
|
||||
signersdata,
|
||||
isSelectListId,
|
||||
setSignerObjId,
|
||||
setIsSelectId,
|
||||
setContractName
|
||||
}) {
|
||||
const color = [
|
||||
"#93a3db",
|
||||
"#e6c3db",
|
||||
"#c0e3bc",
|
||||
"#bce3db",
|
||||
"#b8ccdb",
|
||||
"#ceb8db",
|
||||
"#ffccff",
|
||||
"#99ffcc",
|
||||
"#cc99ff",
|
||||
"#ffcc99",
|
||||
"#66ccff",
|
||||
"#ffffcc",
|
||||
];
|
||||
|
||||
const nameColor = [
|
||||
"#304fbf",
|
||||
"#7d5270",
|
||||
"#5f825b",
|
||||
"#578077",
|
||||
"#576e80",
|
||||
"#6d527d",
|
||||
"#cc00cc",
|
||||
"#006666",
|
||||
"#cc00ff",
|
||||
"#ff9900",
|
||||
"#336699",
|
||||
"#cc9900",
|
||||
];
|
||||
const [isHover, setIsHover] = useState();
|
||||
|
||||
//function for onhover signer name change background color
|
||||
const onHoverStyle = (ind) => {
|
||||
const style = {
|
||||
background: color[ind % color.length],
|
||||
padding: "10px",
|
||||
marginTop: "2px",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
borderBottom: "1px solid #e3e1e1",
|
||||
};
|
||||
return style;
|
||||
};
|
||||
//function for onhover signer name remove background color
|
||||
const nonHoverStyle = (ind) => {
|
||||
const style = {
|
||||
// width:"250px",
|
||||
padding: "10px",
|
||||
marginTop: "2px",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
|
||||
justifyContent: "space-between",
|
||||
};
|
||||
return style;
|
||||
};
|
||||
|
||||
const getFirstLetter = (name) => {
|
||||
const firstLetter = name.charAt(0);
|
||||
return firstLetter;
|
||||
};
|
||||
|
||||
return (
|
||||
<div >
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
|
||||
padding: "5px",
|
||||
}}
|
||||
>
|
||||
<span className="signedStyle">Reicipents</span>
|
||||
</div>
|
||||
|
||||
<div className="signerList">
|
||||
{signersdata.Signers &&
|
||||
signersdata.Signers.map((obj, ind) => {
|
||||
return (
|
||||
<div
|
||||
data-tut="reactourFirst"
|
||||
onMouseEnter={() => setIsHover(ind)}
|
||||
onMouseLeave={() => setIsHover(null)}
|
||||
key={ind}
|
||||
style={
|
||||
isHover === ind || isSelectListId === ind
|
||||
? onHoverStyle(ind)
|
||||
: nonHoverStyle(ind)
|
||||
}
|
||||
onClick={() => {
|
||||
setSignerObjId(obj.objectId);
|
||||
setIsSelectId(ind);
|
||||
setContractName(obj.className)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="signerStyle"
|
||||
style={{
|
||||
background: nameColor[ind % nameColor.length],
|
||||
width: 20,
|
||||
height: 20,
|
||||
display: "flex",
|
||||
borderRadius: 30 / 2,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginRight: "20px",
|
||||
marginTop: "5px",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "8px",
|
||||
textAlign: "center",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{" "}
|
||||
{getFirstLetter(obj.Name)}
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
<span className="userName">{obj.Name}</span>
|
||||
<span className="useEmail">{obj.Email}</span>
|
||||
</div>
|
||||
</div>
|
||||
{signerPos.map((data, key) => {
|
||||
return (
|
||||
data.signerObjId === obj.objectId && (
|
||||
<div key={key}>
|
||||
<img alt="no img" src={check} width={20} height={20} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
})}
|
||||
|
||||
<hr />
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SignerListPlace;
|
||||
Reference in New Issue
Block a user