mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-06 09:47:39 +02:00
feat: implement react-tour alert for unsigned widgets
This commit is contained in:
@@ -10,6 +10,7 @@ import { useParams } from "react-router-dom";
|
||||
import SignPad from "./component/signPad";
|
||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Tour from "reactour";
|
||||
import {
|
||||
contractDocument,
|
||||
multiSignEmbed,
|
||||
@@ -66,6 +67,7 @@ function PdfRequestFiles() {
|
||||
const [isDecline, setIsDecline] = useState({ isDeclined: false });
|
||||
const [currentSigner, setCurrentSigner] = useState(false);
|
||||
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
||||
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
|
||||
const [defaultSignAlert, setDefaultSignAlert] = useState({
|
||||
isShow: false,
|
||||
alertMessage: ""
|
||||
@@ -85,6 +87,7 @@ function PdfRequestFiles() {
|
||||
const [alreadySign, setAlreadySign] = useState(false);
|
||||
const [containerWH, setContainerWH] = useState({});
|
||||
const [validateAlert, setValidateAlert] = useState(false);
|
||||
const [widgetsTour, setWidgetsTour] = useState(false);
|
||||
const divRef = useRef(null);
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const rowLevel =
|
||||
@@ -297,6 +300,7 @@ function PdfRequestFiles() {
|
||||
(data) => data.signerObjId === signerObjectId
|
||||
);
|
||||
if (checkUser && checkUser.length > 0) {
|
||||
let unSignUrlData;
|
||||
let checkWidgetSign = 0;
|
||||
let allXyPos = 0;
|
||||
let checkedRequireCount = 0;
|
||||
@@ -307,49 +311,74 @@ function PdfRequestFiles() {
|
||||
const posSignUrlData = checkUser[0].placeHolder[i].pos.filter(
|
||||
(pos) => pos?.SignUrl
|
||||
);
|
||||
const posWidgetData = checkUser[0].placeHolder[i].pos.filter(
|
||||
(pos) => pos?.widgetValue && pos?.type !== "checkbox"
|
||||
unSignUrlData = checkUser[0].placeHolder[i].pos.filter(
|
||||
(pos) => !pos?.SignUrl && !pos.widgetValue
|
||||
);
|
||||
const checkboxReadOnly = checkUser[0].placeHolder[i].pos.filter(
|
||||
(pos) =>
|
||||
pos?.widgetValue &&
|
||||
pos?.type === "checkbox" &&
|
||||
pos?.widgetStatus === "Read only"
|
||||
).length;
|
||||
const checkboxRequire = checkUser[0].placeHolder[i].pos.filter(
|
||||
(pos) => pos?.type === "checkbox" && pos?.widgetStatus === "Required"
|
||||
);
|
||||
CheckboxRequireCount = CheckboxRequireCount + checkboxRequire?.length;
|
||||
checkedRequireCount =
|
||||
checkedRequireCount +
|
||||
checkUser[0].placeHolder[i].pos?.filter(
|
||||
(pos) =>
|
||||
pos?.widgetValue &&
|
||||
pos?.type === "checkbox" &&
|
||||
pos?.widgetStatus === "Required"
|
||||
)?.length;
|
||||
optionalCheckbox = checkUser[0].placeHolder[i].pos.filter(
|
||||
(pos) => pos.type === "checkbox" && pos.widgetStatus === "Optional"
|
||||
).length;
|
||||
checkWidgetSign =
|
||||
checkWidgetSign +
|
||||
posSignUrlData.length +
|
||||
posWidgetData.length +
|
||||
checkboxReadOnly +
|
||||
checkedRequireCount +
|
||||
optionalCheckbox;
|
||||
allXyPos = allXyPos + checkUser[0].placeHolder[i].pos.length;
|
||||
console.log("unsigned", unSignUrlData);
|
||||
|
||||
// const posWidgetData = checkUser[0].placeHolder[i].pos.filter(
|
||||
// (pos) => pos?.widgetValue && pos?.type !== "checkbox"
|
||||
// );
|
||||
// const checkboxReadOnly = checkUser[0].placeHolder[i].pos.filter(
|
||||
// (pos) =>
|
||||
// pos?.widgetValue &&
|
||||
// pos?.type === "checkbox" &&
|
||||
// pos?.widgetStatus === "Read only"
|
||||
// ).length;
|
||||
// const checkboxRequire = checkUser[0].placeHolder[i].pos.filter(
|
||||
// (pos) => pos?.type === "checkbox" && pos?.widgetStatus === "Required"
|
||||
// );
|
||||
// CheckboxRequireCount = CheckboxRequireCount + checkboxRequire?.length;
|
||||
// checkedRequireCount =
|
||||
// checkedRequireCount +
|
||||
// checkUser[0].placeHolder[i].pos?.filter(
|
||||
// (pos) =>
|
||||
// pos?.widgetValue &&
|
||||
// pos?.type === "checkbox" &&
|
||||
// pos?.widgetStatus === "Required"
|
||||
// )?.length;
|
||||
// optionalCheckbox = checkUser[0].placeHolder[i].pos.filter(
|
||||
// (pos) => pos.type === "checkbox" && pos.widgetStatus === "Optional"
|
||||
// ).length;
|
||||
// checkWidgetSign =
|
||||
// checkWidgetSign +
|
||||
// posSignUrlData.length +
|
||||
// posWidgetData.length +
|
||||
// checkboxReadOnly +
|
||||
// checkedRequireCount +
|
||||
// optionalCheckbox;
|
||||
// allXyPos = allXyPos + checkUser[0].placeHolder[i].pos.length;
|
||||
}
|
||||
if (CheckboxRequireCount !== checkedRequireCount) {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "Please check the required checkbox to continue."
|
||||
});
|
||||
} else if (allXyPos !== checkWidgetSign) {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "Please complete your signature!"
|
||||
});
|
||||
// if (CheckboxRequireCount !== checkedRequireCount) {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "Please check the required checkbox to continue."
|
||||
// });
|
||||
// } else if (allXyPos !== checkWidgetSign) {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "Please complete your signature!"
|
||||
// });
|
||||
// }
|
||||
let checkboxExist;
|
||||
let optionRequiredCheckbox;
|
||||
checkboxExist = unSignUrlData.some((data) => data.type === "checkbox");
|
||||
|
||||
if (checkboxExist) {
|
||||
optionRequiredCheckbox = unSignUrlData.filter(
|
||||
(data) => data.widgetStatus !== "Optional"
|
||||
);
|
||||
}
|
||||
if (
|
||||
checkboxExist &&
|
||||
optionRequiredCheckbox &&
|
||||
optionRequiredCheckbox.length > 0
|
||||
) {
|
||||
setUnSignedWidgetId(optionRequiredCheckbox[0].key);
|
||||
setWidgetsTour(true);
|
||||
} else if (!checkboxExist && unSignUrlData && unSignUrlData.length > 0) {
|
||||
setUnSignedWidgetId(unSignUrlData[0].key);
|
||||
setWidgetsTour(true);
|
||||
} else {
|
||||
setIsUiLoading(true);
|
||||
const pngUrl = checkUser[0].placeHolder;
|
||||
@@ -380,34 +409,34 @@ function PdfRequestFiles() {
|
||||
);
|
||||
|
||||
//function for call to embed signature in pdf and get digital signature pdf
|
||||
try {
|
||||
const res = await signPdfFun(
|
||||
pdfBytes,
|
||||
documentId,
|
||||
signerObjectId,
|
||||
pdfOriginalWidth,
|
||||
pngUrl,
|
||||
containerWH,
|
||||
setIsAlert
|
||||
);
|
||||
if (res && res.status === "success") {
|
||||
setPdfUrl(res.data);
|
||||
setIsSigned(true);
|
||||
setSignedSigners([]);
|
||||
setUnSignedSigners([]);
|
||||
getDocumentDetails();
|
||||
} else {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "something went wrong"
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "something went wrong"
|
||||
});
|
||||
}
|
||||
// try {
|
||||
// const res = await signPdfFun(
|
||||
// pdfBytes,
|
||||
// documentId,
|
||||
// signerObjectId,
|
||||
// pdfOriginalWidth,
|
||||
// pngUrl,
|
||||
// containerWH,
|
||||
// setIsAlert
|
||||
// );
|
||||
// if (res && res.status === "success") {
|
||||
// setPdfUrl(res.data);
|
||||
// setIsSigned(true);
|
||||
// setSignedSigners([]);
|
||||
// setUnSignedSigners([]);
|
||||
// getDocumentDetails();
|
||||
// } else {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "something went wrong"
|
||||
// });
|
||||
// }
|
||||
// } catch (err) {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "something went wrong"
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
setIsSignPad(false);
|
||||
@@ -420,6 +449,26 @@ function PdfRequestFiles() {
|
||||
}
|
||||
}
|
||||
|
||||
//function for update TourStatus
|
||||
const closeTour = async () => {
|
||||
setWidgetsTour(false);
|
||||
};
|
||||
|
||||
const tourConfig = [
|
||||
{
|
||||
selector: '[data-tut="IsSigned"]',
|
||||
content: "Please fill out this placeholder.",
|
||||
// content: () => (
|
||||
// <TourContentWithBtn
|
||||
// message={`Please fill out this placeholder.`}
|
||||
// isChecked={handleDontShow}
|
||||
// />
|
||||
// ),
|
||||
position: "top",
|
||||
style: { fontSize: "13px" }
|
||||
}
|
||||
];
|
||||
|
||||
//function for get pdf page details
|
||||
const pageDetails = async (pdf) => {
|
||||
const load = {
|
||||
@@ -690,6 +739,15 @@ function PdfRequestFiles() {
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
|
||||
<Tour
|
||||
onRequestClose={closeTour}
|
||||
steps={tourConfig}
|
||||
isOpen={widgetsTour}
|
||||
rounded={5}
|
||||
closeWithMask={false}
|
||||
/>
|
||||
|
||||
{/* this modal is used to show decline alert */}
|
||||
<CustomModal
|
||||
containerWH={containerWH}
|
||||
@@ -896,6 +954,7 @@ function PdfRequestFiles() {
|
||||
containerWH={containerWH}
|
||||
setIsInitial={setIsInitial}
|
||||
setValidateAlert={setValidateAlert}
|
||||
unSignedWidgetId={unSignedWidgetId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -99,7 +99,10 @@ function Placeholder(props) {
|
||||
|
||||
//onclick placeholder function to open signature pad
|
||||
const handlePlaceholderClick = () => {
|
||||
props.setSelectWidgetId(props.pos.key);
|
||||
if (props.setSelectWidgetId) {
|
||||
props.setSelectWidgetId(props.pos.key);
|
||||
}
|
||||
|
||||
const widgetTypeExist = [
|
||||
"text",
|
||||
"checkbox",
|
||||
@@ -268,11 +271,13 @@ function Placeholder(props) {
|
||||
setIsShowDateFormat(!isShowDateFormat);
|
||||
e.stopPropagation();
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsShowDateFormat(!isShowDateFormat);
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
>
|
||||
<i
|
||||
@@ -388,6 +393,7 @@ function Placeholder(props) {
|
||||
|
||||
return (
|
||||
<Rnd
|
||||
data-tut={props.pos.key === props.unSignedWidgetId ? "IsSigned" : ""}
|
||||
//ref={nodeRef}
|
||||
key={props.pos.key}
|
||||
lockAspectRatio={
|
||||
|
||||
@@ -159,7 +159,7 @@ function FieldsComponent({
|
||||
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 14,
|
||||
id: 15,
|
||||
text: "radio"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
@@ -171,7 +171,7 @@ function FieldsComponent({
|
||||
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 14,
|
||||
id: 16,
|
||||
text: "label"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
@@ -368,191 +368,6 @@ function FieldsComponent({
|
||||
</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;
|
||||
}
|
||||
}}
|
||||
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) {
|
||||
|
||||
}
|
||||
}}
|
||||
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>
|
||||
</>
|
||||
)} */}
|
||||
{/* {updateWidgets.map((item, ind) => {
|
||||
return (
|
||||
<div
|
||||
key={ind}
|
||||
ref={(element) => {
|
||||
item.ref(element);
|
||||
if (element) {
|
||||
signRef.current = element;
|
||||
}
|
||||
}}
|
||||
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)"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginLeft: "5px"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
class="fa-sharp fa-solid fa-grip-vertical"
|
||||
style={{ color: "#908d8d", fontSize: "13px" }}
|
||||
></i>
|
||||
<span
|
||||
style={{
|
||||
fontWeight: "400",
|
||||
fontSize: "15px",
|
||||
// padding: "3px 20px 0px 20px",
|
||||
color: "black",
|
||||
marginLeft: "5px"
|
||||
}}
|
||||
>
|
||||
{item.type}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: themeColor(),
|
||||
padding: "0 5px",
|
||||
display: "flex",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
style={{ color: "white", fontSize: item.iconSize }}
|
||||
className={item.icon}
|
||||
></i>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})} */}
|
||||
<AllWidgets
|
||||
updateWidgets={updateWidgets}
|
||||
handleDivClick={handleDivClick}
|
||||
|
||||
@@ -62,7 +62,8 @@ function RenderPdf({
|
||||
setIsRadio,
|
||||
setCurrWidgetsDetails,
|
||||
setSelectWidgetId,
|
||||
selectWidgetId
|
||||
selectWidgetId,
|
||||
unSignedWidgetId
|
||||
}) {
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = containerWH.width;
|
||||
@@ -270,6 +271,7 @@ function RenderPdf({
|
||||
pdfDetails={pdfDetails}
|
||||
setIsInitial={setIsInitial}
|
||||
setValidateAlert={setValidateAlert}
|
||||
unSignedWidgetId={unSignedWidgetId}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)
|
||||
@@ -441,7 +443,12 @@ function RenderPdf({
|
||||
}}
|
||||
loading={"Loading Document.."}
|
||||
onLoadSuccess={pageDetails}
|
||||
// ref={pdfRef}
|
||||
// ref={pdfRef}'
|
||||
onClick={() => {
|
||||
if (setSelectWidgetId) {
|
||||
setSelectWidgetId("");
|
||||
}
|
||||
}}
|
||||
file={
|
||||
pdfUrl
|
||||
? pdfUrl
|
||||
@@ -617,8 +624,9 @@ function RenderPdf({
|
||||
loading={"Loading Document.."}
|
||||
onLoadSuccess={pageDetails}
|
||||
onClick={() => {
|
||||
console.log("click on pdf");
|
||||
setSelectWidgetId("");
|
||||
if (setSelectWidgetId) {
|
||||
setSelectWidgetId("");
|
||||
}
|
||||
}}
|
||||
// ref={pdfRef}
|
||||
file={
|
||||
|
||||
@@ -427,8 +427,8 @@ function PlaceHolderSign() {
|
||||
};
|
||||
}
|
||||
|
||||
setSelectWidgetId(key);
|
||||
if (signer && dragTypeValue !== "label") {
|
||||
setSelectWidgetId(key);
|
||||
let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
||||
|
||||
const { blockColor, Role } = signer;
|
||||
@@ -454,6 +454,7 @@ function PlaceHolderSign() {
|
||||
const updatesignerPos = signerPos.map((x) =>
|
||||
x.Id === uniqueId ? { ...x, placeHolder: updatePlace } : x
|
||||
);
|
||||
|
||||
setSignerPos(updatesignerPos);
|
||||
} else {
|
||||
const updatesignerPos = signerPos.map((x) =>
|
||||
@@ -465,6 +466,7 @@ function PlaceHolderSign() {
|
||||
}
|
||||
} else {
|
||||
//adding new placeholder for selected signer in pos array (placeholder)
|
||||
const signerData = signerPos;
|
||||
let placeHolderPos;
|
||||
if (contractName) {
|
||||
placeHolderPos = {
|
||||
@@ -489,7 +491,10 @@ function PlaceHolderSign() {
|
||||
Id: uniqueId
|
||||
};
|
||||
}
|
||||
setSignerPos((prev) => [...prev, placeHolderPos]);
|
||||
|
||||
signerData.push(placeHolderPos);
|
||||
|
||||
setSignerPos(signerData);
|
||||
}
|
||||
if (dragTypeValue === "dropdown") {
|
||||
setShowDropdown(true);
|
||||
@@ -500,8 +505,7 @@ function PlaceHolderSign() {
|
||||
}
|
||||
setWidgetType(dragTypeValue);
|
||||
setSignKey(key);
|
||||
} else {
|
||||
setSelectWidgetId(key);
|
||||
} else if (dragTypeValue === "label") {
|
||||
let filterSignerPos = signerPos.filter(
|
||||
(data) => data.Role === "prefill"
|
||||
);
|
||||
@@ -548,6 +552,7 @@ function PlaceHolderSign() {
|
||||
};
|
||||
setSignerPos((prev) => [...prev, placeHolderPos]);
|
||||
}
|
||||
setSignKey(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1235,7 +1240,6 @@ function PlaceHolderSign() {
|
||||
setIsValidate(false);
|
||||
};
|
||||
|
||||
console.log("currentdetails", currWidgetsDetails);
|
||||
return (
|
||||
<>
|
||||
<Title title={state?.title ? state.title : "New Document"} />
|
||||
|
||||
@@ -939,7 +939,6 @@ export const multiSignEmbed = async (
|
||||
imgData.type === "initials" ||
|
||||
imgData.type === "image"
|
||||
) {
|
||||
console.log(images[id]);
|
||||
if (
|
||||
(imgData.ImageType && imgData.ImageType === "image/png") ||
|
||||
imgData.ImageType === "image/jpeg"
|
||||
|
||||
Reference in New Issue
Block a user