mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-24 00:22:34 +02:00
feat: implement changes to ensure compatibility with multiple widgets
This commit is contained in:
@@ -103,9 +103,8 @@ function SignYourSelf() {
|
||||
const [{ isDragSign }, dragSignature] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 1,
|
||||
text: "drag me"
|
||||
text: "signature"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragSign: !!monitor.isDragging()
|
||||
@@ -115,14 +114,14 @@ function SignYourSelf() {
|
||||
const [{ isDragStamp }, dragStamp] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 2,
|
||||
text: "drag me"
|
||||
text: "stamp"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragStamp: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
|
||||
const [{ isDragSignatureSS }, dragSignatureSS] = useDrag({
|
||||
type: "BOX",
|
||||
|
||||
@@ -172,6 +171,17 @@ function SignYourSelf() {
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
|
||||
useEffect(() => {
|
||||
// localStorage.setItem("accesstoken", "r:d70a32032557e982aab7aec1cae668fc");
|
||||
// localStorage.setItem(
|
||||
// "baseUrl",
|
||||
// "https://staging-app.opensignlabs.com/api/app/"
|
||||
// );
|
||||
// localStorage.setItem("parseAppId", "opensignstgn");
|
||||
// localStorage.setItem(
|
||||
// "Parse/opensignstgn/currentUser",
|
||||
// '{"name":"raktima","email":"raktimachaurasiya@gmail.com","phone":"9876567876","username":"raktimachaurasiya@gmail.com","createdAt":"2024-01-03T05:48:49.407Z","sessionToken":"r:d70a32032557e982aab7aec1cae668fc","updatedAt":"2024-01-03T05:48:49.407Z","emailVerified":false,"ACL":{"YHwDtLNto7":{"read":true,"write":true}},"__type":"Object","className":"_User","objectId":"YHwDtLNto7"}'
|
||||
// );
|
||||
// localStorage.setItem("_appName", "contracts");
|
||||
if (documentId) {
|
||||
getDocumentDetails(true);
|
||||
}
|
||||
@@ -316,16 +326,18 @@ function SignYourSelf() {
|
||||
const addPositionOfSignature = (item, monitor) => {
|
||||
const key = Math.floor(1000 + Math.random() * 9000);
|
||||
let dropData = [];
|
||||
let dropObj = {};
|
||||
let filterDropPos = xyPostion.filter(
|
||||
(data) => data.pageNumber === pageNumber
|
||||
);
|
||||
if (item === "onclick") {
|
||||
const dropObj = {
|
||||
dropObj = {
|
||||
xPosition: window.innerWidth / 2 - 100,
|
||||
yPosition: window.innerHeight / 2 - 60,
|
||||
isDrag: false,
|
||||
key: key,
|
||||
isStamp: monitor,
|
||||
type: item.text,
|
||||
yBottom: window.innerHeight / 2 - 60
|
||||
};
|
||||
|
||||
@@ -347,7 +359,7 @@ function SignYourSelf() {
|
||||
const y = offset.y - containerRect.top;
|
||||
const ybottom = containerRect.bottom - offset.y;
|
||||
|
||||
const dropObj = {
|
||||
dropObj = {
|
||||
xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x,
|
||||
yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y,
|
||||
isDrag: false,
|
||||
@@ -355,7 +367,8 @@ function SignYourSelf() {
|
||||
isStamp: isDragStamp || isDragStampSS ? true : false,
|
||||
firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos,
|
||||
firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos,
|
||||
yBottom: ybottom
|
||||
yBottom: ybottom,
|
||||
type: item.text
|
||||
};
|
||||
|
||||
dropData.push(dropObj);
|
||||
@@ -379,8 +392,11 @@ function SignYourSelf() {
|
||||
pos: newSignPos
|
||||
};
|
||||
xyPostion.splice(index, 1, xyPos);
|
||||
setIsSignPad(true);
|
||||
setSignKey(key);
|
||||
if (isDragSign || isDragSignatureSS || isDragStamp || isDragStampSS) {
|
||||
setIsSignPad(true);
|
||||
setSignKey(key);
|
||||
}
|
||||
|
||||
// }
|
||||
} else {
|
||||
const xyPos = {
|
||||
@@ -388,8 +404,11 @@ function SignYourSelf() {
|
||||
pos: dropData
|
||||
};
|
||||
setXyPostion((prev) => [...prev, xyPos]);
|
||||
setIsSignPad(true);
|
||||
setSignKey(key);
|
||||
|
||||
if (isDragSign || isDragSignatureSS) {
|
||||
setIsSignPad(true);
|
||||
setSignKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
// setXyPostion((prev) => [...prev, xyPos]);
|
||||
@@ -405,64 +424,64 @@ function SignYourSelf() {
|
||||
checkSignUrl.push(posData);
|
||||
}
|
||||
}
|
||||
if (xyPostion.length === 0) {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "Please complete your signature!"
|
||||
});
|
||||
return;
|
||||
} else if (xyPostion.length > 0 && checkSignUrl.length > 0) {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "Please complete your signature!"
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
setIsCeleb(true);
|
||||
setTimeout(() => {
|
||||
setIsCeleb(false);
|
||||
}, 3000);
|
||||
const loadObj = {
|
||||
isLoad: true,
|
||||
message: "This might take some time"
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
const url = pdfDetails[0] && pdfDetails[0].URL;
|
||||
// if (xyPostion.length === 0) {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "Please complete your signature!"
|
||||
// });
|
||||
// return;
|
||||
// } else if (xyPostion.length > 0 && checkSignUrl.length > 0) {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "Please complete your signature!"
|
||||
// });
|
||||
// return;
|
||||
// } else {
|
||||
setIsCeleb(true);
|
||||
setTimeout(() => {
|
||||
setIsCeleb(false);
|
||||
}, 3000);
|
||||
const loadObj = {
|
||||
isLoad: true,
|
||||
message: "This might take some time"
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
const url = pdfDetails[0] && pdfDetails[0].URL;
|
||||
|
||||
const existingPdfBytes = await fetch(url).then((res) =>
|
||||
res.arrayBuffer()
|
||||
);
|
||||
const existingPdfBytes = await fetch(url).then((res) => res.arrayBuffer());
|
||||
|
||||
// Load a PDFDocument from the existing PDF bytes
|
||||
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
||||
ignoreEncryption: true
|
||||
});
|
||||
// Load a PDFDocument from the existing PDF bytes
|
||||
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
||||
ignoreEncryption: true
|
||||
});
|
||||
|
||||
const flag = true;
|
||||
//embed document's object id to all pages in pdf document
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
const flag = true;
|
||||
//embed document's object id to all pages in pdf document
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
|
||||
//embed multi signature in pdf
|
||||
const pdfBytes = await multiSignEmbed(
|
||||
xyPostion,
|
||||
pdfDoc,
|
||||
pdfOriginalWidth,
|
||||
flag,
|
||||
containerWH
|
||||
);
|
||||
//embed multi signature in pdf
|
||||
const pdfBytes = await multiSignEmbed(
|
||||
xyPostion,
|
||||
pdfDoc,
|
||||
pdfOriginalWidth,
|
||||
flag,
|
||||
containerWH
|
||||
);
|
||||
|
||||
//function for call to embed signature in pdf and get digital signature pdf
|
||||
signPdfFun(pdfBytes, documentId);
|
||||
setIsSignPad(false);
|
||||
setIsEmail(true);
|
||||
setXyPostion([]);
|
||||
setSignBtnPosition([]);
|
||||
}
|
||||
console.log("pdf", pdfBytes);
|
||||
//function for call to embed signature in pdf and get digital signature pdf
|
||||
signPdfFun(pdfBytes, documentId);
|
||||
|
||||
setIsSignPad(false);
|
||||
setIsEmail(true);
|
||||
setXyPostion([]);
|
||||
setSignBtnPosition([]);
|
||||
// }
|
||||
}
|
||||
|
||||
//function for get digital signature
|
||||
const signPdfFun = async (base64Url, documentId) => {
|
||||
const singleSign = {
|
||||
let singleSign = {
|
||||
pdfFile: base64Url,
|
||||
docId: documentId
|
||||
};
|
||||
@@ -603,7 +622,6 @@ function SignYourSelf() {
|
||||
|
||||
setXyPostion(getUpdatePosition);
|
||||
};
|
||||
|
||||
//function for capture position on hover signature button
|
||||
const handleDivClick = (e) => {
|
||||
const divRect = e.currentTarget.getBoundingClientRect();
|
||||
@@ -664,11 +682,9 @@ function SignYourSelf() {
|
||||
setXyPostion(getXyData);
|
||||
setShowAlreadySignDoc({ status: false });
|
||||
};
|
||||
|
||||
const handleDontShow = (isChecked) => {
|
||||
setIsDontShow(isChecked);
|
||||
};
|
||||
|
||||
const tourConfig = [
|
||||
{
|
||||
selector: '[data-tut="reactourFirst"]',
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import React from "react";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import { getWidgetType } from "../../utils/Utils";
|
||||
|
||||
function AllWidgets(props) {
|
||||
const signStyle = "signatureBtn";
|
||||
|
||||
return props.updateWidgets.map((item, ind) => {
|
||||
return (
|
||||
<div
|
||||
key={ind}
|
||||
ref={(element) => {
|
||||
item.ref(element);
|
||||
if (element) {
|
||||
if (props?.signRef) {
|
||||
props.signRef.current = element;
|
||||
}
|
||||
}
|
||||
}}
|
||||
className={signStyle}
|
||||
onMouseMove={props?.handleDivClick}
|
||||
onMouseDown={props?.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)",
|
||||
marginLeft: `${props?.marginLeft}px`
|
||||
}}
|
||||
>
|
||||
{/* <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> */}
|
||||
{getWidgetType(item)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export default AllWidgets;
|
||||
@@ -0,0 +1,141 @@
|
||||
import React, { useState } from "react";
|
||||
import Modal from "react-bootstrap/Modal";
|
||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
function DropdownWidgetOption(props) {
|
||||
const [dropdownOptionList, setDropdownOptionList] = useState([
|
||||
"option-1",
|
||||
"option-2"
|
||||
]);
|
||||
|
||||
const [dropdownName, setDropdownName] = useState("Dropdown-1");
|
||||
const [error, setError] = useState("");
|
||||
const handleInputChange = (index, value) => {
|
||||
setDropdownOptionList((prevInputs) => {
|
||||
const newInputs = [...prevInputs];
|
||||
newInputs[index] = value;
|
||||
return newInputs;
|
||||
});
|
||||
};
|
||||
|
||||
const handleAddInput = () => {
|
||||
setDropdownOptionList((prevInputs) => [...prevInputs, ""]);
|
||||
};
|
||||
const handleAddOption = () => {
|
||||
setDropdownOptionList([...dropdownOptionList, ""]);
|
||||
};
|
||||
const handleDeleteInput = (ind) => {
|
||||
const getUpdatedOptions = dropdownOptionList.filter(
|
||||
(data, index) => index !== ind
|
||||
);
|
||||
setDropdownOptionList(getUpdatedOptions);
|
||||
};
|
||||
const handleSaveOption = () => {
|
||||
const existEmptyOption = dropdownOptionList.some((data) => data === "");
|
||||
|
||||
if (existEmptyOption) {
|
||||
setError("Enter all option");
|
||||
setTimeout(() => {
|
||||
setError("");
|
||||
}, 1000);
|
||||
} else {
|
||||
props.handleSaveDropdownOptions(dropdownName, dropdownOptionList);
|
||||
props.setShowDropdown(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
//props.showDropdown
|
||||
<Modal show={props.showDropdown} size="sm">
|
||||
<ModalHeader style={{ color: "white", background: themeColor() }}>
|
||||
Dropdown options
|
||||
</ModalHeader>
|
||||
<Modal.Body>
|
||||
<div className="dropdownContainer">
|
||||
<label style={{ fontSize: "13px", fontWeight: "600" }}>Name</label>
|
||||
<input
|
||||
defaultValue={dropdownName}
|
||||
value={dropdownName}
|
||||
onChange={(e) => setDropdownName(e.target.value)}
|
||||
className="drodown-input"
|
||||
/>
|
||||
<label
|
||||
style={{ fontSize: "13px", fontWeight: "600", marginTop: "5px" }}
|
||||
>
|
||||
Options
|
||||
</label>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap"
|
||||
}}
|
||||
>
|
||||
{dropdownOptionList.map((option, index) => (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
marginBottom: "5px"
|
||||
}}
|
||||
>
|
||||
<input
|
||||
className="drodown-input"
|
||||
type="text"
|
||||
value={option}
|
||||
onChange={(e) => handleInputChange(index, e.target.value)}
|
||||
/>
|
||||
|
||||
<i
|
||||
className="fa-solid fa-rectangle-xmark"
|
||||
onClick={() => handleDeleteInput(index)}
|
||||
style={{ color: "red", fontSize: "25px", marginLeft: "10px" }}
|
||||
></i>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<i
|
||||
onClick={handleAddInput}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
color: themeColor(),
|
||||
fontSize: "25px",
|
||||
marginLeft: "10px"
|
||||
}}
|
||||
className="fa-solid fa-square-plus"
|
||||
></i>
|
||||
</div>
|
||||
</div>
|
||||
<span style={{ fontSize: "13px", color: "red" }}>{error}</span>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<button
|
||||
onClick={() => props.setShowDropdown(false)}
|
||||
style={{
|
||||
color: "black"
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn"
|
||||
>
|
||||
cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleSaveOption()}
|
||||
disabled={dropdownOptionList.length === 0 && true}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
color: "white"
|
||||
}}
|
||||
type="button"
|
||||
className={"finishBtn"}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default DropdownWidgetOption;
|
||||
@@ -0,0 +1,236 @@
|
||||
import React from "react";
|
||||
import BorderResize from "../component/borderResize";
|
||||
import PlaceholderBorder from "./placeholderBorder";
|
||||
import { Rnd } from "react-rnd";
|
||||
import { defaultWidthHeight } from "../../utils/Utils";
|
||||
import PlaceholderType from "./placeholderType";
|
||||
|
||||
function Placeholder(props) {
|
||||
const handlePlaceholderClick = () => {
|
||||
if (!props.data && !props.isDragging) {
|
||||
if (props.pos.type) {
|
||||
if (props.pos.type === "signature" || props.pos.type === "stamp") {
|
||||
props.setIsSignPad(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setIsStamp(props.pos.isStamp);
|
||||
} else if (props.pos.type === "dropdown") {
|
||||
props.setShowDropdown(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
}
|
||||
} else {
|
||||
props.setIsSignPad(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setIsStamp(props.pos?.isStamp ? props.pos.isStamp : false);
|
||||
}
|
||||
} else if (props.isPlaceholder && props.pos.type) {
|
||||
if (props.pos.type === "dropdown") {
|
||||
props.setShowDropdown(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
!props.pos.type &&
|
||||
props.isNeedSign &&
|
||||
props.data.signerObjId === props.signerObjId
|
||||
) {
|
||||
props.setIsSignPad(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setIsStamp(props.pos.isStamp);
|
||||
} else if (
|
||||
(props.isNeedSign && props.pos.type === "signature") ||
|
||||
props.pos.type === "stamp"
|
||||
) {
|
||||
props.setIsSignPad(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setIsStamp(props.pos.isStamp);
|
||||
} else if (props.isNeedSign && props.pos.type === "dropdown") {
|
||||
props.setSignKey(props.pos.key);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Rnd
|
||||
// ref={nodeRef}
|
||||
key={props.pos.key}
|
||||
lockAspectRatio={
|
||||
props.pos.Width
|
||||
? props.pos.Width / props.pos.Height
|
||||
: defaultWidthHeight(props.pos.type).width /
|
||||
defaultWidthHeight(props.pos.type).height
|
||||
}
|
||||
enableResizing={{
|
||||
top: false,
|
||||
right: false,
|
||||
bottom: false,
|
||||
left: false,
|
||||
topRight: false,
|
||||
bottomRight:
|
||||
props.data && props.isNeedSign
|
||||
? props.data?.signerObjId === props.signerObjId
|
||||
? true
|
||||
: false
|
||||
: true,
|
||||
bottomLeft: false,
|
||||
topLeft: false
|
||||
}}
|
||||
bounds="parent"
|
||||
className="signYourselfBlock"
|
||||
style={{
|
||||
border: "1px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
cursor:
|
||||
props.data && props.isNeedSign
|
||||
? props.data?.signerObjId === props.signerObjId
|
||||
? "pointer"
|
||||
: "not-allowed"
|
||||
: "all-scroll",
|
||||
zIndex: "1",
|
||||
background: props.data ? props.data.blockColor : "rgb(203 233 237)"
|
||||
}}
|
||||
onDrag={() => props.handleTabDrag && props.handleTabDrag(props.pos.key)}
|
||||
size={{
|
||||
width: props.posWidth(props.pos, props.isSignYourself),
|
||||
height: props.posHeight(props.pos, props.isSignYourself)
|
||||
}}
|
||||
onResizeStart={() => {
|
||||
props.setIsResize && props.setIsResize(true);
|
||||
}}
|
||||
onResizeStop={() => {
|
||||
props.setIsResize && props.setIsResize(false);
|
||||
}}
|
||||
disableDragging={props.isNeedSign || (props.isRecipient && true)}
|
||||
onDragStop={(event, dragElement) =>
|
||||
props.handleStop &&
|
||||
props.handleStop(event, dragElement, props.signerObjId, props.pos.key)
|
||||
}
|
||||
default={{
|
||||
x: props.xPos(props.pos, props.isSignYourself),
|
||||
y: props.yPos(props.pos, props.isSignYourself)
|
||||
}}
|
||||
onResize={(e, direction, ref, delta, position) => {
|
||||
props.handleSignYourselfImageResize &&
|
||||
props.handleSignYourselfImageResize(
|
||||
ref,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.setXyPostion,
|
||||
props.index,
|
||||
props.data && props.data.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
onClick={() => handlePlaceholderClick()}
|
||||
>
|
||||
{props.isShowBorder ? (
|
||||
<BorderResize right={-12} top={-11} />
|
||||
) : props.data && props.isNeedSign ? (
|
||||
props.data?.signerObjId === props.signerObjId ? (
|
||||
<BorderResize />
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
) : (
|
||||
<BorderResize />
|
||||
)}
|
||||
|
||||
{props.isShowBorder && <PlaceholderBorder pos={props.pos} />}
|
||||
<div
|
||||
style={{
|
||||
left: props.xPos(props.pos, props.isSignYourself),
|
||||
top: props.yPos(props.pos, props.isSignYourself),
|
||||
width: props.posWidth(props.pos, props.isSignYourself),
|
||||
height: props.posHeight(props.pos, props.isSignYourself),
|
||||
zIndex: "10"
|
||||
}}
|
||||
onTouchEnd={(e) => handlePlaceholderClick()}
|
||||
>
|
||||
{props.isShowBorder && (
|
||||
<>
|
||||
{props.isPlaceholder && (
|
||||
<i
|
||||
data-tut="reactourLinkUser"
|
||||
className="fa-regular fa-user signUserIcon"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
props.handleLinkUser(props.data.Id);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
props.handleLinkUser(props.data.Id);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
style={{
|
||||
color: "#188ae2"
|
||||
}}
|
||||
></i>
|
||||
)}
|
||||
|
||||
<i
|
||||
className="fa-regular fa-copy signCopy"
|
||||
onClick={(e) => {
|
||||
if (props.data) {
|
||||
props.setSignerObjId(props.data.signerObjId);
|
||||
}
|
||||
e.stopPropagation();
|
||||
props.setIsPageCopy(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
if (props.data) {
|
||||
props.setSignerObjId(props.data.signerObjId);
|
||||
}
|
||||
e.stopPropagation();
|
||||
props.setIsPageCopy(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
}}
|
||||
style={{
|
||||
color: "#188ae2"
|
||||
}}
|
||||
></i>
|
||||
<i
|
||||
className="fa-regular fa-circle-xmark signCloseBtn"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (props.data) {
|
||||
props.handleDeleteSign(props.pos.key, props.data.signerObjId);
|
||||
} else {
|
||||
props.handleDeleteSign(props.pos.key);
|
||||
props.setIsStamp(false);
|
||||
}
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
if (props.data) {
|
||||
props.handleDeleteSign(props.pos.key, props.data.signerObjId);
|
||||
} else {
|
||||
props.handleDeleteSign(props.pos.key);
|
||||
props.setIsStamp(false);
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
color: "#188ae2"
|
||||
}}
|
||||
></i>
|
||||
</>
|
||||
)}
|
||||
|
||||
<PlaceholderType
|
||||
pos={props.pos}
|
||||
xyPostion={props.xyPostion}
|
||||
index={props.index}
|
||||
setXyPostion={props.setXyPostion}
|
||||
data={props.data}
|
||||
setSignKey={props.setSignKey}
|
||||
isShowDropdown={props.isShowDropdown}
|
||||
isPlaceholder={props.isPlaceholder}
|
||||
signerObjId={props.signerObjId}
|
||||
handleUserName={props.handleUserName}
|
||||
/>
|
||||
</div>
|
||||
</Rnd>
|
||||
);
|
||||
}
|
||||
|
||||
export default Placeholder;
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import { defaultWidthHeight, resizeBorderExtraWidth } from "../../utils/Utils";
|
||||
function PlaceholderBorder(props) {
|
||||
const getResizeBorderExtraWidth = resizeBorderExtraWidth();
|
||||
const defaultWidth = defaultWidthHeight(props.pos.type).width;
|
||||
const defaultHeight = defaultWidthHeight(props.pos.type).height;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="borderResize"
|
||||
style={{
|
||||
borderColor: themeColor(),
|
||||
borderStyle: "dashed",
|
||||
|
||||
width: props.pos.Width
|
||||
? props.pos.Width + getResizeBorderExtraWidth
|
||||
: defaultWidth + getResizeBorderExtraWidth,
|
||||
height: props.pos.Height
|
||||
? props.pos.Height + getResizeBorderExtraWidth
|
||||
: defaultHeight + getResizeBorderExtraWidth,
|
||||
borderWidth: "0.2px",
|
||||
overflow: "hidden"
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlaceholderBorder;
|
||||
@@ -0,0 +1,165 @@
|
||||
import React, { useState } from "react";
|
||||
import { onChangeInput } from "../../utils/Utils";
|
||||
|
||||
function PlaceholderType(props) {
|
||||
const [selectOption, setSelectOption] = useState("");
|
||||
|
||||
switch (props.pos.type) {
|
||||
case "signature":
|
||||
return props.pos.SignUrl ? (
|
||||
<div style={{ pointerEvents: "none" }}>
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
fontSize: "10px",
|
||||
color: "black",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<div>{props.pos.type}</div>
|
||||
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(props?.data.signerObjId, props?.data.Role)}
|
||||
</div>
|
||||
);
|
||||
|
||||
case "stamp":
|
||||
return props.pos.SignUrl ? (
|
||||
<div style={{ pointerEvents: "none" }}>
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
color: "black",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<div>{props.pos.type}</div>
|
||||
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(props?.data?.signerObjId, props?.data?.Role)}
|
||||
</div>
|
||||
);
|
||||
|
||||
case "checkbox":
|
||||
return (
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="checkbox"
|
||||
disabled={props.isPlaceholder}
|
||||
onChange={(e) =>
|
||||
onChangeInput(
|
||||
e.target.checked,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data.signerObjId,
|
||||
false
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
case "text":
|
||||
return (
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
disabled={props.isPlaceholder}
|
||||
onChange={(e) =>
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data.signerObjId,
|
||||
false
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
case "dropdown":
|
||||
return !props.isPlaceholder ? (
|
||||
<select
|
||||
className="inputPlaceholder"
|
||||
id="myDropdown"
|
||||
value={selectOption}
|
||||
onChange={(e) => {
|
||||
setSelectOption(e.target.value);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data.signerObjId,
|
||||
false
|
||||
);
|
||||
}}
|
||||
>
|
||||
{/* Default/Title option */}
|
||||
<option value="" disabled hidden>
|
||||
{props.pos.widgetName}
|
||||
</option>
|
||||
|
||||
{props.pos.widgetOption.map((data, ind) => {
|
||||
return <option value={data}>{data}</option>;
|
||||
})}
|
||||
</select>
|
||||
) : (
|
||||
<div className="inputPlaceholder">
|
||||
{props.pos.widgetName ? props.pos.widgetName : props.pos.type}
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return props.pos.SignUrl ? (
|
||||
<div style={{ pointerEvents: "none" }}>
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
fontSize: "10px",
|
||||
color: "black",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
{props.pos.isStamp ? <div>stamp</div> : <div>signature</div>}
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(props?.data?.signerObjId, props?.data?.Role)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PlaceholderType;
|
||||
@@ -1,6 +1,9 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import ModalUi from "../../premitives/ModalUi";
|
||||
import RecipientList from "../../premitives/RecipientList";
|
||||
import { useDrag } from "react-dnd";
|
||||
import AllWidgets from "../WidgetComponent/allWidgets";
|
||||
import { widgets } from "../../utils/Utils";
|
||||
|
||||
function FieldsComponent({
|
||||
pdfUrl,
|
||||
@@ -39,9 +42,44 @@ function FieldsComponent({
|
||||
title
|
||||
}) {
|
||||
const [isSignersModal, setIsSignersModal] = useState(false);
|
||||
const signStyle = pdfUrl ? "disableSign" : "signatureBtn";
|
||||
|
||||
const [{ isDragDropdown }, dropdown] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 5,
|
||||
text: "dropdown"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragDropdown: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [{ isDragCheck }, checkbox] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 6,
|
||||
text: "checkbox"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragCheck: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [{ isDragText }, text] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 2,
|
||||
text: "text"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragText: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const signStyle = pdfUrl ? "disableSign" : "signatureBtn";
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const scrollContainerRef = useRef(null);
|
||||
const [widget, setWidget] = useState([]);
|
||||
|
||||
const color = [
|
||||
"#93a3db",
|
||||
@@ -57,13 +95,31 @@ function FieldsComponent({
|
||||
"#66ccff",
|
||||
"#ffffcc"
|
||||
];
|
||||
|
||||
const handleModal = () => {
|
||||
setIsSignersModal(!isSignersModal);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const widgetRef = [dragSignature, dragStamp, dropdown, checkbox, text];
|
||||
const getWidgetArray = widgets;
|
||||
const newUpdateSigner = getWidgetArray.map((obj, ind) => {
|
||||
return { ...obj, ref: widgetRef[ind] };
|
||||
});
|
||||
setWidget(newUpdateSigner);
|
||||
}, []);
|
||||
|
||||
const filterWidgets = widget.filter((data) => data.type !== "dropdown");
|
||||
const updateWidgets = isSignYourself ? filterWidgets : widget;
|
||||
|
||||
const handleScroll = (scrollOffset) => {
|
||||
if (scrollContainerRef.current) {
|
||||
scrollContainerRef.current.scrollLeft += scrollOffset;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{isMobile && isSignYourself ? (
|
||||
{isMobile ? (
|
||||
!isMailSend && (
|
||||
<div
|
||||
data-tut={dataTut}
|
||||
@@ -152,7 +208,7 @@ function FieldsComponent({
|
||||
<span style={{ marginLeft: 2 }}>Add role</span>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
{/* <div
|
||||
data-tut={dataTut2}
|
||||
className="signLayoutContainer2"
|
||||
style={{ backgroundColor: themeColor() }}
|
||||
@@ -222,6 +278,107 @@ function FieldsComponent({
|
||||
Stamp
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
style={{
|
||||
overflowX: "scroll",
|
||||
whiteSpace: "nowrap",
|
||||
padding: "10px",
|
||||
background: "white",
|
||||
borderTop: `2px solid ${themeColor()}`
|
||||
}}
|
||||
>
|
||||
<i
|
||||
style={{
|
||||
color: "rgb(140 142 149)",
|
||||
position: "fixed",
|
||||
left: "1%",
|
||||
bottom: "6%",
|
||||
fontSize: "23px"
|
||||
}}
|
||||
onClick={() => handleScroll(-100)}
|
||||
className="fa-solid fa-circle-chevron-left"
|
||||
></i>
|
||||
<div style={{ display: "flex" }}>
|
||||
{/* {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)",
|
||||
marginLeft: "5px"
|
||||
}}
|
||||
>
|
||||
<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}
|
||||
handleMouseLeave={handleMouseLeave}
|
||||
signRef={signRef}
|
||||
marginLeft={5}
|
||||
/>
|
||||
</div>
|
||||
<i
|
||||
style={{
|
||||
color: "rgb(140 142 149)",
|
||||
position: "fixed",
|
||||
left: "95%",
|
||||
bottom: "6%",
|
||||
fontSize: "23px"
|
||||
}}
|
||||
onClick={() => handleScroll(100)}
|
||||
className="fa-solid fa-circle-chevron-right"
|
||||
></i>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -237,7 +394,7 @@ function FieldsComponent({
|
||||
</div>
|
||||
|
||||
<div className="signLayoutContainer1">
|
||||
{pdfUrl ? (
|
||||
{/* {pdfUrl ? (
|
||||
<>
|
||||
<button className={signStyle} disabled={true}>
|
||||
<span
|
||||
@@ -291,8 +448,6 @@ function FieldsComponent({
|
||||
dragSignature(element);
|
||||
if (element) {
|
||||
signRef.current = element;
|
||||
// const height = signRef && signRef.current.offsetHeight;
|
||||
// const width = signRef && signRef.current.offsetWidth;
|
||||
}
|
||||
}}
|
||||
className={signStyle}
|
||||
@@ -319,17 +474,18 @@ function FieldsComponent({
|
||||
style={{
|
||||
width: "30px",
|
||||
height: "28px",
|
||||
background: themeColor()
|
||||
background: themeColor(),
|
||||
}}
|
||||
src={sign}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div
|
||||
ref={(element) => {
|
||||
dragStamp(element);
|
||||
dragRef.current = element;
|
||||
if (isDragStamp) {
|
||||
// setIsStamp(true);
|
||||
|
||||
}
|
||||
}}
|
||||
className={!pdfUrl ? signStyle : "disableSign"}
|
||||
@@ -364,7 +520,71 @@ function FieldsComponent({
|
||||
/>
|
||||
</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}
|
||||
handleMouseLeave={handleMouseLeave}
|
||||
signRef={signRef}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,7 +66,7 @@ function SignPad({
|
||||
|
||||
setIsSignImg("");
|
||||
} else if (isTab === "uploadImage") {
|
||||
setImage("");
|
||||
setImage("");
|
||||
}
|
||||
};
|
||||
//function for set signature url
|
||||
@@ -388,7 +388,8 @@ function SignPad({
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
border: "1.3px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
@@ -417,7 +418,8 @@ function SignPad({
|
||||
!image ? (
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
border: "1.3px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
@@ -444,7 +446,8 @@ function SignPad({
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
border: "1.3px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
marginBottom: 6,
|
||||
|
||||
overflow: "hidden"
|
||||
@@ -533,7 +536,11 @@ function SignPad({
|
||||
ref={canvasRef}
|
||||
penColor={penColor}
|
||||
canvasProps={{
|
||||
className: "signatureCanvas"
|
||||
className: "signatureCanvas",
|
||||
style: {
|
||||
border: "1.6px solid #007bff",
|
||||
borderRadius: "2px"
|
||||
}
|
||||
}}
|
||||
backgroundColor="rgb(255, 255, 255)"
|
||||
onEnd={() =>
|
||||
|
||||
@@ -31,6 +31,7 @@ import LinkUserModal from "./component/LinkUserModal";
|
||||
import Title from "./component/Title";
|
||||
import TourContentWithBtn from "../premitives/TourContentWithBtn";
|
||||
import ModalUi from "../premitives/ModalUi";
|
||||
import DropdownWidgetOption from "../Component/WidgetComponent/dropdownWidgetOption";
|
||||
|
||||
function PlaceHolderSign() {
|
||||
const navigate = useNavigate();
|
||||
@@ -84,6 +85,8 @@ function PlaceHolderSign() {
|
||||
const [signerExistModal, setSignerExistModal] = useState(false);
|
||||
const [isDontShow, setIsDontShow] = useState(false);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
|
||||
const color = [
|
||||
"#93a3db",
|
||||
"#e6c3db",
|
||||
@@ -111,7 +114,7 @@ function PlaceHolderSign() {
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 1,
|
||||
text: "drag me"
|
||||
text: "signature"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragSign: !!monitor.isDragging()
|
||||
@@ -122,7 +125,13 @@ function PlaceHolderSign() {
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 2,
|
||||
text: "drag me"
|
||||
text: "stamp"
|
||||
},
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 2,
|
||||
text: "stamp"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragStamp: !!monitor.isDragging()
|
||||
@@ -132,9 +141,8 @@ function PlaceHolderSign() {
|
||||
const [{ isDragSignatureSS }, dragSignatureSS] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 3,
|
||||
text: "drag me"
|
||||
text: "signature"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragSignatureSS: !!monitor.isDragging()
|
||||
@@ -144,9 +152,8 @@ function PlaceHolderSign() {
|
||||
const [{ isDragStampSS }, dragStampSS] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 4,
|
||||
text: "drag me"
|
||||
text: "stamp"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragStampSS: !!monitor.isDragging()
|
||||
@@ -339,6 +346,7 @@ function PlaceHolderSign() {
|
||||
let placeHolder;
|
||||
if (item === "onclick") {
|
||||
const dropObj = {
|
||||
//onclick put placeholder center on pdf
|
||||
xPosition: window.innerWidth / 2 - 100,
|
||||
yPosition: window.innerHeight / 2 - 60,
|
||||
isStamp: monitor,
|
||||
@@ -347,7 +355,8 @@ function PlaceHolderSign() {
|
||||
scale: scale,
|
||||
isMobile: isMobile,
|
||||
yBottom: window.innerHeight / 2 - 60,
|
||||
zIndex: posZIndex
|
||||
zIndex: posZIndex,
|
||||
type: item.text
|
||||
};
|
||||
dropData.push(dropObj);
|
||||
placeHolder = {
|
||||
@@ -375,7 +384,8 @@ function PlaceHolderSign() {
|
||||
yBottom: ybottom,
|
||||
scale: scale,
|
||||
isMobile: isMobile,
|
||||
zIndex: posZIndex
|
||||
zIndex: posZIndex,
|
||||
type: item.text
|
||||
};
|
||||
|
||||
dropData.push(dropObj);
|
||||
@@ -642,7 +652,6 @@ function PlaceHolderSign() {
|
||||
setIsSendAlert(alert);
|
||||
}
|
||||
};
|
||||
|
||||
const sendEmailToSigners = async () => {
|
||||
const loadObj = {
|
||||
isLoad: true,
|
||||
@@ -682,7 +691,7 @@ function PlaceHolderSign() {
|
||||
|
||||
const hostUrl = window.location.origin + "/loadmf/signmicroapp";
|
||||
let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}/${serverParams}`;
|
||||
const openSignUrl = "https://www.opensignlabs.com/contact-us";
|
||||
const openSignUrl = "https://www.opensignlabs.com/";
|
||||
const orgName = pdfDetails[0]?.ExtUserPtr.Company
|
||||
? pdfDetails[0].ExtUserPtr.Company
|
||||
: "";
|
||||
@@ -787,12 +796,11 @@ function PlaceHolderSign() {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleDontShow = (isChecked) => {
|
||||
setIsDontShow(isChecked);
|
||||
};
|
||||
|
||||
//here you can add your messages in content and selector is key of particular steps
|
||||
|
||||
const tourConfig = [
|
||||
{
|
||||
selector: '[data-tut="reactourFirst"]',
|
||||
@@ -851,6 +859,55 @@ function PlaceHolderSign() {
|
||||
}
|
||||
];
|
||||
|
||||
const handleSaveDropdownOptions = (dropdownName, dropdownOptions) => {
|
||||
//get current signers placeholder position data
|
||||
const currentSigner = signerPos.filter(
|
||||
(data) => data.signerObjId === signerObjId
|
||||
);
|
||||
//get current pagenumber placeholder index
|
||||
const getIndex = currentSigner[0].placeHolder.findIndex((object) => {
|
||||
return object.pageNumber === pageNumber;
|
||||
});
|
||||
|
||||
const placeholderPosition = currentSigner[0].placeHolder;
|
||||
//function of save signature image and get updated position with signature image url
|
||||
|
||||
let getXYdata = placeholderPosition[getIndex].pos;
|
||||
const updateXYData = getXYdata.map((position) => {
|
||||
if (position.key === signKey) {
|
||||
return {
|
||||
...position,
|
||||
widgetName: dropdownName,
|
||||
widgetOption: dropdownOptions
|
||||
};
|
||||
}
|
||||
return position;
|
||||
});
|
||||
|
||||
const getUpdatePosition = placeholderPosition.map((obj, ind) => {
|
||||
if (ind === getIndex) {
|
||||
return { ...obj, pos: updateXYData };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
const updateSignerData = currentSigner.map((obj, ind) => {
|
||||
if (obj.signerObjId === signerObjId) {
|
||||
return { ...obj, placeHolder: getUpdatePosition };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
const index = signerPos.findIndex(
|
||||
(data) => data.signerObjId === signerObjId
|
||||
);
|
||||
setSignerPos((prevState) => {
|
||||
const newState = [...prevState];
|
||||
newState.splice(index, 1, ...updateSignerData);
|
||||
return newState;
|
||||
});
|
||||
};
|
||||
|
||||
//function for update TourStatus
|
||||
const closeTour = async () => {
|
||||
setPlaceholderTour(false);
|
||||
@@ -925,7 +982,6 @@ function PlaceHolderSign() {
|
||||
}
|
||||
return { ...x };
|
||||
});
|
||||
// console.log("updateSigner ", updateSigner);
|
||||
if (updateSigner && updateSigner.length > 0) {
|
||||
const currEmail = pdfDetails[0].ExtUserPtr.Email;
|
||||
const getCurrentUserDeatils = updateSigner.filter(
|
||||
@@ -935,6 +991,7 @@ function PlaceHolderSign() {
|
||||
setCurrentId(getCurrentUserDeatils[0].Email);
|
||||
}
|
||||
}
|
||||
// console.log("updateSigner ", updateSigner);
|
||||
|
||||
setSignersData(updateSigner);
|
||||
const index = signersdata.findIndex((x) => x.Id === uniqueId);
|
||||
@@ -1027,7 +1084,7 @@ function PlaceHolderSign() {
|
||||
|
||||
{isSendAlert.mssg === "confirm" && (
|
||||
<button
|
||||
onClick={() => sendEmailToSigners()}
|
||||
// onClick={() => sendEmailToSigners()}
|
||||
style={{
|
||||
background: themeColor()
|
||||
}}
|
||||
@@ -1154,6 +1211,11 @@ function PlaceHolderSign() {
|
||||
// signerObjId={signerObjId}
|
||||
Id={uniqueId}
|
||||
/>
|
||||
<DropdownWidgetOption
|
||||
showDropdown={showDropdown}
|
||||
setShowDropdown={setShowDropdown}
|
||||
handleSaveDropdownOptions={handleSaveDropdownOptions}
|
||||
/>
|
||||
{/* pdf header which contain funish back button */}
|
||||
<Header
|
||||
isPlaceholder={true}
|
||||
@@ -1198,6 +1260,7 @@ function PlaceHolderSign() {
|
||||
handleLinkUser={handleLinkUser}
|
||||
setUniqueId={setUniqueId}
|
||||
isDragging={isDragging}
|
||||
setShowDropdown={setShowDropdown}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -1221,7 +1284,7 @@ function PlaceHolderSign() {
|
||||
dragStamp={dragStamp}
|
||||
dragRef={dragRef}
|
||||
isDragStamp={isDragStamp}
|
||||
isSignYourself={true}
|
||||
isSignYourself={false}
|
||||
isDragSignatureSS={isDragSignatureSS}
|
||||
dragSignatureSS={dragSignatureSS}
|
||||
dragStampSS={dragStampSS}
|
||||
@@ -1309,7 +1372,6 @@ function PlaceHolderSign() {
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
|
||||
<LinkUserModal
|
||||
handleAddUser={handleAddUser}
|
||||
isAddUser={isAddUser}
|
||||
|
||||
@@ -3,7 +3,91 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Delicious+Handrawn&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Cedarville+Cursive&display=swap');
|
||||
|
||||
.placeholderBlock {
|
||||
padding: 0px;
|
||||
position: absolute;
|
||||
border-style: dashed;
|
||||
width: 150px;
|
||||
height: 60px;
|
||||
background: #daebe0;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
border-width: 0.2px;
|
||||
|
||||
}
|
||||
|
||||
.dropdownContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: scroll;
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
.dropdownContainer::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inputPlaceholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #007bff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.inputPlaceholder:focus {
|
||||
outline: none;
|
||||
border: 1px solid #188ae2;
|
||||
}
|
||||
|
||||
.drodown-input {
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
border: 1px solid #8ad5ce;
|
||||
/* border: 1px solid #e2dddd; */
|
||||
/* background-color: #e0e5f5; */
|
||||
color: black;
|
||||
font-family: inherit;
|
||||
font-feature-settings: inherit;
|
||||
font-variation-settings: inherit;
|
||||
font-weight: inherit;
|
||||
overflow: visible;
|
||||
|
||||
}
|
||||
|
||||
.drodown-input:focus {
|
||||
outline: none;
|
||||
border: 1px solid #099b8d;
|
||||
}
|
||||
|
||||
.dropdownAdd {
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
|
||||
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
border: none;
|
||||
margin-left: 10px;
|
||||
|
||||
}
|
||||
|
||||
.dropdownAdd:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dropdownList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.signatureCanvas {
|
||||
|
||||
border: 2px solid #888;
|
||||
background-color: rgb(255, 255, 255);
|
||||
width: 460px;
|
||||
@@ -247,7 +331,7 @@
|
||||
|
||||
.finishBtn:hover {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
||||
|
||||
|
||||
}
|
||||
|
||||
.saveBtn {
|
||||
@@ -412,10 +496,12 @@
|
||||
margin: 7px !important;
|
||||
font-size: 15px !important;
|
||||
}
|
||||
|
||||
.cancelBtn {
|
||||
color: black;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.draggable-button {
|
||||
padding: 10px 20px;
|
||||
background: #3498db;
|
||||
|
||||
@@ -1,8 +1,192 @@
|
||||
import axios from "axios";
|
||||
import { rgb } from "pdf-lib";
|
||||
|
||||
import { themeColor } from "./ThemeColor/backColor";
|
||||
const isMobile = window.innerWidth < 767;
|
||||
|
||||
export const onChangeInput = (
|
||||
value,
|
||||
signKey,
|
||||
xyPostion,
|
||||
index,
|
||||
setXyPostion,
|
||||
signerObjId
|
||||
) => {
|
||||
const isSigners = xyPostion.some((data) => data.signerPtr);
|
||||
console.log("isSigner", isSigners);
|
||||
if (isSigners) {
|
||||
const filterSignerPos = xyPostion.filter(
|
||||
(data) => data.signerObjId === signerObjId
|
||||
);
|
||||
|
||||
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
||||
const getPageNumer = getPlaceHolder.filter(
|
||||
(data) => data.pageNumber === index
|
||||
);
|
||||
if (getPageNumer.length > 0) {
|
||||
const getXYdata = getPageNumer[0].pos;
|
||||
const getPosData = getXYdata;
|
||||
const addSignPos = getPosData.map((url, ind) => {
|
||||
if (url.key === signKey) {
|
||||
return {
|
||||
...url,
|
||||
widgetValue: value
|
||||
};
|
||||
}
|
||||
return url;
|
||||
});
|
||||
|
||||
const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
|
||||
if (obj.pageNumber === index) {
|
||||
return { ...obj, pos: addSignPos };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
const newUpdateSigner = xyPostion.map((obj, ind) => {
|
||||
if (obj.Id === signerObjId) {
|
||||
return { ...obj, placeHolder: newUpdateSignPos };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
setXyPostion(newUpdateSigner);
|
||||
}
|
||||
} else {
|
||||
let getXYdata = xyPostion[index].pos;
|
||||
|
||||
const updatePosition = getXYdata.map((positionData, ind) => {
|
||||
if (positionData.key === signKey) {
|
||||
return {
|
||||
...positionData,
|
||||
widgetValue: value
|
||||
};
|
||||
}
|
||||
return positionData;
|
||||
});
|
||||
|
||||
const updatePlaceholder = xyPostion.map((obj, ind) => {
|
||||
if (ind === index) {
|
||||
return { ...obj, pos: updatePosition };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
setXyPostion(updatePlaceholder);
|
||||
}
|
||||
};
|
||||
|
||||
export const widgets = [
|
||||
{
|
||||
type: "signature",
|
||||
icon: "fa-solid fa-signature",
|
||||
iconSize: "16px"
|
||||
},
|
||||
{
|
||||
type: "stamp",
|
||||
icon: "fa-solid fa-stamp",
|
||||
iconSize: "19px"
|
||||
},
|
||||
{
|
||||
type: "dropdown",
|
||||
icon: "fa-solid fa-circle-chevron-down",
|
||||
iconSize: "19px"
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
icon: "fa-solid fa-square-check",
|
||||
iconSize: "21px"
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
icon: "fa-solid fa-font",
|
||||
iconSize: "21px"
|
||||
}
|
||||
];
|
||||
|
||||
export const getWidgetType = (item) => {
|
||||
return (
|
||||
<>
|
||||
<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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const defaultWidthHeight = (type) => {
|
||||
let obj;
|
||||
switch (type) {
|
||||
case "signature":
|
||||
obj = {
|
||||
width: 150,
|
||||
height: 60
|
||||
};
|
||||
return obj;
|
||||
|
||||
case "stamp":
|
||||
obj = {
|
||||
width: 150,
|
||||
height: 60
|
||||
};
|
||||
return obj;
|
||||
case "checkbox":
|
||||
obj = {
|
||||
width: 15,
|
||||
height: 15
|
||||
};
|
||||
return obj;
|
||||
case "text":
|
||||
obj = {
|
||||
width: 150,
|
||||
height: 25
|
||||
};
|
||||
return obj;
|
||||
case "dropdown":
|
||||
obj = {
|
||||
width: 120,
|
||||
height: 22
|
||||
};
|
||||
return obj;
|
||||
default:
|
||||
obj = {
|
||||
width: 150,
|
||||
height: 60
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
export const resizeBorderExtraWidth = () => {
|
||||
return 20;
|
||||
};
|
||||
@@ -400,7 +584,7 @@ export function urlValidator(url) {
|
||||
|
||||
export const placeholderWidth = (pos, scale, signyourself) => {
|
||||
let width;
|
||||
const defaultWidth = 150;
|
||||
const defaultWidth = defaultWidthHeight(pos.type).width;
|
||||
const posWidth = pos.Width ? pos.Width : defaultWidth;
|
||||
|
||||
if (signyourself) {
|
||||
@@ -443,12 +627,12 @@ export const placeholderWidth = (pos, scale, signyourself) => {
|
||||
export const placeholderHeight = (pos, scale, signyourself) => {
|
||||
let height;
|
||||
const posHeight = pos.Height;
|
||||
const defaultHeight = 60;
|
||||
const defaultHeight = defaultWidthHeight(pos.type).height;
|
||||
if (signyourself) {
|
||||
if (isMobile) {
|
||||
return posHeight * scale;
|
||||
return posHeight ? posHeight * scale : defaultHeight * scale;
|
||||
} else {
|
||||
return posHeight;
|
||||
return posHeight ? posHeight : defaultHeight;
|
||||
}
|
||||
} else {
|
||||
if (isMobile) {
|
||||
@@ -497,41 +681,42 @@ export const multiSignEmbed = async (
|
||||
const pageNo = item.pageNumber;
|
||||
const imgUrlList = item.pos;
|
||||
const pages = pdfDoc.getPages();
|
||||
const form = pdfDoc.getForm();
|
||||
const page = pages[pageNo - 1];
|
||||
const images = await Promise.all(
|
||||
imgUrlList.map(async (url) => {
|
||||
let signUrl = url.SignUrl;
|
||||
if (url.ImageType === "image/png") {
|
||||
//function for convert signature png base64 url to jpeg base64
|
||||
const newUrl = await convertPNGtoJPEG(signUrl);
|
||||
signUrl = newUrl;
|
||||
let signUrl = url.SignUrl && url.SignUrl;
|
||||
if (signUrl) {
|
||||
if (url.ImageType === "image/png") {
|
||||
//function for convert signature png base64 url to jpeg base64
|
||||
const newUrl = await convertPNGtoJPEG(signUrl);
|
||||
signUrl = newUrl;
|
||||
}
|
||||
const checkUrl = urlValidator(signUrl);
|
||||
if (checkUrl) {
|
||||
signUrl = signUrl + "?get";
|
||||
}
|
||||
const res = await fetch(signUrl);
|
||||
return res.arrayBuffer();
|
||||
}
|
||||
const checkUrl = urlValidator(signUrl);
|
||||
if (checkUrl) {
|
||||
signUrl = signUrl + "?get";
|
||||
}
|
||||
const res = await fetch(signUrl);
|
||||
return res.arrayBuffer();
|
||||
})
|
||||
);
|
||||
images.forEach(async (imgData, id) => {
|
||||
let img;
|
||||
if (
|
||||
(imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/png") ||
|
||||
imgUrlList[id].ImageType === "image/jpeg"
|
||||
) {
|
||||
img = await pdfDoc.embedJpg(imgData);
|
||||
} else {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
}
|
||||
|
||||
const scaleWidth = placeholderWidth(imgUrlList[id], scale, signyourself);
|
||||
const scaleHeight = placeholderHeight(
|
||||
imgUrlList[id],
|
||||
scale,
|
||||
signyourself
|
||||
);
|
||||
imgUrlList.forEach(async (imgData, id) => {
|
||||
let img;
|
||||
if (imgData.type === "signature" || imgData.type === "stamp") {
|
||||
if (
|
||||
(imgData.ImageType && imgData.ImageType === "image/png") ||
|
||||
imgData.ImageType === "image/jpeg"
|
||||
) {
|
||||
img = await pdfDoc.embedJpg(images[id]);
|
||||
} else {
|
||||
img = await pdfDoc.embedPng(images[id]);
|
||||
}
|
||||
}
|
||||
let scaleWidth, scaleHeight;
|
||||
scaleWidth = placeholderWidth(imgData, scale, signyourself);
|
||||
scaleHeight = placeholderHeight(imgData, scale, signyourself);
|
||||
|
||||
const xPos = (pos) => {
|
||||
const resizePos = pos.xPosition;
|
||||
@@ -565,7 +750,7 @@ export const multiSignEmbed = async (
|
||||
};
|
||||
|
||||
const yPos = (pos) => {
|
||||
const resizePos = imgUrlList[id].yPosition;
|
||||
const resizePos = pos.yPosition;
|
||||
if (signyourself) {
|
||||
if (isMobile) {
|
||||
return page.getHeight() - resizePos * scale - scaleHeight;
|
||||
@@ -603,13 +788,48 @@ export const multiSignEmbed = async (
|
||||
}
|
||||
}
|
||||
};
|
||||
const checkboxId = "checkbox_" + id;
|
||||
if (imgData.type === "checkbox") {
|
||||
const checkBox = form.createCheckBox(checkboxId);
|
||||
|
||||
page.drawImage(img, {
|
||||
x: xPos(imgUrlList[id]),
|
||||
y: yPos(imgUrlList[id]),
|
||||
width: scaleWidth,
|
||||
height: scaleHeight
|
||||
});
|
||||
checkBox.addToPage(page, {
|
||||
x: xPos(imgData),
|
||||
y: yPos(imgData),
|
||||
width: scaleWidth,
|
||||
height: scaleHeight
|
||||
});
|
||||
checkBox.check();
|
||||
checkBox.enableReadOnly();
|
||||
} else if (imgData.type === "text") {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
const fontSize = 12;
|
||||
const textContent = imgData.widgetValue;
|
||||
page.drawText(textContent, {
|
||||
x: xPos(imgData),
|
||||
y: yPos(imgData),
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0, 0, 0)
|
||||
});
|
||||
} else if (imgData.type === "dropdown") {
|
||||
const dropdown = form.createDropdown(checkboxId);
|
||||
dropdown.addOptions(imgData.widgetOption);
|
||||
dropdown.select(imgData.widgetValue);
|
||||
dropdown.addToPage(page, {
|
||||
x: xPos(imgData),
|
||||
y: yPos(imgData),
|
||||
width: scaleWidth,
|
||||
height: scaleHeight
|
||||
});
|
||||
dropdown.disableEditing();
|
||||
} else {
|
||||
page.drawImage(img, {
|
||||
x: xPos(imgData),
|
||||
y: yPos(imgData),
|
||||
width: scaleWidth,
|
||||
height: scaleHeight
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -646,13 +866,10 @@ export const pdfNewWidthFun = (divRef) => {
|
||||
export const handleImageResize = (
|
||||
ref,
|
||||
key,
|
||||
signerId,
|
||||
position,
|
||||
signerPos,
|
||||
pageNumber,
|
||||
setSignerPos,
|
||||
pdfOriginalWidth,
|
||||
containerWH,
|
||||
pageNumber,
|
||||
signerId,
|
||||
showResize
|
||||
) => {
|
||||
// const filterSignerPos = signerPos.filter(
|
||||
@@ -752,8 +969,8 @@ export const handleSignYourselfImageResize = (
|
||||
ref,
|
||||
key,
|
||||
xyPostion,
|
||||
index,
|
||||
setXyPostion
|
||||
setXyPostion,
|
||||
index
|
||||
) => {
|
||||
// const updateFilter = xyPostion[index].pos.filter(
|
||||
// (data) => data.key === key && data.Width && data.Height
|
||||
|
||||
Reference in New Issue
Block a user