Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
350854ab6b | ||
|
|
cc980758fd | ||
|
|
0f1ce43cc5 | ||
|
|
5e1a9cdc20 | ||
|
|
550ce10c92 | ||
|
|
6080c59bd7 | ||
|
|
273a35d42f | ||
|
|
2f195fe02e | ||
|
|
0715ca9d85 | ||
|
|
1ec10fbcfc | ||
|
|
274620d17b | ||
|
|
06db7d2360 | ||
|
|
2b3549e4df | ||
|
|
d16478792c | ||
|
|
7ba2ef6420 | ||
|
|
b5d98796b7 | ||
|
|
97c17cfe84 | ||
|
|
4b4e200090 | ||
|
|
232d38440d | ||
|
|
341bd9bef0 | ||
|
|
2f4d04c722 | ||
|
|
148ae40e1a | ||
|
|
9cb0ced4f6 | ||
|
|
9a3b70de43 | ||
|
|
742b8f7eae | ||
|
|
abc58941e3 | ||
|
|
aac200bfd3 | ||
|
|
27d3297d61 | ||
|
|
72431b2c82 | ||
|
|
3ca48e5848 | ||
|
|
14784ec80f | ||
|
|
127741eb27 | ||
|
|
2ed987fe10 | ||
|
|
7aaa1876c8 | ||
|
|
390ffb83a2 | ||
|
|
d63e51b8cb | ||
|
|
7bd8d64649 | ||
|
|
f9e6f49ede | ||
|
|
b701d2863f | ||
|
|
cf47093227 | ||
|
|
81d0aea66c | ||
|
|
506ca35be8 | ||
|
|
1cd6718489 | ||
|
|
153c5db4b5 | ||
|
|
ac9367a715 | ||
|
|
081dae0b90 | ||
|
|
e286390aec | ||
|
|
cf88eb2124 | ||
|
|
3226e4fd85 | ||
|
|
cab94eb63d | ||
|
|
bbd5d6805e | ||
|
|
2904ba3085 | ||
|
|
ee609061ed | ||
|
|
6c98a4e899 | ||
|
|
eef9ee7f3c | ||
|
|
2cb4575db1 | ||
|
|
e7bcad80cc | ||
|
|
353839a1dc | ||
|
|
e6d30744ba | ||
|
|
b67932f448 | ||
|
|
c185c42b80 | ||
|
|
4648ace84e | ||
|
|
ccdf50dbe0 | ||
|
|
852a3dc8bb | ||
|
|
d49b7bd201 | ||
|
|
07f2ceed6e | ||
|
|
751c7b5787 | ||
|
|
e82384dff8 | ||
|
|
92d3a85147 | ||
|
|
c5762a0baf | ||
|
|
dc40b04a18 | ||
|
|
1cca5a3085 | ||
|
|
4fe4ca638c | ||
|
|
b8c7110c63 | ||
|
|
711ab6a556 | ||
|
|
7a12f54587 | ||
|
|
056f4b3e80 | ||
|
|
730a7a4e15 | ||
|
|
a4b4dc885c | ||
|
|
8562a4bb46 | ||
|
|
d3b56432e0 | ||
|
|
527c5be42c | ||
|
|
6c1d0c712a | ||
|
|
fd0ec5fd31 | ||
|
|
f5f19c9b52 | ||
|
|
642ef4f5b7 | ||
|
|
66b65e600b | ||
|
|
01a130ef8c | ||
|
|
c3bccb5412 | ||
|
|
b32e6e71f8 | ||
|
|
3b5875e283 | ||
|
|
da42fe97ae | ||
|
|
56bb7d36eb | ||
|
|
d86b7345d7 | ||
|
|
c1c17160ff | ||
|
|
d400c843e4 | ||
|
|
4e67ab50fe | ||
|
|
74c9e21d55 | ||
|
|
fefcdf6ffc | ||
|
|
5170e4eee2 | ||
|
|
8ebfd781c3 | ||
|
|
4e8988bf57 | ||
|
|
c26734751f | ||
|
|
ca6b4e7d82 | ||
|
|
cb4a94d036 | ||
|
|
300ddb810f | ||
|
|
0b687310fd | ||
|
|
3e741ac2f9 | ||
|
|
f65b23ca26 | ||
|
|
db9b8d2ba1 | ||
|
|
2b345ff840 |
@@ -45,14 +45,14 @@ DO_REGION=us-west
|
|||||||
USE_LOCAL=TRUE
|
USE_LOCAL=TRUE
|
||||||
|
|
||||||
# Email mailgun or set SMTP_ENABLE true to use SMTP config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
# Email mailgun or set SMTP_ENABLE true to use SMTP config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
||||||
MAILGUN_API_KEY=XXXXX
|
MAILGUN_API_KEY=
|
||||||
MAILGUN_DOMAIN=mail.yourdomain.com
|
MAILGUN_DOMAIN=mail.yourdomain.com
|
||||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||||
SMTP_ENABLE=
|
SMTP_ENABLE=
|
||||||
SMTP_HOST=
|
SMTP_HOST=smtp.yourhost.com
|
||||||
SMTP_PORT=
|
SMTP_PORT=443
|
||||||
SMTP_USER_EMAIL=
|
SMTP_USER_EMAIL=mailer@yourdomain.com
|
||||||
SMTP_PASS=
|
SMTP_PASS=password
|
||||||
|
|
||||||
|
|
||||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
v1.0.5-beta
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import ForgetPassword from "./routes/ForgetPassword";
|
|||||||
import ChangePassword from "./routes/ChangePassword";
|
import ChangePassword from "./routes/ChangePassword";
|
||||||
import ReportMicroapp from "./components/ReportMicroapp";
|
import ReportMicroapp from "./components/ReportMicroapp";
|
||||||
import LoadMf from "./routes/LoadMf";
|
import LoadMf from "./routes/LoadMf";
|
||||||
|
import ValidateRoute from "./primitives/ValidateRoute";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [isloading, setIsLoading] = useState(true);
|
const [isloading, setIsLoading] = useState(true);
|
||||||
@@ -58,8 +59,24 @@ function App() {
|
|||||||
) : (
|
) : (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route exact path="/" element={<Login />} />
|
<Route
|
||||||
<Route exact path="/signup" element={<Signup />} />
|
exact
|
||||||
|
path="/"
|
||||||
|
element={
|
||||||
|
<ValidateRoute>
|
||||||
|
<Login />
|
||||||
|
</ValidateRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/signup"
|
||||||
|
element={
|
||||||
|
<ValidateRoute>
|
||||||
|
<Signup />
|
||||||
|
</ValidateRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
||||||
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
||||||
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ const AppendFormInForm = (props) => {
|
|||||||
// Define a function to handle form submission
|
// Define a function to handle form submission
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
setIsLoader(true);
|
setIsLoader(true);
|
||||||
Parse.serverURL = parseBaseUrl;
|
Parse.serverURL = parseBaseUrl;
|
||||||
Parse.initialize(parseAppId);
|
Parse.initialize(parseAppId);
|
||||||
@@ -105,13 +106,18 @@ const AppendFormInForm = (props) => {
|
|||||||
const res = await contactQuery.save();
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
if (props.details) {
|
||||||
props.details({
|
props.details({
|
||||||
value: parseData[props.valueKey],
|
value: parseData[props.valueKey],
|
||||||
label: parseData[props.displayKey]
|
label: parseData[props.displayKey]
|
||||||
});
|
});
|
||||||
|
}
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
// Reset the form fields
|
// Reset the form fields
|
||||||
@@ -158,13 +164,18 @@ const AppendFormInForm = (props) => {
|
|||||||
const res = await contactQuery.save();
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
if (props.details) {
|
||||||
props.details({
|
props.details({
|
||||||
value: parseData[props.valueKey],
|
value: parseData[props.valueKey],
|
||||||
label: parseData[props.displayKey]
|
label: parseData[props.displayKey]
|
||||||
});
|
});
|
||||||
|
}
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
// Reset the form fields
|
// Reset the form fields
|
||||||
setAddYourself(false);
|
setAddYourself(false);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const LoginFacebook = ({
|
|||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
// "passsword":userDetails.Phone,
|
// "passsword":userDetails.Phone,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails.Phone,
|
||||||
role: "contracts_Admin",
|
role: "contracts_User",
|
||||||
company: userDetails.Company
|
company: userDetails.Company
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ const GoogleSignInBtn = ({
|
|||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
// "passsword":userDetails.Phone,
|
// "passsword":userDetails.Phone,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails.Phone,
|
||||||
role: "contracts_Admin",
|
role: "contracts_User",
|
||||||
company: userDetails.Company,
|
company: userDetails.Company,
|
||||||
jobTitle: userDetails.Destination
|
jobTitle: userDetails.Destination
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import Parse from "parse";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import "../styles/spinner.css";
|
import "../styles/spinner.css";
|
||||||
import TreeFormComponent from "./TreeFormComponent";
|
import TreeFormComponent from "./TreeFormComponent";
|
||||||
import TreeEditForm from "./TreeEditForm";
|
// import TreeEditForm from "./TreeEditForm";
|
||||||
import "../styles/modal.css";
|
import "../styles/modal.css";
|
||||||
import Modal from "react-modal";
|
import Modal from "react-modal";
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ const TreeWidget = (props) => {
|
|||||||
const [schemaState, setSchemaState] = useState({});
|
const [schemaState, setSchemaState] = useState({});
|
||||||
const [TabURL, setTabURL] = useState("");
|
const [TabURL, setTabURL] = useState("");
|
||||||
const [editable, setEditable] = useState(false);
|
const [editable, setEditable] = useState(false);
|
||||||
const [editId, setEditId] = useState("");
|
// const [editId, setEditId] = useState("");
|
||||||
const [defaultState, setDefaultState] = useState(false);
|
const [defaultState, setDefaultState] = useState(false);
|
||||||
const [isShowModal, setIsShowModal] = useState(false);
|
const [isShowModal, setIsShowModal] = useState(false);
|
||||||
const selectFolderHandle = async () => {
|
const selectFolderHandle = async () => {
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import Alert from "../../primitives/Alert";
|
||||||
|
|
||||||
|
const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: parentFolderId
|
||||||
|
};
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [folderList, setFolderList] = useState([]);
|
||||||
|
const [isAlert, setIsAlert] = useState(false);
|
||||||
|
const [selectedParent, setSelectedParent] = useState();
|
||||||
|
const [alert, setAlert] = useState({ type: "info", message: "" });
|
||||||
|
useEffect(() => {
|
||||||
|
fetchFolder();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchFolder = async () => {
|
||||||
|
try {
|
||||||
|
const FolderQuery = new Parse.Query(folderCls);
|
||||||
|
if (parentFolderId) {
|
||||||
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
} else {
|
||||||
|
FolderQuery.doesNotExist("Folder");
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await FolderQuery.find();
|
||||||
|
if (res) {
|
||||||
|
const result = JSON.parse(JSON.stringify(res));
|
||||||
|
if (result) {
|
||||||
|
setFolderList(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Err ", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCreateFolder = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (name) {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const exsitQuery = new Parse.Query(folderCls);
|
||||||
|
exsitQuery.equalTo("Name", name);
|
||||||
|
exsitQuery.equalTo("Type", "Folder");
|
||||||
|
if (parentFolderId) {
|
||||||
|
exsitQuery.equalTo("Folder", folderPtr);
|
||||||
|
}
|
||||||
|
const templExist = await exsitQuery.first();
|
||||||
|
if (templExist) {
|
||||||
|
setAlert({ type: "dange", message: "Folder already exist!" });
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
const template = new Parse.Object(folderCls);
|
||||||
|
template.set("Name", name);
|
||||||
|
template.set("Type", "Folder");
|
||||||
|
|
||||||
|
if (selectedParent) {
|
||||||
|
template.set("Folder", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: selectedParent
|
||||||
|
});
|
||||||
|
} else if (parentFolderId) {
|
||||||
|
template.set("Folder", folderPtr);
|
||||||
|
}
|
||||||
|
template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||||
|
const res = await template.save();
|
||||||
|
if (res) {
|
||||||
|
setAlert({
|
||||||
|
type: "success",
|
||||||
|
message: "Folder created successfully!"
|
||||||
|
});
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
if (onSuccess) {
|
||||||
|
onSuccess(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setAlert({ type: "info", message: "Please fill folder name" });
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleOptions = (e) => {
|
||||||
|
setSelectedParent(e.target.value);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{isAlert && <Alert type={alert.type}>{alert.message}</Alert>}
|
||||||
|
<div id="createFolder">
|
||||||
|
<h1 className="text-base font-semibold">Create Folder</h1>
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">
|
||||||
|
Name<span className="text-red-500 text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">Parent Folder</label>
|
||||||
|
<select
|
||||||
|
value={selectedParent}
|
||||||
|
onChange={handleOptions}
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
>
|
||||||
|
<option>select</option>
|
||||||
|
{folderList.length > 0 &&
|
||||||
|
folderList.map((x) => (
|
||||||
|
<option key={x.objectId} value={x.objectId}>
|
||||||
|
{x.Name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={handleCreateFolder}
|
||||||
|
className="flex items-center rounded p-2 bg-[#32a3ac] text-white mt-3"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-plus mr-1"></i>
|
||||||
|
<span>Create</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateFolder;
|
||||||
@@ -41,7 +41,8 @@ export default function DropboxChooser({ children, onSuccess, onCancel }) {
|
|||||||
[onSuccess, onCancel]
|
[onSuccess, onCancel]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleChoose = useCallback(() => {
|
const handleChoose = useCallback((e) => {
|
||||||
|
e.preventDefault()
|
||||||
if (window.Dropbox) {
|
if (window.Dropbox) {
|
||||||
window.Dropbox.choose(options);
|
window.Dropbox.choose(options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ const FileUpload = (props) => {
|
|||||||
<div className="flex gap-2 justify-center items-center">
|
<div className="flex gap-2 justify-center items-center">
|
||||||
<div className="flex justify-between items-center px-2 py-[3px] w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]">
|
<div className="flex justify-between items-center px-2 py-[3px] w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]">
|
||||||
<div className="break-all">
|
<div className="break-all">
|
||||||
file selected : {props.formData.split("/")[3]}
|
file selected : {props.formData?.split("/")[3]?.split("_")[1]}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -271,10 +271,12 @@ const FileUpload = (props) => {
|
|||||||
<i className="fa-solid fa-xmark"></i>
|
<i className="fa-solid fa-xmark"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{process.env.REACT_APP_DROPBOX_API_KEY && (
|
||||||
<DropboxChooser
|
<DropboxChooser
|
||||||
onSuccess={dropboxSuccess}
|
onSuccess={dropboxSuccess}
|
||||||
onCancel={dropboxCancel}
|
onCancel={dropboxCancel}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex gap-2 justify-center items-center">
|
<div className="flex gap-2 justify-center items-center">
|
||||||
@@ -294,10 +296,12 @@ const FileUpload = (props) => {
|
|||||||
accept="application/pdf,application/vnd.ms-excel"
|
accept="application/pdf,application/vnd.ms-excel"
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
|
{process.env.REACT_APP_DROPBOX_API_KEY && (
|
||||||
<DropboxChooser
|
<DropboxChooser
|
||||||
onSuccess={dropboxSuccess}
|
onSuccess={dropboxSuccess}
|
||||||
onCancel={dropboxCancel}
|
onCancel={dropboxCancel}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -0,0 +1,261 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import CreateFolder from "./CreateFolder";
|
||||||
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
|
|
||||||
|
const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||||
|
const [isOpen, SetIsOpen] = useState(false);
|
||||||
|
const [clickFolder, setClickFolder] = useState("");
|
||||||
|
const [selectFolder, setSelectedFolder] = useState({});
|
||||||
|
const [folderList, setFolderList] = useState([]);
|
||||||
|
const [tabList, setTabList] = useState([]);
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [folderPath, setFolderPath] = useState("");
|
||||||
|
const [isAdd, setIsAdd] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen) {
|
||||||
|
setIsAdd(false);
|
||||||
|
setClickFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
fetchFolder();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isOpen]);
|
||||||
|
const fetchFolder = async (folderPtr) => {
|
||||||
|
setIsLoader(true);
|
||||||
|
try {
|
||||||
|
const FolderQuery = new Parse.Query(folderCls);
|
||||||
|
if (folderPtr) {
|
||||||
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
} else {
|
||||||
|
FolderQuery.doesNotExist("Folder");
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await FolderQuery.find();
|
||||||
|
if (res) {
|
||||||
|
const result = JSON.parse(JSON.stringify(res));
|
||||||
|
if (result) {
|
||||||
|
setFolderList(result);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSelect = (item) => {
|
||||||
|
setFolderList([]);
|
||||||
|
setClickFolder({ ObjectId: item.objectId, Name: item.Name });
|
||||||
|
if (tabList.length > 0) {
|
||||||
|
const tab = tabList.some((x) => x.objectId === item.objectId);
|
||||||
|
if (!tab) {
|
||||||
|
setTabList((tabs) => [...tabs, item]);
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: item.objectId
|
||||||
|
};
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTabList((tabs) => [...tabs, item]);
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: item.objectId
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
let url = "Root";
|
||||||
|
tabList.forEach((t) => {
|
||||||
|
url = url + " / " + t.Name;
|
||||||
|
});
|
||||||
|
setFolderPath(url);
|
||||||
|
setSelectedFolder(clickFolder);
|
||||||
|
if (onSuccess) {
|
||||||
|
onSuccess(clickFolder);
|
||||||
|
}
|
||||||
|
SetIsOpen(false);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
SetIsOpen(false);
|
||||||
|
setClickFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeTabListItem = async (e, i) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// setEditable(false);
|
||||||
|
if (!isAdd) {
|
||||||
|
setIsLoader(true);
|
||||||
|
let folderPtr;
|
||||||
|
if (i) {
|
||||||
|
setFolderList([]);
|
||||||
|
let list = tabList.filter((itm, j) => {
|
||||||
|
if (j <= i) {
|
||||||
|
return itm;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let _len = list.length - 1;
|
||||||
|
folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: list[_len].objectId
|
||||||
|
};
|
||||||
|
setTabList(list);
|
||||||
|
} else {
|
||||||
|
setClickFolder({});
|
||||||
|
setSelectedFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
}
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCreate = () => {
|
||||||
|
setIsAdd(!isAdd);
|
||||||
|
};
|
||||||
|
const handleAddFolder = () => {
|
||||||
|
setFolderList([]);
|
||||||
|
if (clickFolder && clickFolder.ObjectId) {
|
||||||
|
fetchFolder({
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: clickFolder.ObjectId
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fetchFolder();
|
||||||
|
}
|
||||||
|
handleCreate();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="text-xs mt-2 ">
|
||||||
|
<div>
|
||||||
|
<label className="block">
|
||||||
|
Select Folder
|
||||||
|
{required && <span className="text-red-500 text-[13px]">*</span>}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="rounded px-[20px] py-[20px] bg-white border border-gray-200 shadow flex max-w-sm gap-8 items-center">
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
className="far fa-folder-open text-[40px] text-[#33bbff]"
|
||||||
|
style={{ fontSize: "40px" }}
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
<div className="font-semibold ">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<p>
|
||||||
|
{selectFolder && selectFolder.Name ? selectFolder.Name : "Root"}
|
||||||
|
</p>
|
||||||
|
<div className="text-black text-sm" onClick={() => SetIsOpen(true)}>
|
||||||
|
<i
|
||||||
|
className="fa fa-pencil"
|
||||||
|
title="Select Folder"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="text-[10px] text-gray-400">
|
||||||
|
{selectFolder && selectFolder.Name ? `(${folderPath})` : ""}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalUi
|
||||||
|
title={"Select Folder"}
|
||||||
|
isOpen={isOpen}
|
||||||
|
handleClose={handleCancel}
|
||||||
|
>
|
||||||
|
<div className="w-full min-w-[300px] md:min-w-[500px] px-3">
|
||||||
|
<div className="py-2 text-[#ac4848] text-[14px] font-[500]">
|
||||||
|
<span
|
||||||
|
className="cursor-pointer"
|
||||||
|
title="Root"
|
||||||
|
onClick={(e) => removeTabListItem(e)}
|
||||||
|
>
|
||||||
|
Root /{" "}
|
||||||
|
</span>
|
||||||
|
{tabList &&
|
||||||
|
tabList.map((tab, i) => (
|
||||||
|
<React.Fragment key={`${tab.objectId}-${i}`}>
|
||||||
|
<span
|
||||||
|
className="cursor-pointer"
|
||||||
|
title={tab.Name}
|
||||||
|
onClick={(e) => removeTabListItem(e, i)}
|
||||||
|
>
|
||||||
|
{tab.Name}
|
||||||
|
</span>
|
||||||
|
{" / "}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 mb-3">
|
||||||
|
{!isAdd &&
|
||||||
|
folderList.length > 0 &&
|
||||||
|
folderList.map((folder) => (
|
||||||
|
<div
|
||||||
|
key={folder.Name}
|
||||||
|
className="border-[1px] border-[#8a8a8a] px-2 py-2 mb-2 cursor-pointer"
|
||||||
|
onClick={() => handleSelect(folder)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<i
|
||||||
|
className="fa fa-folder text-[#33bbff] text-[1.4rem]"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span className="font-semibold">{folder.Name}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{isAdd && (
|
||||||
|
<CreateFolder
|
||||||
|
parentFolderId={clickFolder && clickFolder.ObjectId}
|
||||||
|
folderCls={folderCls}
|
||||||
|
onSuccess={handleAddFolder}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isLoader && (
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<i className="fa-solid fa-spinner fa-spin-pulse text-[30px]"></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div className="flex justify-between items-center py-[.75rem] px-[1.25rem]">
|
||||||
|
<div
|
||||||
|
className="text-[30px] cursor-pointer text-[#32a3ac]"
|
||||||
|
title="Save Here"
|
||||||
|
onClick={handleCreate}
|
||||||
|
>
|
||||||
|
{isAdd ? (
|
||||||
|
<i className="fa-solid fa-arrow-left" aria-hidden="true"></i>
|
||||||
|
) : (
|
||||||
|
<i className="fa-solid fa-square-plus" aria-hidden="true"></i>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="text-[30px] cursor-pointer"
|
||||||
|
title="Save Here"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
<i className="fas fa-save" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SelectFolder;
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Select from "react-select";
|
||||||
|
import AppendFormInForm from "../AppendFormInForm";
|
||||||
|
import Modal from "react-modal";
|
||||||
|
import Parse from "parse";
|
||||||
|
function arrayMove(array, from, to) {
|
||||||
|
array = array.slice();
|
||||||
|
array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* react-sortable-hoc is depcreated not usable from react 18.x.x
|
||||||
|
* need to replace it with @dnd-kit
|
||||||
|
* code changes required
|
||||||
|
*/
|
||||||
|
|
||||||
|
const SignersInput = (props) => {
|
||||||
|
Modal.setAppElement("body");
|
||||||
|
const [state, setState] = useState(undefined);
|
||||||
|
// const [editFormData, setEditFormData] = useState([]);
|
||||||
|
const [selected, setSelected] = React.useState([]);
|
||||||
|
const [isModal, setIsModel] = useState(false);
|
||||||
|
const onChange = (selectedOptions) => setSelected(selectedOptions);
|
||||||
|
const [modalIsOpen, setModalIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const onSortEnd = ({ oldIndex, newIndex }) => {
|
||||||
|
const newValue = arrayMove(selected, oldIndex, newIndex);
|
||||||
|
setSelected(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetSelectListData = async () => {
|
||||||
|
try {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const contactbook = new Parse.Query("contracts_Contactbook");
|
||||||
|
contactbook.equalTo(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
contactbook.notEqualTo("IsDeleted", true);
|
||||||
|
const contactRes = await contactbook.find();
|
||||||
|
if (contactRes) {
|
||||||
|
const res = JSON.parse(JSON.stringify(contactRes));
|
||||||
|
let list = [];
|
||||||
|
|
||||||
|
// let _selected = [];
|
||||||
|
res.forEach((x) => {
|
||||||
|
let obj = {
|
||||||
|
label: x.Name,
|
||||||
|
value: x.objectId,
|
||||||
|
isChecked: true
|
||||||
|
};
|
||||||
|
|
||||||
|
list.push(obj);
|
||||||
|
});
|
||||||
|
setState(list);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("err", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
GetSelectListData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selected && selected.length) {
|
||||||
|
let newData = [];
|
||||||
|
selected.forEach((x) => {
|
||||||
|
newData.push(x.value);
|
||||||
|
});
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(newData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [selected]);
|
||||||
|
|
||||||
|
const handleModalCloseClick = () => {
|
||||||
|
setIsModel(false);
|
||||||
|
setModalIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openModal = () => {
|
||||||
|
setModalIsOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// `handleNewDetails` is used to set just save from quick form to selected option in dropdown
|
||||||
|
const handleNewDetails = (data) => {
|
||||||
|
setState([...state, data]);
|
||||||
|
if (selected.length > 0) {
|
||||||
|
setSelected([...selected, data]);
|
||||||
|
} else {
|
||||||
|
setSelected([data]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="text-xs mt-2 ">
|
||||||
|
<label className="block">
|
||||||
|
Signers
|
||||||
|
{props.required && <span className="text-red-500 text-[13px]">*</span>}
|
||||||
|
</label>
|
||||||
|
<div style={{ display: "flex", gap: 5 }}>
|
||||||
|
<div style={{ flexWrap: "wrap", width: "100%" }}>
|
||||||
|
<Select
|
||||||
|
onSortEnd={onSortEnd}
|
||||||
|
distance={4}
|
||||||
|
isMulti
|
||||||
|
options={state || []}
|
||||||
|
value={selected}
|
||||||
|
onChange={onChange}
|
||||||
|
closeMenuOnSelect={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setIsModel(true);
|
||||||
|
openModal();
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
borderRadius: 4,
|
||||||
|
border: "1px solid #ccc",
|
||||||
|
minHeight: 38,
|
||||||
|
minWidth: 48,
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="fas fa-plus"></i>
|
||||||
|
</div>
|
||||||
|
<Modal
|
||||||
|
isOpen={modalIsOpen}
|
||||||
|
onRequestClose={handleModalCloseClick}
|
||||||
|
shouldCloseOnOverlayClick={false}
|
||||||
|
id="modal1"
|
||||||
|
contentLabel="Modal"
|
||||||
|
style={{
|
||||||
|
content: {
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
right: "auto",
|
||||||
|
bottom: "auto",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
padding: 0
|
||||||
|
},
|
||||||
|
overlay: {
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
||||||
|
zIndex: 50
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="min-w-full md:min-w-[500px]">
|
||||||
|
<div
|
||||||
|
type="button"
|
||||||
|
className="flex justify-between items-center p-3 border-b-[1px] border-gray-300"
|
||||||
|
>
|
||||||
|
<div className=" text-black text-xl font-semibold pl-3">
|
||||||
|
Add Signer
|
||||||
|
</div>
|
||||||
|
<button onClick={handleModalCloseClick}>
|
||||||
|
<i
|
||||||
|
style={{ fontSize: 25 }}
|
||||||
|
className="fa fa-times-circle"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isModal && (
|
||||||
|
<AppendFormInForm
|
||||||
|
valueKey={"objectId"}
|
||||||
|
displayKey={"Name"}
|
||||||
|
details={handleNewDetails}
|
||||||
|
closePopup={handleModalCloseClick}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SignersInput;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export const contactCls = "contracts_Contactbook";
|
||||||
|
export const templateCls = "contracts_Template";
|
||||||
@@ -5,3 +5,14 @@
|
|||||||
body{
|
body{
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Custom CSS to hide scrollbar */
|
||||||
|
.hide-scrollbar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-scrollbar {
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ export const formJson = (id) => {
|
|||||||
});
|
});
|
||||||
formData = {
|
formData = {
|
||||||
jsonSchema: {
|
jsonSchema: {
|
||||||
title: "New Document",
|
title: "Request signatures",
|
||||||
description: "",
|
description: "",
|
||||||
type: "object",
|
type: "object",
|
||||||
required: ["URL", "Name", "Note", "TimeToCompleteDays", "Signers"],
|
required: ["URL", "Name", "Note", "TimeToCompleteDays", "Signers"],
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
export default function reportJson(id) {
|
export default function reportJson(id) {
|
||||||
// console.log("json ", json);
|
// console.log("json ", json);
|
||||||
const head = ["Sr.No", "Name", "Note", "Folder", "File", "Owner", "Signers"];
|
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
||||||
const contactbook = ["Sr.No", "Name", "Email", "Phone"];
|
const contactbook = ["Sr.No", "Title", "Email", "Phone"];
|
||||||
|
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
// draft documents report
|
// draft documents report
|
||||||
case "ByHuevtCFY":
|
case "ByHuevtCFY":
|
||||||
@@ -103,7 +105,7 @@ export default function reportJson(id) {
|
|||||||
case "d9k3UfYHBc":
|
case "d9k3UfYHBc":
|
||||||
return {
|
return {
|
||||||
reportName: "Recently sent for signatures",
|
reportName: "Recently sent for signatures",
|
||||||
heading: head,
|
heading: dashboardReportHead,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -119,7 +121,7 @@ export default function reportJson(id) {
|
|||||||
case "5Go51Q7T8r":
|
case "5Go51Q7T8r":
|
||||||
return {
|
return {
|
||||||
reportName: "Recent signature requests",
|
reportName: "Recent signature requests",
|
||||||
heading: head,
|
heading: dashboardReportHead,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "Sign",
|
btnLabel: "Sign",
|
||||||
@@ -135,7 +137,7 @@ export default function reportJson(id) {
|
|||||||
case "kC5mfynCi4":
|
case "kC5mfynCi4":
|
||||||
return {
|
return {
|
||||||
reportName: "Drafts",
|
reportName: "Drafts",
|
||||||
heading: head,
|
heading: ["Title", "Note", "Folder", "File", "Owner", "Signers"],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
@@ -159,6 +161,31 @@ export default function reportJson(id) {
|
|||||||
textColor: "white",
|
textColor: "white",
|
||||||
btnIcon: "fa-solid fa-trash"
|
btnIcon: "fa-solid fa-trash"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
form: "ContactBook"
|
||||||
|
};
|
||||||
|
// template report
|
||||||
|
case "6TeaPr321t":
|
||||||
|
return {
|
||||||
|
reportName: "Templates",
|
||||||
|
heading: head,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
btnLabel: "Use",
|
||||||
|
btnColor: "#4bd396",
|
||||||
|
textColor: "white",
|
||||||
|
btnIcon: "fa fa-plus",
|
||||||
|
redirectUrl:
|
||||||
|
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/placeHolderSign"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
btnLabel: "Edit",
|
||||||
|
btnColor: "#00c9d5",
|
||||||
|
textColor: "white",
|
||||||
|
btnIcon: "fa fa-plus",
|
||||||
|
redirectUrl:
|
||||||
|
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/template"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -7,10 +7,35 @@ import Tour from "reactour";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const HomeLayout = ({ children }) => {
|
const HomeLayout = ({ children }) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
const [isOpen, setIsOpen] = useState(true);
|
const [isOpen, setIsOpen] = useState(true);
|
||||||
const arr = useSelector((state) => state.TourSteps);
|
const arr = useSelector((state) => state.TourSteps);
|
||||||
|
const [isUserValid, setIsUserValid] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
// Use the session token to validate the user
|
||||||
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
|
const user = await userQuery.get(Parse.User.current().id, {
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
setIsUserValid(true);
|
||||||
|
} else {
|
||||||
|
setIsUserValid(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Session token is invalid or there was an error
|
||||||
|
setIsUserValid(false);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
// reactour state
|
// reactour state
|
||||||
const [isCloseBtn, setIsCloseBtn] = useState(true);
|
const [isCloseBtn, setIsCloseBtn] = useState(true);
|
||||||
@@ -19,7 +44,7 @@ const HomeLayout = ({ children }) => {
|
|||||||
const [tourConfigs, setTourConfigs] = useState([]);
|
const [tourConfigs, setTourConfigs] = useState([]);
|
||||||
|
|
||||||
const showSidebar = () => {
|
const showSidebar = () => {
|
||||||
setIsOpen(value => !value);
|
setIsOpen((value) => !value);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (width && width <= 768) {
|
if (width && width <= 768) {
|
||||||
@@ -28,9 +53,7 @@ const HomeLayout = ({ children }) => {
|
|||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("domain") === "sign" && arr && arr.length > 0) {
|
if (
|
||||||
handleDynamicSteps();
|
|
||||||
} else if (
|
|
||||||
localStorage.getItem("domain") === "contracts" &&
|
localStorage.getItem("domain") === "contracts" &&
|
||||||
arr &&
|
arr &&
|
||||||
arr.length > 0
|
arr.length > 0
|
||||||
@@ -153,11 +176,24 @@ const HomeLayout = ({ children }) => {
|
|||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleLoginBtn = () => {
|
||||||
|
try {
|
||||||
|
Parse.User.logOut();
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
} finally {
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
navigate("/", { replace: true });
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="sticky top-0 z-50">
|
<div className="sticky top-0 z-50">
|
||||||
<Header showSidebar={showSidebar} />
|
<Header showSidebar={showSidebar} />
|
||||||
</div>
|
</div>
|
||||||
|
{isUserValid ? (
|
||||||
|
<>
|
||||||
<div className="flex md:flex-row flex-col z-50">
|
<div className="flex md:flex-row flex-col z-50">
|
||||||
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
|
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
|
||||||
|
|
||||||
@@ -179,6 +215,20 @@ const HomeLayout = ({ children }) => {
|
|||||||
rounded={5}
|
rounded={5}
|
||||||
showCloseButton={isCloseBtn}
|
showCloseButton={isCloseBtn}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<ModalUi title={"Session Expired"} isOpen={true} showClose={false}>
|
||||||
|
<div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5">
|
||||||
|
<p className="text-xl font-normal">Your session has expired.</p>
|
||||||
|
<button
|
||||||
|
onClick={handleLoginBtn}
|
||||||
|
className="text-base px-3 py-1.5 rounded shadow-md text-white bg-[#1ab6ce]"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Alert = ({ children, type }) => {
|
||||||
|
const textcolor = type ? theme(type) : theme();
|
||||||
|
function theme(color) {
|
||||||
|
switch (color) {
|
||||||
|
case "success":
|
||||||
|
return "border-[#c3e6cb] bg-[#d4edda] text-[#155724]";
|
||||||
|
case "info":
|
||||||
|
return "border-[#adcdeb] bg-[#c1daf0] text-[#153756]";
|
||||||
|
case "danger":
|
||||||
|
return "border-[#f0a8a8] bg-[#f4bebe] text-[#c42121]";
|
||||||
|
default:
|
||||||
|
return "border-[#d6d6d6] bg-[#d9d9d9] text-[#575757]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children && (
|
||||||
|
<div
|
||||||
|
className={`z-40 fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm ${textcolor} rounded py-[.75rem] px-[1.25rem] `}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Alert;
|
||||||
@@ -3,6 +3,8 @@ import pad from "../assets/images/pad.svg";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import "../styles/report.css";
|
import "../styles/report.css";
|
||||||
|
import ModalUi from "./ModalUi";
|
||||||
|
import AppendFormInForm from "../components/AppendFormInForm";
|
||||||
const ReportTable = ({
|
const ReportTable = ({
|
||||||
ReportName,
|
ReportName,
|
||||||
List,
|
List,
|
||||||
@@ -11,13 +13,19 @@ const ReportTable = ({
|
|||||||
heading,
|
heading,
|
||||||
setIsNextRecord,
|
setIsNextRecord,
|
||||||
isMoreDocs,
|
isMoreDocs,
|
||||||
docPerPage
|
docPerPage,
|
||||||
|
form
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [actLoader, setActLoader] = useState({});
|
const [actLoader, setActLoader] = useState({});
|
||||||
const [isAlert, setIsAlert] = useState(false);
|
const [isAlert, setIsAlert] = useState(false);
|
||||||
const [isErr, setIsErr] = useState(false);
|
const [isErr, setIsErr] = useState(false);
|
||||||
|
const [isDocErr, setIsDocErr] = useState(false);
|
||||||
|
const [isContactform, setIsContactform] = useState(false);
|
||||||
|
const [isDeleteModal, setIsDeleteModal] = useState({});
|
||||||
|
const startIndex = (currentPage - 1) * docPerPage;
|
||||||
|
|
||||||
// For loop is used to calculate page numbers visible below table
|
// For loop is used to calculate page numbers visible below table
|
||||||
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
|
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
|
||||||
const pageNumbers = useMemo(() => {
|
const pageNumbers = useMemo(() => {
|
||||||
@@ -55,14 +63,151 @@ const ReportTable = ({
|
|||||||
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
||||||
|
|
||||||
// `handlemicroapp` is used to open microapp
|
// `handlemicroapp` is used to open microapp
|
||||||
const handlemicroapp = (item, url) => {
|
const handlemicroapp = async (item, url, btnLabel) => {
|
||||||
|
if (ReportName === "Templates") {
|
||||||
|
if (btnLabel === "Edit") {
|
||||||
|
navigate(`/asmf/${url}/${item.objectId}`);
|
||||||
|
} else {
|
||||||
|
setActLoader({ [`${item.objectId}_${btnLabel}`]: true });
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
templateId: item.objectId
|
||||||
|
};
|
||||||
|
const templateDeatils = await axios.post(
|
||||||
|
`${localStorage.getItem("baseUrl")}functions/getTemplate`,
|
||||||
|
params,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// console.log("templateDeatils.data ", templateDeatils.data);
|
||||||
|
const templateData =
|
||||||
|
templateDeatils.data && templateDeatils.data.result;
|
||||||
|
if (!templateData.error) {
|
||||||
|
const Doc = templateData;
|
||||||
|
|
||||||
|
let signers = [];
|
||||||
|
if (Doc.Signers?.length > 0) {
|
||||||
|
Doc.Signers?.forEach((x) => {
|
||||||
|
if (x.objectId) {
|
||||||
|
const obj = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Contactbook",
|
||||||
|
objectId: x.objectId
|
||||||
|
};
|
||||||
|
signers.push(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let placeholdersArr = [];
|
||||||
|
if (Doc.Placeholders?.length > 0) {
|
||||||
|
placeholdersArr = Doc.Placeholders;
|
||||||
|
const data = {
|
||||||
|
Name: Doc.Name,
|
||||||
|
URL: Doc.URL,
|
||||||
|
SignedUrl: Doc.SignedUrl,
|
||||||
|
Description: Doc.Description,
|
||||||
|
Note: Doc.Note,
|
||||||
|
Placeholders: placeholdersArr,
|
||||||
|
ExtUserPtr: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Users",
|
||||||
|
objectId: Doc.ExtUserPtr.objectId
|
||||||
|
},
|
||||||
|
CreatedBy: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: Doc.CreatedBy.objectId
|
||||||
|
},
|
||||||
|
Signers: signers
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(
|
||||||
|
`${localStorage.getItem(
|
||||||
|
"baseUrl"
|
||||||
|
)}classes/${localStorage.getItem("_appName")}_Document`,
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id":
|
||||||
|
localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token":
|
||||||
|
localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// console.log("Res ", res.data);
|
||||||
|
if (res.data && res.data.objectId) {
|
||||||
|
setActLoader({});
|
||||||
|
setIsAlert(true);
|
||||||
|
navigate(`/asmf/${url}/${res.data.objectId}`, {
|
||||||
|
state: { title: "Use Template" }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err", err);
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsDocErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err", err);
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
localStorage.removeItem("rowlevel");
|
localStorage.removeItem("rowlevel");
|
||||||
navigate("/rpmf/" + url);
|
navigate("/rpmf/" + url);
|
||||||
localStorage.setItem("rowlevel", JSON.stringify(item));
|
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||||
|
}
|
||||||
|
|
||||||
// localStorage.setItem("rowlevelMicro");
|
// localStorage.setItem("rowlevelMicro");
|
||||||
};
|
};
|
||||||
const handlebtn = async (item) => {
|
const handlebtn = async (item) => {
|
||||||
if (ReportName === "Contactbook") {
|
if (ReportName === "Contactbook") {
|
||||||
|
setIsDeleteModal({ [item.objectId]: true });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get current list
|
||||||
|
const indexOfLastDoc = currentPage * docPerPage;
|
||||||
|
const indexOfFirstDoc = indexOfLastDoc - docPerPage;
|
||||||
|
// `currentLists` is total record render on current page
|
||||||
|
const currentLists = List.slice(indexOfFirstDoc, indexOfLastDoc);
|
||||||
|
|
||||||
|
// Change page
|
||||||
|
const paginateFront = () => setCurrentPage(currentPage + 1);
|
||||||
|
const paginateBack = () => setCurrentPage(currentPage - 1);
|
||||||
|
|
||||||
|
const handleContactFormModal = () => {
|
||||||
|
setIsContactform(!isContactform);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUserData = (data) => {
|
||||||
|
setList((prevData) => [data, ...prevData]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = async (item) => {
|
||||||
|
setIsDeleteModal({});
|
||||||
setActLoader({ [item.objectId]: true });
|
setActLoader({ [item.objectId]: true });
|
||||||
try {
|
try {
|
||||||
const url =
|
const url =
|
||||||
@@ -88,18 +233,8 @@ const ReportTable = ({
|
|||||||
setIsErr(true);
|
setIsErr(true);
|
||||||
setActLoader({});
|
setActLoader({});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
const handleCloseDeleteModal = () => setIsDeleteModal({});
|
||||||
// Get current list
|
|
||||||
const indexOfLastDoc = currentPage * docPerPage;
|
|
||||||
const indexOfFirstDoc = indexOfLastDoc - docPerPage;
|
|
||||||
// `currentLists` is total record render on current page
|
|
||||||
const currentLists = List.slice(indexOfFirstDoc, indexOfLastDoc);
|
|
||||||
|
|
||||||
// Change page
|
|
||||||
const paginateFront = () => setCurrentPage(currentPage + 1);
|
|
||||||
const paginateBack = () => setCurrentPage(currentPage - 1);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
||||||
@@ -115,7 +250,23 @@ const ReportTable = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
||||||
|
<div className="font-light">{ReportName}</div>
|
||||||
|
{ReportName === "Templates" && (
|
||||||
|
<i
|
||||||
|
onClick={() => navigate("/form/template")}
|
||||||
|
className="fa-solid fa-square-plus text-sky-400 text-[25px]"
|
||||||
|
></i>
|
||||||
|
)}
|
||||||
|
{form && (
|
||||||
|
<div
|
||||||
|
className="cursor-pointer"
|
||||||
|
onClick={() => handleContactFormModal()}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-square-plus text-sky-400 text-[25px]"></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<table className="table-auto w-full border-collapse">
|
<table className="table-auto w-full border-collapse">
|
||||||
<thead className="text-[14px]">
|
<thead className="text-[14px]">
|
||||||
<tr className="border-y-[1px]">
|
<tr className="border-y-[1px]">
|
||||||
@@ -135,11 +286,13 @@ const ReportTable = ({
|
|||||||
{currentLists.map((item, index) =>
|
{currentLists.map((item, index) =>
|
||||||
ReportName === "Contactbook" ? (
|
ReportName === "Contactbook" ? (
|
||||||
<tr className="border-y-[1px]" key={index}>
|
<tr className="border-y-[1px]" key={index}>
|
||||||
<td className="px-4 py-2">{index + 1}</td>
|
{heading.includes("Sr.No") && (
|
||||||
|
<td className="px-4 py-2">{startIndex + index + 1}</td>
|
||||||
|
)}
|
||||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||||
<td className="px-4 py-2">{item?.Email || "-"}</td>
|
<td className="px-4 py-2">{item?.Email || "-"}</td>
|
||||||
<td className="px-4 py-2">{item?.Phone || "-"}</td>
|
<td className="px-4 py-2">{item?.Phone || "-"}</td>
|
||||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
<td className="px-3 py-2 text-white">
|
||||||
{actions?.length > 0 &&
|
{actions?.length > 0 &&
|
||||||
actions.map((act, index) => (
|
actions.map((act, index) => (
|
||||||
<button
|
<button
|
||||||
@@ -149,7 +302,7 @@ const ReportTable = ({
|
|||||||
? handlemicroapp(item, act.redirectUrl)
|
? handlemicroapp(item, act.redirectUrl)
|
||||||
: handlebtn(item)
|
: handlebtn(item)
|
||||||
}
|
}
|
||||||
className={`flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
className={`mb-1 flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: act.btnColor
|
backgroundColor: act.btnColor
|
||||||
? act.btnColor
|
? act.btnColor
|
||||||
@@ -175,16 +328,52 @@ const ReportTable = ({
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
{isDeleteModal[item.objectId] && (
|
||||||
|
<ModalUi
|
||||||
|
isOpen
|
||||||
|
title={"Delete Contact"}
|
||||||
|
handleClose={handleCloseDeleteModal}
|
||||||
|
>
|
||||||
|
<div className="m-[20px]">
|
||||||
|
<div className="text-lg font-normal text-black">
|
||||||
|
Are you sure you want to delete this contact?
|
||||||
|
</div>
|
||||||
|
<hr className="bg-[#ccc] mt-4 " />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
onClick={() => handleDelete(item)}
|
||||||
|
className="bg-[#1ab6ce] rounded-sm shadow-md text-[12px] font-semibold uppercase text-white py-1.5 px-3 focus:outline-none"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleCloseDeleteModal}
|
||||||
|
className="bg-[#188ae2] rounded-sm shadow-md text-[12px] font-semibold uppercase text-white py-1.5 px-3 text-center ml-[2px] focus:outline-none"
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
<tr className="border-y-[1px]" key={index}>
|
<tr className="border-y-[1px]" key={index}>
|
||||||
<td className="px-4 py-2">{index + 1}</td>
|
{heading.includes("Sr.No") && (
|
||||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
<td className="px-4 py-2">{startIndex + index + 1}</td>
|
||||||
|
)}
|
||||||
|
<td className="px-4 py-2 font-semibold w-56">
|
||||||
|
{item?.Name}{" "}
|
||||||
|
</td>
|
||||||
|
{heading.includes("Note") && (
|
||||||
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
||||||
|
)}
|
||||||
|
{heading.includes("Folder") && (
|
||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2">
|
||||||
{item?.Folder?.Name || "OpenSignDrive"}
|
{item?.Folder?.Name || "OpenSignDrive"}
|
||||||
</td>
|
</td>
|
||||||
|
)}
|
||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2">
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -202,17 +391,21 @@ const ReportTable = ({
|
|||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2">
|
||||||
{item?.Signers ? formatRow(item?.Signers) : "-"}
|
{item?.Signers ? formatRow(item?.Signers) : "-"}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
<td className="px-3 py-2 text-white">
|
||||||
{actions?.length > 0 &&
|
{actions?.length > 0 &&
|
||||||
actions.map((act, index) => (
|
actions.map((act, index) => (
|
||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
act?.redirectUrl
|
act?.redirectUrl
|
||||||
? handlemicroapp(item, act.redirectUrl)
|
? handlemicroapp(
|
||||||
|
item,
|
||||||
|
act.redirectUrl,
|
||||||
|
act.btnLabel
|
||||||
|
)
|
||||||
: handlebtn(item)
|
: handlebtn(item)
|
||||||
}
|
}
|
||||||
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
className={`mb-1 flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: act.btnColor
|
backgroundColor: act.btnColor
|
||||||
? act.btnColor
|
? act.btnColor
|
||||||
@@ -224,7 +417,9 @@ const ReportTable = ({
|
|||||||
{act?.btnIcon && (
|
{act?.btnIcon && (
|
||||||
<i
|
<i
|
||||||
className={
|
className={
|
||||||
actLoader[item.objectId]
|
actLoader[
|
||||||
|
`${item.objectId}_${act.btnLabel}`
|
||||||
|
]
|
||||||
? "fa-solid fa-spinner fa-spin-pulse"
|
? "fa-solid fa-spinner fa-spin-pulse"
|
||||||
: act.btnIcon
|
: act.btnIcon
|
||||||
}
|
}
|
||||||
@@ -235,7 +430,6 @@ const ReportTable = ({
|
|||||||
{act?.btnLabel ? act.btnLabel : "view"}
|
{act?.btnLabel ? act.btnLabel : "view"}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
// )
|
|
||||||
))}
|
))}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -293,6 +487,26 @@ const ReportTable = ({
|
|||||||
<div className="text-sm font-semibold">No Data Available</div>
|
<div className="text-sm font-semibold">No Data Available</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<ModalUi
|
||||||
|
title={"Add Contact"}
|
||||||
|
isOpen={isContactform}
|
||||||
|
handleClose={handleContactFormModal}
|
||||||
|
>
|
||||||
|
<AppendFormInForm
|
||||||
|
handleUserData={handleUserData}
|
||||||
|
closePopup={handleContactFormModal}
|
||||||
|
/>
|
||||||
|
</ModalUi>
|
||||||
|
<ModalUi
|
||||||
|
headColor={"#dc3545"}
|
||||||
|
isOpen={isDocErr}
|
||||||
|
title={"Receipent required"}
|
||||||
|
handleClose={() => setIsDocErr(false)}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>Please add receipent in template!</p>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
const Modal = ({ children, Title }) => {
|
||||||
|
const [isOpen, SetIsOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children && (
|
||||||
|
<div
|
||||||
|
className={`fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm bg-white rounded `}
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-center py-[.75rem] px-[1.25rem] ">
|
||||||
|
<div className="font-semibold text-xl text-black">{Title}</div>
|
||||||
|
<div
|
||||||
|
onClick={() => SetIsOpen()}
|
||||||
|
className="px-2 py-1 bg-gray-400 rounded cursor-pointer"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-xmark"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
{isOpen && <div>{children}</div>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Modal;
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import React from "react";
|
||||||
|
const ModalUi = ({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
isOpen,
|
||||||
|
headColor,
|
||||||
|
handleClose,
|
||||||
|
showHeader = true,
|
||||||
|
showClose = true
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isOpen && (
|
||||||
|
<div className="fixed z-[999] top-0 left-0 w-[100%] h-[100%] bg-black bg-opacity-[75%]">
|
||||||
|
<div className="fixed z-[1000] top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-sm bg-white rounded shadow-md max-h-90 min-w-[90%] md:min-w-[500px] overflow-y-auto hide-scrollbar">
|
||||||
|
{showHeader && (
|
||||||
|
<div
|
||||||
|
className="flex justify-between rounded-t items-center py-[15px] px-[20px] text-white"
|
||||||
|
style={{ background: headColor ? headColor : "#32a3ac" }}
|
||||||
|
>
|
||||||
|
<div className="text-[1.2rem] font-normal">{title}</div>
|
||||||
|
{showClose && (
|
||||||
|
<div
|
||||||
|
className="text-[1.5rem] cursor-pointer"
|
||||||
|
onClick={() => handleClose && handleClose()}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div>{children}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalUi;
|
||||||
@@ -0,0 +1,336 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import sanitizeFileName from "./sanitizeFileName";
|
||||||
|
import Parse from "parse";
|
||||||
|
import DropboxChooser from "../components/fields/DropboxChoose";
|
||||||
|
import Alert from "./Alert";
|
||||||
|
import SelectFolder from "../components/fields/SelectFolder";
|
||||||
|
// import SignersInput from "../components/fields/SignersInput";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { templateCls } from "../constant/const";
|
||||||
|
|
||||||
|
const TemplateForm = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [signers, setSigners] = useState([]);
|
||||||
|
const [folder, setFolder] = useState({ ObjectId: "", Name: "" });
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
Name: "",
|
||||||
|
Description: "",
|
||||||
|
Note: "Please review and sign this document"
|
||||||
|
});
|
||||||
|
const [fileupload, setFileUpload] = useState([]);
|
||||||
|
const [fileload, setfileload] = useState(false);
|
||||||
|
const [percentage, setpercentage] = useState(0);
|
||||||
|
const [isAlert, setIsAlert] = useState(false);
|
||||||
|
const [isSubmit, setIsSubmit] = useState(false);
|
||||||
|
const [isErr, setIsErr] = useState("");
|
||||||
|
const handleStrInput = (e) => {
|
||||||
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileInput = (e) => {
|
||||||
|
setpercentage(0);
|
||||||
|
try {
|
||||||
|
let files = e.target.files;
|
||||||
|
if (typeof files[0] !== "undefined") {
|
||||||
|
const mb = Math.round(files[0].bytes / Math.pow(1024, 2));
|
||||||
|
if (mb > 10) {
|
||||||
|
alert(
|
||||||
|
`The selected file size is too large. Please select a file less than ${Math.round(
|
||||||
|
10
|
||||||
|
)} MB`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFileUpload(files[0]);
|
||||||
|
} else {
|
||||||
|
alert("Please select file.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
alert(error.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileUpload = async (file) => {
|
||||||
|
Parse.serverURL = process.env.REACT_APP_SERVERURL;
|
||||||
|
Parse.initialize(process.env.REACT_APP_APPID);
|
||||||
|
setfileload(true);
|
||||||
|
const fileName = file.name;
|
||||||
|
const name = sanitizeFileName(fileName);
|
||||||
|
const pdfFile = file;
|
||||||
|
const parseFile = new Parse.File(name, pdfFile);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await parseFile.save({
|
||||||
|
progress: (progressValue, loaded, total, { type }) => {
|
||||||
|
if (type === "upload" && progressValue !== null) {
|
||||||
|
const percentCompleted = Math.round((loaded * 100) / total);
|
||||||
|
setpercentage(percentCompleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The response object will contain information about the uploaded file
|
||||||
|
// You can access the URL of the uploaded file using response.url()
|
||||||
|
setFileUpload(response.url());
|
||||||
|
setfileload(false);
|
||||||
|
if (response.url()) {
|
||||||
|
return response.url();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setfileload(false);
|
||||||
|
setpercentage(0);
|
||||||
|
console.error("Error uploading file:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const dropboxSuccess = async (files) => {
|
||||||
|
setfileload(true);
|
||||||
|
const file = files[0];
|
||||||
|
const url = file.link;
|
||||||
|
const mb = Math.round(file.bytes / Math.pow(1024, 2));
|
||||||
|
|
||||||
|
if (mb > 10) {
|
||||||
|
setTimeout(() => {
|
||||||
|
alert(
|
||||||
|
`The selected file size is too large. Please select a file less than 10 MB`
|
||||||
|
);
|
||||||
|
}, 500);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
const name = sanitizeFileName(file.name);
|
||||||
|
|
||||||
|
const parseFile = new Parse.File(name, { uri: url });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await parseFile.save({
|
||||||
|
progress: (progressValue, loaded, total, { type }) => {
|
||||||
|
if (type === "upload" && progressValue !== null) {
|
||||||
|
const percentCompleted = Math.round((loaded * 100) / total);
|
||||||
|
setpercentage(percentCompleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setFileUpload(response.url());
|
||||||
|
setfileload(false);
|
||||||
|
|
||||||
|
if (response.url()) {
|
||||||
|
return response.url();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setfileload(false);
|
||||||
|
setpercentage(0);
|
||||||
|
console.error("Error uploading file:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const dropboxCancel = async () => {};
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsSubmit(true);
|
||||||
|
try {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const template = new Parse.Object(templateCls);
|
||||||
|
Object.entries(formData).forEach((item) =>
|
||||||
|
template.set(item[0], item[1])
|
||||||
|
);
|
||||||
|
template.set("URL", fileupload);
|
||||||
|
template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||||
|
if (folder && folder.ObjectId) {
|
||||||
|
template.set("Folder", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: templateCls,
|
||||||
|
objectId: folder.ObjectId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
template.set("Signers", signers);
|
||||||
|
}
|
||||||
|
const ExtCls = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||||
|
template.set("ExtUserPtr", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Users",
|
||||||
|
objectId: ExtCls[0].objectId
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await template.save();
|
||||||
|
if (res) {
|
||||||
|
setSigners([]);
|
||||||
|
setFolder({ ObjectId: "", Name: "" });
|
||||||
|
setFormData({
|
||||||
|
Name: "",
|
||||||
|
Description: "",
|
||||||
|
Note: ""
|
||||||
|
});
|
||||||
|
setFileUpload([]);
|
||||||
|
setpercentage(0);
|
||||||
|
navigate(
|
||||||
|
"/asmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/template/" +
|
||||||
|
res.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
setIsErr(true);
|
||||||
|
} finally {
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
setIsSubmit(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFolder = (data) => {
|
||||||
|
setFolder(data);
|
||||||
|
};
|
||||||
|
// const handleSigners = (data) => {
|
||||||
|
// if (data && data.length > 0) {
|
||||||
|
// const updateSigners = data.map((x) => ({
|
||||||
|
// __type: "Pointer",
|
||||||
|
// className: "contracts_Contactbook",
|
||||||
|
// objectId: x
|
||||||
|
// }));
|
||||||
|
// setSigners(updateSigners);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
setSigners([]);
|
||||||
|
setFolder({ ObjectId: "", Name: "" });
|
||||||
|
setFormData({
|
||||||
|
Name: "",
|
||||||
|
Description: "",
|
||||||
|
Note: ""
|
||||||
|
});
|
||||||
|
setFileUpload([]);
|
||||||
|
setpercentage(0);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="shadow-md rounded my-2 p-3 bg-[#ffffff] md:border-[1px] md:border-gray-600/50">
|
||||||
|
<Title title="New Template" />
|
||||||
|
{isAlert && (
|
||||||
|
<Alert type={isErr ? "danger" : "success"}>
|
||||||
|
{isErr
|
||||||
|
? "Something went wrong please try again!"
|
||||||
|
: "Template created successfully!"}
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<h1 className="text-[20px] font-semibold mb-4">New Template</h1>
|
||||||
|
{fileload && (
|
||||||
|
<div className="flex items-center gap-x-2">
|
||||||
|
<div className="h-2 rounded-full w-[200px] md:w-[400px] bg-gray-200">
|
||||||
|
<div
|
||||||
|
className="h-2 rounded-full bg-blue-500"
|
||||||
|
style={{ width: `${percentage}%` }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<span className="text-black text-sm">{percentage}%</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="text-xs">
|
||||||
|
<label className="block">
|
||||||
|
File<span className="text-red-500 text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
{fileupload.length > 0 ? (
|
||||||
|
<div className="flex gap-2 justify-center items-center">
|
||||||
|
<div className="flex justify-between items-center px-2 py-2 w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]">
|
||||||
|
<div className="break-all">
|
||||||
|
file selected : {fileupload?.split("/")[3]?.split("_")[1]}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setFileUpload([]);
|
||||||
|
}}
|
||||||
|
className="cursor-pointer px-[10px] text-[20px] font-bold bg-white text-red-500"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-xmark"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{process.env.REACT_APP_DROPBOX_API_KEY && (
|
||||||
|
<DropboxChooser
|
||||||
|
onSuccess={dropboxSuccess}
|
||||||
|
onCancel={dropboxCancel}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex gap-2 justify-center items-center">
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="bg-white px-2 py-1.5 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
onChange={(e) => handleFileInput(e)}
|
||||||
|
accept="application/pdf,application/vnd.ms-excel"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
{process.env.REACT_APP_DROPBOX_API_KEY && (
|
||||||
|
<DropboxChooser
|
||||||
|
onSuccess={dropboxSuccess}
|
||||||
|
onCancel={dropboxCancel}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">
|
||||||
|
Title<span className="text-red-500 text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
name="Name"
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
value={formData.Name}
|
||||||
|
onChange={(e) => handleStrInput(e)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">
|
||||||
|
Note<span className="text-red-500 text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
name="Note"
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
value={formData.Note}
|
||||||
|
onChange={(e) => handleStrInput(e)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">Description</label>
|
||||||
|
<input
|
||||||
|
name="Description"
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
value={formData.Description}
|
||||||
|
onChange={(e) => handleStrInput(e)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* <SignersInput onChange={handleSigners} /> */}
|
||||||
|
<SelectFolder onSuccess={handleFolder} folderCls={templateCls} />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
className={`${
|
||||||
|
isSubmit && "cursor-progress"
|
||||||
|
} bg-[#1ab6ce] rounded-sm shadow-md text-[14px] font-semibold uppercase text-white py-1.5 px-2.5 focus:outline-none`}
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmit}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
className="bg-[#188ae2] rounded-sm shadow-md text-[14px] font-semibold uppercase text-white py-1.5 px-2.5 text-center ml-[2px] focus:outline-none"
|
||||||
|
onClick={() => handleReset()}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TemplateForm;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
|
||||||
|
const ValidateRoute = ({ children }) => {
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
// Use the session token to validate the user
|
||||||
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
|
const user = await userQuery.get(Parse.User.current().id, {
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
});
|
||||||
|
if (!user) {
|
||||||
|
handlelogout();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
handlelogout();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
const handlelogout = async () => {
|
||||||
|
try {
|
||||||
|
Parse.User.logOut();
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
} finally {
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return <div>{children}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ValidateRoute;
|
||||||
@@ -25,6 +25,7 @@ import TreeWidget from "../components/TreeWidget";
|
|||||||
import parse from "html-react-parser";
|
import parse from "html-react-parser";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import { formJson } from "../json/FormJson";
|
import { formJson } from "../json/FormJson";
|
||||||
|
import TemplateForm from "../primitives/TemplateForm";
|
||||||
const widget = {
|
const widget = {
|
||||||
TimeWidget: TimeWidget
|
TimeWidget: TimeWidget
|
||||||
};
|
};
|
||||||
@@ -41,6 +42,9 @@ const fields = () => {
|
|||||||
function FormBuilderFn(props) {
|
function FormBuilderFn(props) {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
if (id === "template") {
|
||||||
|
return <TemplateForm />;
|
||||||
|
} else {
|
||||||
return (
|
return (
|
||||||
<FormBuilder
|
<FormBuilder
|
||||||
removeState={props.removeState}
|
removeState={props.removeState}
|
||||||
@@ -51,6 +55,7 @@ function FormBuilderFn(props) {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
class FormBuilder extends Component {
|
class FormBuilder extends Component {
|
||||||
state = {
|
state = {
|
||||||
schema: {},
|
schema: {},
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ const PgSignUp = (props) => {
|
|||||||
const res = await Parse.Cloud.run("getUserDetails", params);
|
const res = await Parse.Cloud.run("getUserDetails", params);
|
||||||
// console.log("res", res);
|
// console.log("res", res);
|
||||||
if (res) {
|
if (res) {
|
||||||
const checkUser = new Parse.Query(extClass);
|
const updateQuery = new Parse.Object(extClass);
|
||||||
const updateQuery = await checkUser.get(res.id);
|
updateQuery.id = res.id;
|
||||||
updateQuery.set(
|
updateQuery.set(
|
||||||
"Next_billing_date",
|
"Next_billing_date",
|
||||||
new Date(zohoRes.data.result.nextBillingDate)
|
new Date(zohoRes.data.result.nextBillingDate)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const Report = () => {
|
|||||||
const [heading, setHeading] = useState([]);
|
const [heading, setHeading] = useState([]);
|
||||||
const [isNextRecord, setIsNextRecord] = useState(false);
|
const [isNextRecord, setIsNextRecord] = useState(false);
|
||||||
const [isMoreDocs, setIsMoreDocs] = useState(true);
|
const [isMoreDocs, setIsMoreDocs] = useState(true);
|
||||||
|
const [form, setForm]= useState("")
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const docPerPage = 10;
|
const docPerPage = 10;
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ const Report = () => {
|
|||||||
setActions(json.actions);
|
setActions(json.actions);
|
||||||
setHeading(json.heading);
|
setHeading(json.heading);
|
||||||
setReportName(json.reportName);
|
setReportName(json.reportName);
|
||||||
|
setForm(json.form)
|
||||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||||
Parse.initialize(localStorage.getItem("AppID12"));
|
Parse.initialize(localStorage.getItem("AppID12"));
|
||||||
const currentUser = Parse.User.current().id;
|
const currentUser = Parse.User.current().id;
|
||||||
@@ -154,6 +156,7 @@ const Report = () => {
|
|||||||
setIsNextRecord={setIsNextRecord}
|
setIsNextRecord={setIsNextRecord}
|
||||||
isMoreDocs={isMoreDocs}
|
isMoreDocs={isMoreDocs}
|
||||||
docPerPage={docPerPage}
|
docPerPage={docPerPage}
|
||||||
|
form={form}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||||
|
|||||||
@@ -2211,7 +2211,5 @@
|
|||||||
background-position: -2em 0;
|
background-position: -2em 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.box:nth-of-type(n + 43) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -17,6 +17,8 @@ import getUserDetails from './parsefunction/getUserDetails.js';
|
|||||||
import getDocument from './parsefunction/getDocument.js';
|
import getDocument from './parsefunction/getDocument.js';
|
||||||
import getDrive from './parsefunction/getDrive.js';
|
import getDrive from './parsefunction/getDrive.js';
|
||||||
import getReport from './parsefunction/getReport.js';
|
import getReport from './parsefunction/getReport.js';
|
||||||
|
import TemplateAfterSave from './parsefunction/TemplateAfterSave.js';
|
||||||
|
import GetTemplate from './parsefunction/GetTemplate.js';
|
||||||
|
|
||||||
Parse.Cloud.define('AddUserToRole', addUserToGroups);
|
Parse.Cloud.define('AddUserToRole', addUserToGroups);
|
||||||
Parse.Cloud.define('UserGroups', getUserGroups);
|
Parse.Cloud.define('UserGroups', getUserGroups);
|
||||||
@@ -26,9 +28,6 @@ Parse.Cloud.define('googlesign', GoogleSign);
|
|||||||
Parse.Cloud.define('zohodetails', ZohoDetails);
|
Parse.Cloud.define('zohodetails', ZohoDetails);
|
||||||
Parse.Cloud.define('usersignup', usersignup);
|
Parse.Cloud.define('usersignup', usersignup);
|
||||||
Parse.Cloud.define('facebooksign', FacebookSign);
|
Parse.Cloud.define('facebooksign', FacebookSign);
|
||||||
Parse.Cloud.afterSave('contracts_Document', DocumentAftersave);
|
|
||||||
Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave);
|
|
||||||
Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave);
|
|
||||||
Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1);
|
Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1);
|
||||||
Parse.Cloud.define('sendmail', SendMailv1);
|
Parse.Cloud.define('sendmail', SendMailv1);
|
||||||
Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
|
Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
|
||||||
@@ -37,3 +36,8 @@ Parse.Cloud.define('getUserDetails', getUserDetails);
|
|||||||
Parse.Cloud.define('getDocument', getDocument);
|
Parse.Cloud.define('getDocument', getDocument);
|
||||||
Parse.Cloud.define('getDrive', getDrive)
|
Parse.Cloud.define('getDrive', getDrive)
|
||||||
Parse.Cloud.define('getReport', getReport)
|
Parse.Cloud.define('getReport', getReport)
|
||||||
|
Parse.Cloud.define("getTemplate", GetTemplate)
|
||||||
|
Parse.Cloud.afterSave('contracts_Document', DocumentAftersave);
|
||||||
|
Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave);
|
||||||
|
Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave);
|
||||||
|
Parse.Cloud.afterSave("contracts_Template", TemplateAfterSave)
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export default async function GetTemplate(request) {
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
const templateId = request.params.templateId;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
|
// console.log("templateId ", templateId)
|
||||||
|
// console.log("userId ",userId)
|
||||||
|
if (templateId && userId) {
|
||||||
|
try {
|
||||||
|
const template = new Parse.Query('contracts_Template');
|
||||||
|
template.equalTo('objectId', templateId);
|
||||||
|
template.include('ExtUserPtr');
|
||||||
|
template.include('Signers');
|
||||||
|
template.include('CreateBy');
|
||||||
|
const res = await template.first({ useMasterKey: true });
|
||||||
|
// console.log("res ", res)
|
||||||
|
if (res) {
|
||||||
|
// console.log("res ",res)
|
||||||
|
const acl = res.getACL();
|
||||||
|
console.log("acl", acl.getReadAccess(userId))
|
||||||
|
if (acl && acl.getReadAccess(userId)) {
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return { error: "You don't have access of this document!" };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { error: "You don't have access of this document!" };
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err', err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { error: 'Please pass required parameters!' };
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err', err);
|
||||||
|
if (err.code == 209) {
|
||||||
|
return { error: 'Invalid session token' };
|
||||||
|
} else {
|
||||||
|
return { error: "You don't have access of this document!" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
export default async function TemplateAfterSave(request) {
|
||||||
|
try {
|
||||||
|
if (!request.original) {
|
||||||
|
console.log('new entry is insert in contracts_Template');
|
||||||
|
// update acl of New Document If There are signers present in array
|
||||||
|
const signers = request.object.get('Signers');
|
||||||
|
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
await updateAclDoc(request.object.id);
|
||||||
|
} else {
|
||||||
|
await updateSelfDoc(request.object.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.user) {
|
||||||
|
const signers = request.object.get('Signers');
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
await updateAclDoc(request.object.id);
|
||||||
|
} else {
|
||||||
|
await updateSelfDoc(request.object.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err in aftersave of contracts_Template');
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateAclDoc(objId) {
|
||||||
|
// console.log("In side updateAclDoc func")
|
||||||
|
// console.log(objId)
|
||||||
|
const Query = new Parse.Query('contracts_Template');
|
||||||
|
Query.include('Signers');
|
||||||
|
const updateACL = await Query.get(objId, { useMasterKey: true });
|
||||||
|
const res = JSON.parse(JSON.stringify(updateACL));
|
||||||
|
// console.log("res");
|
||||||
|
// console.log(JSON.stringify(res));
|
||||||
|
const UsersPtr = res.Signers.map(item => item.UserId);
|
||||||
|
|
||||||
|
if (res.Signers[0].ExtUserPtr) {
|
||||||
|
const ExtUserSigners = res.Signers.map(item => {
|
||||||
|
return {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Users',
|
||||||
|
objectId: item.ExtUserPtr.objectId,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
updateACL.set('Signers', ExtUserSigners);
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("UsersPtr")
|
||||||
|
// console.log(JSON.stringify(UsersPtr))
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(request.user, true);
|
||||||
|
newACL.setWriteAccess(request.user, true);
|
||||||
|
|
||||||
|
UsersPtr.forEach(x => {
|
||||||
|
newACL.setReadAccess(x.objectId, true);
|
||||||
|
newACL.setWriteAccess(x.objectId, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
updateACL.setACL(newACL);
|
||||||
|
updateACL.save(null, { useMasterKey: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateSelfDoc(objId) {
|
||||||
|
// console.log("Inside updateSelfDoc func")
|
||||||
|
|
||||||
|
const Query = new Parse.Query('contracts_Template');
|
||||||
|
const updateACL = await Query.get(objId, { useMasterKey: true });
|
||||||
|
// const res = JSON.parse(JSON.stringify(updateACL));
|
||||||
|
// console.log("res");
|
||||||
|
// console.log(JSON.stringify(res));
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(request.user, true);
|
||||||
|
newACL.setWriteAccess(request.user, true);
|
||||||
|
updateACL.setACL(newACL);
|
||||||
|
updateACL.save(null, { useMasterKey: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ export default async function getDocument(request) {
|
|||||||
query.include('Signers');
|
query.include('Signers');
|
||||||
query.include('AuditTrail.UserPtr');
|
query.include('AuditTrail.UserPtr');
|
||||||
query.include('Placeholders');
|
query.include('Placeholders');
|
||||||
|
query.notEqualTo('IsArchive', true)
|
||||||
const res = await query.first({ useMasterKey: true });
|
const res = await query.first({ useMasterKey: true });
|
||||||
if (res) {
|
if (res) {
|
||||||
const acl = res.getACL();
|
const acl = res.getACL();
|
||||||
@@ -40,7 +41,7 @@ export default async function getDocument(request) {
|
|||||||
return { error: 'Please pass required parameters!' };
|
return { error: 'Please pass required parameters!' };
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('err');
|
console.log('err', err);
|
||||||
if (err.code == 209) {
|
if (err.code == 209) {
|
||||||
return { error: 'Invalid session token' };
|
return { error: 'Invalid session token' };
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ export default async function getDrive(request) {
|
|||||||
if (userId) {
|
if (userId) {
|
||||||
let url;
|
let url;
|
||||||
if (docId) {
|
if (docId) {
|
||||||
url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&include=ExtUserPtr,Signers,Folder`;
|
url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers,Folder`;
|
||||||
} else {
|
} else {
|
||||||
url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&include=ExtUserPtr,Signers`;
|
url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers`;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(url, {
|
const res = await axios.get(url, {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default async function getReport(request) {
|
|||||||
const userId = userRes.data && userRes.data.objectId;
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
if (userId) {
|
if (userId) {
|
||||||
const json = reportId && reportJson(reportId, userId);
|
const json = reportId && reportJson(reportId, userId);
|
||||||
const clsName = reportId === '5KhaPr482K' ? 'contracts_Contactbook' : 'contracts_Document';
|
const clsName = json?.reportClass ? json.reportClass : 'contracts_Document';
|
||||||
if (json) {
|
if (json) {
|
||||||
const { params, keys } = json;
|
const { params, keys } = json;
|
||||||
const orderBy = '-updatedAt';
|
const orderBy = '-updatedAt';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import SignPDF from './SignPDF.min.cjs';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import plainplaceholder from './customSignPdf/plainplaceholder.min.js';
|
// import plainplaceholder from './customSignPdf/plainplaceholder.min.js';
|
||||||
import { plainAddPlaceholder } from 'node-signpdf/dist/helpers/index.js';
|
import { plainAddPlaceholder } from 'node-signpdf/dist/helpers/index.js';
|
||||||
const serverUrl = process.env.SERVER_URL,
|
const serverUrl = process.env.SERVER_URL,
|
||||||
APPID = process.env.APP_ID,
|
APPID = process.env.APP_ID,
|
||||||
@@ -19,20 +19,20 @@ async function uploadFile(a) {
|
|||||||
console.log('err ', e), fs.unlinkSync(a);
|
console.log('err ', e), fs.unlinkSync(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function updateDoc(t, s, r, i, o, n) {
|
async function updateDoc(t, s, r, i, n, o) {
|
||||||
try {
|
try {
|
||||||
var d = {
|
var d = {
|
||||||
UserPtr: { __type: 'Pointer', className: n, objectId: r },
|
UserPtr: { __type: 'Pointer', className: o, objectId: r },
|
||||||
SignedUrl: s,
|
SignedUrl: s,
|
||||||
Activity: 'Signed',
|
Activity: 'Signed',
|
||||||
ipAddress: i,
|
ipAddress: i,
|
||||||
};
|
};
|
||||||
let e;
|
let e;
|
||||||
var l = (e = o.AuditTrail && 0 < o.AuditTrail.length ? [...o.AuditTrail, d] : [d]).filter(
|
var l = (e = n.AuditTrail && 0 < n.AuditTrail.length ? [...n.AuditTrail, d] : [d]).filter(
|
||||||
e => 'Signed' === e.Activity
|
e => 'Signed' === e.Activity
|
||||||
);
|
);
|
||||||
let a = !1;
|
let a = !1;
|
||||||
!((o.Signers && 0 < o.Signers.length && l.length !== o.Signers.length) || !(a = !0));
|
!((n.Signers && 0 < n.Signers.length && l.length !== n.Signers.length) || !(a = !0));
|
||||||
var p = { SignedUrl: s, AuditTrail: e, IsCompleted: a };
|
var p = { SignedUrl: s, AuditTrail: e, IsCompleted: a };
|
||||||
await axios.put(serverUrl + '/classes/contracts_Document/' + t, p, {
|
await axios.put(serverUrl + '/classes/contracts_Document/' + t, p, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -61,7 +61,7 @@ async function sendMail(e) {
|
|||||||
s +
|
s +
|
||||||
' 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 ' +
|
' 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 ' +
|
||||||
t.Mail +
|
t.Mail +
|
||||||
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>',
|
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>'
|
||||||
};
|
};
|
||||||
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -86,7 +86,7 @@ async function sendCompletedMail(e) {
|
|||||||
s +
|
s +
|
||||||
'. 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 ' +
|
'. 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 ' +
|
||||||
t.Mail +
|
t.Mail +
|
||||||
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>',
|
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>',
|
||||||
};
|
};
|
||||||
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -96,115 +96,135 @@ async function sendCompletedMail(e) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function PDF(s, r) {
|
async function PDF(i, n) {
|
||||||
try {
|
try {
|
||||||
var i = s.params.sign,
|
i.params.sign;
|
||||||
e = s.params.docId,
|
var e = i.params.docId,
|
||||||
o = s.params.userId,
|
a = i.params.userId,
|
||||||
n = await axios.get(serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr', {
|
o = await axios.get(
|
||||||
|
serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr,Signers',
|
||||||
|
{
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Master-Key': masterKEY,
|
'X-Parse-Master-Key': masterKEY,
|
||||||
},
|
},
|
||||||
}),
|
}
|
||||||
d = await axios.get(serverUrl + '/users/me', {
|
),
|
||||||
|
t = await axios.get(serverUrl + '/users/me', {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
'X-Parse-Session-Token': i.headers.sessiontoken,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!d.data || !d.data.objectId) return { status: 'error', message: 'this user not allowed!' };
|
if (!t.data || !t.data.objectId) return { status: 'error', message: 'this user not allowed!' };
|
||||||
{
|
{
|
||||||
var l,
|
var d,
|
||||||
|
l,
|
||||||
p,
|
p,
|
||||||
c,
|
c = JSON.stringify({ objectId: a });
|
||||||
m = JSON.stringify({ objectId: o });
|
let s, r;
|
||||||
let a, t;
|
r = a
|
||||||
t = o
|
? (d = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + c, {
|
||||||
? (l = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + m, {
|
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
'X-Parse-Session-Token': i.headers.sessiontoken,
|
||||||
},
|
|
||||||
})).data && 0 < l.data.results.length
|
|
||||||
? ((a = l), 'contracts_Contactbook')
|
|
||||||
: ((a = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, {
|
|
||||||
headers: {
|
|
||||||
'X-Parse-Application-Id': APPID,
|
|
||||||
'X-Parse-Master-Key': masterKEY,
|
|
||||||
},
|
},
|
||||||
|
})).data && 0 < d.data.results.length
|
||||||
|
? ((s = d), 'contracts_Contactbook')
|
||||||
|
: ((s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + c, {
|
||||||
|
headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY },
|
||||||
})),
|
})),
|
||||||
'contracts_Users')
|
'contracts_Users')
|
||||||
: ((p = JSON.stringify({
|
: ((l = JSON.stringify({
|
||||||
UserId: { __type: 'Pointer', className: '_User', objectId: d.data.objectId },
|
UserId: { __type: 'Pointer', className: '_User', objectId: t.data.objectId },
|
||||||
})),
|
})),
|
||||||
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
|
(p = await axios.get(serverUrl + '/classes/contracts_Users?where=' + l, {
|
||||||
|
headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY },
|
||||||
|
})).data && 0 < p.data.results.length
|
||||||
|
? ((s = p), 'contracts_Users')
|
||||||
|
: ((s = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + l, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Master-Key': masterKEY,
|
'X-Parse-Session-Token': i.headers.sessiontoken,
|
||||||
},
|
|
||||||
})).data && 0 < c.data.results.length
|
|
||||||
? ((a = c), 'contracts_Users')
|
|
||||||
: ((a = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, {
|
|
||||||
headers: {
|
|
||||||
'X-Parse-Application-Id': APPID,
|
|
||||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
'contracts_Contactbook'));
|
'contracts_Contactbook'));
|
||||||
var g = a.data.results[0].Name,
|
var m = s.data.results[0].Name,
|
||||||
h = a.data.results[0].Email;
|
g = s.data.results[0].Email;
|
||||||
if (!s.params.pdfFile) return { status: 'error', message: 'pdf file not present!' };
|
if (!i.params.pdfFile) return { status: 'error', message: 'pdf file not present!' };
|
||||||
{
|
{
|
||||||
let e = Buffer.from(s.params.pdfFile, 'base64');
|
let e = Buffer.from(i.params.pdfFile, 'base64');
|
||||||
var u = process.env.PFX_BASE64,
|
var u = process.env.PFX_BASE64,
|
||||||
f = Buffer.from(u, 'base64');
|
h = Buffer.from(u, 'base64'),
|
||||||
e = i
|
f = {
|
||||||
? plainplaceholder({
|
UserPtr: { __type: 'Pointer', className: r, objectId: s.data.results[0].objectId },
|
||||||
|
SignedUrl: '',
|
||||||
|
Activity: 'Signed',
|
||||||
|
ipAddress: i.headers['x-real-ip'],
|
||||||
|
};
|
||||||
|
let a;
|
||||||
|
var y = (a =
|
||||||
|
o.data.AuditTrail && 0 < o.data.AuditTrail.length
|
||||||
|
? [...o.data.AuditTrail, f]
|
||||||
|
: [f]).filter(e => 'Signed' === e.Activity);
|
||||||
|
let t = !1;
|
||||||
|
!(
|
||||||
|
(o.data.Signers && 0 < o.data.Signers.length && y.length !== o.data.Signers.length) ||
|
||||||
|
!(t = !0)
|
||||||
|
);
|
||||||
|
var v,
|
||||||
|
P,
|
||||||
|
x = `./exports/exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
|
||||||
|
A =
|
||||||
|
(t
|
||||||
|
? ((v = o.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')),
|
||||||
|
(e =
|
||||||
|
v && 0 < v.length
|
||||||
|
? plainAddPlaceholder({
|
||||||
pdfBuffer: e,
|
pdfBuffer: e,
|
||||||
reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>',
|
reason: 'Digitally signed by Open sign for ' + v?.join(', '),
|
||||||
location: 'test location',
|
location: 'location',
|
||||||
signatureLength: 1e4,
|
signatureLength: 1e4,
|
||||||
sign: i,
|
|
||||||
})
|
})
|
||||||
: plainAddPlaceholder({
|
: plainAddPlaceholder({
|
||||||
pdfBuffer: e,
|
pdfBuffer: e,
|
||||||
reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>',
|
reason: 'Digitally signed by Open sign for ' + m + ' <' + g + '>',
|
||||||
location: 'test location',
|
location: 'location',
|
||||||
signatureLength: 1e4,
|
signatureLength: 1e4,
|
||||||
});
|
})),
|
||||||
var y = await new SignPDF(e, f).signPDF(),
|
(P = await new SignPDF(e, h).signPDF()),
|
||||||
v = `./exports/exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
|
fs.writeFileSync(x, P))
|
||||||
P = (fs.writeFileSync(v, y), await uploadFile(v));
|
: fs.writeFileSync(x, e),
|
||||||
if (P && P.imageUrl) {
|
await uploadFile(x));
|
||||||
const r = await updateDoc(
|
if (A && A.imageUrl) {
|
||||||
s.params.docId,
|
const n = await updateDoc(
|
||||||
P.imageUrl,
|
i.params.docId,
|
||||||
a.data.results[0].objectId,
|
A.imageUrl,
|
||||||
s.headers['x-real-ip'],
|
s.data.results[0].objectId,
|
||||||
n.data,
|
i.headers['x-real-ip'],
|
||||||
t
|
o.data,
|
||||||
|
r
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
sendMail({
|
sendMail({
|
||||||
url: P.imageUrl,
|
url: A.imageUrl,
|
||||||
sender: { Mail: n.data.ExtUserPtr.Email, Name: n.data.ExtUserPtr.Name },
|
sender: { Mail: o.data.ExtUserPtr.Email, Name: o.data.ExtUserPtr.Name },
|
||||||
pdfName: n.data.Name,
|
pdfName: o.data.Name,
|
||||||
receiver: h,
|
receiver: g,
|
||||||
}),
|
}),
|
||||||
r &&
|
n &&
|
||||||
r.isCompleted &&
|
n.isCompleted &&
|
||||||
sendCompletedMail({
|
sendCompletedMail({
|
||||||
url: P.imageUrl,
|
url: A.imageUrl,
|
||||||
sender: { Mail: n.data.ExtUserPtr.Email, Name: 'Open sign' },
|
sender: { Mail: o.data.ExtUserPtr.Email, Name: 'Open sign' },
|
||||||
pdfName: n.data.Name,
|
pdfName: o.data.Name,
|
||||||
receiver: n.data.ExtUserPtr.Email,
|
receiver: o.data.ExtUserPtr.Email,
|
||||||
}),
|
}),
|
||||||
fs.unlinkSync(v),
|
fs.unlinkSync(x),
|
||||||
console.log('New Signed PDF created called: ' + v),
|
console.log('New Signed PDF created called: ' + x),
|
||||||
'success' === r.message
|
'success' === n.message
|
||||||
? { status: 'success', data: P.imageUrl }
|
? { status: 'success', data: A.imageUrl }
|
||||||
: { status: 'error', message: 'please provide required parameters!' }
|
: { status: 'error', message: 'please provide required parameters!' }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ export default function reportJson(id, userId) {
|
|||||||
return {
|
return {
|
||||||
reportName: 'Draft Documents',
|
reportName: 'Draft Documents',
|
||||||
params: {
|
params: {
|
||||||
Type: null,
|
Type: { $ne: 'Folder' },
|
||||||
$or: [
|
IsCompleted: { $ne: true },
|
||||||
{ Signers: null, SignedUrl: null },
|
IsDeclined: { $ne: true },
|
||||||
{ Signers: { $exists: true }, Placeholders: null },
|
IsArchive: { $ne: true },
|
||||||
],
|
$or: [{Signers:{$eq:[]}}, { Signers: null }, { Signers: { $exists: true }, Placeholders: null }],
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
className: '_User',
|
className: '_User',
|
||||||
@@ -28,10 +28,23 @@ export default function reportJson(id, userId) {
|
|||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
ExpiryDate: {
|
ExpiryDate: {
|
||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
|
Signers: {
|
||||||
|
$inQuery: {
|
||||||
|
where: {
|
||||||
|
UserId: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
keys: [
|
keys: [
|
||||||
'Name',
|
'Name',
|
||||||
@@ -50,10 +63,11 @@ export default function reportJson(id, userId) {
|
|||||||
reportName: 'In-progress documents',
|
reportName: 'In-progress documents',
|
||||||
params: {
|
params: {
|
||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
Signers: { $ne: null },
|
Signers: { $exists: true, $ne: [] },
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
className: '_User',
|
className: '_User',
|
||||||
@@ -70,7 +84,7 @@ export default function reportJson(id, userId) {
|
|||||||
return {
|
return {
|
||||||
reportName: 'Completed Documents',
|
reportName: 'Completed Documents',
|
||||||
params: {
|
params: {
|
||||||
Type: null,
|
Type: { $ne: 'Folder' },
|
||||||
IsCompleted: true,
|
IsCompleted: true,
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
@@ -78,6 +92,7 @@ export default function reportJson(id, userId) {
|
|||||||
objectId: currentUserId,
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
},
|
},
|
||||||
keys: [
|
keys: [
|
||||||
'Name',
|
'Name',
|
||||||
@@ -96,6 +111,7 @@ export default function reportJson(id, userId) {
|
|||||||
reportName: 'Declined Documents',
|
reportName: 'Declined Documents',
|
||||||
params: {
|
params: {
|
||||||
Type: null,
|
Type: null,
|
||||||
|
IsArchive: { $ne: true },
|
||||||
IsDeclined: true,
|
IsDeclined: true,
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
@@ -113,6 +129,7 @@ export default function reportJson(id, userId) {
|
|||||||
params: {
|
params: {
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
$and: [
|
$and: [
|
||||||
{
|
{
|
||||||
@@ -141,10 +158,11 @@ export default function reportJson(id, userId) {
|
|||||||
reportName: 'Recently sent for signatures',
|
reportName: 'Recently sent for signatures',
|
||||||
params: {
|
params: {
|
||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
Signers: { $ne: null },
|
Signers: { $exists: true, $ne: [] },
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
className: '_User',
|
className: '_User',
|
||||||
@@ -154,7 +172,7 @@ export default function reportJson(id, userId) {
|
|||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
keys: ['Name', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
};
|
};
|
||||||
// Recent signature requests report show on dashboard
|
// Recent signature requests report show on dashboard
|
||||||
case '5Go51Q7T8r':
|
case '5Go51Q7T8r':
|
||||||
@@ -164,32 +182,36 @@ export default function reportJson(id, userId) {
|
|||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
ExpiryDate: {
|
ExpiryDate: {
|
||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
|
Signers: {
|
||||||
|
$inQuery: {
|
||||||
|
where: {
|
||||||
|
UserId: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
keys: [
|
},
|
||||||
'Name',
|
className: 'contracts_Contactbook',
|
||||||
'Note',
|
},
|
||||||
'Folder.Name',
|
},
|
||||||
'URL',
|
},
|
||||||
'ExtUserPtr.Name',
|
keys: ['Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name', 'Signers.UserId', 'AuditTrail'],
|
||||||
'Signers.Name',
|
|
||||||
'Signers.UserId',
|
|
||||||
'AuditTrail',
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
// Drafts report show on dashboard
|
// Drafts report show on dashboard
|
||||||
case 'kC5mfynCi4':
|
case 'kC5mfynCi4':
|
||||||
return {
|
return {
|
||||||
reportName: 'Drafts',
|
reportName: 'Drafts',
|
||||||
params: {
|
params: {
|
||||||
Type: null,
|
Type: { $ne: 'Folder' },
|
||||||
$or: [
|
IsCompleted: { $ne: true },
|
||||||
{ Signers: null, SignedUrl: null },
|
IsDeclined: { $ne: true },
|
||||||
{ Signers: { $exists: true }, Placeholders: null },
|
IsArchive: { $ne: true },
|
||||||
],
|
$or: [{Signers:{$eq:[]}}, { Signers: null }, { Signers: { $exists: true }, Placeholders: null }],
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
className: '_User',
|
className: '_User',
|
||||||
@@ -202,6 +224,7 @@ export default function reportJson(id, userId) {
|
|||||||
case '5KhaPr482K':
|
case '5KhaPr482K':
|
||||||
return {
|
return {
|
||||||
reportName: 'Contactbook',
|
reportName: 'Contactbook',
|
||||||
|
reportClass: 'contracts_Contactbook',
|
||||||
params: {
|
params: {
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
@@ -212,6 +235,22 @@ export default function reportJson(id, userId) {
|
|||||||
},
|
},
|
||||||
keys: ['Name', 'Email', 'Phone'],
|
keys: ['Name', 'Email', 'Phone'],
|
||||||
};
|
};
|
||||||
|
// Templates report
|
||||||
|
case '6TeaPr321t':
|
||||||
|
return {
|
||||||
|
reportName: 'Templates',
|
||||||
|
reportClass: 'contracts_Template',
|
||||||
|
params: {
|
||||||
|
Type: { $ne: 'Folder' },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
|
CreatedBy: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ exports.up = async Parse => {
|
|||||||
pageType: 'form',
|
pageType: 'form',
|
||||||
description: '',
|
description: '',
|
||||||
objectId: '8mZzFxbG1z',
|
objectId: '8mZzFxbG1z',
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,588 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const updateUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
updateUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const AdminMenu = new Parse.Query(className);
|
||||||
|
const updateAdminMenu = await AdminMenu.get('VPh91h0ZHk');
|
||||||
|
updateAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [updateUserMenu, updateAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const revertUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
revertUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSignDrive™',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const adminMenu = new Parse.Query(className);
|
||||||
|
const revertAdminMenu = await adminMenu.get('VPh91h0ZHk');
|
||||||
|
revertAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSignDrive™',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [revertUserMenu, revertAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
const className = 'contracts_Template';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
|
||||||
|
schema.addString('Name');
|
||||||
|
schema.addString('URL');
|
||||||
|
schema.addString('Note');
|
||||||
|
schema.addString('Description');
|
||||||
|
schema.addArray('Signers');
|
||||||
|
schema.addBoolean('IsArchive');
|
||||||
|
schema.addArray('Placeholders');
|
||||||
|
schema.addPointer('Folder', 'contracts_Template');
|
||||||
|
schema.addString('Type');
|
||||||
|
schema.addPointer('CreatedBy', '_User');
|
||||||
|
schema.addPointer('ExtUserPtr', 'contracts_Users');
|
||||||
|
schema.addBoolean('EnablePhoneOTP')
|
||||||
|
schema.addBoolean('EnableEmailOTP')
|
||||||
|
schema.addBoolean('SendinOrder')
|
||||||
|
schema.addBoolean('SentToOthers')
|
||||||
|
schema.addBoolean('AutomaticReminders')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return schema.save();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
const className = 'contracts_Template';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
|
||||||
|
return schema.purge().then(() => schema.delete());
|
||||||
|
};
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'contracts_Document';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
schema.addBoolean('IsArchive');
|
||||||
|
return schema.update();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'contracts_Document';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
schema.deleteField('IsArchive');
|
||||||
|
return schema.update();
|
||||||
|
};
|
||||||
@@ -69,7 +69,9 @@ if (process.env.SMTP_ENABLE) {
|
|||||||
export const config = {
|
export const config = {
|
||||||
databaseURI:
|
databaseURI:
|
||||||
process.env.DATABASE_URI || process.env.MONGODB_URI || 'mongodb://localhost:27017/dev',
|
process.env.DATABASE_URI || process.env.MONGODB_URI || 'mongodb://localhost:27017/dev',
|
||||||
cloud: process.env.CLOUD || __dirname + '/cloud/main.js',
|
cloud: function () {
|
||||||
|
import('./cloud/main.js');
|
||||||
|
},
|
||||||
appId: process.env.APP_ID || 'myAppId',
|
appId: process.env.APP_ID || 'myAppId',
|
||||||
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
|
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
|
||||||
masterKeyIps: ['0.0.0.0/0', '::1'], // '::1'
|
masterKeyIps: ['0.0.0.0/0', '::1'], // '::1'
|
||||||
|
|||||||
@@ -29,14 +29,15 @@
|
|||||||
"react-dnd-touch-backend": "^16.0.1",
|
"react-dnd-touch-backend": "^16.0.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-draggable": "^4.4.6",
|
"react-draggable": "^4.4.6",
|
||||||
|
"react-helmet": "^6.1.0",
|
||||||
"react-pdf": "^7.4.0",
|
"react-pdf": "^7.4.0",
|
||||||
"react-rnd": "^10.4.1",
|
"react-rnd": "^10.4.1",
|
||||||
"react-router-dom": "^6.16.0",
|
"react-router-dom": "^6.16.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-scrollbars-custom": "^4.1.1",
|
"react-scrollbars-custom": "^4.1.1",
|
||||||
|
"react-select": "^5.8.0",
|
||||||
"react-signature-canvas": "^1.0.6",
|
"react-signature-canvas": "^1.0.6",
|
||||||
"reactour": "^1.19.1",
|
"reactour": "^1.19.1",
|
||||||
"select-dom": "^9.0.0",
|
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2310,6 +2311,65 @@
|
|||||||
"postcss-selector-parser": "^6.0.10"
|
"postcss-selector-parser": "^6.0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@emotion/babel-plugin": {
|
||||||
|
"version": "11.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
|
||||||
|
"integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-module-imports": "^7.16.7",
|
||||||
|
"@babel/runtime": "^7.18.3",
|
||||||
|
"@emotion/hash": "^0.9.1",
|
||||||
|
"@emotion/memoize": "^0.8.1",
|
||||||
|
"@emotion/serialize": "^1.1.2",
|
||||||
|
"babel-plugin-macros": "^3.1.0",
|
||||||
|
"convert-source-map": "^1.5.0",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"find-root": "^1.1.0",
|
||||||
|
"source-map": "^0.5.7",
|
||||||
|
"stylis": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/babel-plugin/node_modules/source-map": {
|
||||||
|
"version": "0.5.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||||
|
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/cache": {
|
||||||
|
"version": "11.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
|
||||||
|
"integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/memoize": "^0.8.1",
|
||||||
|
"@emotion/sheet": "^1.2.2",
|
||||||
|
"@emotion/utils": "^1.2.1",
|
||||||
|
"@emotion/weak-memoize": "^0.3.1",
|
||||||
|
"stylis": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/hash": {
|
||||||
|
"version": "0.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
|
||||||
|
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
|
||||||
|
},
|
||||||
"node_modules/@emotion/is-prop-valid": {
|
"node_modules/@emotion/is-prop-valid": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
|
||||||
@@ -2322,8 +2382,52 @@
|
|||||||
"node_modules/@emotion/memoize": {
|
"node_modules/@emotion/memoize": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
||||||
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
|
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
|
||||||
"peer": true
|
},
|
||||||
|
"node_modules/@emotion/react": {
|
||||||
|
"version": "11.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz",
|
||||||
|
"integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.18.3",
|
||||||
|
"@emotion/babel-plugin": "^11.11.0",
|
||||||
|
"@emotion/cache": "^11.11.0",
|
||||||
|
"@emotion/serialize": "^1.1.2",
|
||||||
|
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
|
||||||
|
"@emotion/utils": "^1.2.1",
|
||||||
|
"@emotion/weak-memoize": "^0.3.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/serialize": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/hash": "^0.9.1",
|
||||||
|
"@emotion/memoize": "^0.8.1",
|
||||||
|
"@emotion/unitless": "^0.8.1",
|
||||||
|
"@emotion/utils": "^1.2.1",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/serialize/node_modules/@emotion/unitless": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/sheet": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/stylis": {
|
"node_modules/@emotion/stylis": {
|
||||||
"version": "0.8.5",
|
"version": "0.8.5",
|
||||||
@@ -2337,6 +2441,24 @@
|
|||||||
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
|
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/utils": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/weak-memoize": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
|
||||||
|
"integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
@@ -10608,6 +10730,11 @@
|
|||||||
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
|
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/find-root": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
|
||||||
|
},
|
||||||
"node_modules/find-up": {
|
"node_modules/find-up": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||||
@@ -14810,6 +14937,11 @@
|
|||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/memoize-one": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
||||||
|
},
|
||||||
"node_modules/merge-descriptors": {
|
"node_modules/merge-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
@@ -17748,6 +17880,25 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
||||||
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-fast-compare": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
||||||
|
},
|
||||||
|
"node_modules/react-helmet": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"react-fast-compare": "^3.1.1",
|
||||||
|
"react-side-effect": "^2.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@@ -18003,6 +18154,34 @@
|
|||||||
"react": ">=16.0.0"
|
"react": ">=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-select": {
|
||||||
|
"version": "5.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz",
|
||||||
|
"integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.0",
|
||||||
|
"@emotion/cache": "^11.4.0",
|
||||||
|
"@emotion/react": "^11.8.1",
|
||||||
|
"@floating-ui/dom": "^1.0.1",
|
||||||
|
"@types/react-transition-group": "^4.4.0",
|
||||||
|
"memoize-one": "^6.0.0",
|
||||||
|
"prop-types": "^15.6.0",
|
||||||
|
"react-transition-group": "^4.3.0",
|
||||||
|
"use-isomorphic-layout-effect": "^1.1.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-side-effect": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.3.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-signature-canvas": {
|
"node_modules/react-signature-canvas": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/react-signature-canvas/-/react-signature-canvas-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/react-signature-canvas/-/react-signature-canvas-1.0.6.tgz",
|
||||||
@@ -18703,20 +18882,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz",
|
||||||
"integrity": "sha512-HSdN78VMvFCSGCkh0oYX/tY4R3P1DW61f8+TeZZ4j2VLgfwvw0bpRSOv4PCVKisktIwbzHCfZsx+rLbbDBqIBA=="
|
"integrity": "sha512-HSdN78VMvFCSGCkh0oYX/tY4R3P1DW61f8+TeZZ4j2VLgfwvw0bpRSOv4PCVKisktIwbzHCfZsx+rLbbDBqIBA=="
|
||||||
},
|
},
|
||||||
"node_modules/select-dom": {
|
|
||||||
"version": "9.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/select-dom/-/select-dom-9.0.0.tgz",
|
|
||||||
"integrity": "sha512-AD1NfASSwJQc1Sy713R1vT9CMmUSUo2tg0j1FtkRGIxllTphDrkuH2pYYvhRlGaoq3pS6tcKkKS/diEZLy+7BQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"typed-query-selector": "^2.11.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/fregante"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/select-hose": {
|
"node_modules/select-hose": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||||
@@ -19527,6 +19692,11 @@
|
|||||||
"postcss": "^8.2.15"
|
"postcss": "^8.2.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/stylis": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
|
||||||
|
},
|
||||||
"node_modules/sucrase": {
|
"node_modules/sucrase": {
|
||||||
"version": "3.34.0",
|
"version": "3.34.0",
|
||||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
||||||
@@ -20218,11 +20388,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typed-query-selector": {
|
|
||||||
"version": "2.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.11.0.tgz",
|
|
||||||
"integrity": "sha512-qBs4sfmnLlPOyo2oSdvHbIFHe2CPgU54/1UGfSNceb7LARpIEVxUaeRX0Doje6oKpuySS2stqy90R3YrynR8Kg=="
|
|
||||||
},
|
|
||||||
"node_modules/typedarray-to-buffer": {
|
"node_modules/typedarray-to-buffer": {
|
||||||
"version": "3.1.5",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
||||||
@@ -20443,6 +20608,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-isomorphic-layout-effect": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/use-sidecar": {
|
"node_modules/use-sidecar": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
|
||||||
|
|||||||
@@ -25,14 +25,15 @@
|
|||||||
"react-dnd-touch-backend": "^16.0.1",
|
"react-dnd-touch-backend": "^16.0.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-draggable": "^4.4.6",
|
"react-draggable": "^4.4.6",
|
||||||
|
"react-helmet": "^6.1.0",
|
||||||
"react-pdf": "^7.4.0",
|
"react-pdf": "^7.4.0",
|
||||||
"react-rnd": "^10.4.1",
|
"react-rnd": "^10.4.1",
|
||||||
"react-router-dom": "^6.16.0",
|
"react-router-dom": "^6.16.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-scrollbars-custom": "^4.1.1",
|
"react-scrollbars-custom": "^4.1.1",
|
||||||
|
"react-select": "^5.8.0",
|
||||||
"react-signature-canvas": "^1.0.6",
|
"react-signature-canvas": "^1.0.6",
|
||||||
"reactour": "^1.19.1",
|
"reactour": "^1.19.1",
|
||||||
"select-dom": "^9.0.0",
|
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -47,65 +47,34 @@ function DraftDocument() {
|
|||||||
//check document type and render on signyour self and placeholder route
|
//check document type and render on signyour self and placeholder route
|
||||||
const handleDraftDoc = () => {
|
const handleDraftDoc = () => {
|
||||||
const data = pdfDetails[0];
|
const data = pdfDetails[0];
|
||||||
const checkSignerExist =
|
|
||||||
pdfDetails[0] && pdfDetails[0].Signers && pdfDetails[0].Signers;
|
|
||||||
const isPlaceholder =
|
|
||||||
pdfDetails[0].Placeholders && pdfDetails[0].Placeholders;
|
|
||||||
const isDecline = data.IsDeclined && data.IsDeclined;
|
|
||||||
const signUrl = data.SignedUrl && data.SignedUrl;
|
|
||||||
const expireDate =
|
|
||||||
pdfDetails[0] &&
|
|
||||||
pdfDetails[0].ExpiryDate.iso &&
|
|
||||||
pdfDetails[0].ExpiryDate.iso;
|
|
||||||
const expireUpdateDate = new Date(expireDate).getTime();
|
|
||||||
const currDate = new Date().getTime();
|
|
||||||
const hostUrl = getHostUrl();
|
const hostUrl = getHostUrl();
|
||||||
|
const signerExist = data.Signers && data.Signers;
|
||||||
|
const isDecline = data.IsDeclined && data.IsDeclined;
|
||||||
|
const isPlaceholder = data.Placeholders && data.Placeholders;
|
||||||
|
|
||||||
//checking document is completed and signer exist then navigate to pdfRequestFiles file
|
//checking if document has completed and request signature flow
|
||||||
if (data.IsCompleted && checkSignerExist) {
|
if (data?.IsCompleted && signerExist?.length > 0) {
|
||||||
navigate(`${hostUrl}pdfRequestFiles`);
|
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//checking document is completed and signer does not exist then navigate to recipientSignPdf file
|
//checking if document has completed and signyour-self flow
|
||||||
else if (data.IsCompleted && !checkSignerExist) {
|
else if (!signerExist && !isPlaceholder) {
|
||||||
navigate(`${hostUrl}signaturePdf`);
|
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//checking document is declined by someone then navigate to pdfRequestFiles file
|
//checking if document has declined by someone
|
||||||
else if (isDecline) {
|
else if (isDecline) {
|
||||||
navigate(`${hostUrl}pdfRequestFiles`);
|
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||||
|
//checking draft type document
|
||||||
}
|
}
|
||||||
//checking document has expired and signers exist and placeholder does not set yet then navigate to pdfRequestFiles file
|
//Inprogress document
|
||||||
//draft type request sign document
|
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
|
||||||
|
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||||
|
} //placeholder draft document
|
||||||
else if (
|
else if (
|
||||||
currDate > expireUpdateDate &&
|
(signerExist?.length > 0 &&
|
||||||
checkSignerExist &&
|
(!isPlaceholder || isPlaceholder?.length === 0)) ||
|
||||||
!isPlaceholder
|
((!signerExist || signerExist?.length === 0) && isPlaceholder?.length > 0)
|
||||||
) {
|
) {
|
||||||
navigate(`${hostUrl}placeHolderSign`);
|
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
|
||||||
}
|
|
||||||
//checking document has expired and signers does not exist and document not signed yet then navigate to pdfRequestFiles file
|
|
||||||
//draft type signyouselfdocument
|
|
||||||
else if (
|
|
||||||
currDate > expireUpdateDate &&
|
|
||||||
!checkSignerExist &&
|
|
||||||
!isPlaceholder &&
|
|
||||||
!signUrl
|
|
||||||
) {
|
|
||||||
// window.location.hash = `/signaturePdf`;
|
|
||||||
navigate(`${hostUrl}signaturePdf`);
|
|
||||||
}
|
|
||||||
//checking document has expired and signers exist and document then navigate to pdfRequestFiles file
|
|
||||||
else if (currDate > expireUpdateDate) {
|
|
||||||
// window.location.hash = `/pdfRequestFiles`;
|
|
||||||
navigate(`${hostUrl}pdfRequestFiles`);
|
|
||||||
}
|
|
||||||
//checking document has expired not been expired yet and signers exist and placeholder does not set yet then navigate to pdfRequestFiles file
|
|
||||||
//draft type request sign document
|
|
||||||
else if (!signUrl && checkSignerExist) {
|
|
||||||
navigate(`${hostUrl}placeHolderSign`);
|
|
||||||
// window.location.hash = `/placeHolderSign`;
|
|
||||||
} else {
|
|
||||||
// window.location.hash = `/signaturePdf/`;
|
|
||||||
navigate(`${hostUrl}signaturePdf`);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import { getHostUrl } from "../../../utils/Utils";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Table from "react-bootstrap/Table";
|
import Table from "react-bootstrap/Table";
|
||||||
import * as HoverCard from "@radix-ui/react-hover-card";
|
import * as HoverCard from "@radix-ui/react-hover-card";
|
||||||
|
import SelectFolder from "../../../premitives/SelectFolder";
|
||||||
|
import ModalUi from "../../../premitives/ModalUi";
|
||||||
|
import { themeColor } from "../../../utils/ThemeColor/backColor";
|
||||||
|
|
||||||
function PdfFileComponent({
|
function PdfFileComponent({
|
||||||
pdfData,
|
pdfData,
|
||||||
@@ -18,11 +21,20 @@ function PdfFileComponent({
|
|||||||
setIsLoading,
|
setIsLoading,
|
||||||
setPdfData,
|
setPdfData,
|
||||||
isList,
|
isList,
|
||||||
|
setIsAlert
|
||||||
}) {
|
}) {
|
||||||
const [rename, setRename] = useState("");
|
const [rename, setRename] = useState("");
|
||||||
const [renameValue, setRenameValue] = useState("");
|
const [renameValue, setRenameValue] = useState("");
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
|
const [isOpenMoveModal, setIsOpenMoveModal] = useState(false);
|
||||||
|
const [selectDoc, setSelectDoc] = useState();
|
||||||
|
const [isDeleteDoc, setIsDeleteDoc] = useState(false);
|
||||||
|
const contextMenu = [
|
||||||
|
{ type: "Download", icon: "fa-solid fa-arrow-down" },
|
||||||
|
{ type: "Rename", icon: "fa-solid fa-font" },
|
||||||
|
{ type: "Move", icon: "fa-solid fa-file-export" },
|
||||||
|
{ type: "Delete", icon: "fa-solid fa-trash" }
|
||||||
|
];
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
//to focus input box on press rename to change doc name
|
//to focus input box on press rename to change doc name
|
||||||
@@ -39,12 +51,12 @@ function PdfFileComponent({
|
|||||||
const handleOnclikFolder = (data) => {
|
const handleOnclikFolder = (data) => {
|
||||||
const folderData = {
|
const folderData = {
|
||||||
name: data.Name,
|
name: data.Name,
|
||||||
objectId: data.objectId,
|
objectId: data.objectId
|
||||||
};
|
};
|
||||||
setFolderName((prev) => [...prev, folderData]);
|
setFolderName((prev) => [...prev, folderData]);
|
||||||
const loadObj = {
|
const loadObj = {
|
||||||
isLoad: true,
|
isLoad: true,
|
||||||
message: "This might take some time",
|
message: "This might take some time"
|
||||||
};
|
};
|
||||||
|
|
||||||
setIsLoading(loadObj);
|
setIsLoading(loadObj);
|
||||||
@@ -57,7 +69,7 @@ function PdfFileComponent({
|
|||||||
|
|
||||||
if (trimmedValue.length > 0) {
|
if (trimmedValue.length > 0) {
|
||||||
const updateName = {
|
const updateName = {
|
||||||
Name: renameValue,
|
Name: renameValue
|
||||||
};
|
};
|
||||||
const docId = data.objectId;
|
const docId = data.objectId;
|
||||||
|
|
||||||
@@ -83,8 +95,8 @@ function PdfFileComponent({
|
|||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
@@ -92,89 +104,191 @@ function PdfFileComponent({
|
|||||||
// console.log("res", res);
|
// console.log("res", res);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("error updating field is decline ", err);
|
setIsAlert({
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: "something went wrong"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for navigate user to microapp-signature component
|
//function for navigate user to microapp-signature component
|
||||||
const checkPdfStatus = async (data) => {
|
const checkPdfStatus = async (data) => {
|
||||||
|
|
||||||
const hostUrl = getHostUrl();
|
const hostUrl = getHostUrl();
|
||||||
const expireDate = data.ExpiryDate.iso;
|
|
||||||
const expireUpdateDate = new Date(expireDate).getTime();
|
|
||||||
const currDate = new Date().getTime();
|
|
||||||
const signerExist = data.Signers && data.Signers;
|
const signerExist = data.Signers && data.Signers;
|
||||||
const signUrl = data.SignedUrl && data.SignedUrl;
|
|
||||||
const isDecline = data.IsDeclined && data.IsDeclined;
|
const isDecline = data.IsDeclined && data.IsDeclined;
|
||||||
const isPlaceholder = data.Placeholders && data.Placeholders;
|
const isPlaceholder = data.Placeholders && data.Placeholders;
|
||||||
//checking and navigate to signyouself page
|
|
||||||
const checkPlaceHolder = data.Placeholders;
|
|
||||||
//checking if document has completed
|
|
||||||
if (data.IsCompleted && signerExist) {
|
|
||||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
|
||||||
|
|
||||||
// window.location.hash = `/pdfRequestFiles/${data.objectId}`;
|
//checking if document has completed and request signature flow
|
||||||
} else if (data.IsCompleted && !signerExist) {
|
if (data?.IsCompleted && signerExist?.length > 0) {
|
||||||
navigate(
|
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||||
`${hostUrl}signaturePdf/${data.objectId}`
|
}
|
||||||
);
|
//checking if document has completed and signyour-self flow
|
||||||
// window.location.hash = `/recipientSignPdf/${data.objectId}/${data.ExtUserPtr.Phone}`;
|
else if (!signerExist && !isPlaceholder) {
|
||||||
|
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//checking if document has declined by someone
|
//checking if document has declined by someone
|
||||||
else if (isDecline) {
|
else if (isDecline) {
|
||||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||||
// window.location.hash = `/pdfRequestFiles/${data.objectId}`;
|
//checking draft type document
|
||||||
} else if (currDate > expireUpdateDate && signerExist && !isPlaceholder) {
|
|
||||||
// window.location.hash = `/placeHolderSign/${data.objectId}`;
|
|
||||||
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
|
|
||||||
} else if (
|
|
||||||
currDate > expireUpdateDate &&
|
|
||||||
!signerExist &&
|
|
||||||
!isPlaceholder &&
|
|
||||||
!signUrl
|
|
||||||
) {
|
|
||||||
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
|
|
||||||
// window.location.hash = `/signaturePdf/${data.objectId}`;
|
|
||||||
}
|
}
|
||||||
//checking if document has expired
|
//Inprogress document
|
||||||
else if (currDate > expireUpdateDate) {
|
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
|
||||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||||
// window.location.hash = `/pdfRequestFiles/${data.objectId}`;
|
} //placeholder draft document
|
||||||
} //checking if document is draft signers type and signers placeholder does not placed yet
|
|
||||||
else if (!signUrl && signerExist) {
|
|
||||||
// window.location.hash = `/placeHolderSign/${data.objectId}`;
|
|
||||||
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
|
|
||||||
}
|
|
||||||
//checking if document is request type and signers placeholder exist and does not completed yet
|
|
||||||
//then user can check progress of document and sign also
|
|
||||||
else if (
|
else if (
|
||||||
checkPlaceHolder &&
|
(signerExist?.length > 0 &&
|
||||||
checkPlaceHolder.length > 0 &&
|
(!isPlaceholder || isPlaceholder?.length === 0)) ||
|
||||||
!data.IsCompleted
|
((!signerExist || signerExist?.length === 0) && isPlaceholder?.length > 0)
|
||||||
) {
|
) {
|
||||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
|
||||||
// window.location.hash = `/pdfRequestFiles/${data.objectId}`;
|
|
||||||
}
|
}
|
||||||
//checking document is draft and signyourself type then user can sign document
|
};
|
||||||
else {
|
|
||||||
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
|
const handleMenuItemClick = (selectType, data) => {
|
||||||
// navigate(`/signaturePdf/${data.objectId}`);
|
switch (selectType) {
|
||||||
// window.location.hash = `/signaturePdf/${data.objectId}`;
|
case "Download":
|
||||||
|
const pdfName = data && data.Name;
|
||||||
|
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
|
||||||
|
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||||
|
break;
|
||||||
|
case "Rename":
|
||||||
|
setRenameValue(data.Name);
|
||||||
|
setRename(data.objectId);
|
||||||
|
break;
|
||||||
|
case "Delete":
|
||||||
|
setIsDeleteDoc(true);
|
||||||
|
setSelectDoc(data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Move":
|
||||||
|
handleMoveDocument(data);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//function for delete document
|
||||||
|
const handleDeleteDocument = async (docData) => {
|
||||||
|
setIsDeleteDoc(false);
|
||||||
|
const docId = docData.objectId;
|
||||||
|
const data = {
|
||||||
|
IsArchive: true
|
||||||
|
};
|
||||||
|
|
||||||
|
await axios
|
||||||
|
.put(
|
||||||
|
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||||
|
"_appName"
|
||||||
|
)}_Document/${docId}`,
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((result) => {
|
||||||
|
const res = result.data;
|
||||||
|
if (res) {
|
||||||
|
const updatedData = pdfData.filter((x) => x.objectId !== docId);
|
||||||
|
setPdfData(updatedData);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: "something went wrong"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleMoveDocument = async (docData) => {
|
||||||
|
setIsOpenMoveModal(true);
|
||||||
|
setSelectDoc(docData);
|
||||||
|
};
|
||||||
|
//function for move document from one folder to another folder
|
||||||
|
const handleMoveFolder = async (selectFolderData) => {
|
||||||
|
const selecFolderId = selectDoc?.Folder?.objectId;
|
||||||
|
const moveFolderId = selectFolderData?.ObjectId;
|
||||||
|
let updateDocId = selectDoc?.objectId;
|
||||||
|
let updateData;
|
||||||
|
const checkExist = moveFolderId
|
||||||
|
? selecFolderId === moveFolderId
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
: selecFolderId
|
||||||
|
? false
|
||||||
|
: true;
|
||||||
|
if (!checkExist) {
|
||||||
|
if (moveFolderId) {
|
||||||
|
updateData = {
|
||||||
|
Folder: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: `${localStorage.getItem("_appName")}_Document`,
|
||||||
|
objectId: moveFolderId
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
updateData = {
|
||||||
|
Folder: { __op: "Delete" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await axios
|
||||||
|
.put(
|
||||||
|
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||||
|
"_appName"
|
||||||
|
)}_Document/${updateDocId}`,
|
||||||
|
updateData,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
.then((Listdata) => {
|
||||||
|
// console.log("Listdata ", Listdata);
|
||||||
|
const res = Listdata.data;
|
||||||
|
if (res) {
|
||||||
|
const updatedData = pdfData.filter(
|
||||||
|
(x) => x.objectId !== updateDocId
|
||||||
|
);
|
||||||
|
setPdfData(updatedData);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log("err", err);
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsOpenMoveModal(false);
|
||||||
|
} else {
|
||||||
|
alert("folder already exist!");
|
||||||
|
setIsOpenMoveModal(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const sanitizeFileName = (pdfName) => {
|
||||||
|
// Replace spaces with underscore
|
||||||
|
return pdfName.replace(/ /g, "_");
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEnterPress = (e, data) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
handledRenameDoc(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDraftDoc = (data) => {
|
||||||
|
window.location.hash = `/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9MZWdhR2VuaWUtTWljcm9hcHBWMi9yZW1vdGVFbnRyeS5qcw==&moduleToLoad=AppRoutes&remoteName=legageniemicroapp/legagenie?${data.objectId}`;
|
||||||
|
};
|
||||||
|
|
||||||
//component to handle type of document and render according to type
|
//component to handle type of document and render according to type
|
||||||
const handleFolderData = (data, ind, listType) => {
|
const handleFolderData = (data, ind, listType) => {
|
||||||
// console.log("data", data);
|
let createddate, status, isDecline, signerExist, isComplete, isPlaceholder;
|
||||||
let createddate,
|
|
||||||
status,
|
|
||||||
isDecline,
|
|
||||||
signerExist,
|
|
||||||
isExpire,
|
|
||||||
isComplete,
|
|
||||||
signUrl,
|
|
||||||
isPlaceholder;
|
|
||||||
if (data.Type !== "Folder") {
|
if (data.Type !== "Folder") {
|
||||||
const expireDate = data.ExpiryDate && data.ExpiryDate.iso;
|
const expireDate = data.ExpiryDate && data.ExpiryDate.iso;
|
||||||
const createdDate = data.createdAt && data.createdAt;
|
const createdDate = data.createdAt && data.createdAt;
|
||||||
@@ -183,67 +297,51 @@ function PdfFileComponent({
|
|||||||
isDecline = data.IsDeclined && data.IsDeclined;
|
isDecline = data.IsDeclined && data.IsDeclined;
|
||||||
isPlaceholder = data.Placeholders && data.Placeholders;
|
isPlaceholder = data.Placeholders && data.Placeholders;
|
||||||
signerExist = data.Signers && data.Signers;
|
signerExist = data.Signers && data.Signers;
|
||||||
signUrl = data.SignedUrl && data.SignedUrl;
|
|
||||||
const expireUpdateDate = new Date(expireDate).getTime();
|
const expireUpdateDate = new Date(expireDate).getTime();
|
||||||
const currDate = new Date().getTime();
|
const currDate = new Date().getTime();
|
||||||
|
let isExpire = false;
|
||||||
if (currDate > expireUpdateDate) {
|
if (currDate > expireUpdateDate) {
|
||||||
isExpire = true;
|
isExpire = true;
|
||||||
} else {
|
|
||||||
isExpire = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isComplete) {
|
if (isComplete) {
|
||||||
status = "Completed";
|
status = "Completed";
|
||||||
} else if (isDecline) {
|
} else if (isDecline) {
|
||||||
status = "Declined";
|
status = "Declined";
|
||||||
} else if (isExpire && !isPlaceholder && signerExist) {
|
} else if (!signerExist || signerExist?.length === 0) {
|
||||||
// status = "Expired";
|
|
||||||
status = "Draft";
|
status = "Draft";
|
||||||
} else if (isExpire && !isPlaceholder && !signerExist && !signUrl) {
|
} else if (
|
||||||
// status = "Expired";
|
signerExist?.length > 0 &&
|
||||||
|
(!isPlaceholder || isPlaceholder?.length === 0)
|
||||||
|
) {
|
||||||
status = "Draft";
|
status = "Draft";
|
||||||
} else if (isExpire) {
|
} else if (isExpire) {
|
||||||
status = "Expired";
|
status = "Expired";
|
||||||
} else if (!signUrl) {
|
|
||||||
status = "Draft";
|
|
||||||
} else {
|
} else {
|
||||||
status = "InComplete";
|
status = "In Progress";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDraftDoc = (data) => {
|
const signersName = () => {
|
||||||
window.location.hash = `/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9MZWdhR2VuaWUtTWljcm9hcHBWMi9yZW1vdGVFbnRyeS5qcw==&moduleToLoad=AppRoutes&remoteName=legageniemicroapp/legagenie?${data.objectId}`;
|
const getSignersName = signerExist.map((data) => data.Name);
|
||||||
|
const signerName = getSignersName.join(",");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className="statusSpan"
|
||||||
|
style={{ width: "90%", wordWrap: "break-word" }}
|
||||||
|
>
|
||||||
|
{signerName}{" "}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMenuItemClick = (selectType, data) => {
|
|
||||||
// console.log("data",data)
|
|
||||||
if (selectType === "Download") {
|
|
||||||
// console.log("download")
|
|
||||||
const pdfName = data && data.Name;
|
|
||||||
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
|
|
||||||
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
|
||||||
} else if (selectType === "Rename") {
|
|
||||||
// console.log("rename")
|
|
||||||
setRenameValue(data.Name);
|
|
||||||
setRename(data.objectId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const sanitizeFileName = (pdfName) => {
|
|
||||||
// Replace spaces with underscore
|
|
||||||
return pdfName.replace(/ /g, '_');
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleEnterPress = (e, data) => {
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
handledRenameDoc(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return listType === "table" ? (
|
return listType === "table" ? (
|
||||||
data.Type === "Folder" ? (
|
data.Type === "Folder" ? (
|
||||||
<tr onClick={() => handleOnclikFolder(data)}>
|
<tr onClick={() => handleOnclikFolder(data)}>
|
||||||
<td>
|
<td
|
||||||
|
style={{ cursor: "pointer", display: "flex", alignItems: "center" }}
|
||||||
|
>
|
||||||
<i
|
<i
|
||||||
className="fa fa-folder"
|
className="fa fa-folder"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -261,7 +359,9 @@ function PdfFileComponent({
|
|||||||
</tr>
|
</tr>
|
||||||
) : data.Type === "AIDoc" ? (
|
) : data.Type === "AIDoc" ? (
|
||||||
<tr onClick={() => handleDraftDoc(data)}>
|
<tr onClick={() => handleDraftDoc(data)}>
|
||||||
<td>
|
<td
|
||||||
|
style={{ cursor: "pointer", display: "flex", alignItems: "center" }}
|
||||||
|
>
|
||||||
<i
|
<i
|
||||||
className="fa fa-file-text"
|
className="fa fa-file-text"
|
||||||
style={{ color: "#0ea3ed", marginRight: "8px", fontSize: "26px" }}
|
style={{ color: "#0ea3ed", marginRight: "8px", fontSize: "26px" }}
|
||||||
@@ -278,7 +378,9 @@ function PdfFileComponent({
|
|||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
<tr onClick={() => checkPdfStatus(data)}>
|
<tr onClick={() => checkPdfStatus(data)}>
|
||||||
<td>
|
<td
|
||||||
|
style={{ cursor: "pointer", display: "flex", alignItems: "center" }}
|
||||||
|
>
|
||||||
<i
|
<i
|
||||||
className="fa fa-file-pdf"
|
className="fa fa-file-pdf"
|
||||||
style={{ color: "#ed4d0e", marginRight: "8px", fontSize: "26px" }}
|
style={{ color: "#ed4d0e", marginRight: "8px", fontSize: "26px" }}
|
||||||
@@ -312,7 +414,7 @@ function PdfFileComponent({
|
|||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
cursor: "pointer",
|
cursor: "pointer"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@@ -333,7 +435,6 @@ function PdfFileComponent({
|
|||||||
}}
|
}}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
type="text"
|
type="text"
|
||||||
// onFocus={()=>console.log("focus")}
|
|
||||||
onBlur={() => handledRenameDoc(data)}
|
onBlur={() => handledRenameDoc(data)}
|
||||||
onKeyDown={(e) => handleEnterPress(e, data)}
|
onKeyDown={(e) => handleEnterPress(e, data)}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
@@ -344,7 +445,7 @@ function PdfFileComponent({
|
|||||||
width: "100px",
|
width: "100px",
|
||||||
border: "1.5px solid black",
|
border: "1.5px solid black",
|
||||||
borderRadius: "2px",
|
borderRadius: "2px",
|
||||||
fontSize: "10px",
|
fontSize: "10px"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -359,19 +460,12 @@ function PdfFileComponent({
|
|||||||
sideOffset={5}
|
sideOffset={5}
|
||||||
align="end"
|
align="end"
|
||||||
>
|
>
|
||||||
{/* <ContextMenu.Item
|
|
||||||
onClick={() => handleMenuItemClick("Download", data)}
|
|
||||||
onSelect={(e) => console.log("event", e)}
|
|
||||||
className="ContextMenuItem"
|
|
||||||
>
|
|
||||||
Download
|
|
||||||
</ContextMenu.Item> */}
|
|
||||||
|
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
onClick={() => handleMenuItemClick("Rename", data)}
|
onClick={() => handleMenuItemClick("Rename", data)}
|
||||||
className="ContextMenuItem"
|
className="ContextMenuItem"
|
||||||
>
|
>
|
||||||
Rename
|
<i class="fa-solid fa-font"></i>
|
||||||
|
<span style={{ marginLeft: "8px" }}>Rename</span>
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Content>
|
</ContextMenu.Content>
|
||||||
</ContextMenu.Portal>
|
</ContextMenu.Portal>
|
||||||
@@ -385,7 +479,7 @@ function PdfFileComponent({
|
|||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
cursor: "pointer",
|
cursor: "pointer"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@@ -406,7 +500,6 @@ function PdfFileComponent({
|
|||||||
}}
|
}}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
type="text"
|
type="text"
|
||||||
// onFocus={()=>console.log("focus")}
|
|
||||||
onBlur={() => handledRenameDoc(data)}
|
onBlur={() => handledRenameDoc(data)}
|
||||||
onKeyDown={(e) => handleEnterPress(e, data)}
|
onKeyDown={(e) => handleEnterPress(e, data)}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
@@ -417,7 +510,7 @@ function PdfFileComponent({
|
|||||||
width: "100px",
|
width: "100px",
|
||||||
border: "1.5px solid black",
|
border: "1.5px solid black",
|
||||||
borderRadius: "2px",
|
borderRadius: "2px",
|
||||||
fontSize: "10px",
|
fontSize: "10px"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -432,26 +525,19 @@ function PdfFileComponent({
|
|||||||
sideOffset={5}
|
sideOffset={5}
|
||||||
align="end"
|
align="end"
|
||||||
>
|
>
|
||||||
{/* <ContextMenu.Item
|
|
||||||
onClick={() => handleMenuItemClick("Download", data)}
|
|
||||||
onSelect={(e) => console.log("event", e)}
|
|
||||||
className="ContextMenuItem"
|
|
||||||
>
|
|
||||||
Download
|
|
||||||
</ContextMenu.Item> */}
|
|
||||||
|
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
onClick={() => handleMenuItemClick("Rename", data)}
|
onClick={() => handleMenuItemClick("Rename", data)}
|
||||||
className="ContextMenuItem"
|
className="ContextMenuItem"
|
||||||
>
|
>
|
||||||
Rename
|
<i class="fa-solid fa-font"></i>
|
||||||
|
<span style={{ marginLeft: "8px" }}>Rename</span>
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Content>
|
</ContextMenu.Content>
|
||||||
</ContextMenu.Portal>
|
</ContextMenu.Portal>
|
||||||
</ContextMenu.Root>
|
</ContextMenu.Root>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<HoverCard.Root>
|
<HoverCard.Root openDelay={0} closeDelay={100}>
|
||||||
<HoverCard.Trigger asChild>
|
<HoverCard.Trigger asChild>
|
||||||
<div>
|
<div>
|
||||||
<ContextMenu.Root>
|
<ContextMenu.Root>
|
||||||
@@ -484,7 +570,7 @@ function PdfFileComponent({
|
|||||||
width: "100px",
|
width: "100px",
|
||||||
border: "1.5px solid black",
|
border: "1.5px solid black",
|
||||||
borderRadius: "2px",
|
borderRadius: "2px",
|
||||||
fontSize: "10px",
|
fontSize: "10px"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -508,7 +594,7 @@ function PdfFileComponent({
|
|||||||
<i className="fa fa-file"></i>
|
<i className="fa fa-file"></i>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
status === "InComplete" && (
|
status === "In Progress" && (
|
||||||
<div className="status-badge in-progress">
|
<div className="status-badge in-progress">
|
||||||
<i className="fa fa-paper-plane"></i>
|
<i className="fa fa-paper-plane"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -522,20 +608,18 @@ function PdfFileComponent({
|
|||||||
sideOffset={5}
|
sideOffset={5}
|
||||||
align="end"
|
align="end"
|
||||||
>
|
>
|
||||||
|
{contextMenu.map((menu, ind) => {
|
||||||
|
return (
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
onClick={() => handleMenuItemClick("Download", data)}
|
key={ind}
|
||||||
onSelect={(e) => console.log("event", e)}
|
onClick={() => handleMenuItemClick(menu.type, data)}
|
||||||
className="ContextMenuItem"
|
className="ContextMenuItem"
|
||||||
>
|
>
|
||||||
Download
|
<i class={menu.icon}></i>
|
||||||
</ContextMenu.Item>
|
<span style={{ marginLeft: "8px" }}>{menu.type}</span>
|
||||||
|
|
||||||
<ContextMenu.Item
|
|
||||||
onClick={() => handleMenuItemClick("Rename", data)}
|
|
||||||
className="ContextMenuItem"
|
|
||||||
>
|
|
||||||
Rename
|
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</ContextMenu.Content>
|
</ContextMenu.Content>
|
||||||
</ContextMenu.Portal>
|
</ContextMenu.Portal>
|
||||||
</ContextMenu.Root>
|
</ContextMenu.Root>
|
||||||
@@ -558,24 +642,22 @@ function PdfFileComponent({
|
|||||||
{signerExist && (
|
{signerExist && (
|
||||||
<>
|
<>
|
||||||
<strong style={{ fontSize: "13px" }}>Signers: </strong>
|
<strong style={{ fontSize: "13px" }}>Signers: </strong>
|
||||||
{signerExist.map((data, key) => {
|
{/* <span className="statusSpan">kjefjjnejkfnkbjs bbfjkdsbjbfjkbjk kscbjkbjkb</span> */}
|
||||||
return (
|
{signersName()}
|
||||||
<React.Fragment key={key}>
|
|
||||||
<span className="statusSpan">{data.Name}, </span>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<HoverCard.Arrow className="HoverCardArrow" />
|
<HoverCard.Arrow className="HoverCardArrow" />
|
||||||
</HoverCard.Content>
|
</HoverCard.Content>
|
||||||
</HoverCard.Portal>
|
</HoverCard.Portal>
|
||||||
</HoverCard.Root>
|
</HoverCard.Root>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
//component to handle type of document and render according to type
|
|
||||||
|
|
||||||
return isList ? (
|
//component to handle type of document and render according to type
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isList ? (
|
||||||
<div className="container" style={{ overflowX: "auto" }}>
|
<div className="container" style={{ overflowX: "auto" }}>
|
||||||
<Table striped bordered hover>
|
<Table striped bordered hover>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -608,6 +690,62 @@ function PdfFileComponent({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
{isOpenMoveModal && (
|
||||||
|
<SelectFolder
|
||||||
|
onSuccess={handleMoveFolder}
|
||||||
|
isOpenModal={isOpenMoveModal}
|
||||||
|
folderCls={"contracts_Document"}
|
||||||
|
setIsOpenMoveModal={setIsOpenMoveModal}
|
||||||
|
setPdfData={setPdfData}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<ModalUi
|
||||||
|
isOpen={isDeleteDoc}
|
||||||
|
headerColor={themeColor()}
|
||||||
|
title={"Delete Document"}
|
||||||
|
handleClose={() => {
|
||||||
|
setIsDeleteDoc(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>Are you sure you want to delete this document?</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
handleDeleteDocument(selectDoc);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
background: themeColor(),
|
||||||
|
color: "white"
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setIsDeleteDoc(false);
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,13 @@
|
|||||||
|
|
||||||
.ContextMenuContent,
|
.ContextMenuContent,
|
||||||
.ContextMenuSubContent {
|
.ContextMenuSubContent {
|
||||||
min-width: 150px;
|
min-width: 135px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
box-shadow: 0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2);
|
box-shadow: 0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2);
|
||||||
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ContextMenuItem,
|
.ContextMenuItem,
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
height: 25px;
|
height: 25px;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 25px;
|
padding-left: 15px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
@@ -115,7 +116,9 @@
|
|||||||
margin: 30px;
|
margin: 30px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.inputStyle{
|
||||||
|
border: 1.6px solid #ccc !important;
|
||||||
|
}
|
||||||
.folderComponent::-webkit-scrollbar {
|
.folderComponent::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
/* for Chrome, Safari, and Opera */
|
/* for Chrome, Safari, and Opera */
|
||||||
@@ -395,6 +398,7 @@ a {
|
|||||||
will-change: transform, opacity;
|
will-change: transform, opacity;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.HoverCardContent[data-side='top'] {
|
.HoverCardContent[data-side='top'] {
|
||||||
@@ -496,12 +500,34 @@ a {
|
|||||||
/* for Chrome, Safari, and Opera */
|
/* for Chrome, Safari, and Opera */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.docDeleteBtn {
|
||||||
|
/* box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18); */
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
|
padding: 7px 17px;
|
||||||
|
color: white;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docDeleteBtn:focus {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docDeleteBtn:hover {
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width:766px) {
|
@media screen and (max-width:766px) {
|
||||||
.itemColor {
|
.itemColor {
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 310px) and (max-width:550px) {
|
@media (min-width: 310px) and (max-width:550px) {
|
||||||
|
|
||||||
.pdfContainer {
|
.pdfContainer {
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import React, { useEffect, useState, useRef } from "react";
|
import React, { useEffect, useState, useRef } from "react";
|
||||||
import axios from "axios";
|
|
||||||
import "./LegaDrive.css";
|
import "./LegaDrive.css";
|
||||||
import loader from "../../assests/loader2.gif";
|
import loader from "../../assests/loader2.gif";
|
||||||
import PdfFileComponent from "./FolderDrive/legaDriveComponent";
|
import PdfFileComponent from "./FolderDrive/legaDriveComponent";
|
||||||
import Modal from "react-bootstrap/Modal";
|
|
||||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
|
||||||
import { themeColor, iconColor } from "../../utils/ThemeColor/backColor";
|
import { themeColor, iconColor } from "../../utils/ThemeColor/backColor";
|
||||||
import { getDrive } from "../../utils/Utils";
|
import { getDrive } from "../../utils/Utils";
|
||||||
import AlertComponent from "../component/alertComponent";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import Title from "../component/Title";
|
||||||
|
import Parse from "parse";
|
||||||
|
import ModalUi from "../../premitives/ModalUi";
|
||||||
|
|
||||||
function PdfFile() {
|
function PdfFile() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -27,7 +26,7 @@ function PdfFile() {
|
|||||||
message: "This might take some time"
|
message: "This might take some time"
|
||||||
});
|
});
|
||||||
const [docId, setDocId] = useState();
|
const [docId, setDocId] = useState();
|
||||||
const [handleError, setHandleError] = useState();
|
const [handleError, setHandleError] = useState("");
|
||||||
const [folderName, setFolderName] = useState([]);
|
const [folderName, setFolderName] = useState([]);
|
||||||
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
||||||
const [isNewFol, setIsNewFol] = useState(false);
|
const [isNewFol, setIsNewFol] = useState(false);
|
||||||
@@ -54,15 +53,18 @@ function PdfFile() {
|
|||||||
isLoad: true,
|
isLoad: true,
|
||||||
message: "This might take some time"
|
message: "This might take some time"
|
||||||
};
|
};
|
||||||
|
let driveDetails;
|
||||||
setIsLoading(load);
|
setIsLoading(load);
|
||||||
const driveDetails = await getDrive();
|
try {
|
||||||
|
driveDetails = await getDrive();
|
||||||
if (driveDetails) {
|
if (driveDetails) {
|
||||||
if (driveDetails.length > 0) {
|
if (driveDetails.length > 0) {
|
||||||
setPdfData(driveDetails);
|
setPdfData(driveDetails);
|
||||||
|
sortApps(null, null, driveDetails);
|
||||||
}
|
}
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
name: "OpenSignDrive™",
|
name: "OpenSign™ Drive",
|
||||||
objectId: ""
|
objectId: ""
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -78,6 +80,12 @@ function PdfFile() {
|
|||||||
setHandleError("Error: Something went wrong!");
|
setHandleError("Error: Something went wrong!");
|
||||||
setIsLoading(loadObj);
|
setIsLoading(loadObj);
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: "something went wrong"
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
//function for get parent folder document list
|
//function for get parent folder document list
|
||||||
const getPdfFolderDocumentList = async () => {
|
const getPdfFolderDocumentList = async () => {
|
||||||
@@ -86,10 +94,14 @@ function PdfFile() {
|
|||||||
message: "This might take some time"
|
message: "This might take some time"
|
||||||
};
|
};
|
||||||
setIsLoading(load);
|
setIsLoading(load);
|
||||||
const driveDetails = await getDrive(docId);
|
let driveDetails;
|
||||||
|
try {
|
||||||
|
driveDetails = await getDrive(docId);
|
||||||
|
|
||||||
if (driveDetails) {
|
if (driveDetails) {
|
||||||
if (driveDetails.length > 0) {
|
if (driveDetails.length > 0) {
|
||||||
setPdfData(driveDetails);
|
setPdfData(driveDetails);
|
||||||
|
sortApps(null, null, driveDetails);
|
||||||
} else {
|
} else {
|
||||||
setPdfData([]);
|
setPdfData([]);
|
||||||
}
|
}
|
||||||
@@ -104,6 +116,12 @@ function PdfFile() {
|
|||||||
setHandleError("Error: Something went wrong!");
|
setHandleError("Error: Something went wrong!");
|
||||||
setIsLoading(loadObj);
|
setIsLoading(loadObj);
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: "something went wrong!"
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for get all pdf document list
|
//function for get all pdf document list
|
||||||
@@ -111,43 +129,16 @@ function PdfFile() {
|
|||||||
setIsFolder(true);
|
setIsFolder(true);
|
||||||
};
|
};
|
||||||
//function for handle folder name path
|
//function for handle folder name path
|
||||||
const handleRoute = (data) => {
|
const handleRoute = (index) => {
|
||||||
let loadObj = {
|
const updateFolderName = folderName.filter((x, i) => {
|
||||||
isLoad: true,
|
if (i <= index) {
|
||||||
message: "This might take some time"
|
return x;
|
||||||
};
|
|
||||||
if (data.name === "LegaDrive™") {
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
if (docId) {
|
|
||||||
setDocId();
|
|
||||||
} else {
|
|
||||||
setTimeout(() => {
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
} else if (data.name === folderName[folderName.length - 1].name) {
|
});
|
||||||
setIsLoading(loadObj);
|
|
||||||
setTimeout(() => {
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
|
||||||
const findIndex = folderName.findIndex(
|
|
||||||
(fold) => fold.objectId === data.objectId
|
|
||||||
);
|
|
||||||
const newFolder = folderName.slice(0, findIndex + 1);
|
|
||||||
|
|
||||||
setFolderName(newFolder);
|
|
||||||
const getLastId = newFolder[newFolder.length - 1];
|
|
||||||
|
|
||||||
|
setFolderName(updateFolderName);
|
||||||
|
const getLastId = updateFolderName[updateFolderName.length - 1];
|
||||||
setDocId(getLastId.objectId);
|
setDocId(getLastId.objectId);
|
||||||
setIsLoading(loadObj);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for add new folder name
|
//function for add new folder name
|
||||||
@@ -156,78 +147,60 @@ function PdfFile() {
|
|||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
setNewFolderName(value);
|
setNewFolderName(value);
|
||||||
};
|
};
|
||||||
//function for add folder
|
//function for create folder
|
||||||
const handleAddFolder = async () => {
|
const handleAddFolder = async () => {
|
||||||
if (newFolderName) {
|
if (newFolderName) {
|
||||||
setIsFolderLoader(true);
|
setIsFolderLoader(true);
|
||||||
|
|
||||||
const getParentObjId = folderName[folderName.length - 1];
|
const getParentObjId = folderName[folderName.length - 1];
|
||||||
const parentId = getParentObjId && getParentObjId.objectId;
|
const parentId = getParentObjId && getParentObjId.objectId;
|
||||||
let data;
|
const foldercls = `${localStorage.getItem("_appName")}_Document`;
|
||||||
if (parentId) {
|
const folderPtr = {
|
||||||
data = {
|
|
||||||
Name: newFolderName,
|
|
||||||
Type: "Folder",
|
|
||||||
Folder: {
|
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
className: `${localStorage.getItem("_appName")}_Document`,
|
className: foldercls,
|
||||||
objectId: parentId
|
objectId: parentId
|
||||||
},
|
};
|
||||||
CreatedBy: {
|
const CreatedBy = {
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
className: "_User",
|
className: "_User",
|
||||||
objectId: jsonCurrentUser.objectId
|
objectId: jsonCurrentUser.objectId
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exsitQuery = new Parse.Query(foldercls);
|
||||||
|
exsitQuery.equalTo("Name", newFolderName);
|
||||||
|
exsitQuery.equalTo("Type", "Folder");
|
||||||
|
if (parentId) {
|
||||||
|
exsitQuery.equalTo("Folder", folderPtr);
|
||||||
|
}
|
||||||
|
const templExist = await exsitQuery.first();
|
||||||
|
if (templExist) {
|
||||||
|
setError("Folder already exist!");
|
||||||
|
setIsFolderLoader(false);
|
||||||
} else {
|
} else {
|
||||||
data = {
|
const template = new Parse.Object(foldercls);
|
||||||
Name: newFolderName,
|
template.set("Name", newFolderName);
|
||||||
Type: "Folder",
|
template.set("Type", "Folder");
|
||||||
CreatedBy: {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: "_User",
|
|
||||||
objectId: jsonCurrentUser.objectId
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
await axios
|
if (parentId) {
|
||||||
.post(
|
template.set("Folder", folderPtr);
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
|
||||||
"_appName"
|
|
||||||
)}_Document`,
|
|
||||||
data,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
}
|
||||||
}
|
template.set("CreatedBy", CreatedBy);
|
||||||
)
|
const res = await template.save();
|
||||||
|
if (res) {
|
||||||
|
const result = JSON.parse(JSON.stringify(res));
|
||||||
|
|
||||||
.then((Listdata) => {
|
setPdfData((prev) => [...prev, result]);
|
||||||
// console.log("Listdata ", Listdata);
|
|
||||||
const json = Listdata.data;
|
|
||||||
// console.log("json ", json);
|
|
||||||
if (json) {
|
|
||||||
setNewFolderName();
|
setNewFolderName();
|
||||||
|
|
||||||
setIsFolderLoader(false);
|
setIsFolderLoader(false);
|
||||||
setIsFolder(false);
|
setIsFolder(false);
|
||||||
if (docId) {
|
|
||||||
getPdfFolderDocumentList();
|
|
||||||
} else {
|
|
||||||
getPdfDocumentList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
} catch (e) {
|
||||||
.catch((err) => {
|
|
||||||
setIsAlert({
|
setIsAlert({
|
||||||
isShow: true,
|
isShow: true,
|
||||||
alertMessage: "something went wrong"
|
alertMessage: "something went wrong!"
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setError("Please fill out this field");
|
setError("Please fill out this field");
|
||||||
}
|
}
|
||||||
@@ -249,11 +222,11 @@ function PdfFile() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortApps = () => {
|
const sortApps = (type, order, driveDetails) => {
|
||||||
const selectedSortType = selectedSort;
|
const selectedSortType = type ? type : selectedSort ? selectedSort : "Date";
|
||||||
const sortOrder = sortingOrder;
|
const sortOrder = order ? order : sortingOrder ? sortingOrder : "Decending";
|
||||||
|
|
||||||
let sortingData = pdfData;
|
let sortingData = driveDetails;
|
||||||
if (selectedSortType === "Name") {
|
if (selectedSortType === "Name") {
|
||||||
sortingApp(sortingData, "Name", sortOrder);
|
sortingApp(sortingData, "Name", sortOrder);
|
||||||
} else if (selectedSortType === "Date") {
|
} else if (selectedSortType === "Date") {
|
||||||
@@ -315,9 +288,9 @@ function PdfFile() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const closeMenuOnOutsideClick = (e) => {
|
const closeMenuOnOutsideClick = (e) => {
|
||||||
if (isShowSort && !e.target.closest("#menu-container")) {
|
if (isShowSort && !e.target.closest("#menu-container")) {
|
||||||
setIsShowSort(false);
|
setIsShowSort(!isShowSort);
|
||||||
} else if (isNewFol && !e.target.closest("#folder-menu")) {
|
} else if (isNewFol && !e.target.closest("#folder-menu")) {
|
||||||
setIsNewFol(false);
|
setIsNewFol(!isNewFol);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -327,33 +300,88 @@ function PdfFile() {
|
|||||||
// Cleanup the event listener when the component unmounts
|
// Cleanup the event listener when the component unmounts
|
||||||
document.removeEventListener("click", closeMenuOnOutsideClick);
|
document.removeEventListener("click", closeMenuOnOutsideClick);
|
||||||
};
|
};
|
||||||
}, [isShowSort]);
|
}, [isShowSort || isNewFol]);
|
||||||
|
|
||||||
|
const handleFolderTab = (folderData, isMove) => {
|
||||||
|
return folderData.map((data, id) => {
|
||||||
return (
|
return (
|
||||||
<div className="folderComponent ">
|
<React.Fragment key={id}>
|
||||||
<div>
|
|
||||||
<AlertComponent
|
|
||||||
isShow={isAlert.isShow}
|
|
||||||
alertMessage={isAlert.alertMessage}
|
|
||||||
setIsAlert={setIsAlert}
|
|
||||||
/>
|
|
||||||
<Modal show={isFolder}>
|
|
||||||
<ModalHeader style={{ background: themeColor() }}>
|
|
||||||
<span style={{ color: "white" }}>Add New Folder</span>
|
|
||||||
{!folderLoader && (
|
|
||||||
<span
|
<span
|
||||||
style={{ cursor: "pointer" }}
|
onClick={() => handleRoute(id)}
|
||||||
onClick={() => {
|
style={{
|
||||||
setNewFolderName("");
|
color: "#a64b4e",
|
||||||
setIsFolder(false);
|
fontWeight: "400",
|
||||||
|
cursor: "pointer"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
X
|
{data.name}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: "#a64b4e",
|
||||||
|
fontWeight: "200",
|
||||||
|
cursor: "pointer",
|
||||||
|
margin: "0 4px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
)}
|
</span>
|
||||||
</ModalHeader>
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const oncloseFolder = () => {
|
||||||
|
setIsFolder(false);
|
||||||
|
setNewFolderName("");
|
||||||
|
setError("");
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="folderComponent ">
|
||||||
|
<Title title={"OpenSign™ Drive"} drive={true} />
|
||||||
|
<div>
|
||||||
|
<ModalUi
|
||||||
|
headerColor={"#dc3545"}
|
||||||
|
isOpen={isAlert.isShow}
|
||||||
|
title={"Alert"}
|
||||||
|
handleClose={() => {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>{isAlert.alertMessage}</p>
|
||||||
|
|
||||||
<Modal.Body>
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setIsAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
<ModalUi
|
||||||
|
isOpen={isFolder}
|
||||||
|
title={"Add New Folder"}
|
||||||
|
handleClose={oncloseFolder}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
{folderLoader ? (
|
{folderLoader ? (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -374,7 +402,13 @@ function PdfFile() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<form style={{ display: "flex", flexDirection: "column" }}>
|
<form
|
||||||
|
onSubmit={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleAddFolder();
|
||||||
|
}}
|
||||||
|
style={{ display: "flex", flexDirection: "column" }}
|
||||||
|
>
|
||||||
<label
|
<label
|
||||||
style={{
|
style={{
|
||||||
margin: "10px 0px 10px 0px",
|
margin: "10px 0px 10px 0px",
|
||||||
@@ -382,57 +416,54 @@ function PdfFile() {
|
|||||||
fontWeight: "400"
|
fontWeight: "400"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Name*
|
Name
|
||||||
|
<span style={{ color: "red" }}>*</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
required
|
required
|
||||||
className="form-control"
|
className="form-control inputStyle"
|
||||||
type="text"
|
type="text"
|
||||||
value={newFolderName}
|
value={newFolderName}
|
||||||
onChange={(e) => handleFolderName(e)}
|
onChange={(e) => handleFolderName(e)}
|
||||||
// className="addFolderInput"
|
// className="addFolderInput"
|
||||||
/>
|
/>
|
||||||
<span style={{ color: "red", fontSize: "12px" }}>{error}</span>
|
<span
|
||||||
|
style={{ color: "red", fontSize: "12px", marginTop: "6px" }}
|
||||||
|
>
|
||||||
|
{error}
|
||||||
|
</span>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
margin: "20px 10px 10px 10px ",
|
height: "1px",
|
||||||
display: "flex",
|
backgroundColor: "#9f9f9f",
|
||||||
alignItems: "flex-end",
|
width: "100%",
|
||||||
justifyContent: "flex-end",
|
marginTop: "15px",
|
||||||
alignContent: "flex-end"
|
marginBottom: "15px"
|
||||||
}}
|
}}
|
||||||
>
|
></div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
|
||||||
style={{
|
|
||||||
borderRadius: "0px",
|
|
||||||
border: "1.5px solid #e3e2e1",
|
|
||||||
fontWeight: "600",
|
|
||||||
color: "black"
|
|
||||||
}}
|
|
||||||
className="finishBtn"
|
|
||||||
onClick={() => setIsFolder(false)}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={() => handleAddFolder()}
|
|
||||||
style={{
|
style={{
|
||||||
background: themeColor()
|
background: themeColor()
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="submit"
|
||||||
className="finishBtn"
|
className="finishBtn"
|
||||||
>
|
>
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
onClick={oncloseFolder}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
</Modal.Body>
|
</div>
|
||||||
</Modal>
|
</ModalUi>
|
||||||
|
|
||||||
{isLoading.isLoad ? (
|
{isLoading.isLoad ? (
|
||||||
<div
|
<div
|
||||||
@@ -479,31 +510,7 @@ function PdfFile() {
|
|||||||
}}
|
}}
|
||||||
className="folderPath"
|
className="folderPath"
|
||||||
>
|
>
|
||||||
{folderName.map((data, id) => {
|
{handleFolderTab(folderName)}
|
||||||
return (
|
|
||||||
<span
|
|
||||||
key={id}
|
|
||||||
onClick={() => handleRoute(data)}
|
|
||||||
style={{
|
|
||||||
color: "#a64b4e",
|
|
||||||
fontWeight: "400",
|
|
||||||
cursor: "pointer"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{data.name}
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: "#a64b4e",
|
|
||||||
fontWeight: "200",
|
|
||||||
cursor: "pointer",
|
|
||||||
margin: "0 4px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="dropMenuBD">
|
<div className="dropMenuBD">
|
||||||
<div
|
<div
|
||||||
@@ -603,7 +610,7 @@ function PdfFile() {
|
|||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedSort("Name");
|
setSelectedSort("Name");
|
||||||
sortApps();
|
sortApps("Name", null, pdfData);
|
||||||
}}
|
}}
|
||||||
className="dropdown-item itemColor"
|
className="dropdown-item itemColor"
|
||||||
>
|
>
|
||||||
@@ -625,7 +632,7 @@ function PdfFile() {
|
|||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedSort("Date");
|
setSelectedSort("Date");
|
||||||
sortApps();
|
sortApps("Date", null, pdfData);
|
||||||
}}
|
}}
|
||||||
className="dropdown-item itemColor"
|
className="dropdown-item itemColor"
|
||||||
>
|
>
|
||||||
@@ -648,7 +655,7 @@ function PdfFile() {
|
|||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSortingOrder("Accending");
|
setSortingOrder("Accending");
|
||||||
sortApps();
|
sortApps(null, "Accending", pdfData);
|
||||||
}}
|
}}
|
||||||
className="dropdown-item itemColor"
|
className="dropdown-item itemColor"
|
||||||
>
|
>
|
||||||
@@ -670,7 +677,7 @@ function PdfFile() {
|
|||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSortingOrder("Decending");
|
setSortingOrder("Decending");
|
||||||
sortApps();
|
sortApps(null, "Decending", pdfData);
|
||||||
}}
|
}}
|
||||||
className="dropdown-item itemColor"
|
className="dropdown-item itemColor"
|
||||||
>
|
>
|
||||||
@@ -738,6 +745,7 @@ function PdfFile() {
|
|||||||
isDocId={docId}
|
isDocId={docId}
|
||||||
setPdfData={setPdfData}
|
setPdfData={setPdfData}
|
||||||
isList={isList}
|
isList={isList}
|
||||||
|
setIsAlert={setIsAlert}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ const ManageSign = () => {
|
|||||||
file = base64StringtoFile(image, `${replaceSpace}.png`);
|
file = base64StringtoFile(image, `${replaceSpace}.png`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("isUrl ", isUrl);
|
// console.log("isUrl ", isUrl);
|
||||||
let imgUrl;
|
let imgUrl;
|
||||||
if (!isUrl) {
|
if (!isUrl) {
|
||||||
imgUrl = await uploadFile(file);
|
imgUrl = await uploadFile(file);
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import { themeColor } from "../utils/ThemeColor/backColor";
|
|||||||
import { PDFDocument } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import "../css/signature.css";
|
import "../css/signature.css";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
|
||||||
import Modal from "react-bootstrap/Modal";
|
|
||||||
import loader from "../assests/loader2.gif";
|
import loader from "../assests/loader2.gif";
|
||||||
import { DndProvider } from "react-dnd";
|
import { DndProvider } from "react-dnd";
|
||||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||||
@@ -12,17 +10,15 @@ import { useParams } from "react-router-dom";
|
|||||||
import SignPad from "./component/signPad";
|
import SignPad from "./component/signPad";
|
||||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||||
import {
|
import {
|
||||||
convertPNGtoJPEG,
|
|
||||||
contractDocument,
|
contractDocument,
|
||||||
getBase64FromIMG,
|
|
||||||
getBase64FromUrl,
|
|
||||||
urlValidator,
|
|
||||||
multiSignEmbed,
|
multiSignEmbed,
|
||||||
embedDocId,
|
embedDocId,
|
||||||
pdfNewWidthFun,
|
pdfNewWidthFun,
|
||||||
signPdfFun,
|
signPdfFun,
|
||||||
calculateImgAspectRatio,
|
onImageSelect,
|
||||||
onImageSelect
|
onSaveSign,
|
||||||
|
onSaveImage,
|
||||||
|
addDefaultSignatureImg
|
||||||
} from "../utils/Utils";
|
} from "../utils/Utils";
|
||||||
import Loader from "./component/loader";
|
import Loader from "./component/loader";
|
||||||
import HandleError from "./component/HandleError";
|
import HandleError from "./component/HandleError";
|
||||||
@@ -30,7 +26,9 @@ import Nodata from "./component/Nodata";
|
|||||||
import Header from "./component/header";
|
import Header from "./component/header";
|
||||||
import RenderPdf from "./component/renderPdf";
|
import RenderPdf from "./component/renderPdf";
|
||||||
import CustomModal from "./component/CustomModal";
|
import CustomModal from "./component/CustomModal";
|
||||||
import AlertComponent from "./component/alertComponent";
|
import Title from "./component/Title";
|
||||||
|
import DefaultSignature from "./component/defaultSignature";
|
||||||
|
import ModalUi from "../premitives/ModalUi";
|
||||||
|
|
||||||
function PdfRequestFiles() {
|
function PdfRequestFiles() {
|
||||||
const { docId } = useParams();
|
const { docId } = useParams();
|
||||||
@@ -65,6 +63,10 @@ function PdfRequestFiles() {
|
|||||||
const [isDecline, setIsDecline] = useState({ isDeclined: false });
|
const [isDecline, setIsDecline] = useState({ isDeclined: false });
|
||||||
const [currentSigner, setCurrentSigner] = useState(false);
|
const [currentSigner, setCurrentSigner] = useState(false);
|
||||||
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
||||||
|
const [defaultSignAlert, setDefaultSignAlert] = useState({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
const [isCompleted, setIsCompleted] = useState({
|
const [isCompleted, setIsCompleted] = useState({
|
||||||
isCertificate: false,
|
isCertificate: false,
|
||||||
isModal: false
|
isModal: false
|
||||||
@@ -193,7 +195,7 @@ function PdfRequestFiles() {
|
|||||||
for (let i = 0; i < signerRes.length; i++) {
|
for (let i = 0; i < signerRes.length; i++) {
|
||||||
const signerId = signerRes[i].objectId;
|
const signerId = signerRes[i].objectId;
|
||||||
|
|
||||||
let isSigned = false;
|
let isSignedSignature = false;
|
||||||
for (let j = 0; j < checkDocIdExist.length; j++) {
|
for (let j = 0; j < checkDocIdExist.length; j++) {
|
||||||
const signedExist =
|
const signedExist =
|
||||||
checkDocIdExist[j] && checkDocIdExist[j].UserPtr.objectId;
|
checkDocIdExist[j] && checkDocIdExist[j].UserPtr.objectId;
|
||||||
@@ -202,12 +204,12 @@ function PdfRequestFiles() {
|
|||||||
|
|
||||||
if (signerId === signedExist) {
|
if (signerId === signedExist) {
|
||||||
signers.push({ ...signerRes[i], ...signerRes[i] });
|
signers.push({ ...signerRes[i], ...signerRes[i] });
|
||||||
isSigned = true;
|
isSignedSignature = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if does not match then add unsigned data in unSignedSigner array
|
// if does not match then add unsigned data in unSignedSigner array
|
||||||
}
|
}
|
||||||
if (!isSigned) {
|
if (!isSignedSignature) {
|
||||||
unSignedSigner.push({ ...signerRes[i], ...signerRes[i] });
|
unSignedSigner.push({ ...signerRes[i], ...signerRes[i] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,96 +315,98 @@ function PdfRequestFiles() {
|
|||||||
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
||||||
ignoreEncryption: true
|
ignoreEncryption: true
|
||||||
});
|
});
|
||||||
let pdfBase64;
|
// let pdfBase64;
|
||||||
|
|
||||||
//checking if signature is only one then send image url in jpeg formate to server
|
//checking if signature is only one then send image url in jpeg formate to server
|
||||||
if (pngUrl.length === 1 && pngUrl[0].pos.length === 1) {
|
// if (pngUrl.length === 1 && pngUrl[0].pos.length === 1) {
|
||||||
if (isDocId) {
|
// if (isDocId) {
|
||||||
try {
|
// try {
|
||||||
pdfBase64 = await getBase64FromUrl(pdfUrl);
|
// pdfBase64 = await getBase64FromUrl(pdfUrl);
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
console.log(err);
|
// console.log(err);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
//embed document's object id to all pages in pdf document
|
// //embed document's object id to all pages in pdf document
|
||||||
try {
|
// try {
|
||||||
await embedDocId(pdfDoc, documentId, allPages);
|
// await embedDocId(pdfDoc, documentId, allPages);
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
console.log(err);
|
// console.log(err);
|
||||||
}
|
// }
|
||||||
try {
|
// try {
|
||||||
pdfBase64 = await pdfDoc.saveAsBase64({
|
// pdfBase64 = await pdfDoc.saveAsBase64({
|
||||||
useObjectStreams: false
|
// useObjectStreams: false
|
||||||
});
|
// });
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
console.log(err);
|
// console.log(err);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for (let pngData of pngUrl) {
|
// for (let pngData of pngUrl) {
|
||||||
const imgUrlList = pngData.pos;
|
// const imgUrlList = pngData.pos;
|
||||||
const pageNo = pngData.pageNumber;
|
// const pageNo = pngData.pageNumber;
|
||||||
imgUrlList.map(async (data) => {
|
// imgUrlList.map(async (data) => {
|
||||||
//cheking signUrl is defau;t signature url of custom url
|
// //cheking signUrl is defau;t signature url of custom url
|
||||||
let ImgUrl = data.SignUrl;
|
// let ImgUrl = data.SignUrl;
|
||||||
const checkUrl = urlValidator(ImgUrl);
|
// const checkUrl = urlValidator(ImgUrl);
|
||||||
//if default signature url then convert it in base 64
|
// //if default signature url then convert it in base 64
|
||||||
if (checkUrl) {
|
// if (checkUrl) {
|
||||||
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
// ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
||||||
}
|
// }
|
||||||
//function for called convert png signatre to jpeg in base 64
|
// //function for called convert png signatre to jpeg in base 64
|
||||||
convertPNGtoJPEG(ImgUrl)
|
// convertPNGtoJPEG(ImgUrl)
|
||||||
.then((jpegBase64Data) => {
|
// .then((jpegBase64Data) => {
|
||||||
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
// const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
||||||
const newImgUrl = jpegBase64Data.replace(
|
// const newImgUrl = jpegBase64Data.replace(
|
||||||
removeBase64Fromjpeg,
|
// removeBase64Fromjpeg,
|
||||||
""
|
// ""
|
||||||
);
|
// );
|
||||||
|
|
||||||
//function for call to embed signature in pdf and get digital signature pdf
|
// //function for call to embed signature in pdf and get digital signature pdf
|
||||||
signPdfFun(
|
// signPdfFun(
|
||||||
newImgUrl,
|
// newImgUrl,
|
||||||
documentId,
|
// documentId,
|
||||||
signerObjectId,
|
// signerObjectId,
|
||||||
pdfOriginalWidth,
|
// pdfOriginalWidth,
|
||||||
pngUrl,
|
// pngUrl,
|
||||||
containerWH,
|
// containerWH,
|
||||||
setIsAlert,
|
// setIsAlert,
|
||||||
data,
|
// data,
|
||||||
pdfBase64,
|
// pdfBase64,
|
||||||
pageNo
|
// pageNo
|
||||||
)
|
// )
|
||||||
.then((res) => {
|
// .then((res) => {
|
||||||
if (res && res.status === "success") {
|
// if (res && res.status === "success") {
|
||||||
setPdfUrl(res.data);
|
// setPdfUrl(res.data);
|
||||||
setIsSigned(true);
|
// setIsSigned(true);
|
||||||
setSignedSigners([]);
|
// setSignedSigners([]);
|
||||||
setUnSignedSigners([]);
|
// setUnSignedSigners([]);
|
||||||
getDocumentDetails();
|
// getDocumentDetails();
|
||||||
} else {
|
// } else {
|
||||||
setIsAlert({
|
// setIsAlert({
|
||||||
isShow: true,
|
// isShow: true,
|
||||||
alertMessage: "something went wrong"
|
// alertMessage: "something went wrong"
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
.catch((err) => {
|
// .catch((err) => {
|
||||||
setIsAlert({
|
// setIsAlert({
|
||||||
isShow: true,
|
// isShow: true,
|
||||||
alertMessage: "something went wrong"
|
// alertMessage: "something went wrong"
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
})
|
// })
|
||||||
.catch((error) => {
|
// .catch((error) => {
|
||||||
console.error("Error:", error);
|
// console.error("Error:", error);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
//else if signature is more than one then embed all sign with the use of pdf-lib
|
// //else if signature is more than one then embed all sign with the use of pdf-lib
|
||||||
else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) {
|
// else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) {
|
||||||
const flag = false;
|
const flag = false;
|
||||||
//embed document's object id to all pages in pdf document
|
//embed document's object id to all pages in pdf document
|
||||||
|
if (!isDocId) {
|
||||||
await embedDocId(pdfDoc, documentId, allPages);
|
await embedDocId(pdfDoc, documentId, allPages);
|
||||||
|
}
|
||||||
//embed multi signature in pdf
|
//embed multi signature in pdf
|
||||||
const pdfBytes = await multiSignEmbed(
|
const pdfBytes = await multiSignEmbed(
|
||||||
pngUrl,
|
pngUrl,
|
||||||
@@ -411,7 +415,6 @@ function PdfRequestFiles() {
|
|||||||
flag,
|
flag,
|
||||||
containerWH
|
containerWH
|
||||||
);
|
);
|
||||||
|
|
||||||
//function for call to embed signature in pdf and get digital signature pdf
|
//function for call to embed signature in pdf and get digital signature pdf
|
||||||
try {
|
try {
|
||||||
const res = await signPdfFun(
|
const res = await signPdfFun(
|
||||||
@@ -444,7 +447,7 @@ function PdfRequestFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
}
|
// }
|
||||||
} else {
|
} else {
|
||||||
setIsAlert({
|
setIsAlert({
|
||||||
isShow: true,
|
isShow: true,
|
||||||
@@ -482,168 +485,89 @@ function PdfRequestFiles() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
//function for upload stamp image
|
//function for upload stamp image
|
||||||
const onSaveImage = () => {
|
const saveImage = () => {
|
||||||
|
//get current signers placeholder position data
|
||||||
const currentSigner = signerPos.filter(
|
const currentSigner = signerPos.filter(
|
||||||
(data) => data.signerObjId === signerObjectId
|
(data) => data.signerObjId === signerObjectId
|
||||||
);
|
);
|
||||||
const i = currentSigner[0].placeHolder.findIndex((object) => {
|
//get current pagenumber placeholder index
|
||||||
|
const getIndex = currentSigner[0].placeHolder.findIndex((object) => {
|
||||||
return object.pageNumber === pageNumber;
|
return object.pageNumber === pageNumber;
|
||||||
});
|
});
|
||||||
const updateFilter = currentSigner[0].placeHolder[i].pos.filter(
|
//get current signer placeholder position data
|
||||||
(data) =>
|
const placeholderPosition = currentSigner[0].placeHolder;
|
||||||
data.key === signKey && data.Width && data.Height && data.SignUrl
|
//function of save image and get updated position with image url
|
||||||
|
const getUpdatePosition = onSaveImage(
|
||||||
|
placeholderPosition,
|
||||||
|
getIndex,
|
||||||
|
signKey,
|
||||||
|
imgWH,
|
||||||
|
image
|
||||||
);
|
);
|
||||||
let getIMGWH = calculateImgAspectRatio(imgWH);
|
|
||||||
|
|
||||||
if (updateFilter.length > 0) {
|
|
||||||
const getXYdata = currentSigner[0].placeHolder[i].pos;
|
|
||||||
const getPosData = getXYdata;
|
|
||||||
const addSign = getPosData.map((url, ind) => {
|
|
||||||
if (url.key === signKey) {
|
|
||||||
return {
|
|
||||||
...url,
|
|
||||||
Width: getIMGWH.newWidth,
|
|
||||||
Height: getIMGWH.newHeight,
|
|
||||||
SignUrl: image.src,
|
|
||||||
ImageType: image.imgType
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateUrl = currentSigner[0].placeHolder.map((obj, ind) => {
|
|
||||||
if (ind === i) {
|
|
||||||
return { ...obj, pos: addSign };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
const getPlaceData = currentSigner[0].placeHolder;
|
|
||||||
getPlaceData.splice(0, getPlaceData.length, ...newUpdateUrl);
|
|
||||||
|
|
||||||
|
//replace updated placeholder position with old data
|
||||||
|
placeholderPosition.splice(
|
||||||
|
0,
|
||||||
|
placeholderPosition.length,
|
||||||
|
...getUpdatePosition
|
||||||
|
);
|
||||||
|
//get current signers placeholder position data index number in array
|
||||||
const indexofSigner = signerPos.findIndex((object) => {
|
const indexofSigner = signerPos.findIndex((object) => {
|
||||||
return object.signerObjId === signerObjectId;
|
return object.signerObjId === signerObjectId;
|
||||||
});
|
});
|
||||||
|
//update current signers data with new placeholder position array data
|
||||||
setSignerPos((prevState) => {
|
setSignerPos((prevState) => {
|
||||||
const newState = [...prevState]; // Create a copy of the state
|
const newState = [...prevState]; // Create a copy of the state
|
||||||
newState.splice(indexofSigner, 1, ...currentSigner); // Modify the copy
|
newState.splice(indexofSigner, 1, ...currentSigner); // Modify the copy
|
||||||
return newState; // Update the state with the modified copy
|
return newState; // Update the state with the modified copy
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
const getXYdata = currentSigner[0].placeHolder[i].pos;
|
|
||||||
|
|
||||||
const getPosData = getXYdata;
|
|
||||||
|
|
||||||
const addSign = getPosData.map((url, ind) => {
|
|
||||||
if (url.key === signKey) {
|
|
||||||
return {
|
|
||||||
...url,
|
|
||||||
Width: getIMGWH.newWidth,
|
|
||||||
Height: getIMGWH.newHeight,
|
|
||||||
SignUrl: image.src,
|
|
||||||
ImageType: image.imgType
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateUrl = currentSigner[0].placeHolder.map((obj, ind) => {
|
|
||||||
if (ind === i) {
|
|
||||||
return { ...obj, pos: addSign };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getPlaceData = currentSigner[0].placeHolder;
|
|
||||||
getPlaceData.splice(0, getPlaceData.length, ...newUpdateUrl);
|
|
||||||
|
|
||||||
const indexofSigner = signerPos.findIndex((object) => {
|
|
||||||
return object.signerObjId === signerObjectId;
|
|
||||||
});
|
|
||||||
setSignerPos((prevState) => {
|
|
||||||
const newState = [...prevState]; // Create a copy of the state
|
|
||||||
newState.splice(indexofSigner, 1, ...currentSigner); // Modify the copy
|
|
||||||
return newState; // Update the state with the modified copy
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for save button to save signature or image url
|
//function for save button to save signature or image url
|
||||||
const onSaveSign = (isDefaultSign) => {
|
const saveSign = (isDefaultSign, width, height) => {
|
||||||
|
const isTypeText = width && height ? true : false;
|
||||||
const signatureImg = isDefaultSign ? defaultSignImg : signature;
|
const signatureImg = isDefaultSign ? defaultSignImg : signature;
|
||||||
const isSign = true;
|
let imgWH = { width: width ? width : "", height: height ? height : "" };
|
||||||
let getIMGWH;
|
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
setIsImageSelect(false);
|
setIsImageSelect(false);
|
||||||
setImage();
|
setImage();
|
||||||
|
|
||||||
|
//get current signers placeholder position data
|
||||||
|
const currentSigner = signerPos.filter(
|
||||||
|
(data) => data.signerObjId === signerObjectId
|
||||||
|
);
|
||||||
|
//get current pagenumber placeholder index
|
||||||
|
const getIndex = currentSigner[0].placeHolder.findIndex((object) => {
|
||||||
|
return object.pageNumber === pageNumber;
|
||||||
|
});
|
||||||
|
|
||||||
|
//set default signature image width and height
|
||||||
if (isDefaultSign) {
|
if (isDefaultSign) {
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.src = defaultSignImg;
|
img.src = defaultSignImg;
|
||||||
if (img.complete) {
|
if (img.complete) {
|
||||||
let imgWH = {
|
imgWH = {
|
||||||
width: img.width,
|
width: img.width,
|
||||||
height: img.height
|
height: img.height
|
||||||
};
|
};
|
||||||
getIMGWH = calculateImgAspectRatio(imgWH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const currentSigner = signerPos.filter(
|
//get current signer placeholder position data
|
||||||
(data) => data.signerObjId === signerObjectId
|
const placeholderPosition = currentSigner[0].placeHolder;
|
||||||
|
//function of save signature image and get updated position with signature image url
|
||||||
|
const getUpdatePosition = onSaveSign(
|
||||||
|
placeholderPosition,
|
||||||
|
getIndex,
|
||||||
|
signKey,
|
||||||
|
signatureImg,
|
||||||
|
imgWH,
|
||||||
|
isDefaultSign,
|
||||||
|
isTypeText
|
||||||
);
|
);
|
||||||
|
|
||||||
const i = currentSigner[0].placeHolder.findIndex((object) => {
|
const updateSignerData = currentSigner.map((obj, ind) => {
|
||||||
return object.pageNumber === pageNumber;
|
|
||||||
});
|
|
||||||
|
|
||||||
let updateFilter;
|
|
||||||
|
|
||||||
updateFilter = currentSigner[0].placeHolder[i].pos.filter(
|
|
||||||
(data) => data.key === signKey && data.SignUrl
|
|
||||||
);
|
|
||||||
|
|
||||||
const getXYdata = currentSigner[0].placeHolder[i].pos;
|
|
||||||
const getPosData = getXYdata;
|
|
||||||
const posWidth = isDefaultSign
|
|
||||||
? getIMGWH.newWidth
|
|
||||||
: isSign && getPosData[0].ImageType
|
|
||||||
? 150
|
|
||||||
: getPosData[0].Width
|
|
||||||
? getPosData[0].Width
|
|
||||||
: 150;
|
|
||||||
const posHidth = isDefaultSign
|
|
||||||
? getIMGWH.newHeight
|
|
||||||
: isSign && getPosData[0].ImageType
|
|
||||||
? 60
|
|
||||||
: getPosData[0].Height
|
|
||||||
? getPosData[0].Height
|
|
||||||
: 60;
|
|
||||||
if (updateFilter.length > 0) {
|
|
||||||
updateFilter[0].SignUrl = signatureImg;
|
|
||||||
updateFilter[0].Width = posWidth;
|
|
||||||
updateFilter[0].Height = posHidth;
|
|
||||||
} else {
|
|
||||||
const addSign = getPosData.map((url, ind) => {
|
|
||||||
if (url.key === signKey) {
|
|
||||||
return {
|
|
||||||
...url,
|
|
||||||
SignUrl: signatureImg,
|
|
||||||
Width: posWidth,
|
|
||||||
Height: posHidth,
|
|
||||||
ImageType: "sign"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateUrl = currentSigner[0].placeHolder.map((obj, ind) => {
|
|
||||||
if (obj.pageNumber === pageNumber) {
|
|
||||||
return { ...obj, pos: addSign };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdatePos = currentSigner.map((obj, ind) => {
|
|
||||||
if (obj.signerObjId === signerObjectId) {
|
if (obj.signerObjId === signerObjectId) {
|
||||||
return { ...obj, placeHolder: newUpdateUrl };
|
return { ...obj, placeHolder: getUpdatePosition };
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
@@ -652,11 +576,10 @@ function PdfRequestFiles() {
|
|||||||
(data) => data.signerObjId === signerObjectId
|
(data) => data.signerObjId === signerObjectId
|
||||||
);
|
);
|
||||||
setSignerPos((prevState) => {
|
setSignerPos((prevState) => {
|
||||||
const newState = [...prevState]; // Create a copy of the state
|
const newState = [...prevState];
|
||||||
newState.splice(index, 1, ...newUpdatePos); // Modify the copy
|
newState.splice(index, 1, ...updateSignerData);
|
||||||
return newState; // Update the state with the modified copy
|
return newState;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkSignerBackColor = (obj) => {
|
const checkSignerBackColor = (obj) => {
|
||||||
@@ -701,9 +624,31 @@ function PdfRequestFiles() {
|
|||||||
console.log("error updating field is decline ", err);
|
console.log("error updating field is decline ", err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
//function to add default signature for all requested placeholder of sign
|
||||||
|
const addDefaultSignature = () => {
|
||||||
|
//get current signers placeholder position data
|
||||||
|
const currentSignerPosition = signerPos.filter(
|
||||||
|
(data) => data.signerObjId === signerObjectId
|
||||||
|
);
|
||||||
|
//function for save default signature url for all placeholder position
|
||||||
|
const updatePlace = addDefaultSignatureImg(
|
||||||
|
currentSignerPosition[0].placeHolder,
|
||||||
|
defaultSignImg
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatesignerPos = signerPos.map((x) =>
|
||||||
|
x.signerObjId === signerObjectId ? { ...x, placeHolder: updatePlace } : x
|
||||||
|
);
|
||||||
|
setSignerPos(updatesignerPos);
|
||||||
|
setDefaultSignAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
|
<Title title={"Request Sign"} />
|
||||||
{isLoading.isLoad ? (
|
{isLoading.isLoad ? (
|
||||||
<Loader isLoading={isLoading} />
|
<Loader isLoading={isLoading} />
|
||||||
) : handleError ? (
|
) : handleError ? (
|
||||||
@@ -739,16 +684,49 @@ function PdfRequestFiles() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="signatureContainer" ref={divRef}>
|
<div className="signatureContainer" ref={divRef}>
|
||||||
<AlertComponent
|
<ModalUi
|
||||||
isShow={isAlert.isShow}
|
headerColor={"#dc3545"}
|
||||||
alertMessage={isAlert.alertMessage}
|
isOpen={isAlert.isShow}
|
||||||
setIsAlert={setIsAlert}
|
title={"Alert message"}
|
||||||
/>
|
handleClose={() => {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>{isAlert.alertMessage}</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
>
|
||||||
|
Ok
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
{/* this modal is used to show decline alert */}
|
{/* this modal is used to show decline alert */}
|
||||||
<CustomModal
|
<CustomModal
|
||||||
containerWH={containerWH}
|
containerWH={containerWH}
|
||||||
show={isDecline.isDeclined}
|
show={isDecline.isDeclined}
|
||||||
headMsg="Document Declined Alert!"
|
headMsg="Document Declined"
|
||||||
bodyMssg={
|
bodyMssg={
|
||||||
isDecline.currnt === "Sure" ? (
|
isDecline.currnt === "Sure" ? (
|
||||||
<p className="pTagBody">
|
<p className="pTagBody">
|
||||||
@@ -776,12 +754,77 @@ function PdfRequestFiles() {
|
|||||||
headMsg="Document Expired!"
|
headMsg="Document Expired!"
|
||||||
bodyMssg="This Document is no longer available."
|
bodyMssg="This Document is no longer available."
|
||||||
/>
|
/>
|
||||||
|
<ModalUi
|
||||||
|
headerColor={defaultSignImg ? themeColor() : "#dc3545"}
|
||||||
|
isOpen={defaultSignAlert.isShow}
|
||||||
|
title={"Auto sign"}
|
||||||
|
handleClose={() => {
|
||||||
|
setDefaultSignAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>{defaultSignAlert.alertMessage}</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
{defaultSignImg ? (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
onClick={() => addDefaultSignature()}
|
||||||
|
style={{
|
||||||
|
background: themeColor()
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setDefaultSignAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
>
|
||||||
|
Ok
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
{/* this component used to render all pdf pages in left side */}
|
{/* this component used to render all pdf pages in left side */}
|
||||||
<RenderAllPdfPage
|
<RenderAllPdfPage
|
||||||
signPdfUrl={pdfDetails[0].URL}
|
signPdfUrl={pdfDetails[0].URL}
|
||||||
allPages={allPages}
|
allPages={allPages}
|
||||||
setAllPages={setAllPages}
|
setAllPages={setAllPages}
|
||||||
setPageNumber={setPageNumber}
|
setPageNumber={setPageNumber}
|
||||||
|
pageNumber={pageNumber}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* pdf render view */}
|
{/* pdf render view */}
|
||||||
@@ -792,33 +835,37 @@ function PdfRequestFiles() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* this modal is used show this document is already sign */}
|
{/* this modal is used show this document is already sign */}
|
||||||
|
<ModalUi
|
||||||
<Modal show={isCompleted.isModal}>
|
isOpen={isCompleted.isModal}
|
||||||
<ModalHeader style={{ background: themeColor() }}>
|
title={"Sign Documents"}
|
||||||
<span className="spanTagHead"> Sign Documents</span>
|
handleClose={() => {
|
||||||
</ModalHeader>
|
setIsCompleted({ isModal: false, isCertificate: true });
|
||||||
|
|
||||||
<Modal.Body>
|
|
||||||
<p className="pTagBody">
|
|
||||||
This document has been signed by all Signers.
|
|
||||||
</p>
|
|
||||||
</Modal.Body>
|
|
||||||
|
|
||||||
<Modal.Footer>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "black"
|
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>This document has been signed by all Signers.</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn"
|
className="finishBtn cancelBtn"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setIsCompleted({ isModal: false, isCertificate: true })
|
setIsCompleted({ isModal: false, isCertificate: true })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
</Modal.Footer>
|
</div>
|
||||||
</Modal>
|
</ModalUi>
|
||||||
|
|
||||||
{/* this component is used for signature pad modal */}
|
{/* this component is used for signature pad modal */}
|
||||||
<SignPad
|
<SignPad
|
||||||
isSignPad={isSignPad}
|
isSignPad={isSignPad}
|
||||||
@@ -831,8 +878,8 @@ function PdfRequestFiles() {
|
|||||||
onImageChange={onImageChange}
|
onImageChange={onImageChange}
|
||||||
setSignature={setSignature}
|
setSignature={setSignature}
|
||||||
image={image}
|
image={image}
|
||||||
onSaveImage={onSaveImage}
|
onSaveImage={saveImage}
|
||||||
onSaveSign={onSaveSign}
|
onSaveSign={saveSign}
|
||||||
defaultSign={defaultSignImg}
|
defaultSign={defaultSignImg}
|
||||||
/>
|
/>
|
||||||
{/* pdf header which contain funish back button */}
|
{/* pdf header which contain funish back button */}
|
||||||
@@ -880,6 +927,10 @@ function PdfRequestFiles() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="signerComponent">
|
<div className="signerComponent">
|
||||||
|
<div
|
||||||
|
style={{ maxHeight: window.innerHeight - 70 + "px" }}
|
||||||
|
className="autoSignScroll"
|
||||||
|
>
|
||||||
{signedSigners.length > 0 && (
|
{signedSigners.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@@ -888,7 +939,7 @@ function PdfRequestFiles() {
|
|||||||
}}
|
}}
|
||||||
className="signedStyle"
|
className="signedStyle"
|
||||||
>
|
>
|
||||||
Signed By
|
Signed by
|
||||||
</div>
|
</div>
|
||||||
<div style={{ marginTop: "2px" }}>
|
<div style={{ marginTop: "2px" }}>
|
||||||
{signedSigners.map((obj, ind) => {
|
{signedSigners.map((obj, ind) => {
|
||||||
@@ -897,8 +948,8 @@ function PdfRequestFiles() {
|
|||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
padding: "10px",
|
alignItems: "center",
|
||||||
|
padding: "10px 0",
|
||||||
background: checkSignerBackColor(obj)
|
background: checkSignerBackColor(obj)
|
||||||
}}
|
}}
|
||||||
key={ind}
|
key={ind}
|
||||||
@@ -913,17 +964,18 @@ function PdfRequestFiles() {
|
|||||||
borderRadius: 30 / 2,
|
borderRadius: 30 / 2,
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginRight: "20px"
|
margin: "0 10px 0 5px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: "10px",
|
fontSize: "12px",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
fontWeight: "bold"
|
fontWeight: "bold",
|
||||||
|
color: "black",
|
||||||
|
textTransform: "uppercase"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{" "}
|
|
||||||
{getFirstLetter(obj.Name)}
|
{getFirstLetter(obj.Name)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -954,7 +1006,7 @@ function PdfRequestFiles() {
|
|||||||
marginTop: signedSigners.length > 0 && "20px"
|
marginTop: signedSigners.length > 0 && "20px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Yet To Sign
|
Yet to sign
|
||||||
</div>
|
</div>
|
||||||
<div style={{ marginTop: "5px" }}>
|
<div style={{ marginTop: "5px" }}>
|
||||||
{unsignedSigners.map((obj, ind) => {
|
{unsignedSigners.map((obj, ind) => {
|
||||||
@@ -963,7 +1015,8 @@ function PdfRequestFiles() {
|
|||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
padding: "10px",
|
alignItems: "center",
|
||||||
|
padding: "10px 0",
|
||||||
background: checkSignerBackColor(obj)
|
background: checkSignerBackColor(obj)
|
||||||
}}
|
}}
|
||||||
key={ind}
|
key={ind}
|
||||||
@@ -972,23 +1025,24 @@ function PdfRequestFiles() {
|
|||||||
className="signerStyle"
|
className="signerStyle"
|
||||||
style={{
|
style={{
|
||||||
background: "#abd1d0",
|
background: "#abd1d0",
|
||||||
width: 20,
|
width: 30,
|
||||||
height: 20,
|
height: 30,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
borderRadius: 30 / 2,
|
borderRadius: 30 / 2,
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginRight: "20px"
|
margin: "0 10px 0 5px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: "8px",
|
fontSize: "12px",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
fontWeight: "bold"
|
fontWeight: "bold",
|
||||||
|
color: "black",
|
||||||
|
textTransform: "uppercase"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{" "}
|
|
||||||
{getFirstLetter(obj.Name)}
|
{getFirstLetter(obj.Name)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1008,6 +1062,18 @@ function PdfRequestFiles() {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{defaultSignImg && !alreadySign && (
|
||||||
|
<DefaultSignature
|
||||||
|
themeColor={themeColor}
|
||||||
|
defaultSignImg={defaultSignImg}
|
||||||
|
setDefaultSignImg={setDefaultSignImg}
|
||||||
|
userObjectId={signerObjectId}
|
||||||
|
setIsLoading={setIsLoading}
|
||||||
|
xyPostion={signerPos}
|
||||||
|
setDefaultSignAlert={setDefaultSignAlert}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,12 +13,8 @@ import { useDrag, useDrop } from "react-dnd";
|
|||||||
import SignPad from "./component/signPad";
|
import SignPad from "./component/signPad";
|
||||||
import EmailComponent from "./component/emailComponent";
|
import EmailComponent from "./component/emailComponent";
|
||||||
import FieldsComponent from "./component/fieldsComponent";
|
import FieldsComponent from "./component/fieldsComponent";
|
||||||
import Modal from "react-bootstrap/Modal";
|
|
||||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
|
||||||
import {
|
import {
|
||||||
convertPNGtoJPEG,
|
|
||||||
contractDocument,
|
contractDocument,
|
||||||
getBase64FromIMG,
|
|
||||||
embedDocId,
|
embedDocId,
|
||||||
multiSignEmbed,
|
multiSignEmbed,
|
||||||
pdfNewWidthFun,
|
pdfNewWidthFun,
|
||||||
@@ -33,9 +29,11 @@ import HandleError from "./component/HandleError";
|
|||||||
import Nodata from "./component/Nodata";
|
import Nodata from "./component/Nodata";
|
||||||
import Header from "./component/header";
|
import Header from "./component/header";
|
||||||
import RenderPdf from "./component/renderPdf";
|
import RenderPdf from "./component/renderPdf";
|
||||||
import { contractUsers, contactBook, urlValidator } from "../utils/Utils";
|
import { contractUsers, contactBook } from "../utils/Utils";
|
||||||
import { modalAlign } from "../utils/Utils";
|
import PlaceholderCopy from "./component/PlaceholderCopy";
|
||||||
import AlertComponent from "./component/alertComponent";
|
import TourContentWithBtn from "../premitives/TourContentWithBtn";
|
||||||
|
import Title from "./component/Title";
|
||||||
|
import ModalUi from "../premitives/ModalUi";
|
||||||
|
|
||||||
//For signYourself inProgress section signer can add sign and complete doc sign.
|
//For signYourself inProgress section signer can add sign and complete doc sign.
|
||||||
function SignYourSelf() {
|
function SignYourSelf() {
|
||||||
@@ -79,6 +77,7 @@ function SignYourSelf() {
|
|||||||
const [noData, setNoData] = useState(false);
|
const [noData, setNoData] = useState(false);
|
||||||
const [contractName, setContractName] = useState("");
|
const [contractName, setContractName] = useState("");
|
||||||
const [containerWH, setContainerWH] = useState({});
|
const [containerWH, setContainerWH] = useState({});
|
||||||
|
const [isPageCopy, setIsPageCopy] = useState(false);
|
||||||
const [showAlreadySignDoc, setShowAlreadySignDoc] = useState({
|
const [showAlreadySignDoc, setShowAlreadySignDoc] = useState({
|
||||||
status: false
|
status: false
|
||||||
});
|
});
|
||||||
@@ -87,6 +86,7 @@ function SignYourSelf() {
|
|||||||
type: "load"
|
type: "load"
|
||||||
});
|
});
|
||||||
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
||||||
|
const [isDontShow, setIsDontShow] = useState(false);
|
||||||
const divRef = useRef(null);
|
const divRef = useRef(null);
|
||||||
const nodeRef = useRef(null);
|
const nodeRef = useRef(null);
|
||||||
const [{ isOver }, drop] = useDrop({
|
const [{ isOver }, drop] = useDrop({
|
||||||
@@ -102,7 +102,6 @@ function SignYourSelf() {
|
|||||||
|
|
||||||
const [{ isDragSign }, dragSignature] = useDrag({
|
const [{ isDragSign }, dragSignature] = useDrag({
|
||||||
type: "BOX",
|
type: "BOX",
|
||||||
|
|
||||||
item: {
|
item: {
|
||||||
type: "BOX",
|
type: "BOX",
|
||||||
id: 1,
|
id: 1,
|
||||||
@@ -115,7 +114,6 @@ function SignYourSelf() {
|
|||||||
|
|
||||||
const [{ isDragStamp }, dragStamp] = useDrag({
|
const [{ isDragStamp }, dragStamp] = useDrag({
|
||||||
type: "BOX",
|
type: "BOX",
|
||||||
|
|
||||||
item: {
|
item: {
|
||||||
type: "BOX",
|
type: "BOX",
|
||||||
id: 2,
|
id: 2,
|
||||||
@@ -140,7 +138,6 @@ function SignYourSelf() {
|
|||||||
|
|
||||||
const [{ isDragStampSS }, dragStampSS] = useDrag({
|
const [{ isDragStampSS }, dragStampSS] = useDrag({
|
||||||
type: "BOX",
|
type: "BOX",
|
||||||
|
|
||||||
item: {
|
item: {
|
||||||
type: "BOX",
|
type: "BOX",
|
||||||
id: 4,
|
id: 4,
|
||||||
@@ -329,7 +326,6 @@ function SignYourSelf() {
|
|||||||
isDrag: false,
|
isDrag: false,
|
||||||
key: key,
|
key: key,
|
||||||
isStamp: monitor,
|
isStamp: monitor,
|
||||||
|
|
||||||
yBottom: window.innerHeight / 2 - 60
|
yBottom: window.innerHeight / 2 - 60
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -442,44 +438,6 @@ function SignYourSelf() {
|
|||||||
ignoreEncryption: true
|
ignoreEncryption: true
|
||||||
});
|
});
|
||||||
|
|
||||||
//checking if signature is only one then send image url in jpeg formate to server
|
|
||||||
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
|
||||||
//embed document's object id to all pages in pdf document
|
|
||||||
await embedDocId(pdfDoc, documentId, allPages);
|
|
||||||
const pdfBase64 = await pdfDoc.saveAsBase64({
|
|
||||||
useObjectStreams: false
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let xyData of xyPostion) {
|
|
||||||
const imgUrlList = xyData.pos;
|
|
||||||
const pageNo = xyData.pageNumber;
|
|
||||||
imgUrlList.map(async (data) => {
|
|
||||||
let ImgUrl = data.SignUrl;
|
|
||||||
//cheking signUrl is defau;t signature url of custom url
|
|
||||||
const checkUrl = urlValidator(ImgUrl);
|
|
||||||
//if default signature url then convert it in base 64
|
|
||||||
if (checkUrl) {
|
|
||||||
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
|
||||||
}
|
|
||||||
//function for convert signature png base64 url to jpeg base64
|
|
||||||
convertPNGtoJPEG(ImgUrl)
|
|
||||||
.then((jpegBase64Data) => {
|
|
||||||
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
|
||||||
const newImgUrl = jpegBase64Data.replace(
|
|
||||||
removeBase64Fromjpeg,
|
|
||||||
""
|
|
||||||
);
|
|
||||||
//function for call to embed signature in pdf and get digital signature pdf
|
|
||||||
signPdfFun(newImgUrl, documentId, data, pdfBase64, pageNo);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Error:", error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//else if signature is more than one then embed all sign with the use of pdf-lib
|
|
||||||
else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
|
||||||
const flag = true;
|
const flag = true;
|
||||||
//embed document's object id to all pages in pdf document
|
//embed document's object id to all pages in pdf document
|
||||||
await embedDocId(pdfDoc, documentId, allPages);
|
await embedDocId(pdfDoc, documentId, allPages);
|
||||||
@@ -495,7 +453,6 @@ function SignYourSelf() {
|
|||||||
|
|
||||||
//function for call to embed signature in pdf and get digital signature pdf
|
//function for call to embed signature in pdf and get digital signature pdf
|
||||||
signPdfFun(pdfBytes, documentId);
|
signPdfFun(pdfBytes, documentId);
|
||||||
}
|
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
setIsEmail(true);
|
setIsEmail(true);
|
||||||
setXyPostion([]);
|
setXyPostion([]);
|
||||||
@@ -504,43 +461,11 @@ function SignYourSelf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//function for get digital signature
|
//function for get digital signature
|
||||||
const signPdfFun = async (
|
const signPdfFun = async (base64Url, documentId) => {
|
||||||
base64Url,
|
const singleSign = {
|
||||||
documentId,
|
|
||||||
xyPosData,
|
|
||||||
pdfBase64Url,
|
|
||||||
pageNo
|
|
||||||
) => {
|
|
||||||
let singleSign;
|
|
||||||
const newWidth = containerWH.width;
|
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
|
||||||
|
|
||||||
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
|
||||||
const height = xyPosData.Height ? xyPosData.Height : 60;
|
|
||||||
const bottomY = xyPosData.isDrag
|
|
||||||
? xyPosData.yBottom * scale - height * scale
|
|
||||||
: xyPosData.firstYPos
|
|
||||||
? xyPosData.yBottom * scale - height * scale + xyPosData.firstYPos
|
|
||||||
: xyPosData.yBottom * scale - height * scale;
|
|
||||||
|
|
||||||
singleSign = {
|
|
||||||
pdfFile: pdfBase64Url,
|
|
||||||
docId: documentId,
|
|
||||||
sign: {
|
|
||||||
Base64: base64Url,
|
|
||||||
Left: isMobile ? xyPosData.xPosition * scale : xyPosData.xPosition,
|
|
||||||
Bottom: bottomY,
|
|
||||||
Width: xyPosData.Width ? xyPosData.Width * scale : 150 * scale,
|
|
||||||
Height: height * scale,
|
|
||||||
Page: pageNo
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
|
||||||
singleSign = {
|
|
||||||
pdfFile: base64Url,
|
pdfFile: base64Url,
|
||||||
docId: documentId
|
docId: documentId
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
await axios
|
await axios
|
||||||
.post(`${localStorage.getItem("baseUrl")}functions/signPdf`, singleSign, {
|
.post(`${localStorage.getItem("baseUrl")}functions/signPdf`, singleSign, {
|
||||||
@@ -648,10 +573,10 @@ function SignYourSelf() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//function for save button to save signature or image url
|
//function for save button to save signature or image url
|
||||||
const saveSign = (isDefaultSign) => {
|
const saveSign = (isDefaultSign, width, height) => {
|
||||||
|
const isTypeText = width && height ? true : false;
|
||||||
const signatureImg = isDefaultSign ? defaultSignImg : signature;
|
const signatureImg = isDefaultSign ? defaultSignImg : signature;
|
||||||
const signFlag = true;
|
let imgWH = { width: width ? width : "", height: height ? height : "" };
|
||||||
let imgWH = { width: "", height: "" };
|
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
setIsImageSelect(false);
|
setIsImageSelect(false);
|
||||||
setImage();
|
setImage();
|
||||||
@@ -673,7 +598,7 @@ function SignYourSelf() {
|
|||||||
signatureImg,
|
signatureImg,
|
||||||
imgWH,
|
imgWH,
|
||||||
isDefaultSign,
|
isDefaultSign,
|
||||||
signFlag
|
isTypeText
|
||||||
);
|
);
|
||||||
|
|
||||||
setXyPostion(getUpdatePosition);
|
setXyPostion(getUpdatePosition);
|
||||||
@@ -739,16 +664,31 @@ function SignYourSelf() {
|
|||||||
setXyPostion(getXyData);
|
setXyPostion(getXyData);
|
||||||
setShowAlreadySignDoc({ status: false });
|
setShowAlreadySignDoc({ status: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDontShow = (isChecked) => {
|
||||||
|
setIsDontShow(isChecked);
|
||||||
|
};
|
||||||
|
|
||||||
const tourConfig = [
|
const tourConfig = [
|
||||||
{
|
{
|
||||||
selector: '[data-tut="reactourFirst"]',
|
selector: '[data-tut="reactourFirst"]',
|
||||||
content: `Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`,
|
content: () => (
|
||||||
|
<TourContentWithBtn
|
||||||
|
message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`}
|
||||||
|
isChecked={handleDontShow}
|
||||||
|
/>
|
||||||
|
),
|
||||||
position: "top",
|
position: "top",
|
||||||
style: { fontSize: "13px" }
|
style: { fontSize: "13px" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: '[data-tut="reactourSecond"]',
|
selector: '[data-tut="reactourSecond"]',
|
||||||
content: `Drag and drop anywhere in this area. You can resize and move it later.`,
|
content: () => (
|
||||||
|
<TourContentWithBtn
|
||||||
|
message={`Drag and drop anywhere in this area. You can resize and move it later.`}
|
||||||
|
isChecked={handleDontShow}
|
||||||
|
/>
|
||||||
|
),
|
||||||
position: "top",
|
position: "top",
|
||||||
style: { fontSize: "13px" }
|
style: { fontSize: "13px" }
|
||||||
}
|
}
|
||||||
@@ -757,7 +697,7 @@ function SignYourSelf() {
|
|||||||
//function for update TourStatus
|
//function for update TourStatus
|
||||||
const closeTour = async () => {
|
const closeTour = async () => {
|
||||||
setSignTour(false);
|
setSignTour(false);
|
||||||
|
if (isDontShow) {
|
||||||
let updatedTourStatus = [];
|
let updatedTourStatus = [];
|
||||||
if (tourStatus.length > 0) {
|
if (tourStatus.length > 0) {
|
||||||
updatedTourStatus = [...tourStatus];
|
updatedTourStatus = [...tourStatus];
|
||||||
@@ -794,10 +734,12 @@ function SignYourSelf() {
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("axois err ", err);
|
console.log("axois err ", err);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
|
<Title title={"Self Sign"} />
|
||||||
{isLoading.isLoad ? (
|
{isLoading.isLoad ? (
|
||||||
<Loader isLoading={isLoading} />
|
<Loader isLoading={isLoading} />
|
||||||
) : handleError ? (
|
) : handleError ? (
|
||||||
@@ -826,6 +768,7 @@ function SignYourSelf() {
|
|||||||
setAllPages={setAllPages}
|
setAllPages={setAllPages}
|
||||||
setPageNumber={setPageNumber}
|
setPageNumber={setPageNumber}
|
||||||
setSignBtnPosition={setSignBtnPosition}
|
setSignBtnPosition={setSignBtnPosition}
|
||||||
|
pageNumber={pageNumber}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* pdf render view */}
|
{/* pdf render view */}
|
||||||
@@ -835,52 +778,82 @@ function SignYourSelf() {
|
|||||||
marginRight: !isMobile && pdfOriginalWidth > 500 && "20px"
|
marginRight: !isMobile && pdfOriginalWidth > 500 && "20px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AlertComponent
|
<ModalUi
|
||||||
isShow={isAlert.isShow}
|
headerColor={"#dc3545"}
|
||||||
alertMessage={isAlert.alertMessage}
|
isOpen={isAlert.isShow}
|
||||||
setIsAlert={setIsAlert}
|
title={"Alert"}
|
||||||
/>
|
handleClose={() => {
|
||||||
{/* this modal is used show this document is already sign */}
|
setIsAlert({
|
||||||
<Modal
|
isShow: false,
|
||||||
show={showAlreadySignDoc.status}
|
alertMessage: ""
|
||||||
onShow={() => modalAlign()}
|
});
|
||||||
backdropClassName="signature-backdrop"
|
|
||||||
>
|
|
||||||
<ModalHeader style={{ background: themeColor() }}>
|
|
||||||
<span style={{ color: "white" }}> Sign Documents</span>
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<Modal.Body>
|
|
||||||
<p>{showAlreadySignDoc.mssg}</p>
|
|
||||||
</Modal.Body>
|
|
||||||
|
|
||||||
<Modal.Footer>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
borderRadius: "0px",
|
|
||||||
border: "1.5px solid #e3e2e1",
|
|
||||||
fontWeight: "600",
|
|
||||||
color: "black"
|
|
||||||
}}
|
}}
|
||||||
className="btn"
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>{isAlert.alertMessage}</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setIsAlert({
|
||||||
|
isShow: false,
|
||||||
|
alertMessage: ""
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
>
|
||||||
|
Ok
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
|
||||||
|
{/* this modal is used show this document is already sign */}
|
||||||
|
<ModalUi
|
||||||
|
isOpen={showAlreadySignDoc.status}
|
||||||
|
title={"Sign Documents"}
|
||||||
|
handleClose={() => {
|
||||||
|
setShowAlreadySignDoc({ status: false });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>{showAlreadySignDoc.mssg}</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<button
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
onClick={() => setShowAlreadySignDoc({ status: false })}
|
onClick={() => setShowAlreadySignDoc({ status: false })}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
{showAlreadySignDoc.sure && (
|
</div>
|
||||||
<button
|
</ModalUi>
|
||||||
onClick={() => addDefaultSignature()}
|
|
||||||
style={{
|
<PlaceholderCopy
|
||||||
background: themeColor()
|
isPageCopy={isPageCopy}
|
||||||
}}
|
setIsPageCopy={setIsPageCopy}
|
||||||
type="button"
|
xyPostion={xyPostion}
|
||||||
className="finishBtn"
|
setXyPostion={setXyPostion}
|
||||||
>
|
allPages={allPages}
|
||||||
Yes
|
pageNumber={pageNumber}
|
||||||
</button>
|
signKey={signKey}
|
||||||
)}
|
/>
|
||||||
</Modal.Footer>
|
|
||||||
</Modal>
|
|
||||||
{/* this is modal of signature pad */}
|
{/* this is modal of signature pad */}
|
||||||
<SignPad
|
<SignPad
|
||||||
isSignPad={isSignPad}
|
isSignPad={isSignPad}
|
||||||
@@ -952,6 +925,7 @@ function SignYourSelf() {
|
|||||||
setXyPostion={setXyPostion}
|
setXyPostion={setXyPostion}
|
||||||
index={index}
|
index={index}
|
||||||
containerWH={containerWH}
|
containerWH={containerWH}
|
||||||
|
setIsPageCopy={setIsPageCopy}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ModalUi from "../../premitives/ModalUi";
|
||||||
|
|
||||||
|
const AddRoleModal = (props) => {
|
||||||
|
return (
|
||||||
|
<ModalUi
|
||||||
|
title={"Add Role"}
|
||||||
|
isOpen={props.isModalRole}
|
||||||
|
handleClose={props.handleCloseRoleModal}
|
||||||
|
>
|
||||||
|
<div className="addusercontainer">
|
||||||
|
<form
|
||||||
|
style={{ display: "flex", flexDirection: "column" }}
|
||||||
|
onSubmit={props.handleAddRole}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
value={props.roleName}
|
||||||
|
onChange={(e) => props.setRoleName(e.target.value)}
|
||||||
|
placeholder={
|
||||||
|
props.signersdata.length > 0
|
||||||
|
? "User " + (props.signersdata.length + 1)
|
||||||
|
: "User 1"
|
||||||
|
}
|
||||||
|
className="addUserInput"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "grey",
|
||||||
|
fontSize: 11,
|
||||||
|
margin: "10px 0 10px 5px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
e.g: Hr, Director, Manager, New joinee, Accountant, etc...
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
style={{
|
||||||
|
background: "#00a2b7"
|
||||||
|
}}
|
||||||
|
className="finishBtn"
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={props.handleCloseRoleModal}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddRoleModal;
|
||||||
@@ -25,19 +25,19 @@ function CustomModal({
|
|||||||
<div className="modalHeadDiv bg-danger">{headMsg && headMsg}</div>
|
<div className="modalHeadDiv bg-danger">{headMsg && headMsg}</div>
|
||||||
<div className="modalBodyDIv">
|
<div className="modalBodyDIv">
|
||||||
<p className="pTagBody">{bodyMssg && bodyMssg}</p>
|
<p className="pTagBody">{bodyMssg && bodyMssg}</p>
|
||||||
</div>
|
|
||||||
{footerMessage && (
|
{footerMessage && (
|
||||||
<div className="modalFooterDiv">
|
<>
|
||||||
<button
|
<div
|
||||||
style={{
|
style={{
|
||||||
color: "black"
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
}}
|
}}
|
||||||
type="button"
|
></div>
|
||||||
className="finishBtn"
|
<div className="modalFooterDiv">
|
||||||
onClick={() => setIsDecline({ isDeclined: false })}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
style={{
|
style={{
|
||||||
background: "#de4337"
|
background: "#de4337"
|
||||||
@@ -48,10 +48,19 @@ function CustomModal({
|
|||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
onClick={() => setIsDecline({ isDeclined: false })}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import "../../css/AddUser.css";
|
||||||
|
// import SelectFolder from "../../premitives/SelectFolder";
|
||||||
|
|
||||||
|
const EditTemplate = ({ template, onSuccess }) => {
|
||||||
|
// const [folder, setFolder] = useState({ ObjectId: "", Name: "" });
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
Name: template?.Name || "",
|
||||||
|
Note: template?.Note || "",
|
||||||
|
Description: template?.Description || ""
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleStrInput = (e) => {
|
||||||
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
|
};
|
||||||
|
// const handleFolder = (data) => {
|
||||||
|
// console.log("handleFolder ", data)
|
||||||
|
// setFolder(data);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Define a function to handle form submission
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const data = {...formData }
|
||||||
|
onSuccess(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="addusercontainer">
|
||||||
|
<div className="form-wrapper">
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="name" style={{ fontSize: 13 }}>
|
||||||
|
File
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: "0.5rem 0.75rem",
|
||||||
|
border: "1px solid #d1d5db",
|
||||||
|
borderRadius: "0.375rem",
|
||||||
|
fontSize: "0.75rem",
|
||||||
|
fontWeight: "700"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{template.URL?.split("/")[3]?.split("_")[1]}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="form-section">
|
||||||
|
<label htmlFor="name" style={{ fontSize: 13 }}>
|
||||||
|
Name
|
||||||
|
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="Name"
|
||||||
|
value={formData.Name}
|
||||||
|
onChange={(e) => handleStrInput(e)}
|
||||||
|
required
|
||||||
|
className="addUserInput"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-section">
|
||||||
|
<label htmlFor="Note" style={{ fontSize: 13 }}>
|
||||||
|
Note
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="Note"
|
||||||
|
id="Note"
|
||||||
|
value={formData.Note}
|
||||||
|
onChange={(e) => handleStrInput(e)}
|
||||||
|
className="addUserInput"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-section">
|
||||||
|
<label htmlFor="Description" style={{ fontSize: 13 }}>
|
||||||
|
Description
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="Description"
|
||||||
|
id="Description"
|
||||||
|
value={formData.Description}
|
||||||
|
onChange={(e) => handleStrInput(e)}
|
||||||
|
className="addUserInput"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* <SelectFolder onSuccess={handleFolder} folderCls={"contracts_Template"} /> */}
|
||||||
|
<div className="buttoncontainer">
|
||||||
|
<button type="submit" className="submitbutton">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditTemplate;
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import React from "react";
|
||||||
|
import SelectSigners from "../../premitives/SelectSigners";
|
||||||
|
import AddUser from "../../premitives/AddUser";
|
||||||
|
import ModalUi from "../../premitives/ModalUi";
|
||||||
|
|
||||||
|
const LinkUserModal = (props) => {
|
||||||
|
return (
|
||||||
|
<ModalUi title={"Add/Choose Signer"} isOpen={props.isAddUser[props.uniqueId]} handleClose={props.closePopup}>
|
||||||
|
<SelectSigners
|
||||||
|
details={props.handleAddUser}
|
||||||
|
closePopup={props.closePopup}
|
||||||
|
/>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", gap: 5, margin:"0 30%", color:"#808080" }}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
height: 1,
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "#ccc"
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
<span>or</span>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
height: 1,
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "#ccc"
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
<AddUser details={props.handleAddUser} closePopup={props.closePopup} />
|
||||||
|
</ModalUi>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LinkUserModal;
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||||
|
import ModalUi from "../../premitives/ModalUi";
|
||||||
|
|
||||||
|
function PlaceholderCopy(props) {
|
||||||
|
const copyType = ["All pages", "All pages but last", "All pages but first"];
|
||||||
|
const [selectCopyType, setSelectCopyType] = useState("");
|
||||||
|
|
||||||
|
//get RandomKey Id
|
||||||
|
const randomKey = () => {
|
||||||
|
const randomId = Math.floor(1000 + Math.random() * 9000);
|
||||||
|
return randomId;
|
||||||
|
};
|
||||||
|
|
||||||
|
//function for get copy placeholder position
|
||||||
|
const getCopyPlaceholderPosition = (
|
||||||
|
type,
|
||||||
|
rest,
|
||||||
|
newPageNumber,
|
||||||
|
existPlaceholderPosition
|
||||||
|
) => {
|
||||||
|
let obj;
|
||||||
|
|
||||||
|
const filterPosition =
|
||||||
|
existPlaceholderPosition &&
|
||||||
|
existPlaceholderPosition.filter(
|
||||||
|
(data) => data.xPosition !== rest.xPosition
|
||||||
|
);
|
||||||
|
//copy all page placeholder at requested position except first page
|
||||||
|
if (newPageNumber === 1 && type === "first") {
|
||||||
|
if (filterPosition && filterPosition.length > 0) {
|
||||||
|
return (obj = {
|
||||||
|
pageNumber: newPageNumber,
|
||||||
|
pos: [...filterPosition]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//copy all page placeholder at requested position except last page
|
||||||
|
else if (newPageNumber === props.allPages && type === "last") {
|
||||||
|
if (existPlaceholderPosition) {
|
||||||
|
return (obj = {
|
||||||
|
pageNumber: newPageNumber,
|
||||||
|
pos: [...filterPosition]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//copy all page placeholder at requested position with existing placeholder position
|
||||||
|
else if (existPlaceholderPosition) {
|
||||||
|
return (obj = {
|
||||||
|
pageNumber: newPageNumber,
|
||||||
|
pos: [...filterPosition, rest]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//copy all page placeholder at requested position
|
||||||
|
else {
|
||||||
|
return (obj = {
|
||||||
|
pageNumber: newPageNumber,
|
||||||
|
pos: [rest]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//function for copy placeholder as per select copy type
|
||||||
|
const copyPlaceholder = (type) => {
|
||||||
|
let newPlaceholderPosition = [];
|
||||||
|
let newPageNumber = 1;
|
||||||
|
const signerPosition = props.xyPostion;
|
||||||
|
const signerId = props.signerObjId ? props.signerObjId : props.Id;
|
||||||
|
//handle placeholder array and copy for multiple signers placeholder at requested location
|
||||||
|
if (signerId) {
|
||||||
|
//get current signers data
|
||||||
|
let filterSignerPosition;
|
||||||
|
if (props?.signerObjId) {
|
||||||
|
filterSignerPosition = signerPosition.filter(
|
||||||
|
(data) => data.signerObjId === signerId
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
filterSignerPosition = signerPosition.filter(
|
||||||
|
(item) => item.Id === signerId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//get current pagenumber's all placeholder position data
|
||||||
|
const placeholderPosition = filterSignerPosition[0].placeHolder.filter(
|
||||||
|
(data) => data.pageNumber === props.pageNumber
|
||||||
|
);
|
||||||
|
//get current placeholder position data which user want to copy
|
||||||
|
const currentPlaceholder = placeholderPosition[0].pos.filter(
|
||||||
|
(position) => position.key === props.signKey
|
||||||
|
);
|
||||||
|
const { key, ...rest } = currentPlaceholder[0];
|
||||||
|
for (let i = 0; i < props.allPages; i++) {
|
||||||
|
const newId = randomKey();
|
||||||
|
rest.key = newId;
|
||||||
|
//get exist placeholder position for particular page
|
||||||
|
const existPlaceholder = filterSignerPosition[0].placeHolder.filter(
|
||||||
|
(data) => data.pageNumber === newPageNumber
|
||||||
|
);
|
||||||
|
const existPlaceholderPosition =
|
||||||
|
existPlaceholder[0] && existPlaceholder[0].pos;
|
||||||
|
|
||||||
|
//function for get copy to requested location of placeholder position
|
||||||
|
const getPlaceholderObj = getCopyPlaceholderPosition(
|
||||||
|
type,
|
||||||
|
rest,
|
||||||
|
newPageNumber,
|
||||||
|
existPlaceholderPosition
|
||||||
|
);
|
||||||
|
if (getPlaceholderObj) {
|
||||||
|
newPlaceholderPosition.push(getPlaceholderObj);
|
||||||
|
}
|
||||||
|
newPageNumber++;
|
||||||
|
}
|
||||||
|
let updatedSignerPlaceholder;
|
||||||
|
if (props?.signerObjId) {
|
||||||
|
updatedSignerPlaceholder = signerPosition.map((signersData, ind) => {
|
||||||
|
if (signersData.signerObjId === props.signerObjId) {
|
||||||
|
return {
|
||||||
|
...signersData,
|
||||||
|
placeHolder: newPlaceholderPosition
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return signersData;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
updatedSignerPlaceholder = signerPosition.map((signersData, ind) => {
|
||||||
|
if (signersData.Id === props.Id) {
|
||||||
|
return {
|
||||||
|
...signersData,
|
||||||
|
placeHolder: newPlaceholderPosition
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return signersData;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// const updatedSignerPlaceholder = signerPosition.map(
|
||||||
|
// (signersData, ind) => {
|
||||||
|
// if (signersData.signerObjId === props.signerObjId) {
|
||||||
|
// return {
|
||||||
|
// ...signersData,
|
||||||
|
// placeHolder: newPlaceholderPosition
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// return signersData;
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
const signersData = signerPosition;
|
||||||
|
signersData.splice(0, signerPosition.length, ...updatedSignerPlaceholder);
|
||||||
|
props.setXyPostion(signersData);
|
||||||
|
}
|
||||||
|
//handle signyourself array and copy for single signers placeholder at requested location
|
||||||
|
else {
|
||||||
|
const xyPostion = props.xyPostion;
|
||||||
|
|
||||||
|
const placeholderPosition = xyPostion.filter(
|
||||||
|
(data) => data.pageNumber === props.pageNumber
|
||||||
|
);
|
||||||
|
//get current placeholder position data which user want to copy
|
||||||
|
const currentPlaceholder = placeholderPosition[0].pos.filter(
|
||||||
|
(pos) => pos.key === props.signKey
|
||||||
|
);
|
||||||
|
const { key, ...rest } = currentPlaceholder[0];
|
||||||
|
for (let i = 0; i < props.allPages; i++) {
|
||||||
|
//get exist placeholder position for particular page
|
||||||
|
const existPlaceholder = xyPostion.filter(
|
||||||
|
(data) => data.pageNumber === newPageNumber
|
||||||
|
);
|
||||||
|
const existPlaceholderPosition =
|
||||||
|
existPlaceholder[0] && existPlaceholder[0].pos;
|
||||||
|
|
||||||
|
const newId = randomKey();
|
||||||
|
rest.key = newId;
|
||||||
|
//function for get copy to requested location of placeholder position
|
||||||
|
const getPlaceholderObj = getCopyPlaceholderPosition(
|
||||||
|
type,
|
||||||
|
rest,
|
||||||
|
newPageNumber,
|
||||||
|
existPlaceholderPosition
|
||||||
|
);
|
||||||
|
if (getPlaceholderObj) {
|
||||||
|
newPlaceholderPosition.push(getPlaceholderObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
newPageNumber++;
|
||||||
|
}
|
||||||
|
props.setXyPostion(newPlaceholderPosition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//function for getting selected type placeholder copy
|
||||||
|
const handleApplyCopy = () => {
|
||||||
|
if (selectCopyType === "All pages") {
|
||||||
|
copyPlaceholder("all");
|
||||||
|
} else if (selectCopyType === "All pages but last") {
|
||||||
|
copyPlaceholder("last");
|
||||||
|
} else if (selectCopyType === "All pages but first") {
|
||||||
|
copyPlaceholder("first");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalUi
|
||||||
|
isOpen={props.isPageCopy}
|
||||||
|
title={"Copy to all pages"}
|
||||||
|
handleClose={() => {
|
||||||
|
props.setIsPageCopy(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
{copyType.map((data, key) => {
|
||||||
|
return (
|
||||||
|
<div key={key} style={{ display: "flex", flexDirection: "column" }}>
|
||||||
|
<label key={key} style={{ fontSize: "16px", fontWeight: "500" }}>
|
||||||
|
<input
|
||||||
|
style={{ accentColor: "red", marginRight: "10px" }}
|
||||||
|
type="radio"
|
||||||
|
value={data}
|
||||||
|
onChange={() => setSelectCopyType(data)}
|
||||||
|
checked={selectCopyType === data}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{data}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
handleApplyCopy();
|
||||||
|
props.setIsPageCopy(false);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
background: themeColor()
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
disabled={!selectCopyType}
|
||||||
|
className="finishBtn"
|
||||||
|
>
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
onClick={() => props.setIsPageCopy(false)}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlaceholderCopy;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Helmet } from "react-helmet";
|
||||||
|
|
||||||
|
function Title({ title, drive }) {
|
||||||
|
return (
|
||||||
|
<Helmet>
|
||||||
|
<title>{drive ? title : `${title} - OpenSign™`}</title>
|
||||||
|
<meta name="description" content={`${title} - OpenSign™`} />
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href={localStorage.getItem("fev_Icon")}
|
||||||
|
sizes="40x40"
|
||||||
|
/>
|
||||||
|
</Helmet>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Title;
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
function BorderResize() {
|
function BorderResize({ right, top }) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="borderResize"
|
className="borderResize"
|
||||||
style={{
|
style={{
|
||||||
right: "-1px",
|
right: right ? right + "px" : "-1px",
|
||||||
bottom: "-1px",
|
bottom: top ? top + "px" : "-1px",
|
||||||
borderRight: "3px solid #188ae2",
|
borderRight: "3px solid #188ae2",
|
||||||
borderBottom: "3px solid #188ae2"
|
borderBottom: "3px solid #188ae2"
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -4,27 +4,32 @@ function DefaultSignature({
|
|||||||
themeColor,
|
themeColor,
|
||||||
defaultSignImg,
|
defaultSignImg,
|
||||||
xyPostion,
|
xyPostion,
|
||||||
setIsAlert
|
setDefaultSignAlert
|
||||||
}) {
|
}) {
|
||||||
const confirmToaddDefaultSign = () => {
|
const confirmToaddDefaultSign = () => {
|
||||||
if (xyPostion.length > 0) {
|
if (xyPostion.length > 0) {
|
||||||
setIsAlert({
|
setDefaultSignAlert({
|
||||||
isShow: true,
|
isShow: true,
|
||||||
alertMessage: "Are you sure you want to sign at requested locations?"
|
alertMessage:
|
||||||
|
"Are you sure you want to auto sign at requested all locations?"
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
alert("please select position!");
|
setDefaultSignAlert({
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: "please select position!"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="signerComponent">
|
<div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: themeColor(),
|
background: themeColor(),
|
||||||
color: "white",
|
color: "white",
|
||||||
padding: "5px",
|
padding: "5px",
|
||||||
fontFamily: "sans-serif"
|
fontFamily: "sans-serif",
|
||||||
|
marginTop: "5px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Signature
|
Signature
|
||||||
@@ -38,7 +43,6 @@ function DefaultSignature({
|
|||||||
fontWeight: "600"
|
fontWeight: "600"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{defaultSignImg ? (
|
|
||||||
<>
|
<>
|
||||||
<p>Your Signature</p>
|
<p>Your Signature</p>
|
||||||
<div className="defaultSignBox">
|
<div className="defaultSignBox">
|
||||||
@@ -57,7 +61,8 @@ function DefaultSignature({
|
|||||||
background: themeColor(),
|
background: themeColor(),
|
||||||
color: "white",
|
color: "white",
|
||||||
marginTop: "20px",
|
marginTop: "20px",
|
||||||
cursor: "pointer"
|
cursor: "pointer",
|
||||||
|
marginBottom: "10px"
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn finishnHover"
|
className="finishBtn finishnHover"
|
||||||
@@ -66,13 +71,6 @@ function DefaultSignature({
|
|||||||
Auto Sign All
|
Auto Sign All
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
) : (
|
|
||||||
<div style={{ margin: "10px" }}>
|
|
||||||
<span>
|
|
||||||
Click a signature placeholder to start signing the document!
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { saveAs } from "file-saver";
|
import { saveAs } from "file-saver";
|
||||||
import celebration from "../../assests/newCeleb.gif";
|
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 axios from "axios";
|
||||||
import { getBase64FromUrl } from "../../utils/Utils";
|
import { getBase64FromUrl } from "../../utils/Utils";
|
||||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||||
@@ -39,7 +36,7 @@ function EmailComponent({
|
|||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
};
|
};
|
||||||
const openSignUrl = "https://www.opensignlabs.com/";
|
const openSignUrl = "https://www.opensignlabs.com/contact-us";
|
||||||
const themeBGcolor = themeColor();
|
const themeBGcolor = themeColor();
|
||||||
let params = {
|
let params = {
|
||||||
pdfName: pdfName,
|
pdfName: pdfName,
|
||||||
@@ -52,11 +49,11 @@ function EmailComponent({
|
|||||||
imgPng +
|
imgPng +
|
||||||
" height='50' style='padding:20px,width:170px,height:40px'/> </div><div style='padding:2px;font-family:system-ui; background-color:" +
|
" height='50' style='padding:20px,width:170px,height:40px'/> </div><div style='padding:2px;font-family:system-ui; background-color:" +
|
||||||
themeBGcolor +
|
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 " +
|
";'> <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 <strong>" +
|
||||||
pdfName +
|
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 OpenSign. For any queries regarding this email, please contact the sender " +
|
" </strong>is attached to this email. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender " +
|
||||||
sender.email +
|
sender.email +
|
||||||
" directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSign <a href= " +
|
" directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ <a href= " +
|
||||||
openSignUrl +
|
openSignUrl +
|
||||||
" target=_blank>here</a> </p></div></div></body></html>"
|
" target=_blank>here</a> </p></div></div></body></html>"
|
||||||
};
|
};
|
||||||
@@ -89,6 +86,8 @@ function EmailComponent({
|
|||||||
isShow: true,
|
isShow: true,
|
||||||
alertMessage: "something went wrong"
|
alertMessage: "something went wrong"
|
||||||
});
|
});
|
||||||
|
setEmailValue("");
|
||||||
|
setEmailList([]);
|
||||||
} else {
|
} else {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
setIsEmail(false);
|
setIsEmail(false);
|
||||||
@@ -96,6 +95,8 @@ function EmailComponent({
|
|||||||
isShow: true,
|
isShow: true,
|
||||||
alertMessage: "something went wrong"
|
alertMessage: "something went wrong"
|
||||||
});
|
});
|
||||||
|
setEmailValue("");
|
||||||
|
setEmailList([]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,7 +161,9 @@ function EmailComponent({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{/* isEmail */}
|
{/* isEmail */}
|
||||||
<Modal show={isEmail}>
|
{isEmail && (
|
||||||
|
<div className="modaloverlay">
|
||||||
|
<div className="modalcontainer">
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -186,8 +189,7 @@ function EmailComponent({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<div style={{ background: "#32a3ac" }} className="modalheader">
|
||||||
<ModalHeader style={{ background: themeColor() }}>
|
|
||||||
<span style={{ color: "white" }}>Successfully signed!</span>
|
<span style={{ color: "white" }}>Successfully signed!</span>
|
||||||
|
|
||||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||||
@@ -237,9 +239,8 @@ function EmailComponent({
|
|||||||
Download
|
Download
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ModalHeader>
|
</div>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
<Modal.Body>
|
|
||||||
{isCeleb && (
|
{isCeleb && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -262,7 +263,8 @@ function EmailComponent({
|
|||||||
verticalAlign: "baseline",
|
verticalAlign: "baseline",
|
||||||
fontWeight: "500",
|
fontWeight: "500",
|
||||||
color: "#403f3e",
|
color: "#403f3e",
|
||||||
fontSize: "15px"
|
fontSize: "15px",
|
||||||
|
marginBottom: "5px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Recipients added here will get a copy of the signed document.
|
Recipients added here will get a copy of the signed document.
|
||||||
@@ -297,16 +299,18 @@ function EmailComponent({
|
|||||||
>
|
>
|
||||||
{data}
|
{data}
|
||||||
</span>
|
</span>
|
||||||
|
<span
|
||||||
<img
|
style={{
|
||||||
alt="print img"
|
color: "white",
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: 600,
|
||||||
|
marginLeft: 7,
|
||||||
|
cursor: "pointer"
|
||||||
|
}}
|
||||||
onClick={() => removeChip(ind)}
|
onClick={() => removeChip(ind)}
|
||||||
src={close}
|
>
|
||||||
width={10}
|
<i className="fa-solid fa-xmark"></i>
|
||||||
height={10}
|
</span>
|
||||||
style={{ fontWeight: "600", marginLeft: "7px" }}
|
|
||||||
className="emailChipClose"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -318,6 +322,11 @@ function EmailComponent({
|
|||||||
className="addEmailInput"
|
className="addEmailInput"
|
||||||
onChange={handleEmailValue}
|
onChange={handleEmailValue}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
|
onBlur={() => {
|
||||||
|
if (emailValue) {
|
||||||
|
handleEnterPress("add");
|
||||||
|
}
|
||||||
|
}}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -332,6 +341,11 @@ function EmailComponent({
|
|||||||
onChange={handleEmailValue}
|
onChange={handleEmailValue}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
placeholder="Add the email addresses"
|
placeholder="Add the email addresses"
|
||||||
|
onBlur={() => {
|
||||||
|
if (emailValue) {
|
||||||
|
handleEnterPress("add");
|
||||||
|
}
|
||||||
|
}}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -349,9 +363,10 @@ function EmailComponent({
|
|||||||
<i
|
<i
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: themeColor(),
|
backgroundColor: themeColor(),
|
||||||
padding: "2px 10px",
|
padding: "5px 7px",
|
||||||
marginTop: "10px",
|
marginTop: "10px",
|
||||||
color: "white"
|
color: "white",
|
||||||
|
borderRadius: "2px"
|
||||||
}}
|
}}
|
||||||
className="fa fa-plus"
|
className="fa fa-plus"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -361,7 +376,7 @@ function EmailComponent({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: "#e3e2e1",
|
background: "#e3e2e1",
|
||||||
marginTop: "30px",
|
marginTop: "10px",
|
||||||
padding: "5px",
|
padding: "5px",
|
||||||
borderRadius: "3px"
|
borderRadius: "3px"
|
||||||
}}
|
}}
|
||||||
@@ -372,23 +387,15 @@ function EmailComponent({
|
|||||||
You can only send to ten recipients at a time.
|
You can only send to ten recipients at a time.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Modal.Body>
|
<div
|
||||||
|
|
||||||
<Modal.Footer>
|
|
||||||
<button
|
|
||||||
style={{
|
style={{
|
||||||
color: "black"
|
height: "1px",
|
||||||
|
backgroundColor: "#9f9f9f",
|
||||||
|
width: "100%",
|
||||||
|
marginTop: "15px",
|
||||||
|
marginBottom: "15px"
|
||||||
}}
|
}}
|
||||||
type="button"
|
></div>
|
||||||
className="finishBtn"
|
|
||||||
onClick={() => {
|
|
||||||
setIsEmail(false);
|
|
||||||
setEmailValue("");
|
|
||||||
setEmailList([]);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
disabled={emailList.length === 0 && true}
|
disabled={emailList.length === 0 && true}
|
||||||
style={{
|
style={{
|
||||||
@@ -401,8 +408,21 @@ function EmailComponent({
|
|||||||
>
|
>
|
||||||
Send
|
Send
|
||||||
</button>
|
</button>
|
||||||
</Modal.Footer>
|
<button
|
||||||
</Modal>
|
type="button"
|
||||||
|
className="finishBtn cancelBtn"
|
||||||
|
onClick={() => {
|
||||||
|
setIsEmail(false);
|
||||||
|
setEmailValue("");
|
||||||
|
setEmailList([]);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import * as Select from "@radix-ui/react-select";
|
import ModalUi from "../../premitives/ModalUi";
|
||||||
import classnames from "classnames";
|
import RecipientList from "../../premitives/RecipientList";
|
||||||
|
|
||||||
function FieldsComponent({
|
function FieldsComponent({
|
||||||
pdfUrl,
|
pdfUrl,
|
||||||
@@ -20,7 +20,6 @@ function FieldsComponent({
|
|||||||
isDragSignatureSS,
|
isDragSignatureSS,
|
||||||
isSignYourself,
|
isSignYourself,
|
||||||
addPositionOfSignature,
|
addPositionOfSignature,
|
||||||
|
|
||||||
signersdata,
|
signersdata,
|
||||||
isSelectListId,
|
isSelectListId,
|
||||||
setSignerObjId,
|
setSignerObjId,
|
||||||
@@ -29,30 +28,21 @@ function FieldsComponent({
|
|||||||
isSigners,
|
isSigners,
|
||||||
dataTut,
|
dataTut,
|
||||||
dataTut2,
|
dataTut2,
|
||||||
setIsShowEmail,
|
|
||||||
isMailSend,
|
isMailSend,
|
||||||
selectedEmail,
|
handleAddSigner,
|
||||||
setSelectedEmail,
|
setUniqueId,
|
||||||
|
setRoleName,
|
||||||
|
handleDeleteUser,
|
||||||
|
signerPos,
|
||||||
|
handleRoleChange,
|
||||||
|
handleOnBlur,
|
||||||
|
title
|
||||||
}) {
|
}) {
|
||||||
|
const [isSignersModal, setIsSignersModal] = useState(false);
|
||||||
const signStyle = pdfUrl ? "disableSign" : "signatureBtn";
|
const signStyle = pdfUrl ? "disableSign" : "signatureBtn";
|
||||||
|
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
|
|
||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const color = [
|
const color = [
|
||||||
"#93a3db",
|
"#93a3db",
|
||||||
"#e6c3db",
|
"#e6c3db",
|
||||||
@@ -65,9 +55,12 @@ function FieldsComponent({
|
|||||||
"#cc99ff",
|
"#cc99ff",
|
||||||
"#ffcc99",
|
"#ffcc99",
|
||||||
"#66ccff",
|
"#66ccff",
|
||||||
"#ffffcc",
|
"#ffffcc"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const handleModal = () => {
|
||||||
|
setIsSignersModal(!isSignersModal);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isMobile && isSignYourself ? (
|
{isMobile && isSignYourself ? (
|
||||||
@@ -88,102 +81,75 @@ function FieldsComponent({
|
|||||||
padding: "10px 20px",
|
padding: "10px 20px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center"
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
// if (signersdata?.length) {
|
||||||
|
handleModal();
|
||||||
|
// }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span style={{ fontSize: "18px", fontWeight: "500" }}>
|
<span
|
||||||
Signer :
|
style={{
|
||||||
|
fontSize: "13px",
|
||||||
|
fontWeight: "700",
|
||||||
|
textAlign: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{title ? title : "Recipient"}
|
||||||
</span>
|
</span>
|
||||||
|
<span
|
||||||
<Select.Root
|
style={{
|
||||||
onValueChange={(obj) => {
|
fontSize: "13px",
|
||||||
const [selectedKey, selectedData] = obj.split("|");
|
fontWeight: "700",
|
||||||
const parseData = JSON.parse(selectedData);
|
display: "flex",
|
||||||
|
alignItems: "center"
|
||||||
setSignerObjId(parseData.objectId);
|
|
||||||
setIsSelectId(selectedKey);
|
|
||||||
setContractName(parseData.className);
|
|
||||||
setSelectedEmail(true);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Select.Trigger
|
{signersdata[isSelectListId]?.Role && (
|
||||||
className={selectedEmail ? "selectEmail": "SelectTrigger"}
|
<div>
|
||||||
|
{signersdata[isSelectListId]?.Name ? (
|
||||||
|
<>
|
||||||
|
:{" "}
|
||||||
|
{signersdata[isSelectListId]?.Name?.length > 12
|
||||||
|
? `${signersdata[isSelectListId].Name.slice(
|
||||||
|
0,
|
||||||
|
12
|
||||||
|
)}...`
|
||||||
|
: signersdata[isSelectListId]?.Name}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
:{" "}
|
||||||
|
{signersdata[isSelectListId]?.Role?.length > 12
|
||||||
|
? `${signersdata[isSelectListId].Role.slice(
|
||||||
|
0,
|
||||||
|
12
|
||||||
|
)}...`
|
||||||
|
: signersdata[isSelectListId]?.Role}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div style={{ marginLeft: 6, fontSize: 16 }}>
|
||||||
|
<i className="fa-solid fa-angle-down"></i>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{handleAddSigner && (
|
||||||
|
<div
|
||||||
|
data-tut="reactourAddbtn"
|
||||||
style={{
|
style={{
|
||||||
background: isSelectListId
|
margin: "5px 0 5px 0",
|
||||||
? color[isSelectListId % color.length]
|
backgroundColor: themeColor(),
|
||||||
: color[0],
|
color: "white"
|
||||||
}}
|
}}
|
||||||
aria-label="Food"
|
className="addSignerBtn"
|
||||||
|
onClick={() => handleAddSigner()}
|
||||||
>
|
>
|
||||||
<Select.Value
|
<i className="fa-solid fa-plus"></i>
|
||||||
|
<span style={{ marginLeft: 2 }}>Add role</span>
|
||||||
placeholder="Select signer.." />
|
|
||||||
{!selectedEmail &&
|
|
||||||
<Select.Icon className="SelectIcon">
|
|
||||||
<i
|
|
||||||
style={{
|
|
||||||
marginTop: "5px",
|
|
||||||
marginLeft: "5px",
|
|
||||||
color: "#3b15d1",
|
|
||||||
fontSize: "20px",
|
|
||||||
}}
|
|
||||||
className="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",
|
|
||||||
}}
|
|
||||||
className="fa fa-angle-down"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</Select.ScrollUpButton>
|
|
||||||
<Select.Viewport className="SelectViewport">
|
|
||||||
<Select.Group>
|
|
||||||
{signersdata.Signers.map((obj, ind) => {
|
|
||||||
return (
|
|
||||||
<SelectItem
|
|
||||||
selected
|
|
||||||
key={ind}
|
|
||||||
value={`${ind}|${JSON.stringify(obj)}`}
|
|
||||||
// value={(obj)}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
{obj.Email}
|
|
||||||
</SelectItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
{/* <SelectItem value="orange">Orange</SelectItem>
|
|
||||||
<SelectItem value="apple">Apple</SelectItem>
|
|
||||||
<SelectItem value="grape"></SelectItem> */}
|
|
||||||
</Select.Group>
|
|
||||||
</Select.Viewport>
|
|
||||||
<Select.ScrollDownButton className="SelectScrollButton">
|
|
||||||
<i
|
|
||||||
style={{
|
|
||||||
marginTop: "5px",
|
|
||||||
marginLeft: "5px",
|
|
||||||
color: "#3b15d1",
|
|
||||||
fontSize: "20px",
|
|
||||||
}}
|
|
||||||
className="fa fa-angle-down"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</Select.ScrollDownButton>
|
|
||||||
</Select.Content>
|
|
||||||
</Select.Portal>
|
|
||||||
</Select.Root>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
@@ -192,17 +158,7 @@ function FieldsComponent({
|
|||||||
style={{ backgroundColor: themeColor() }}
|
style={{ backgroundColor: themeColor() }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => addPositionOfSignature("onclick", false)}
|
||||||
if (isSigners) {
|
|
||||||
if (selectedEmail) {
|
|
||||||
addPositionOfSignature("onclick", false);
|
|
||||||
} else {
|
|
||||||
setIsShowEmail(true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addPositionOfSignature("onclick", false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
ref={(element) => {
|
ref={(element) => {
|
||||||
dragSignatureSS(element);
|
dragSignatureSS(element);
|
||||||
if (element) {
|
if (element) {
|
||||||
@@ -221,24 +177,15 @@ function FieldsComponent({
|
|||||||
backgroundSize: "70% 70%",
|
backgroundSize: "70% 70%",
|
||||||
backgroundRepeat: "no-repeat",
|
backgroundRepeat: "no-repeat",
|
||||||
backgroundPosition: "center center",
|
backgroundPosition: "center center",
|
||||||
paddingBottom: "2.2rem",
|
paddingBottom: "2.2rem"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* <img
|
|
||||||
alt="sign img"
|
|
||||||
style={{
|
|
||||||
width: "30px",
|
|
||||||
height: "30px",
|
|
||||||
background: themeColor(),
|
|
||||||
}}
|
|
||||||
src={sign}
|
|
||||||
/> */}
|
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: "white",
|
color: "white",
|
||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
position: "relative",
|
position: "relative",
|
||||||
top: "2.6rem",
|
top: "2.6rem"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Signature
|
Signature
|
||||||
@@ -261,7 +208,7 @@ function FieldsComponent({
|
|||||||
backgroundSize: "32px 33px",
|
backgroundSize: "32px 33px",
|
||||||
backgroundRepeat: "no-repeat",
|
backgroundRepeat: "no-repeat",
|
||||||
backgroundPosition: "center center",
|
backgroundPosition: "center center",
|
||||||
paddingBottom: "2.2rem",
|
paddingBottom: "2.2rem"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@@ -269,7 +216,7 @@ function FieldsComponent({
|
|||||||
color: "white",
|
color: "white",
|
||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
position: "relative",
|
position: "relative",
|
||||||
top: "2.6rem",
|
top: "2.6rem"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Stamp
|
Stamp
|
||||||
@@ -283,8 +230,7 @@ function FieldsComponent({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: themeColor(),
|
background: themeColor(),
|
||||||
|
padding: "5px"
|
||||||
padding: "5px",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="signedStyle">Fields</span>
|
<span className="signedStyle">Fields</span>
|
||||||
@@ -299,7 +245,7 @@ function FieldsComponent({
|
|||||||
fontWeight: "400",
|
fontWeight: "400",
|
||||||
fontSize: "15px",
|
fontSize: "15px",
|
||||||
padding: "3px 20px 0px 20px",
|
padding: "3px 20px 0px 20px",
|
||||||
color: "#bfbfbf",
|
color: "#bfbfbf"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Signature
|
Signature
|
||||||
@@ -310,7 +256,7 @@ function FieldsComponent({
|
|||||||
style={{
|
style={{
|
||||||
width: "30px",
|
width: "30px",
|
||||||
height: "28px",
|
height: "28px",
|
||||||
background: "#d3edeb",
|
background: "#d3edeb"
|
||||||
}}
|
}}
|
||||||
src={sign}
|
src={sign}
|
||||||
/>
|
/>
|
||||||
@@ -321,7 +267,7 @@ function FieldsComponent({
|
|||||||
fontWeight: "400",
|
fontWeight: "400",
|
||||||
fontSize: "15px",
|
fontSize: "15px",
|
||||||
padding: "3px 0px 0px 35px",
|
padding: "3px 0px 0px 35px",
|
||||||
color: "#bfbfbf",
|
color: "#bfbfbf"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Stamp
|
Stamp
|
||||||
@@ -332,7 +278,7 @@ function FieldsComponent({
|
|||||||
style={{
|
style={{
|
||||||
width: "25px",
|
width: "25px",
|
||||||
height: "28px",
|
height: "28px",
|
||||||
background: "#d3edeb",
|
background: "#d3edeb"
|
||||||
}}
|
}}
|
||||||
src={stamp}
|
src={stamp}
|
||||||
/>
|
/>
|
||||||
@@ -355,7 +301,7 @@ function FieldsComponent({
|
|||||||
style={{
|
style={{
|
||||||
opacity: isDragSign ? 0.5 : 1,
|
opacity: isDragSign ? 0.5 : 1,
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)",
|
"0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@@ -363,7 +309,7 @@ function FieldsComponent({
|
|||||||
fontWeight: "400",
|
fontWeight: "400",
|
||||||
fontSize: "15px",
|
fontSize: "15px",
|
||||||
padding: "3px 20px 0px 20px",
|
padding: "3px 20px 0px 20px",
|
||||||
color: "black",
|
color: "black"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Signature
|
Signature
|
||||||
@@ -373,7 +319,7 @@ function FieldsComponent({
|
|||||||
style={{
|
style={{
|
||||||
width: "30px",
|
width: "30px",
|
||||||
height: "28px",
|
height: "28px",
|
||||||
background: themeColor(),
|
background: themeColor()
|
||||||
}}
|
}}
|
||||||
src={sign}
|
src={sign}
|
||||||
/>
|
/>
|
||||||
@@ -393,7 +339,7 @@ function FieldsComponent({
|
|||||||
style={{
|
style={{
|
||||||
opacity: isDragStamp ? 0.5 : 1,
|
opacity: isDragStamp ? 0.5 : 1,
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)",
|
"0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@@ -401,7 +347,7 @@ function FieldsComponent({
|
|||||||
fontWeight: "400",
|
fontWeight: "400",
|
||||||
fontSize: "15px",
|
fontSize: "15px",
|
||||||
padding: "3px 0px 0px 35px",
|
padding: "3px 0px 0px 35px",
|
||||||
color: !pdfUrl ? "black" : "#bfbfbf",
|
color: !pdfUrl ? "black" : "#bfbfbf"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Stamp
|
Stamp
|
||||||
@@ -412,7 +358,7 @@ function FieldsComponent({
|
|||||||
style={{
|
style={{
|
||||||
width: "25px",
|
width: "25px",
|
||||||
height: "28px",
|
height: "28px",
|
||||||
background: themeColor(),
|
background: themeColor()
|
||||||
}}
|
}}
|
||||||
src={stamp}
|
src={stamp}
|
||||||
/>
|
/>
|
||||||
@@ -422,6 +368,41 @@ function FieldsComponent({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{isSignersModal && (
|
||||||
|
<ModalUi
|
||||||
|
title={"Recipients"}
|
||||||
|
isOpen={isSignersModal}
|
||||||
|
handleClose={handleModal}
|
||||||
|
>
|
||||||
|
{signersdata.length > 0 ? (
|
||||||
|
<RecipientList
|
||||||
|
signerPos={signerPos}
|
||||||
|
signersdata={signersdata}
|
||||||
|
isSelectListId={isSelectListId}
|
||||||
|
setSignerObjId={setSignerObjId}
|
||||||
|
setIsSelectId={setIsSelectId}
|
||||||
|
setContractName={setContractName}
|
||||||
|
setUniqueId={setUniqueId}
|
||||||
|
setRoleName={setRoleName}
|
||||||
|
handleDeleteUser={handleDeleteUser}
|
||||||
|
handleRoleChange={handleRoleChange}
|
||||||
|
handleOnBlur={handleOnBlur}
|
||||||
|
handleModal={handleModal}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: 20,
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: "500",
|
||||||
|
textAlign: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Please add Recipient
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ function Header({
|
|||||||
dataTut4,
|
dataTut4,
|
||||||
alreadySign,
|
alreadySign,
|
||||||
isSignYourself,
|
isSignYourself,
|
||||||
setIsEmail
|
setIsEmail,
|
||||||
|
completeBtnTitle,
|
||||||
|
setIsEditTemplate
|
||||||
}) {
|
}) {
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -223,10 +225,7 @@ function Header({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div
|
<div style={{ padding: "5px 0px 5px 0px" }} className="mobileHead">
|
||||||
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
|
|
||||||
className="mobileHead"
|
|
||||||
>
|
|
||||||
{isMobile && isShowHeader ? (
|
{isMobile && isShowHeader ? (
|
||||||
<div
|
<div
|
||||||
id="navbar"
|
id="navbar"
|
||||||
@@ -345,7 +344,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="fa fa-envelope"
|
className="fa fa-envelope"
|
||||||
style={{ marginRight: "2px" }}
|
style={{ marginRight: "2px" }}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
@@ -415,7 +414,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
data-tut={dataTut4}
|
data-tut={dataTut4}
|
||||||
>
|
>
|
||||||
Send
|
{completeBtnTitle ? completeBtnTitle : "Send"}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
@@ -533,17 +532,17 @@ function Header({
|
|||||||
) : isPlaceholder ? (
|
) : isPlaceholder ? (
|
||||||
<>
|
<>
|
||||||
{!isMailSend &&
|
{!isMailSend &&
|
||||||
signersdata.Signers &&
|
signersdata.length > 0 &&
|
||||||
signersdata.Signers.length !== signerPos.length && (
|
signersdata.length !== signerPos.length && (
|
||||||
<div>
|
<div>
|
||||||
{signerPos.length === 0 ? (
|
{signerPos.length === 0 ? (
|
||||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
||||||
Add all {signersdata.Signers.length - signerPos.length}{" "}
|
Add {signersdata.length - signerPos.length} recipients
|
||||||
recipients signature
|
signature
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
||||||
Add {signersdata.Signers.length - signerPos.length} more
|
Add {signersdata.length - signerPos.length} more
|
||||||
recipients signature
|
recipients signature
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -551,6 +550,18 @@ function Header({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
{setIsEditTemplate && (
|
||||||
|
<button
|
||||||
|
onClick={() => setIsEditTemplate(true)}
|
||||||
|
style={{
|
||||||
|
border: "none",
|
||||||
|
outline: "none",
|
||||||
|
textAlign: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-gear fa-lg"></i>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate(-1);
|
navigate(-1);
|
||||||
@@ -573,7 +584,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
className={isMailSend ? "sendMail" : "sendMail sendHover"}
|
className={isMailSend ? "sendMail" : "sendMail sendHover"}
|
||||||
>
|
>
|
||||||
Send
|
{completeBtnTitle ? completeBtnTitle : "Send"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@@ -723,7 +734,7 @@ function Header({
|
|||||||
onClick={() => setIsEmail(true)}
|
onClick={() => setIsEmail(true)}
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="fa fa-envelope"
|
className="fa fa-envelope"
|
||||||
style={{
|
style={{
|
||||||
color: "white",
|
color: "white",
|
||||||
fontSize: "15px",
|
fontSize: "15px",
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||||
|
import { resizeBorderExtraWidth } from "../../utils/Utils";
|
||||||
|
function PlaceholderBorder(props) {
|
||||||
|
const getResizeBorderExtraWidth = resizeBorderExtraWidth();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="borderResize"
|
||||||
|
style={{
|
||||||
|
borderColor: themeColor(),
|
||||||
|
borderStyle: "dashed",
|
||||||
|
// width: props.pos.Width
|
||||||
|
// ? props.pos.Width + getResizeBorderExtraWidth
|
||||||
|
// : 150 + getResizeBorderExtraWidth,
|
||||||
|
// height: props.pos.Height
|
||||||
|
// ? props.pos.Height + getResizeBorderExtraWidth
|
||||||
|
// : 60 + getResizeBorderExtraWidth,
|
||||||
|
width:
|
||||||
|
props?.posWidth(props.pos, props?.isSignYourself) +
|
||||||
|
getResizeBorderExtraWidth,
|
||||||
|
height:
|
||||||
|
props?.posHeight(props.pos, props?.isSignYourself) +
|
||||||
|
getResizeBorderExtraWidth,
|
||||||
|
borderWidth: "0.2px",
|
||||||
|
overflow: "hidden"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlaceholderBorder;
|
||||||
@@ -10,6 +10,7 @@ function RenderAllPdfPage({
|
|||||||
setAllPages,
|
setAllPages,
|
||||||
setPageNumber,
|
setPageNumber,
|
||||||
setSignBtnPosition,
|
setSignBtnPosition,
|
||||||
|
pageNumber
|
||||||
}) {
|
}) {
|
||||||
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
|
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
|
||||||
|
|
||||||
@@ -27,13 +28,12 @@ function RenderAllPdfPage({
|
|||||||
boxShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px",
|
boxShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px",
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
height: "100%"
|
height: "100%"
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ width: "140px" }}>
|
<div style={{ width: "140px" }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: themeColor(),
|
background: themeColor()
|
||||||
// color:"white"
|
// color:"white"
|
||||||
}}
|
}}
|
||||||
className="signedStyle"
|
className="signedStyle"
|
||||||
@@ -41,10 +41,16 @@ function RenderAllPdfPage({
|
|||||||
Pages
|
Pages
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<RSC id="RSC-Example" style={{width:"135px",height:window.innerHeight-130+'px'}} >
|
<RSC
|
||||||
|
id="RSC-Example"
|
||||||
|
style={{
|
||||||
|
width: "135px",
|
||||||
|
height: window.innerHeight - 130 + "px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Document
|
<Document
|
||||||
|
loading={"Loading Document.."}
|
||||||
onLoadSuccess={onDocumentLoad}
|
onLoadSuccess={onDocumentLoad}
|
||||||
file={pdfUrl ? pdfUrl : signPdfUrl}
|
file={pdfUrl ? pdfUrl : signPdfUrl}
|
||||||
// file="https://api.printnode.com/static/test/pdf/multipage.pdf"
|
// file="https://api.printnode.com/static/test/pdf/multipage.pdf"
|
||||||
@@ -54,14 +60,17 @@ function RenderAllPdfPage({
|
|||||||
key={index}
|
key={index}
|
||||||
style={{
|
style={{
|
||||||
width: "100px",
|
width: "100px",
|
||||||
border: "2px solid #878787",
|
border:
|
||||||
|
pageNumber - 1 === index
|
||||||
|
? "2px solid red"
|
||||||
|
: "2px solid #878787",
|
||||||
// padding: "5px",
|
// padding: "5px",
|
||||||
margin: "10px",
|
margin: "10px",
|
||||||
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
contain: "content",
|
contain: "content"
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPageNumber(index + 1);
|
setPageNumber(index + 1);
|
||||||
@@ -86,8 +95,6 @@ function RenderAllPdfPage({
|
|||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import SignatureCanvas from "react-signature-canvas";
|
|||||||
import redPen from "../../assests/redPen.png";
|
import redPen from "../../assests/redPen.png";
|
||||||
import bluePen from "../../assests/bluePen.png";
|
import bluePen from "../../assests/bluePen.png";
|
||||||
import blackPen from "../../assests/blackPen.png";
|
import blackPen from "../../assests/blackPen.png";
|
||||||
import Modal from "react-bootstrap/Modal";
|
|
||||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
@@ -27,15 +26,48 @@ function SignPad({
|
|||||||
const allColor = [bluePen, redPen, blackPen];
|
const allColor = [bluePen, redPen, blackPen];
|
||||||
const canvasRef = useRef(null);
|
const canvasRef = useRef(null);
|
||||||
const [isDefaultSign, setIsDefaultSign] = useState(false);
|
const [isDefaultSign, setIsDefaultSign] = useState(false);
|
||||||
const [isTab, setIsTab] = useState("signature");
|
const [isTab, setIsTab] = useState("draw");
|
||||||
const [isSignImg, setIsSignImg] = useState("");
|
const [isSignImg, setIsSignImg] = useState("");
|
||||||
|
const [signValue, setSignValue] = useState("");
|
||||||
|
const [textWidth, setTextWidth] = useState(null);
|
||||||
|
const [textHeight, setTextHeight] = useState(null);
|
||||||
|
const fontOptions = [
|
||||||
|
{ value: "Fasthand" },
|
||||||
|
{ value: "Dancing Script" },
|
||||||
|
{ value: "Cedarville Cursive" },
|
||||||
|
{ value: "Delicious Handrawn" }
|
||||||
|
// Add more font options as needed
|
||||||
|
];
|
||||||
|
const [fontSelect, setFontSelect] = useState(fontOptions[0].value);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const senderUser =
|
||||||
|
localStorage.getItem(
|
||||||
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||||
|
) &&
|
||||||
|
localStorage.getItem(
|
||||||
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||||
|
);
|
||||||
|
const jsonSender = JSON.parse(senderUser);
|
||||||
|
|
||||||
|
const currentUserName = jsonSender && jsonSender.name;
|
||||||
//function for clear signature
|
//function for clear signature
|
||||||
|
setSignValue(currentUserName);
|
||||||
|
setFontSelect("Fasthand");
|
||||||
|
}, []);
|
||||||
|
//function for clear signature image
|
||||||
const handleClear = () => {
|
const handleClear = () => {
|
||||||
|
if (isTab === "draw") {
|
||||||
if (canvasRef.current) {
|
if (canvasRef.current) {
|
||||||
canvasRef.current.clear();
|
canvasRef.current.clear();
|
||||||
|
} else if (isStamp) {
|
||||||
|
setImage("");
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
|
} else if (isTab === "uploadImage") {
|
||||||
|
setImage("");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
//function for set signature url
|
//function for set signature url
|
||||||
const handleSignatureChange = (dataURL) => {
|
const handleSignatureChange = (dataURL) => {
|
||||||
@@ -47,11 +79,12 @@ function SignPad({
|
|||||||
//save button component
|
//save button component
|
||||||
const SaveBtn = () => {
|
const SaveBtn = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div style={{ marginTop: "2px" }}>
|
||||||
{!isStamp && !isImageSelect && (
|
{(isTab === "draw" || isTab === "uploadImage") && (
|
||||||
<button
|
<button
|
||||||
style={{
|
style={{
|
||||||
color: "black"
|
color: "black",
|
||||||
|
border: "1px solid #ccc"
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn saveBtn"
|
className="finishBtn saveBtn"
|
||||||
@@ -67,10 +100,15 @@ function SignPad({
|
|||||||
if (isDefaultSign) {
|
if (isDefaultSign) {
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
onSaveSign(isDefaultSign);
|
onSaveSign(isDefaultSign);
|
||||||
|
} else {
|
||||||
|
if (isTab === "type") {
|
||||||
|
setIsSignImg("");
|
||||||
|
onSaveSign(false, textWidth, textHeight);
|
||||||
} else {
|
} else {
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
onSaveSign();
|
onSaveSign();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setPenColor("blue");
|
setPenColor("blue");
|
||||||
} else {
|
} else {
|
||||||
@@ -82,16 +120,20 @@ function SignPad({
|
|||||||
setIsImageSelect(false);
|
setIsImageSelect(false);
|
||||||
setIsDefaultSign(false);
|
setIsDefaultSign(false);
|
||||||
setImage();
|
setImage();
|
||||||
setIsTab("signature");
|
setIsTab("draw");
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
background: themeColor(),
|
background: themeColor(),
|
||||||
color: "white"
|
color: "white"
|
||||||
}}
|
}}
|
||||||
disabled={isSignImg || image || isDefaultSign ? false : true}
|
disabled={
|
||||||
|
isSignImg || image || isDefaultSign || textWidth ? false : true
|
||||||
|
}
|
||||||
type="button"
|
type="button"
|
||||||
className={
|
className={
|
||||||
isSignImg || image ? "finishBtn saveBtn" : "disabledFinish saveBtn"
|
isSignImg || image || isDefaultSign || textWidth
|
||||||
|
? "finishBtn saveBtn"
|
||||||
|
: "disabledFinish saveBtn"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
@@ -100,25 +142,98 @@ function SignPad({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadFont = async () => {
|
||||||
|
try {
|
||||||
|
await document.fonts.load(`20px ${fontSelect}`);
|
||||||
|
const selectFontSTyle = fontOptions.find(
|
||||||
|
(font) => font.value === fontSelect
|
||||||
|
);
|
||||||
|
setFontSelect(selectFontSTyle?.value || fontOptions[0].value);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error loading font:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadFont();
|
||||||
|
}, [fontSelect]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Load the default signature after the component mounts
|
// Load the default signature after the component mounts
|
||||||
if (canvasRef.current) {
|
if (canvasRef.current) {
|
||||||
canvasRef.current.fromDataURL(isSignImg);
|
canvasRef.current.fromDataURL(isSignImg);
|
||||||
}
|
}
|
||||||
|
if (isTab === "type") {
|
||||||
|
convertToImg(fontSelect, signValue);
|
||||||
|
}
|
||||||
}, [isTab]);
|
}, [isTab]);
|
||||||
|
//function for convert input text value in image
|
||||||
|
const convertToImg = async (fontStyle, text) => {
|
||||||
|
//get text content to convert in image
|
||||||
|
const textContent = text;
|
||||||
|
const fontfamily = fontStyle
|
||||||
|
? fontStyle
|
||||||
|
: fontSelect
|
||||||
|
? fontSelect
|
||||||
|
: "Fasthand";
|
||||||
|
|
||||||
|
//creating span for getting text content width
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.textContent = textContent;
|
||||||
|
span.style.font = `20px ${fontfamily}`; // here put your text size and font family
|
||||||
|
span.style.display = "hidden";
|
||||||
|
document.body.appendChild(span); // Replace 'container' with the ID of the container element
|
||||||
|
|
||||||
|
//create canvas to render text in canvas and convert in image
|
||||||
|
const canvasElement = document.createElement("canvas");
|
||||||
|
// Draw the text content on the canvas
|
||||||
|
const ctx = canvasElement.getContext("2d");
|
||||||
|
const pixelRatio = window.devicePixelRatio || 1;
|
||||||
|
const width = span.offsetWidth;
|
||||||
|
const height = span.offsetHeight;
|
||||||
|
setTextWidth(width);
|
||||||
|
setTextHeight(height);
|
||||||
|
const font = span.style["font"];
|
||||||
|
// Set the canvas dimensions to match the span
|
||||||
|
canvasElement.width = width * pixelRatio;
|
||||||
|
canvasElement.height = height * pixelRatio;
|
||||||
|
|
||||||
|
// Render the content of the span onto the canvas
|
||||||
|
// ctx.fillStyle = "white"; // Set the background color of the canvas
|
||||||
|
// ctx.fillRect(0, 0, width*pixelRatio, height*pixelRatio);
|
||||||
|
|
||||||
|
// You can customize text styles if needed
|
||||||
|
ctx.font = font;
|
||||||
|
ctx.fillStyle = "black"; // Set the text color
|
||||||
|
ctx.textAlign = "center";
|
||||||
|
ctx.textBaseline = "middle";
|
||||||
|
ctx.scale(pixelRatio, pixelRatio);
|
||||||
|
// Draw the content of the span onto the canvas
|
||||||
|
ctx.fillText(span.textContent, width / 2, height / 2); // Adjust the x,y-coordinate as needed
|
||||||
|
//remove span tag
|
||||||
|
document.body.removeChild(span);
|
||||||
|
// Convert the canvas to image data
|
||||||
|
const dataUrl = canvasElement.toDataURL("image/png");
|
||||||
|
setSignature(dataUrl);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{/*isSignPad */}
|
{isSignPad && (
|
||||||
<Modal show={isSignPad}>
|
<div className="modaloverlay">
|
||||||
|
<div className="modalcontainer">
|
||||||
|
<div
|
||||||
|
className="modalheader"
|
||||||
|
style={{ padding: "0 13px", marginTop: "5px" }}
|
||||||
|
>
|
||||||
|
<div className="modaltitle">
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
background: "white",
|
background: "white",
|
||||||
borderBottom: "1.6px solid #ebe6e6",
|
marginTop: "3px"
|
||||||
marginTop: "15px"
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -128,13 +243,11 @@ function SignPad({
|
|||||||
justifyContent: "space-around",
|
justifyContent: "space-around",
|
||||||
alignItems: "end",
|
alignItems: "end",
|
||||||
gap: 10
|
gap: 10
|
||||||
|
|
||||||
// background: themeColor(),
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isStamp ? (
|
{isStamp ? (
|
||||||
<span style={{ color: themeColor() }} className="signTab">
|
<span style={{ color: themeColor() }} className="signTab">
|
||||||
Upload Image
|
Upload stamp image
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -143,22 +256,24 @@ function SignPad({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsDefaultSign(false);
|
setIsDefaultSign(false);
|
||||||
setIsImageSelect(false);
|
setIsImageSelect(false);
|
||||||
setIsTab("signature");
|
setIsTab("draw");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
color: isTab === "signature" ? themeColor() : "#515252",
|
color:
|
||||||
|
isTab === "draw" ? themeColor() : "#515252",
|
||||||
|
|
||||||
marginLeft: "2px"
|
marginLeft: "2px"
|
||||||
}}
|
}}
|
||||||
className="signTab"
|
className="signTab"
|
||||||
>
|
>
|
||||||
Signature
|
Draw
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border:
|
border:
|
||||||
isTab === "signature"
|
isTab === "draw"
|
||||||
? "1.5px solid #108783"
|
? "1.5px solid #108783"
|
||||||
: "1.5px solid #ffffff"
|
: "1.5px solid #ffffff"
|
||||||
}}
|
}}
|
||||||
@@ -172,7 +287,10 @@ function SignPad({
|
|||||||
setIsTab("uploadImage");
|
setIsTab("uploadImage");
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
color: isTab === "uploadImage" ? themeColor() : "#515252"
|
color:
|
||||||
|
isTab === "uploadImage"
|
||||||
|
? themeColor()
|
||||||
|
: "#515252"
|
||||||
}}
|
}}
|
||||||
className="signTab"
|
className="signTab"
|
||||||
>
|
>
|
||||||
@@ -187,7 +305,34 @@ function SignPad({
|
|||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
onClick={() => {
|
||||||
|
setIsDefaultSign(false);
|
||||||
|
setIsImageSelect(false);
|
||||||
|
setIsTab("type");
|
||||||
|
setImage();
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
color:
|
||||||
|
isTab === "type" ? themeColor() : "#515252",
|
||||||
|
|
||||||
|
marginLeft: "2px"
|
||||||
|
}}
|
||||||
|
className="signTab"
|
||||||
|
>
|
||||||
|
Type
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
border:
|
||||||
|
isTab === "type"
|
||||||
|
? "1.5px solid #108783"
|
||||||
|
: "1.5px solid #ffffff"
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
{defaultSign && (
|
{defaultSign && (
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
@@ -199,7 +344,9 @@ function SignPad({
|
|||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
color:
|
color:
|
||||||
isTab === "mysignature" ? themeColor() : "#515252"
|
isTab === "mysignature"
|
||||||
|
? themeColor()
|
||||||
|
: "#515252"
|
||||||
}}
|
}}
|
||||||
className="signTab"
|
className="signTab"
|
||||||
>
|
>
|
||||||
@@ -218,15 +365,11 @@ function SignPad({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<button
|
</div>
|
||||||
style={{
|
<div
|
||||||
border: "0px",
|
className="closebtn"
|
||||||
background: "none",
|
style={{ color: "black" }}
|
||||||
paddingLeft: "7px",
|
|
||||||
paddingRight: "7px",
|
|
||||||
marginRight: "5px"
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPenColor("blue");
|
setPenColor("blue");
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
@@ -234,15 +377,13 @@ function SignPad({
|
|||||||
setIsImageSelect(false);
|
setIsImageSelect(false);
|
||||||
setIsDefaultSign(false);
|
setIsDefaultSign(false);
|
||||||
setImage();
|
setImage();
|
||||||
setIsTab("signature");
|
setIsTab("draw");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
X
|
×
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{/* signature modal */}
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
<Modal.Body className="modalBody">
|
|
||||||
{isDefaultSign ? (
|
{isDefaultSign ? (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@@ -262,6 +403,7 @@ function SignPad({
|
|||||||
style={{
|
style={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
background: "rgb(255, 255, 255)",
|
||||||
objectFit: "contain"
|
objectFit: "contain"
|
||||||
}}
|
}}
|
||||||
src={defaultSign}
|
src={defaultSign}
|
||||||
@@ -276,6 +418,7 @@ function SignPad({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: "1px solid black",
|
border: "1px solid black",
|
||||||
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
@@ -302,31 +445,88 @@ function SignPad({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: "1px solid black",
|
border: "1px solid black",
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
marginBottom: 6,
|
marginBottom: 6,
|
||||||
cursor: "pointer"
|
|
||||||
|
overflow: "hidden"
|
||||||
}}
|
}}
|
||||||
className="signatureCanvas"
|
className="signatureCanvas"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="stamp img"
|
alt="print img"
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
objectFit: "contain"
|
|
||||||
}}
|
|
||||||
ref={imageRef}
|
ref={imageRef}
|
||||||
src={image.src}
|
src={image.src}
|
||||||
|
style={{
|
||||||
|
objectFit: "contain",
|
||||||
|
height: "100%",
|
||||||
|
width: "100%"
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
<div
|
||||||
|
style={{ display: "flex", justifyContent: "flex-end" }}
|
||||||
|
>
|
||||||
<SaveBtn />
|
<SaveBtn />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
) : isTab === "type" ? (
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="signatureText">Signature:</span>
|
||||||
|
|
||||||
|
<input
|
||||||
|
maxLength={30}
|
||||||
|
style={{ fontFamily: fontSelect }}
|
||||||
|
type="text"
|
||||||
|
className="signatureInput"
|
||||||
|
placeholder="Your signature"
|
||||||
|
value={signValue}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSignValue(e.target.value);
|
||||||
|
convertToImg(fontSelect, e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fontOptionContainer">
|
||||||
|
{fontOptions.map((font, ind) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={ind}
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
fontFamily: font.value,
|
||||||
|
backgroundColor:
|
||||||
|
fontSelect === font.value && "rgb(206 225 247)"
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setFontSelect(font.value);
|
||||||
|
convertToImg(font.value, signValue);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: "5px 10px 5px 10px",
|
||||||
|
fontSize: "20px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{signValue ? signValue : "Your signature"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||||
|
<SaveBtn />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<SignatureCanvas
|
<SignatureCanvas
|
||||||
@@ -347,7 +547,7 @@ function SignPad({
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
marginTop: "4px"
|
marginTop: "10px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||||
@@ -384,12 +584,15 @@ function SignPad({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SaveBtn />
|
<SaveBtn />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Modal.Body>
|
</div>
|
||||||
</Modal>
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,161 +1,34 @@
|
|||||||
import React, { useState } from "react";
|
import React from "react";
|
||||||
import check from "../../assests/checkBox.png";
|
|
||||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||||
|
import "../../css/signerListPlace.css";
|
||||||
|
import RecipientList from "../../premitives/RecipientList";
|
||||||
|
|
||||||
function SignerListPlace({
|
function SignerListPlace(props) {
|
||||||
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: themeColor(),
|
background: themeColor(),
|
||||||
|
padding: "5px"
|
||||||
padding: "5px",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="signedStyle">Reicipents</span>
|
<span className="signedStyle">
|
||||||
</div>
|
{props.title ? props.title : "Recipients"}
|
||||||
|
|
||||||
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
<div className="signerList">
|
||||||
<span className="userName">{obj.Name}</span>
|
<RecipientList {...props} />
|
||||||
<span className="useEmail">{obj.Email}</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
{props.handleAddSigner && (
|
||||||
|
<div
|
||||||
|
data-tut="reactourAddbtn"
|
||||||
|
className="addSignerBtn"
|
||||||
|
onClick={() => props.handleAddSigner()}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-plus"></i>
|
||||||
|
<span style={{ marginLeft: 2 }}>Add role</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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,12 @@ function Login() {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
} else {
|
} else {
|
||||||
let _user = user.data.result;
|
let _user = user.data.result;
|
||||||
|
const parseId = localStorage.getItem("parseAppId");
|
||||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
|
localStorage.setItem(
|
||||||
|
`Parse/${parseId}/currentUser`,
|
||||||
|
JSON.stringify(_user)
|
||||||
|
);
|
||||||
localStorage.setItem("username", _user.name);
|
localStorage.setItem("username", _user.name);
|
||||||
localStorage.setItem("accesstoken", _user.sessionToken);
|
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||||
//save isGuestSigner true in local to handle login flow header in mobile view
|
//save isGuestSigner true in local to handle login flow header in mobile view
|
||||||
|
|||||||
@@ -1,921 +0,0 @@
|
|||||||
import React, { useState, useRef, useEffect } from "react";
|
|
||||||
import { PDFDocument } from "pdf-lib";
|
|
||||||
import "../css/./signature.css";
|
|
||||||
import axios from "axios";
|
|
||||||
import Modal from "react-bootstrap/Modal";
|
|
||||||
import { DndProvider } from "react-dnd";
|
|
||||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
|
||||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
|
||||||
import { themeColor } from "../utils/ThemeColor/backColor";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import SignPad from "./component/signPad";
|
|
||||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
|
||||||
import DefaultSignature from "./component/defaultSignature";
|
|
||||||
import {
|
|
||||||
getBase64FromUrl,
|
|
||||||
getBase64FromIMG,
|
|
||||||
pdfNewWidthFun,
|
|
||||||
convertPNGtoJPEG,
|
|
||||||
contractUsers,
|
|
||||||
contactBook,
|
|
||||||
contractDocument,
|
|
||||||
urlValidator,
|
|
||||||
multiSignEmbed,
|
|
||||||
embedDocId,
|
|
||||||
signPdfFun,
|
|
||||||
addDefaultSignatureImg,
|
|
||||||
onImageSelect
|
|
||||||
} from "../utils/Utils";
|
|
||||||
import Tour from "reactour";
|
|
||||||
import Signedby from "./component/signedby";
|
|
||||||
import { onSaveImage, onSaveSign } from "../utils/Utils";
|
|
||||||
import Loader from "./component/loader";
|
|
||||||
import HandleError from "./component/HandleError";
|
|
||||||
import Nodata from "./component/Nodata";
|
|
||||||
import Header from "./component/header";
|
|
||||||
import RenderPdf from "./component/renderPdf";
|
|
||||||
import CustomModal from "./component/CustomModal";
|
|
||||||
import { modalAlign } from "../utils/Utils";
|
|
||||||
import AlertComponent from "./component/alertComponent";
|
|
||||||
function EmbedPdfImage() {
|
|
||||||
const { id, contactBookId } = useParams();
|
|
||||||
const [isSignPad, setIsSignPad] = useState(false);
|
|
||||||
const [pdfUrl, setPdfUrl] = useState();
|
|
||||||
const [allPages, setAllPages] = useState(null);
|
|
||||||
const numPages = 1;
|
|
||||||
const [pageNumber, setPageNumber] = useState(1);
|
|
||||||
const [image, setImage] = useState(null);
|
|
||||||
const [isImageSelect, setIsImageSelect] = useState(false);
|
|
||||||
const [signature, setSignature] = useState();
|
|
||||||
const [isStamp, setIsStamp] = useState(false);
|
|
||||||
const [signKey, setSignKey] = useState();
|
|
||||||
const [imgWH, setImgWH] = useState({});
|
|
||||||
const [xyPostion, setXyPostion] = useState([]);
|
|
||||||
const [isAlreadySign, setIsAlreadySign] = useState({ status: false });
|
|
||||||
const imageRef = useRef(null);
|
|
||||||
const [signedPdfData, setSignedPdfData] = useState();
|
|
||||||
const [handleError, setHandleError] = useState();
|
|
||||||
const [isLoading, setIsLoading] = useState({
|
|
||||||
isLoad: true,
|
|
||||||
message: "This might take some time"
|
|
||||||
});
|
|
||||||
const [defaultSignImg, setDefaultSignImg] = useState();
|
|
||||||
const [userObjectID, setUserObjectID] = useState();
|
|
||||||
const [isDocId, setIsDocId] = useState(false);
|
|
||||||
const [pdfNewWidth, setPdfNewWidth] = useState();
|
|
||||||
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
|
||||||
const [signTour, setSignTour] = useState(true);
|
|
||||||
const [checkTourStatus, setCheckTourStatus] = useState(false);
|
|
||||||
const [signerUserId, setSignerUserId] = useState();
|
|
||||||
const [tourStatus, setTourStatus] = useState([]);
|
|
||||||
const [isExpired, setIsExpired] = useState(false);
|
|
||||||
const [noData, setNoData] = useState(false);
|
|
||||||
const [contractName, setContractName] = useState("");
|
|
||||||
const [isDecline, setIsDecline] = useState({
|
|
||||||
isDeclined: false
|
|
||||||
});
|
|
||||||
const [addDefaultSign, setAddDefaultSign] = useState({
|
|
||||||
isShow: false,
|
|
||||||
alertMessage: ""
|
|
||||||
});
|
|
||||||
const [pdfLoadFail, setPdfLoadFail] = useState({
|
|
||||||
status: false,
|
|
||||||
type: "load"
|
|
||||||
});
|
|
||||||
const [containerWH, setContainerWH] = useState({});
|
|
||||||
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
|
||||||
const docId = id && id;
|
|
||||||
const isMobile = window.innerWidth < 767;
|
|
||||||
const index = xyPostion.findIndex((object) => {
|
|
||||||
return object.pageNumber === pageNumber;
|
|
||||||
});
|
|
||||||
const divRef = useRef(null);
|
|
||||||
const senderUser = localStorage.getItem(
|
|
||||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
|
||||||
)
|
|
||||||
? localStorage.getItem(
|
|
||||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
|
||||||
)
|
|
||||||
: `${localStorage.getItem("UserInformation")}` &&
|
|
||||||
`${localStorage.getItem("UserInformation")}`;
|
|
||||||
const jsonSender = JSON.parse(senderUser);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getDocumentDetails();
|
|
||||||
}, []);
|
|
||||||
useEffect(() => {
|
|
||||||
if (divRef.current) {
|
|
||||||
const pdfWidth = pdfNewWidthFun(divRef);
|
|
||||||
setPdfNewWidth(pdfWidth);
|
|
||||||
setContainerWH({
|
|
||||||
width: divRef.current.offsetWidth,
|
|
||||||
height: divRef.current.offsetHeight
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [divRef.current]);
|
|
||||||
|
|
||||||
//function for get document details for perticular signer with signer'object id
|
|
||||||
const getDocumentDetails = async () => {
|
|
||||||
let currUserId, userObjectId;
|
|
||||||
//getting contracts_contactBook details
|
|
||||||
const json = await contactBook(contactBookId);
|
|
||||||
if (json && json.length > 0) {
|
|
||||||
setContractName("_Contactbook");
|
|
||||||
|
|
||||||
userObjectId = json[0].UserId.objectId;
|
|
||||||
setUserObjectID(userObjectId);
|
|
||||||
currUserId = json[0].objectId;
|
|
||||||
|
|
||||||
setSignerUserId(currUserId);
|
|
||||||
const tourstatus = json[0].TourStatus && json[0].TourStatus;
|
|
||||||
|
|
||||||
if (tourstatus && tourstatus.length > 0) {
|
|
||||||
setTourStatus(tourstatus);
|
|
||||||
const checkTourRecipients = tourstatus.filter(
|
|
||||||
(data) => data.recipientssign
|
|
||||||
);
|
|
||||||
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
|
||||||
setCheckTourStatus(checkTourRecipients[0].recipientssign);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (json === "Error: Something went wrong!") {
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setHandleError("Error: Something went wrong!");
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
} else {
|
|
||||||
const json = await contractUsers(jsonSender.email);
|
|
||||||
if (json && json.length > 0) {
|
|
||||||
setContractName("_Users");
|
|
||||||
if (json[0]) {
|
|
||||||
userObjectId = json[0].UserId.objectId;
|
|
||||||
setUserObjectID(userObjectId);
|
|
||||||
currUserId = json[0].objectId;
|
|
||||||
|
|
||||||
setSignerUserId(currUserId);
|
|
||||||
const tourstatus = json[0].TourStatus && json[0].TourStatus;
|
|
||||||
|
|
||||||
if (tourstatus && tourstatus.length > 0) {
|
|
||||||
setTourStatus(tourstatus);
|
|
||||||
const checkTourRecipients = tourstatus.filter(
|
|
||||||
(data) => data.recipientssign
|
|
||||||
);
|
|
||||||
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
|
||||||
setCheckTourStatus(checkTourRecipients[0].recipientssign);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setNoData(true);
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
}
|
|
||||||
} else if (json === "Error: Something went wrong!") {
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setHandleError("Error: Something went wrong!");
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
} else {
|
|
||||||
setNoData(true);
|
|
||||||
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//getting document details
|
|
||||||
const documentData = await contractDocument(docId);
|
|
||||||
if (documentData && documentData.length > 0) {
|
|
||||||
const declined = documentData[0].IsDeclined && documentData[0].IsDeclined;
|
|
||||||
const isCompleted =
|
|
||||||
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
|
||||||
const expireDate = documentData[0].ExpiryDate.iso;
|
|
||||||
|
|
||||||
const expireUpdateDate = new Date(expireDate).getTime();
|
|
||||||
const currDate = new Date().getTime();
|
|
||||||
if (isCompleted) {
|
|
||||||
//checking document is completed (signed by all requested signers) than isCompleted true
|
|
||||||
//then show alert with completed message
|
|
||||||
const alreadySign = {
|
|
||||||
status: true,
|
|
||||||
mssg: "This document has been successfully signed!"
|
|
||||||
};
|
|
||||||
setIsAlreadySign(alreadySign);
|
|
||||||
setPdfUrl(documentData[0].SignedUrl);
|
|
||||||
setSignedPdfData(documentData);
|
|
||||||
} else if (declined) {
|
|
||||||
const currentDecline = {
|
|
||||||
currnt: "another",
|
|
||||||
isDeclined: true
|
|
||||||
};
|
|
||||||
setIsDecline(currentDecline);
|
|
||||||
|
|
||||||
setSignedPdfData(documentData);
|
|
||||||
} else if (currDate > expireUpdateDate) {
|
|
||||||
setIsExpired(true);
|
|
||||||
const checkDocIdExist =
|
|
||||||
documentData[0].AuditTrail &&
|
|
||||||
documentData[0].AuditTrail.length > 0 &&
|
|
||||||
documentData[0].AuditTrail.filter(
|
|
||||||
(data) => data.Activity === "Signed"
|
|
||||||
);
|
|
||||||
|
|
||||||
//if signed by someone than go to in if condition
|
|
||||||
// and second signer could not be add documentId
|
|
||||||
//for that setIsDocId true
|
|
||||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
|
||||||
setIsDocId(true);
|
|
||||||
const currUser =
|
|
||||||
documentData.Placeholders &&
|
|
||||||
documentData.Placeholders.filter(
|
|
||||||
(data) => data.signerObjId === currUserId
|
|
||||||
);
|
|
||||||
|
|
||||||
setSignedPdfData(documentData);
|
|
||||||
|
|
||||||
setXyPostion(currUser[0].placeHolder);
|
|
||||||
|
|
||||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
|
||||||
setSignKey(key);
|
|
||||||
}
|
|
||||||
//for show current requested signer's placeholder
|
|
||||||
else {
|
|
||||||
const currUser =
|
|
||||||
documentData[0].Placeholders &&
|
|
||||||
documentData[0].Placeholders.filter(
|
|
||||||
(data) => data.signerObjId === currUserId
|
|
||||||
);
|
|
||||||
|
|
||||||
setSignedPdfData(documentData);
|
|
||||||
|
|
||||||
setXyPostion(currUser[0].placeHolder);
|
|
||||||
|
|
||||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
|
||||||
setSignKey(key);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//checking document has signed by someone or not
|
|
||||||
|
|
||||||
const checkDocIdExist =
|
|
||||||
documentData[0].AuditTrail &&
|
|
||||||
documentData[0].AuditTrail.length > 0 &&
|
|
||||||
documentData[0].AuditTrail.filter(
|
|
||||||
(data) => data.Activity === "Signed"
|
|
||||||
);
|
|
||||||
|
|
||||||
//if signed by someone than go to in if condition
|
|
||||||
// and second signer could not be add documentId
|
|
||||||
//for that setIsDocId true
|
|
||||||
|
|
||||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
|
||||||
setIsDocId(true);
|
|
||||||
|
|
||||||
//condition for checking document signed by current requested user or not
|
|
||||||
const checkAlreadyBySigner = documentData[0].AuditTrail.filter(
|
|
||||||
(data) =>
|
|
||||||
data.UserPtr.objectId === currUserId && data.Activity === "Signed"
|
|
||||||
);
|
|
||||||
|
|
||||||
// if checkAlreadyBySigner has some data that current user already sign this document
|
|
||||||
// then show alert with message
|
|
||||||
if (checkAlreadyBySigner && checkAlreadyBySigner.length > 0) {
|
|
||||||
const alreadySign = {
|
|
||||||
status: true,
|
|
||||||
mssg: "You have successfully signed the document!"
|
|
||||||
};
|
|
||||||
setIsAlreadySign(alreadySign);
|
|
||||||
setPdfUrl(documentData[0].SignedUrl);
|
|
||||||
setSignedPdfData(documentData);
|
|
||||||
}
|
|
||||||
//else show placeholder of current requested signer
|
|
||||||
else {
|
|
||||||
const currUser =
|
|
||||||
documentData[0].Placeholders &&
|
|
||||||
documentData[0].Placeholders.filter(
|
|
||||||
(data) => data.signerObjId === currUserId
|
|
||||||
);
|
|
||||||
|
|
||||||
setSignedPdfData(documentData);
|
|
||||||
|
|
||||||
setXyPostion(currUser[0].placeHolder);
|
|
||||||
|
|
||||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
|
||||||
setSignKey(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//for show current requested signer's placeholder
|
|
||||||
else {
|
|
||||||
const currUser =
|
|
||||||
documentData[0].Placeholders &&
|
|
||||||
documentData[0].Placeholders.filter(
|
|
||||||
(data) => data.signerObjId === currUserId
|
|
||||||
);
|
|
||||||
|
|
||||||
setSignedPdfData(documentData);
|
|
||||||
|
|
||||||
setXyPostion(currUser[0].placeHolder);
|
|
||||||
|
|
||||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
|
||||||
setSignKey(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
documentData === "Error: Something went wrong!" ||
|
|
||||||
(documentData.result && documentData.result.error)
|
|
||||||
) {
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setHandleError("Error: Something went wrong!");
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
} else {
|
|
||||||
setNoData(true);
|
|
||||||
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
}
|
|
||||||
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) => {
|
|
||||||
console.log("axois err ", err);
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setHandleError("Error: Something went wrong!");
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//function for get pdf page details
|
|
||||||
const pageDetails = async (pdf) => {
|
|
||||||
const load = {
|
|
||||||
status: true
|
|
||||||
};
|
|
||||||
setPdfLoadFail(load);
|
|
||||||
pdf.getPage(1).then((pdfPage) => {
|
|
||||||
const pageWidth = pdfPage.view[2];
|
|
||||||
|
|
||||||
setPdfOriginalWidth(pageWidth);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//function for embed signature or image url in pdf
|
|
||||||
async function embedImages() {
|
|
||||||
let checkSignUrl = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < xyPostion.length; i++) {
|
|
||||||
const posData = xyPostion[i].pos.filter((pos) => !pos.SignUrl);
|
|
||||||
|
|
||||||
if (posData && posData.length > 0) {
|
|
||||||
checkSignUrl.push(posData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkSignUrl && checkSignUrl.length > 0) {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "Please complete your signature!"
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: true,
|
|
||||||
message: "This might take some time"
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
const url = pdfUrl
|
|
||||||
? pdfUrl
|
|
||||||
: signedPdfData[0] && signedPdfData[0].SignedUrl;
|
|
||||||
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
|
|
||||||
});
|
|
||||||
|
|
||||||
const pngUrl = xyPostion;
|
|
||||||
|
|
||||||
let pdfBase64;
|
|
||||||
//checking if signature is only one then send image url in jpeg formate to server
|
|
||||||
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
|
||||||
if (isDocId) {
|
|
||||||
pdfBase64 = await getBase64FromUrl(url);
|
|
||||||
} else {
|
|
||||||
//embed document's object id to all pages in pdf document
|
|
||||||
await embedDocId(pdfDoc, docId, allPages);
|
|
||||||
pdfBase64 = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let xyData of xyPostion) {
|
|
||||||
const imgUrlList = xyData.pos;
|
|
||||||
const pageNo = xyData.pageNumber;
|
|
||||||
imgUrlList.map(async (data) => {
|
|
||||||
//cheking signUrl is defau;t signature url of custom url
|
|
||||||
let ImgUrl = data.SignUrl;
|
|
||||||
const checkUrl = urlValidator(ImgUrl);
|
|
||||||
|
|
||||||
//if default signature url then convert it in base 64
|
|
||||||
if (checkUrl) {
|
|
||||||
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
|
||||||
}
|
|
||||||
//function for convert signature png base64 url to jpeg base64
|
|
||||||
convertPNGtoJPEG(ImgUrl)
|
|
||||||
.then((jpegBase64Data) => {
|
|
||||||
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
|
||||||
const newImgUrl = jpegBase64Data.replace(
|
|
||||||
removeBase64Fromjpeg,
|
|
||||||
""
|
|
||||||
);
|
|
||||||
|
|
||||||
//function for embed signature in pdf and get digital signature pdf
|
|
||||||
signPdfFun(
|
|
||||||
newImgUrl,
|
|
||||||
docId,
|
|
||||||
signerUserId,
|
|
||||||
pdfOriginalWidth,
|
|
||||||
xyPostion,
|
|
||||||
containerWH,
|
|
||||||
setIsAlert,
|
|
||||||
data,
|
|
||||||
pdfBase64,
|
|
||||||
pageNo
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
if (res && res.status === "success") {
|
|
||||||
getDocumentDetails();
|
|
||||||
} else {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//else if signature is more than one then embed all sign with the use of pdf-lib
|
|
||||||
else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
|
||||||
const flag = false;
|
|
||||||
//embed document's object id to all pages in pdf document
|
|
||||||
await embedDocId(pdfDoc, docId, allPages);
|
|
||||||
//embed multi signature in pdf
|
|
||||||
const pdfBytes = await multiSignEmbed(
|
|
||||||
pngUrl,
|
|
||||||
pdfDoc,
|
|
||||||
pdfOriginalWidth,
|
|
||||||
flag,
|
|
||||||
containerWH
|
|
||||||
);
|
|
||||||
|
|
||||||
//function for embed signature in pdf and get digital signature pdf
|
|
||||||
try {
|
|
||||||
const res = await signPdfFun(
|
|
||||||
pdfBytes,
|
|
||||||
docId,
|
|
||||||
signerUserId,
|
|
||||||
pdfOriginalWidth,
|
|
||||||
xyPostion,
|
|
||||||
containerWH,
|
|
||||||
setIsAlert
|
|
||||||
);
|
|
||||||
if (res && res.status === "success") {
|
|
||||||
getDocumentDetails();
|
|
||||||
} else {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setIsSignPad(false);
|
|
||||||
setXyPostion([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//function for change page
|
|
||||||
function changePage(offset) {
|
|
||||||
setPageNumber((prevPageNumber) => prevPageNumber + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
//function for image upload or update
|
|
||||||
const onImageChange = (event) => {
|
|
||||||
if (event.target.files && event.target.files[0]) {
|
|
||||||
onImageSelect(event, setImgWH, setImage);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//function for save button to save signature or image url
|
|
||||||
const saveSign = (isDefaultSign) => {
|
|
||||||
const signatureImg = isDefaultSign ? defaultSignImg : signature;
|
|
||||||
const signFlag = true;
|
|
||||||
let imgWH = { width: "", height: "" };
|
|
||||||
setIsSignPad(false);
|
|
||||||
setIsImageSelect(false);
|
|
||||||
setImage();
|
|
||||||
|
|
||||||
if (isDefaultSign) {
|
|
||||||
const img = new Image();
|
|
||||||
img.src = defaultSignImg;
|
|
||||||
if (img.complete) {
|
|
||||||
imgWH = {
|
|
||||||
width: img.width,
|
|
||||||
height: img.height
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const getUpdatePosition = onSaveSign(
|
|
||||||
xyPostion,
|
|
||||||
index,
|
|
||||||
signKey,
|
|
||||||
signatureImg,
|
|
||||||
imgWH,
|
|
||||||
isDefaultSign,
|
|
||||||
signFlag
|
|
||||||
);
|
|
||||||
|
|
||||||
if (getUpdatePosition) {
|
|
||||||
setXyPostion(getUpdatePosition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//function for upload stamp image
|
|
||||||
const saveImage = () => {
|
|
||||||
const getImage = onSaveImage(xyPostion, index, signKey, imgWH, image);
|
|
||||||
setXyPostion(getImage);
|
|
||||||
};
|
|
||||||
|
|
||||||
//function for set decline true on press decline button
|
|
||||||
const declineDoc = async () => {
|
|
||||||
const data = {
|
|
||||||
IsDeclined: true
|
|
||||||
};
|
|
||||||
|
|
||||||
await axios
|
|
||||||
.put(
|
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
|
||||||
"_appName"
|
|
||||||
)}_Document/${docId}`,
|
|
||||||
data,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((result) => {
|
|
||||||
const res = result.data;
|
|
||||||
if (res) {
|
|
||||||
const currentDecline = {
|
|
||||||
currnt: "YouDeclined",
|
|
||||||
isDeclined: true
|
|
||||||
};
|
|
||||||
setIsDecline(currentDecline);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setIsAlert({
|
|
||||||
isShow: true,
|
|
||||||
alertMessage: "something went wrong"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const addDefaultSignature = () => {
|
|
||||||
const getXyData = addDefaultSignatureImg(xyPostion, defaultSignImg);
|
|
||||||
|
|
||||||
setXyPostion(getXyData);
|
|
||||||
setAddDefaultSign({
|
|
||||||
isShow: false,
|
|
||||||
alertMessage: ""
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//function for update TourStatus
|
|
||||||
const closeTour = async () => {
|
|
||||||
setSignTour(false);
|
|
||||||
|
|
||||||
let updatedTourStatus = [];
|
|
||||||
if (tourStatus.length > 0) {
|
|
||||||
updatedTourStatus = [...tourStatus];
|
|
||||||
const recipientssignIndex = tourStatus.findIndex(
|
|
||||||
(obj) =>
|
|
||||||
obj["recipientssign"] === false || obj["recipientssign"] === true
|
|
||||||
);
|
|
||||||
if (recipientssignIndex !== -1) {
|
|
||||||
updatedTourStatus[recipientssignIndex] = { recipientssign: true };
|
|
||||||
} else {
|
|
||||||
updatedTourStatus.push({ recipientssign: true });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updatedTourStatus = [{ recipientssign: true }];
|
|
||||||
}
|
|
||||||
|
|
||||||
await axios
|
|
||||||
.put(
|
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
|
||||||
"_appName"
|
|
||||||
)}${contractName}/${signerUserId}`,
|
|
||||||
{
|
|
||||||
TourStatus: updatedTourStatus
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
// console.log("res", json);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("axois err ", err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const tourFunction = () => {
|
|
||||||
const tourConfig = [
|
|
||||||
{
|
|
||||||
selector: '[data-tut="reactourFirst"]',
|
|
||||||
content: `You can click "Auto Sign All" to automatically sign at all the locations meant to be signed by you.Make sure that you review the document properly before you click this button.`,
|
|
||||||
position: "top",
|
|
||||||
style: { fontSize: "13px" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
selector: '[data-tut="reactourSecond"]',
|
|
||||||
content: `Click any of such placeholders appearing on the document to sign.You will see the options to draw sign or upload an image once you click here.`,
|
|
||||||
position: "top",
|
|
||||||
style: { fontSize: "13px" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
selector: '[data-tut="reactourThird"]',
|
|
||||||
content: `Click here to finish & download the signed document.You will also receive a copy on your email.`,
|
|
||||||
position: "top",
|
|
||||||
style: { fontSize: "13px" }
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
let stepsToShow = [];
|
|
||||||
if (!defaultSignImg || isMobile) {
|
|
||||||
stepsToShow = tourConfig.filter(
|
|
||||||
(step) => step.selector !== '[data-tut="reactourFirst"]'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tour
|
|
||||||
onRequestClose={closeTour}
|
|
||||||
steps={stepsToShow && stepsToShow.length > 0 ? stepsToShow : tourConfig}
|
|
||||||
isOpen={signTour}
|
|
||||||
closeWithMask={false}
|
|
||||||
rounded={5}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DndProvider backend={HTML5Backend}>
|
|
||||||
{isLoading.isLoad ? (
|
|
||||||
<Loader isLoading={isLoading} />
|
|
||||||
) : handleError ? (
|
|
||||||
<HandleError handleError={handleError} />
|
|
||||||
) : noData ? (
|
|
||||||
<Nodata />
|
|
||||||
) : (
|
|
||||||
<div className="signatureContainer" ref={divRef}>
|
|
||||||
{/* this modal is used to show decline alert */}
|
|
||||||
<CustomModal
|
|
||||||
containerWH={containerWH}
|
|
||||||
show={isDecline.isDeclined}
|
|
||||||
headMsg="Document Declined Alert!"
|
|
||||||
bodyMssg={
|
|
||||||
isDecline.currnt === "Sure" ? (
|
|
||||||
<p>Are you sure want to decline this document ?</p>
|
|
||||||
) : isDecline.currnt === "YouDeclined" ? (
|
|
||||||
<p>You have declined this document!</p>
|
|
||||||
) : (
|
|
||||||
isDecline.currnt === "another" && (
|
|
||||||
<p>
|
|
||||||
You cannot sign this document as it has been declined by one
|
|
||||||
or more person(s).
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
footerMessage={isDecline.currnt === "Sure"}
|
|
||||||
declineDoc={declineDoc}
|
|
||||||
setIsDecline={setIsDecline}
|
|
||||||
/>
|
|
||||||
<AlertComponent
|
|
||||||
isShow={isAlert.isShow}
|
|
||||||
alertMessage={isAlert.alertMessage}
|
|
||||||
setIsAlert={setIsAlert}
|
|
||||||
/>
|
|
||||||
<AlertComponent
|
|
||||||
isShow={addDefaultSign.isShow}
|
|
||||||
alertMessage={addDefaultSign.alertMessage}
|
|
||||||
setIsAlert={setAddDefaultSign}
|
|
||||||
isdefaultSign={true}
|
|
||||||
addDefaultSignature={addDefaultSignature}
|
|
||||||
headBG={themeColor()}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* this modal is used for show expired alert */}
|
|
||||||
<CustomModal
|
|
||||||
containerWH={containerWH}
|
|
||||||
show={isExpired}
|
|
||||||
headMsg="Document Expired!"
|
|
||||||
bodyMssg="This Document is no longer available."
|
|
||||||
/>
|
|
||||||
{/* this component used for UI interaction and show their functionality */}
|
|
||||||
{pdfLoadFail.status &&
|
|
||||||
!isExpired &&
|
|
||||||
!checkTourStatus &&
|
|
||||||
tourFunction()}
|
|
||||||
|
|
||||||
{/* this component used to render all pdf pages in left side */}
|
|
||||||
<RenderAllPdfPage
|
|
||||||
pdfUrl={pdfUrl}
|
|
||||||
signPdfUrl={signedPdfData[0] && signedPdfData[0].URL}
|
|
||||||
allPages={allPages}
|
|
||||||
setAllPages={setAllPages}
|
|
||||||
setPageNumber={setPageNumber}
|
|
||||||
/>
|
|
||||||
{/* <div style={{width:"160px",border:"1px solid red"}}>kebjke</div> */}
|
|
||||||
{/* pdf render view */}
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
marginLeft: !isMobile && pdfOriginalWidth > 500 && "20px",
|
|
||||||
marginRight: !isMobile && pdfOriginalWidth > 500 && "20px"
|
|
||||||
}}
|
|
||||||
ref={divRef}
|
|
||||||
>
|
|
||||||
{/* this modal is used show this document is already sign */}
|
|
||||||
<Modal
|
|
||||||
show={isAlreadySign.status}
|
|
||||||
onShow={() => modalAlign()}
|
|
||||||
backdropClassName="signature-backdrop"
|
|
||||||
>
|
|
||||||
<ModalHeader style={{ background: themeColor() }}>
|
|
||||||
<span style={{ color: "white" }}> Sign Documents</span>
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<Modal.Body>
|
|
||||||
<p>{isAlreadySign.mssg}</p>
|
|
||||||
</Modal.Body>
|
|
||||||
|
|
||||||
<Modal.Footer>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
borderRadius: "0px",
|
|
||||||
border: "1.5px solid #e3e2e1",
|
|
||||||
fontWeight: "600",
|
|
||||||
color: "black"
|
|
||||||
}}
|
|
||||||
className="btn"
|
|
||||||
onClick={() => setIsAlreadySign({ status: false })}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
</Modal.Footer>
|
|
||||||
</Modal>
|
|
||||||
{/* this is modal of signature pad */}
|
|
||||||
<SignPad
|
|
||||||
isSignPad={isSignPad}
|
|
||||||
isStamp={isStamp}
|
|
||||||
setIsImageSelect={setIsImageSelect}
|
|
||||||
setIsSignPad={setIsSignPad}
|
|
||||||
setImage={setImage}
|
|
||||||
isImageSelect={isImageSelect}
|
|
||||||
imageRef={imageRef}
|
|
||||||
onImageChange={onImageChange}
|
|
||||||
setSignature={setSignature}
|
|
||||||
image={image}
|
|
||||||
onSaveImage={saveImage}
|
|
||||||
onSaveSign={saveSign}
|
|
||||||
defaultSign={defaultSignImg}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* pdf header which contain finish back button */}
|
|
||||||
<Header
|
|
||||||
recipient={true}
|
|
||||||
pdfDetails={signedPdfData}
|
|
||||||
isAlreadySign={isAlreadySign}
|
|
||||||
pageNumber={pageNumber}
|
|
||||||
allPages={allPages}
|
|
||||||
changePage={changePage}
|
|
||||||
pdfUrl={pdfUrl}
|
|
||||||
setIsDecline={setIsDecline}
|
|
||||||
embedImages={embedImages}
|
|
||||||
isShowHeader={true}
|
|
||||||
currentSigner={true}
|
|
||||||
decline={true}
|
|
||||||
alreadySign={pdfUrl ? true : false}
|
|
||||||
/>
|
|
||||||
{containerWH && (
|
|
||||||
<RenderPdf
|
|
||||||
pageNumber={pageNumber}
|
|
||||||
pdfOriginalWidth={pdfOriginalWidth}
|
|
||||||
pdfNewWidth={pdfNewWidth}
|
|
||||||
setIsSignPad={setIsSignPad}
|
|
||||||
setIsStamp={setIsStamp}
|
|
||||||
setSignKey={setSignKey}
|
|
||||||
pdfDetails={signedPdfData}
|
|
||||||
xyPostion={xyPostion}
|
|
||||||
successEmail={false}
|
|
||||||
pdfUrl={pdfUrl}
|
|
||||||
numPages={numPages}
|
|
||||||
pageDetails={pageDetails}
|
|
||||||
recipient={true}
|
|
||||||
isAlreadySign={isAlreadySign}
|
|
||||||
setPdfLoadFail={setPdfLoadFail}
|
|
||||||
pdfLoadFail={pdfLoadFail}
|
|
||||||
setXyPostion={setXyPostion}
|
|
||||||
index={index}
|
|
||||||
containerWH={containerWH}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{!pdfUrl ? (
|
|
||||||
<div data-tut="reactourFirst">
|
|
||||||
{/* this component is used to render default signature of user in the right side of the component */}
|
|
||||||
|
|
||||||
<DefaultSignature
|
|
||||||
themeColor={themeColor}
|
|
||||||
defaultSignImg={defaultSignImg}
|
|
||||||
setDefaultSignImg={setDefaultSignImg}
|
|
||||||
userObjectId={userObjectID}
|
|
||||||
setIsLoading={setIsLoading}
|
|
||||||
xyPostion={xyPostion}
|
|
||||||
setXyPostion={setXyPostion}
|
|
||||||
setShowAlreadySignDoc={setIsAlreadySign}
|
|
||||||
setIsAlert={setAddDefaultSign}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
<Signedby pdfDetails={signedPdfData[0]} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</DndProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EmbedPdfImage;
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Routes, Route } from "react-router-dom";
|
import { Routes, Route } from "react-router-dom";
|
||||||
import SignYourselfPdf from "./Component/SignYourselfPdf";
|
import SignYourselfPdf from "./Component/SignYourselfPdf";
|
||||||
import RecipientSignPdf from "./Component/recipientSignPdf";
|
|
||||||
import PlaceHolderSign from "./Component/placeHolderSign";
|
import PlaceHolderSign from "./Component/placeHolderSign";
|
||||||
import ManageSign from "./Component/ManageSign";
|
import ManageSign from "./Component/ManageSign";
|
||||||
import Login from "./Component/login";
|
import Login from "./Component/login";
|
||||||
@@ -9,7 +8,10 @@ import DraftDocument from "./Component/DraftDocument";
|
|||||||
import PdfRequestFiles from "./Component/PdfRequestFiles";
|
import PdfRequestFiles from "./Component/PdfRequestFiles";
|
||||||
import LegaDrive from "./Component/LegaDrive/LegaDrive";
|
import LegaDrive from "./Component/LegaDrive/LegaDrive";
|
||||||
import PageNotFound from "./Component/PageNotFound";
|
import PageNotFound from "./Component/PageNotFound";
|
||||||
|
import TemplatePlaceHolder from "./Component/TemplatePlaceholder";
|
||||||
|
import Parse from "parse";
|
||||||
|
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||||
|
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||||
// `AppRoutes` is used to define route path of app and
|
// `AppRoutes` is used to define route path of app and
|
||||||
// it expose to host app, check moduleFederation.config.js for more
|
// it expose to host app, check moduleFederation.config.js for more
|
||||||
function AppRoutes() {
|
function AppRoutes() {
|
||||||
@@ -24,8 +26,8 @@ function AppRoutes() {
|
|||||||
<Route path="/signaturePdf/:docId" element={<SignYourselfPdf />} />
|
<Route path="/signaturePdf/:docId" element={<SignYourselfPdf />} />
|
||||||
{/* recipient signature route with no rowlevel data using docId from url */}
|
{/* recipient signature route with no rowlevel data using docId from url */}
|
||||||
<Route
|
<Route
|
||||||
path="/recipientSignPdf/:id/:contactBookId"
|
path="/recipientSignPdf/:docId/:contactBookId"
|
||||||
element={<RecipientSignPdf />}
|
element={<PdfRequestFiles />}
|
||||||
/>
|
/>
|
||||||
{/* recipient placeholder set route with rowlevel data */}
|
{/* recipient placeholder set route with rowlevel data */}
|
||||||
<Route path="/placeHolderSign" element={<PlaceHolderSign />} />{" "}
|
<Route path="/placeHolderSign" element={<PlaceHolderSign />} />{" "}
|
||||||
@@ -47,6 +49,7 @@ function AppRoutes() {
|
|||||||
{/* lega drive route */}
|
{/* lega drive route */}
|
||||||
<Route path="/legadrive" element={<LegaDrive />} />
|
<Route path="/legadrive" element={<LegaDrive />} />
|
||||||
{/* Page Not Found */}
|
{/* Page Not Found */}
|
||||||
|
<Route path="/template/:templateId" element={<TemplatePlaceHolder />} />
|
||||||
<Route path="*" element={<PageNotFound />} />
|
<Route path="*" element={<PageNotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 324 B |
|
Before Width: | Height: | Size: 259 B |
|
Before Width: | Height: | Size: 272 B |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 208 B |
|
Before Width: | Height: | Size: 7.9 KiB |
@@ -0,0 +1,79 @@
|
|||||||
|
.addusercontainer {
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px 20px 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loaderdiv {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addUserInput {
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
width: 100%;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #d1d5db;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
outline: none;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.buttoncontainer {
|
||||||
|
margin-top: 1rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitbutton {
|
||||||
|
background: #1ab6ce;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
||||||
|
border: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
/* For classes: bg-[#188ae2] text-sm text-white px-4 py-2 rounded ml-2 shadow focus:outline-none */
|
||||||
|
.resetbutton {
|
||||||
|
background-color: #188ae2;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
||||||
|
border: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
outline: none;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
.modaloverlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.75);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalcontainer {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
|
z-index: 901;
|
||||||
|
max-height: 80%;
|
||||||
|
min-width: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
-ms-overflow-style: none; /* Internet Explorer and Edge */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide scrollbar for Webkit browsers */
|
||||||
|
.modalcontainer::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalheader {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styling for the modal title */
|
||||||
|
.modaltitle {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight:normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styling for the close button */
|
||||||
|
.closebtn {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:767px) {
|
||||||
|
|
||||||
|
.modalcontainer {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
|
z-index: 1000;
|
||||||
|
max-height: 80%;
|
||||||
|
min-width: 90%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,10 +6,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.childDiv {
|
.childDiv {
|
||||||
width: 50%;
|
width: 40%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
border-top-left-radius: 0.3rem;
|
border-top-left-radius: 0.3rem;
|
||||||
border-top-right-radius: 0.3rem;
|
border-top-right-radius: 0.3rem;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
font-weight: 500;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modalBodyDIv {
|
.modalBodyDIv {
|
||||||
@@ -48,12 +49,12 @@
|
|||||||
.modalFooterDiv {
|
.modalFooterDiv {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width:500px) {
|
@media screen and (max-width:500px) {
|
||||||
.childDiv {
|
.childDiv {
|
||||||
margin: 50px 7px;
|
margin: 50px 7px;
|
||||||
width: 90%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.hrStyle{
|
||||||
|
border-top-width: 1px !important;
|
||||||
|
color: #c3bcbc !important;
|
||||||
|
height: 0px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Fasthand&display=swap');
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Dancing+Script&display=swap');
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Delicious+Handrawn&display=swap');
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Cedarville+Cursive&display=swap');
|
||||||
|
|
||||||
.signatureCanvas {
|
.signatureCanvas {
|
||||||
border: 2px solid #888;
|
border: 2px solid #888;
|
||||||
background-color: rgb(255, 255, 255);
|
background-color: rgb(255, 255, 255);
|
||||||
@@ -110,10 +115,6 @@
|
|||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.emailChipClose:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addEmailInput {
|
.addEmailInput {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -127,10 +128,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.signatureInput {
|
.signatureInput {
|
||||||
padding: 10px;
|
|
||||||
width: 80%;
|
width: 80%;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.75rem;
|
font-size: 20px;
|
||||||
border: 1px solid #e2dddd;
|
border: 1px solid #e2dddd;
|
||||||
color: black;
|
color: black;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
@@ -138,10 +138,13 @@
|
|||||||
font-variation-settings: inherit;
|
font-variation-settings: inherit;
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signatureInput:focus {
|
.signatureInput:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
|
border: 1px solid blue;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
|
||||||
}
|
}
|
||||||
|
|
||||||
.resizable-box-overlay {
|
.resizable-box-overlay {
|
||||||
@@ -174,17 +177,46 @@
|
|||||||
padding: 0px 5.1px 1px 5px;
|
padding: 0px 5.1px 1px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.placeholderBlock {
|
.signCloseBtn {
|
||||||
padding: 0px;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-style: dashed;
|
right: -8px;
|
||||||
width: 150px;
|
top: -18px;
|
||||||
height: 60px;
|
font-size: 14px;
|
||||||
background: #daebe0;
|
cursor: pointer;
|
||||||
text-align: center;
|
z-index: 2;
|
||||||
justify-content: center;
|
background: white;
|
||||||
border-width: 0.2px;
|
}
|
||||||
|
|
||||||
|
.signCopy {
|
||||||
|
position: absolute;
|
||||||
|
right: 12px;
|
||||||
|
top: -18px;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 2;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signUserIcon {
|
||||||
|
position: absolute;
|
||||||
|
right: 32px;
|
||||||
|
top: -18px;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 2;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ScrollbarsCustom-Track {
|
||||||
|
width: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signYourselfBlock {
|
||||||
|
padding: 0px;
|
||||||
|
display: flex !important;
|
||||||
|
text-align: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
align-items: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.finishBtn {
|
.finishBtn {
|
||||||
@@ -195,6 +227,7 @@
|
|||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
border: none;
|
border: none;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sendMail {
|
.sendMail {
|
||||||
@@ -214,7 +247,7 @@
|
|||||||
|
|
||||||
.finishBtn:hover {
|
.finishBtn:hover {
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.saveBtn {
|
.saveBtn {
|
||||||
@@ -238,7 +271,7 @@
|
|||||||
|
|
||||||
.defaultSignBox {
|
.defaultSignBox {
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
|
||||||
width: 180px;
|
width: 90%;
|
||||||
height: 111px;
|
height: 111px;
|
||||||
padding: 8px 20px;
|
padding: 8px 20px;
|
||||||
color: white;
|
color: white;
|
||||||
@@ -249,6 +282,14 @@
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.backBtn {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backBtn:hover {
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
.defaultBtn {
|
.defaultBtn {
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
|
||||||
padding: 3px 26px;
|
padding: 3px 26px;
|
||||||
@@ -258,14 +299,7 @@
|
|||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
border: "none";
|
||||||
|
|
||||||
.backBtn {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.backBtn:hover {
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.defaultBtn:focus {
|
.defaultBtn:focus {
|
||||||
@@ -375,10 +409,13 @@
|
|||||||
.signTab {
|
.signTab {
|
||||||
cursor: pointer !important;
|
cursor: pointer !important;
|
||||||
font-weight: 400 !important;
|
font-weight: 400 !important;
|
||||||
margin-left: 10px !important;
|
margin: 7px !important;
|
||||||
font-size: 15px !important;
|
font-size: 15px !important;
|
||||||
}
|
}
|
||||||
|
.cancelBtn {
|
||||||
|
color: black;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
.draggable-button {
|
.draggable-button {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
background: #3498db;
|
background: #3498db;
|
||||||
@@ -416,6 +453,7 @@
|
|||||||
width: 180px;
|
width: 180px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modalBody {
|
.modalBody {
|
||||||
@@ -531,7 +569,6 @@
|
|||||||
gap: 5px;
|
gap: 5px;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: #887abf;
|
background-color: #887abf;
|
||||||
|
|
||||||
width: 200px;
|
width: 200px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
@@ -644,7 +681,7 @@ option {
|
|||||||
|
|
||||||
.fontOptionContainer {
|
.fontOptionContainer {
|
||||||
border: 1px solid #d6d3d3;
|
border: 1px solid #d6d3d3;
|
||||||
margin: 10px 5px 5px 5px;
|
margin: 10px 0px 5px 0px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,6 +689,14 @@ option {
|
|||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.autoSignScroll {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autoSignScroll::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width:766px) {
|
@media screen and (max-width:766px) {
|
||||||
|
|
||||||
.showPages {
|
.showPages {
|
||||||
@@ -764,6 +809,11 @@ option {
|
|||||||
.mobileHead {
|
.mobileHead {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.signatureText {
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width:487px) and (min-width:351px) {
|
@media screen and (max-width:487px) and (min-width:351px) {
|
||||||
@@ -789,6 +839,13 @@ option {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.signTab {
|
||||||
|
|
||||||
|
font-weight: 500 !important;
|
||||||
|
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width:350px) and (min-width:311px) {
|
@media screen and (max-width:350px) and (min-width:311px) {
|
||||||
@@ -846,7 +903,7 @@ option {
|
|||||||
|
|
||||||
font-weight: 500 !important;
|
font-weight: 500 !important;
|
||||||
|
|
||||||
font-size: 10px !important;
|
font-size: 8px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uploadImgLogo {
|
.uploadImgLogo {
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.addSignerBtn{
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 2px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #47a3ad;
|
||||||
|
margin: 1px;
|
||||||
|
color: #47a3ad;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
.addSignerBtn:hover{
|
||||||
|
background: #47a3ad;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import axios from "axios";
|
||||||
|
import "../css/AddUser.css";
|
||||||
|
const AddUser = (props) => {
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [phone, setPhone] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [addYourself, setAddYourself] = useState(false);
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [isUserExist, setIsUserExist] = useState(false);
|
||||||
|
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||||
|
const parseAppId = localStorage.getItem("parseAppId");
|
||||||
|
Parse.serverURL = parseBaseUrl;
|
||||||
|
Parse.initialize(parseAppId);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
checkUserExist();
|
||||||
|
}, []);
|
||||||
|
// Load user details from localStorage when the component mounts
|
||||||
|
useEffect(() => {
|
||||||
|
const savedUserDetails = JSON.parse(
|
||||||
|
localStorage.getItem("UserInformation")
|
||||||
|
);
|
||||||
|
if (savedUserDetails && addYourself) {
|
||||||
|
setName(savedUserDetails.name);
|
||||||
|
setPhone(savedUserDetails.phone);
|
||||||
|
setEmail(savedUserDetails.email);
|
||||||
|
}
|
||||||
|
}, [addYourself]);
|
||||||
|
|
||||||
|
const checkUserExist = async () => {
|
||||||
|
const user = Parse.User.current();
|
||||||
|
try {
|
||||||
|
const query = new Parse.Query("contracts_Contactbook");
|
||||||
|
query.equalTo("CreatedBy", user);
|
||||||
|
query.notEqualTo("IsDeleted", true);
|
||||||
|
query.equalTo("Email", user.getEmail());
|
||||||
|
const res = await query.first();
|
||||||
|
// console.log(res);
|
||||||
|
if (!res) {
|
||||||
|
setIsUserExist(true);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Define a function to handle form submission
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsLoader(true);
|
||||||
|
Parse.serverURL = parseBaseUrl;
|
||||||
|
Parse.initialize(parseAppId);
|
||||||
|
try {
|
||||||
|
const contactQuery = new Parse.Object("contracts_Contactbook");
|
||||||
|
contactQuery.set("Name", name);
|
||||||
|
contactQuery.set("Phone", phone);
|
||||||
|
contactQuery.set("Email", email);
|
||||||
|
contactQuery.set("UserRole", "contracts_Guest");
|
||||||
|
|
||||||
|
if (localStorage.getItem("TenetId")) {
|
||||||
|
contactQuery.set("TenantId", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "partners_Tenant",
|
||||||
|
objectId: localStorage.getItem("TenetId")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const _users = Parse.Object.extend("User");
|
||||||
|
const _user = new _users();
|
||||||
|
_user.set("name", name);
|
||||||
|
_user.set("username", email);
|
||||||
|
_user.set("email", email);
|
||||||
|
_user.set("phone", phone);
|
||||||
|
_user.set("password", phone);
|
||||||
|
|
||||||
|
const user = await _user.save();
|
||||||
|
if (user) {
|
||||||
|
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: localStorage.getItem("_appName"),
|
||||||
|
roleName: "contracts_Guest",
|
||||||
|
userId: user.id
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
contactQuery.set(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
contactQuery.set("UserId", user);
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
acl.setPublicWriteAccess(true);
|
||||||
|
acl.setReadAccess(currentUser.id, true);
|
||||||
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
|
||||||
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
props.details(parseData);
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoader(false);
|
||||||
|
// Reset the form fields
|
||||||
|
setAddYourself(false);
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
if (err.code === 202) {
|
||||||
|
const params = { email: email };
|
||||||
|
const userRes = await Parse.Cloud.run("getUserId", params);
|
||||||
|
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: localStorage.getItem("_appName"),
|
||||||
|
roleName: "contracts_Guest",
|
||||||
|
userId: userRes.id
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
contactQuery.set(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
contactQuery.set("UserId", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: userRes.id
|
||||||
|
});
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
acl.setPublicWriteAccess(true);
|
||||||
|
acl.setReadAccess(currentUser.id, true);
|
||||||
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
if(props.details){
|
||||||
|
props.details(parseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
// Reset the form fields
|
||||||
|
setAddYourself(false);
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// console.log("err", err);
|
||||||
|
setIsLoader(false);
|
||||||
|
alert("something went wrong!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define a function to handle the "add yourself" checkbox
|
||||||
|
const handleAddYourselfChange = () => {
|
||||||
|
if (addYourself) {
|
||||||
|
setAddYourself(false);
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
} else {
|
||||||
|
setAddYourself(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleReset = () => {
|
||||||
|
setAddYourself(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="addusercontainer">
|
||||||
|
{isLoader && (
|
||||||
|
<div className="loaderdiv">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "45px",
|
||||||
|
color: "#3dd3e0"
|
||||||
|
}}
|
||||||
|
className="loader-37"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="form-wrapper">
|
||||||
|
<div style={{ fontSize: 14, fontWeight: "700" }}>Add User</div>
|
||||||
|
|
||||||
|
{isUserExist && (
|
||||||
|
<div className="form-section">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="addYourself"
|
||||||
|
checked={addYourself}
|
||||||
|
onChange={handleAddYourselfChange}
|
||||||
|
className="form-checkbox"
|
||||||
|
/>
|
||||||
|
<label htmlFor="addYourself" className="checkbox-label ">
|
||||||
|
Add Yourself
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div className="form-section">
|
||||||
|
<label htmlFor="name" style={{ fontSize: 13 }}>
|
||||||
|
Name
|
||||||
|
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
disabled={addYourself}
|
||||||
|
className="addUserInput"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-section">
|
||||||
|
<label htmlFor="email" style={{ fontSize: 13 }}>
|
||||||
|
Email
|
||||||
|
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
required
|
||||||
|
disabled={addYourself}
|
||||||
|
className="addUserInput"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-section">
|
||||||
|
<label htmlFor="phone" style={{ fontSize: 13 }}>
|
||||||
|
Phone
|
||||||
|
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="phone"
|
||||||
|
value={phone}
|
||||||
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
|
required
|
||||||
|
disabled={addYourself}
|
||||||
|
className="addUserInput"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="buttoncontainer">
|
||||||
|
<button type="submit" className="submitbutton">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleReset()}
|
||||||
|
className="resetbutton"
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddUser;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Alert = ({ children, type }) => {
|
||||||
|
const textcolor = type ? theme(type) : theme();
|
||||||
|
function theme(color) {
|
||||||
|
switch (color) {
|
||||||
|
case "success":
|
||||||
|
return "border-[#c3e6cb] bg-[#d4edda] text-[#155724]";
|
||||||
|
case "info":
|
||||||
|
return "border-[#adcdeb] bg-[#c1daf0] text-[#153756]";
|
||||||
|
case "danger":
|
||||||
|
return "border-[#f0a8a8] bg-[#f4bebe] text-[#c42121]";
|
||||||
|
default:
|
||||||
|
return "border-[#d6d6d6] bg-[#d9d9d9] text-[#575757]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children && (
|
||||||
|
<div
|
||||||
|
className={`z-40 fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm ${textcolor} rounded py-[.75rem] px-[1.25rem] `}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Alert;
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import Alert from "./Alert";
|
||||||
|
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||||
|
|
||||||
|
const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: parentFolderId
|
||||||
|
};
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [folderList, setFolderList] = useState([]);
|
||||||
|
const [isAlert, setIsAlert] = useState(false);
|
||||||
|
const [selectedParent, setSelectedParent] = useState();
|
||||||
|
const [alert, setAlert] = useState({ type: "info", message: "" });
|
||||||
|
useEffect(() => {
|
||||||
|
fetchFolder();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchFolder = async () => {
|
||||||
|
try {
|
||||||
|
const FolderQuery = new Parse.Query(folderCls);
|
||||||
|
if (parentFolderId) {
|
||||||
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
} else {
|
||||||
|
FolderQuery.doesNotExist("Folder");
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await FolderQuery.find();
|
||||||
|
if (res) {
|
||||||
|
const result = JSON.parse(JSON.stringify(res));
|
||||||
|
if (result) {
|
||||||
|
setFolderList(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Err ", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCreateFolder = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (name) {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const exsitQuery = new Parse.Query(folderCls);
|
||||||
|
exsitQuery.equalTo("Name", name);
|
||||||
|
exsitQuery.equalTo("Type", "Folder");
|
||||||
|
if (parentFolderId) {
|
||||||
|
exsitQuery.equalTo("Folder", folderPtr);
|
||||||
|
}
|
||||||
|
const templExist = await exsitQuery.first();
|
||||||
|
if (templExist) {
|
||||||
|
setAlert({ type: "dange", message: "Folder already exist!" });
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
const template = new Parse.Object(folderCls);
|
||||||
|
template.set("Name", name);
|
||||||
|
template.set("Type", "Folder");
|
||||||
|
|
||||||
|
if (selectedParent) {
|
||||||
|
template.set("Folder", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: selectedParent
|
||||||
|
});
|
||||||
|
} else if (parentFolderId) {
|
||||||
|
template.set("Folder", folderPtr);
|
||||||
|
}
|
||||||
|
template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||||
|
const res = await template.save();
|
||||||
|
if (res) {
|
||||||
|
const result = JSON.parse(JSON.stringify(res));
|
||||||
|
if (onSuccess) {
|
||||||
|
setAlert({
|
||||||
|
type: "success",
|
||||||
|
message: "Folder created successfully!"
|
||||||
|
});
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
onSuccess(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setAlert({ type: "info", message: "Please fill folder name" });
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleOptions = (e) => {
|
||||||
|
setSelectedParent(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{isAlert && <Alert type={alert.type}>{alert.message}</Alert>}
|
||||||
|
<div id="createFolder">
|
||||||
|
<h1 style={{ fontWeight: "500", fontSize: "1rem" }}>Create Folder</h1>
|
||||||
|
<div style={{ fontSize: "12px", marginTop: "11px" }}>
|
||||||
|
<label className="block">
|
||||||
|
Name<span style={{ color: "red", fontSize: "13px" }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
style={{
|
||||||
|
padding: "8px 11px",
|
||||||
|
width: "100%",
|
||||||
|
border: "1px solid rgb(195, 188, 188)",
|
||||||
|
borderRadius: "5px",
|
||||||
|
outline: "none",
|
||||||
|
fontSize: "12px"
|
||||||
|
}}
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: "12px", marginTop: "7px" }}>
|
||||||
|
<label className="block">Parent Folder</label>
|
||||||
|
<select
|
||||||
|
value={selectedParent}
|
||||||
|
onChange={handleOptions}
|
||||||
|
style={{
|
||||||
|
padding: "8px 11px",
|
||||||
|
width: "100%",
|
||||||
|
border: "1px solid rgb(195, 188, 188)",
|
||||||
|
borderRadius: "5px",
|
||||||
|
outline: "none",
|
||||||
|
fontSize: "12px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option>select</option>
|
||||||
|
{folderList.length > 0 &&
|
||||||
|
folderList.map((x) => (
|
||||||
|
<option key={x.objectId} value={x.objectId}>
|
||||||
|
{x.Name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={handleCreateFolder}
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
borderRadius: "5px",
|
||||||
|
backgroundColor: themeColor(),
|
||||||
|
color: "white",
|
||||||
|
marginTop: "22px",
|
||||||
|
outline: "none",
|
||||||
|
border: "none",
|
||||||
|
padding: "10px 8px",
|
||||||
|
fontSize: "14px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-plus mr-1"></i>
|
||||||
|
<span>Create</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateFolder;
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import React from "react";
|
||||||
|
import "../css/ModalUi.css";
|
||||||
|
const ModalUi = ({ children, title, isOpen, handleClose, headerColor }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isOpen && (
|
||||||
|
<div className="modaloverlay">
|
||||||
|
<div className="modalcontainer">
|
||||||
|
{title && <div
|
||||||
|
style={{ background: headerColor ? headerColor : "#32a3ac" }}
|
||||||
|
className="modalheader"
|
||||||
|
>
|
||||||
|
<div className="modaltitle">{title}</div>
|
||||||
|
<div
|
||||||
|
className="closebtn"
|
||||||
|
onClick={() => handleClose && handleClose()}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</div>
|
||||||
|
</div>}
|
||||||
|
<div>{children}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalUi;
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
import React, { useRef, useState } from "react";
|
||||||
|
import "../css/signerListPlace.css";
|
||||||
|
import { darkenColor, getFirstLetter } from "../utils/Utils";
|
||||||
|
|
||||||
|
const RecipientList = (props) => {
|
||||||
|
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();
|
||||||
|
const [isEdit, setIsEdit] = useState(false);
|
||||||
|
//function for onhover signer name change background color
|
||||||
|
const inputRef = useRef(null);
|
||||||
|
const onHoverStyle = (ind, blockColor) => {
|
||||||
|
const style = {
|
||||||
|
background: blockColor ? blockColor : color[ind % color.length],
|
||||||
|
padding: "10px",
|
||||||
|
marginTop: "2px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
borderBottom: "1px solid #e3e1e1",
|
||||||
|
alignItems: "center"
|
||||||
|
};
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
//function for onhover signer name remove background color
|
||||||
|
const nonHoverStyle = (ind) => {
|
||||||
|
const style = {
|
||||||
|
padding: "10px",
|
||||||
|
marginTop: "2px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
borderBottom: "1px solid #e3e1e1",
|
||||||
|
alignItems: "center"
|
||||||
|
};
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
const isWidgetExist = (Id) => {
|
||||||
|
return props.signerPos.some((x) => x.Id === Id);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{props.signersdata.length > 0 &&
|
||||||
|
props.signersdata.map((obj, ind) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-tut="reactourFirst"
|
||||||
|
onMouseEnter={() => setIsHover(ind)}
|
||||||
|
onMouseLeave={() => setIsHover(null)}
|
||||||
|
key={ind}
|
||||||
|
style={
|
||||||
|
isHover === ind || props.isSelectListId === ind
|
||||||
|
? onHoverStyle(ind, obj.blockColor)
|
||||||
|
: nonHoverStyle(ind)
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
props.setSignerObjId(obj?.objectId || "");
|
||||||
|
props.setIsSelectId(ind);
|
||||||
|
props.setContractName(obj?.className || "");
|
||||||
|
props.setUniqueId(obj.Id);
|
||||||
|
props.setRoleName(obj.Role);
|
||||||
|
if(props.handleModal){
|
||||||
|
props.handleModal()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "100%"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="signerStyle"
|
||||||
|
style={{
|
||||||
|
background: obj.blockColor
|
||||||
|
? darkenColor(obj.blockColor, 0.4)
|
||||||
|
: nameColor[ind % nameColor.length],
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
display: "flex",
|
||||||
|
borderRadius: 30 / 2,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
marginRight: "12px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: "12px",
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "white",
|
||||||
|
textTransform: "uppercase"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isWidgetExist(obj.Id) ? (
|
||||||
|
<i className="fa-solid fa-check"></i>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{obj.Name
|
||||||
|
? getFirstLetter(obj.Name)
|
||||||
|
: getFirstLetter(obj.Role)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: obj.Name ? "column" : "row",
|
||||||
|
alignItems: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{obj.Name ? (
|
||||||
|
<span className="userName" style={{ cursor: "default" }}>
|
||||||
|
{obj.Name}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span
|
||||||
|
className="userName"
|
||||||
|
onClick={() => {
|
||||||
|
setIsEdit({ [obj.Id]: true });
|
||||||
|
props.setRoleName(obj.Role);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isEdit?.[obj.Id] && props.handleRoleChange ? (
|
||||||
|
<input
|
||||||
|
ref={inputRef}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
width: "inherit"
|
||||||
|
}}
|
||||||
|
value={obj.Role}
|
||||||
|
onChange={(e) => props.handleRoleChange(e, obj.Id)}
|
||||||
|
onBlur={() => {
|
||||||
|
setIsEdit({});
|
||||||
|
props.handleOnBlur(obj.Role, obj.Id);
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
inputRef.current.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
obj.Role
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{obj.Name && (
|
||||||
|
<span className="useEmail" style={{ cursor: "default" }}>
|
||||||
|
{obj.Role}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{props.handleDeleteUser && (
|
||||||
|
<div
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
props.handleDeleteUser(obj.Id);
|
||||||
|
}}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
<i className="fa-regular fa-trash-can"></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RecipientList;
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import CreateFolder from "./CreateFolder";
|
||||||
|
import ModalUi from "./ModalUi";
|
||||||
|
import axios from "axios";
|
||||||
|
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||||
|
import "../css/selectFolder.css";
|
||||||
|
|
||||||
|
const SelectFolder = ({
|
||||||
|
required,
|
||||||
|
onSuccess,
|
||||||
|
folderCls,
|
||||||
|
isOpenModal,
|
||||||
|
setIsOpenMoveModal,
|
||||||
|
setPdfData
|
||||||
|
}) => {
|
||||||
|
const [clickFolder, setClickFolder] = useState("");
|
||||||
|
// const [selectFolder, setSelectedFolder] = useState({});
|
||||||
|
const [folderList, setFolderList] = useState([]);
|
||||||
|
const [tabList, setTabList] = useState([]);
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
// const [folderPath, setFolderPath] = useState("");
|
||||||
|
const [isAdd, setIsAdd] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpenModal) {
|
||||||
|
setIsAdd(false);
|
||||||
|
setClickFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
fetchFolder();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
//fetch folder data
|
||||||
|
const fetchFolder = async (folderPtr) => {
|
||||||
|
setIsLoader(true);
|
||||||
|
let url;
|
||||||
|
const classUrl = `${localStorage.getItem("baseUrl")}classes/${folderCls}`;
|
||||||
|
|
||||||
|
if (folderPtr) {
|
||||||
|
url = `${classUrl}?where={"Folder": {"__type":"Pointer","className":"${folderCls}","objectId":"${folderPtr.objectId}"},"Type":"Folder"}`;
|
||||||
|
} else {
|
||||||
|
url = `${classUrl}?where={"Folder":{"$exists":false},"Type":"Folder"}`;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await axios.get(url, {
|
||||||
|
headers: {
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.data.results) {
|
||||||
|
setFolderList(res.data.results);
|
||||||
|
setIsLoader(false);
|
||||||
|
setIsAdd(false);
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err", err);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSelect = (item) => {
|
||||||
|
setFolderList([]);
|
||||||
|
setClickFolder({ ObjectId: item.objectId, Name: item.Name });
|
||||||
|
if (tabList.length > 0) {
|
||||||
|
const tab = tabList.some((x) => x.objectId === item.objectId);
|
||||||
|
if (!tab) {
|
||||||
|
setTabList((tabs) => [...tabs, item]);
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: item.objectId
|
||||||
|
};
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTabList((tabs) => [...tabs, item]);
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: item.objectId
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
let url = "Root";
|
||||||
|
tabList.forEach((t) => {
|
||||||
|
url = url + " / " + t.Name;
|
||||||
|
});
|
||||||
|
// setFolderPath(url);
|
||||||
|
// setSelectedFolder(clickFolder);
|
||||||
|
if (onSuccess) {
|
||||||
|
onSuccess(clickFolder);
|
||||||
|
}
|
||||||
|
setIsOpenMoveModal(false);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
setIsOpenMoveModal(false);
|
||||||
|
setClickFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeTabListItem = async (e, i) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// setEditable(false);
|
||||||
|
if (!isAdd) {
|
||||||
|
setIsLoader(true);
|
||||||
|
let folderPtr;
|
||||||
|
if (i) {
|
||||||
|
setFolderList([]);
|
||||||
|
let list = tabList.filter((itm, j) => {
|
||||||
|
if (j <= i) {
|
||||||
|
return itm;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let _len = list.length - 1;
|
||||||
|
folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: list[_len].objectId
|
||||||
|
};
|
||||||
|
setTabList(list);
|
||||||
|
} else {
|
||||||
|
setClickFolder({});
|
||||||
|
// setSelectedFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
}
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCreate = () => {
|
||||||
|
setIsAdd(!isAdd);
|
||||||
|
};
|
||||||
|
const handleAddFolder = (res) => {
|
||||||
|
setPdfData((prev) => [...prev, res]);
|
||||||
|
setFolderList([]);
|
||||||
|
if (clickFolder && clickFolder.ObjectId) {
|
||||||
|
fetchFolder({
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: clickFolder.ObjectId
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fetchFolder();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ModalUi
|
||||||
|
id="asd"
|
||||||
|
title={"Select Folder"}
|
||||||
|
isOpen={isOpenModal}
|
||||||
|
handleClose={handleCancel}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
<div style={{ width: "100%", padding: "1rem" }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
paddingTop: "2px",
|
||||||
|
color: "#ac4848",
|
||||||
|
fontSize: "14px",
|
||||||
|
fontWeight: "500"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
title="Root"
|
||||||
|
onClick={(e) => {
|
||||||
|
setIsAdd(false);
|
||||||
|
removeTabListItem(e);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Root /{" "}
|
||||||
|
</span>
|
||||||
|
{tabList &&
|
||||||
|
tabList.map((tab, i) => (
|
||||||
|
<React.Fragment key={`${tab.objectId}-${i}`}>
|
||||||
|
<span
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
title={tab.Name}
|
||||||
|
onClick={(e) => {
|
||||||
|
setIsAdd(false);
|
||||||
|
removeTabListItem(e, i);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tab.Name}
|
||||||
|
</span>
|
||||||
|
{" / "}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
<hr className="hrStyle" />
|
||||||
|
</div>
|
||||||
|
<div style={{ margin: "2px 0 3px 0" }}>
|
||||||
|
{!isAdd &&
|
||||||
|
folderList.length > 0 &&
|
||||||
|
folderList.map((folder) => (
|
||||||
|
<div
|
||||||
|
key={folder.Name}
|
||||||
|
style={{
|
||||||
|
border: "1.7px solid #c3bcbc",
|
||||||
|
padding: "6px",
|
||||||
|
marginBottom: "5px",
|
||||||
|
cursor: "pointer"
|
||||||
|
}}
|
||||||
|
onClick={() => handleSelect(folder)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ display: "flex", alignItems: "center", gap: "2" }}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
style={{ color: "#33bbff", fontSize: "1.4rem" }}
|
||||||
|
className="fa fa-folder "
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontWeight: "500",
|
||||||
|
marginLeft: "10px",
|
||||||
|
fontSize: "14px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{folder.Name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{isAdd && (
|
||||||
|
<CreateFolder
|
||||||
|
parentFolderId={clickFolder && clickFolder.ObjectId}
|
||||||
|
folderCls={folderCls}
|
||||||
|
onSuccess={handleAddFolder}
|
||||||
|
setIsAdd={setIsAdd}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isLoader && (
|
||||||
|
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||||
|
<i
|
||||||
|
style={{ fontSize: "30px" }}
|
||||||
|
className="fa-solid fa-spinner fa-spin-pulse "
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr className="hrStyle" />
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: "0px 16px 12px 16px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ fontSize: "30px", cursor: "pointer", color: themeColor() }}
|
||||||
|
title="Save Here"
|
||||||
|
onClick={handleCreate}
|
||||||
|
>
|
||||||
|
{isAdd ? (
|
||||||
|
<i className="fa-solid fa-arrow-left" aria-hidden="true"></i>
|
||||||
|
) : (
|
||||||
|
<i className="fa-solid fa-square-plus" aria-hidden="true"></i>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{ fontSize: "30px", cursor: "pointer" }}
|
||||||
|
title="Save Here"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
<i className="fas fa-save" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SelectFolder;
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import "../css/AddUser.css";
|
||||||
|
import AsyncSelect from "react-select/async";
|
||||||
|
|
||||||
|
const customStyles = {
|
||||||
|
control: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
fontSize: "13px" // Font size for the control
|
||||||
|
}),
|
||||||
|
option: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
fontSize: "13px" // Font size for the options
|
||||||
|
})
|
||||||
|
};
|
||||||
|
const SelectSigners = (props) => {
|
||||||
|
const [userList, setUserList] = useState([]);
|
||||||
|
const [selected, setSelected] = useState();
|
||||||
|
const [userData, setUserData] = useState({});
|
||||||
|
const [isError, setIsError]= useState(false)
|
||||||
|
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||||
|
const parseAppId = localStorage.getItem("parseAppId");
|
||||||
|
Parse.serverURL = parseBaseUrl;
|
||||||
|
Parse.initialize(parseAppId);
|
||||||
|
|
||||||
|
// `handleOptions` is used to set just save from quick form to selected option in dropdown
|
||||||
|
const handleOptions = (item) => {
|
||||||
|
setSelected(item);
|
||||||
|
const userData = userList.find((x) => x.objectId === item.value);
|
||||||
|
if (userData) {
|
||||||
|
setUserData(userData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleAdd = () => {
|
||||||
|
if(userData && userData.objectId){
|
||||||
|
props.details(userData);
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
setIsError(true)
|
||||||
|
setTimeout(()=> setIsError(false), 1000)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadOptions = async (inputValue) => {
|
||||||
|
try {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const contactbook = new Parse.Query("contracts_Contactbook");
|
||||||
|
contactbook.equalTo(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
if (inputValue.length > 1) {
|
||||||
|
contactbook.matches("Name", new RegExp(inputValue, "i"));
|
||||||
|
}
|
||||||
|
contactbook.notEqualTo("IsDeleted", true);
|
||||||
|
const contactRes = await contactbook.find();
|
||||||
|
if (contactRes) {
|
||||||
|
const res = JSON.parse(JSON.stringify(contactRes));
|
||||||
|
// console.log("userList ", res);
|
||||||
|
setUserList(res);
|
||||||
|
return await res.map((item) => ({
|
||||||
|
label: item.Email,
|
||||||
|
value: item.objectId
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("err", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="addusercontainer">
|
||||||
|
<div className="form-wrapper">
|
||||||
|
<div className="form-section" style={{marginBottom: 0}}>
|
||||||
|
<label style={{ fontSize: 14 , fontWeight: "700"}}>Choose User</label>
|
||||||
|
<AsyncSelect
|
||||||
|
cacheOptions
|
||||||
|
defaultOptions
|
||||||
|
value={selected}
|
||||||
|
loadingMessage={() => "Loading..."}
|
||||||
|
noOptionsMessage={() => "User not Found"}
|
||||||
|
loadOptions={loadOptions}
|
||||||
|
onChange={handleOptions}
|
||||||
|
styles={customStyles}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{isError ? <p style={{color:'red', fontSize: "12px", margin:"5px"}}>Please select signer</p>: <p style={{color:'transparent', fontSize: "12px", margin:"5px"}}>.</p>}
|
||||||
|
<div>
|
||||||
|
<button className="submitbutton" onClick={() => handleAdd()}>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SelectSigners;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
export default function TourContentWithBtn({ message, isChecked }) {
|
||||||
|
const [isCheck, setIsCheck] = useState(false);
|
||||||
|
|
||||||
|
const handleCheck = () => {
|
||||||
|
setIsCheck(!isCheck);
|
||||||
|
if (isChecked) {
|
||||||
|
isChecked(!isCheck);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>{message}</p>
|
||||||
|
<label style={{ textAlign: "center", display: "flex", "justifyContent":'center' }}>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
style={{ marginRight: 3 }}
|
||||||
|
checked={isCheck}
|
||||||
|
onChange={handleCheck}
|
||||||
|
/>{" "}
|
||||||
|
<span style={{color:"#787878", fontSize: 12}}>Don't show this again</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { $ } from "select-dom";
|
|
||||||
import { rgb } from "pdf-lib";
|
import { rgb } from "pdf-lib";
|
||||||
|
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
|
|
||||||
|
export const resizeBorderExtraWidth = () => {
|
||||||
|
return 20;
|
||||||
|
};
|
||||||
export async function getBase64FromUrl(url) {
|
export async function getBase64FromUrl(url) {
|
||||||
const data = await fetch(url);
|
const data = await fetch(url);
|
||||||
const blob = await data.blob();
|
const blob = await data.blob();
|
||||||
@@ -77,91 +79,43 @@ export function getHostUrl() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const calculateImgAspectRatio = (imgWH) => {
|
export const calculateImgAspectRatio = (imgWH, pos) => {
|
||||||
let newWidth, newHeight;
|
let newWidth, newHeight;
|
||||||
|
const placeholderHeight = pos && pos.Width ? pos.Height : 60;
|
||||||
const aspectRatio = imgWH.width / imgWH.height;
|
const aspectRatio = imgWH.width / imgWH.height;
|
||||||
if (aspectRatio === "2.533333333333333") {
|
newWidth = aspectRatio * placeholderHeight;
|
||||||
newWidth = 150;
|
newHeight = placeholderHeight;
|
||||||
newHeight = 60;
|
|
||||||
} else if (aspectRatio === 1) {
|
|
||||||
newWidth = aspectRatio * 100;
|
|
||||||
newHeight = aspectRatio * 100;
|
|
||||||
} else if (aspectRatio < 1) {
|
|
||||||
newWidth = aspectRatio * 70;
|
|
||||||
newHeight = 70;
|
|
||||||
} else if (aspectRatio < 2) {
|
|
||||||
newWidth = aspectRatio * 100;
|
|
||||||
newHeight = 100;
|
|
||||||
} else if (aspectRatio > 2 && aspectRatio < 4) {
|
|
||||||
newWidth = aspectRatio * 70;
|
|
||||||
newHeight = 70;
|
|
||||||
} else if (aspectRatio > 4) {
|
|
||||||
newWidth = aspectRatio * 40;
|
|
||||||
newHeight = 40;
|
|
||||||
} else if (aspectRatio > 5) {
|
|
||||||
newWidth = aspectRatio * 10;
|
|
||||||
newHeight = 10;
|
|
||||||
}
|
|
||||||
return { newHeight, newWidth };
|
return { newHeight, newWidth };
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for upload stamp or image
|
//function for upload stamp or image
|
||||||
export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
||||||
const updateFilter = xyPostion[index].pos.filter(
|
let getIMGWH;
|
||||||
(data, ind) =>
|
//get current page position
|
||||||
data.key === signKey && data.Width && data.Height && data.SignUrl
|
const getXYData = xyPostion[index].pos;
|
||||||
);
|
const updateXYData = getXYData.map((position) => {
|
||||||
let getIMGWH = calculateImgAspectRatio(imgWH);
|
if (position.key === signKey) {
|
||||||
const getXYdata = xyPostion[index].pos;
|
getIMGWH = calculateImgAspectRatio(imgWH, position);
|
||||||
if (updateFilter.length > 0) {
|
|
||||||
const addSign = getXYdata.map((url, ind) => {
|
|
||||||
if (url.key === signKey) {
|
|
||||||
return {
|
return {
|
||||||
...url,
|
...position,
|
||||||
Width: getIMGWH.newWidth,
|
Width: getIMGWH.newWidth,
|
||||||
Height: getIMGWH.newHeight,
|
Height: getIMGWH.newHeight,
|
||||||
SignUrl: image.src,
|
SignUrl: image.src,
|
||||||
ImageType: image.imgType
|
ImageType: image.imgType
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return url;
|
return position;
|
||||||
});
|
});
|
||||||
|
|
||||||
const newUpdateUrl = xyPostion.map((obj, ind) => {
|
const updateXYposition = xyPostion.map((obj, ind) => {
|
||||||
if (ind === index) {
|
if (ind === index) {
|
||||||
return { ...obj, pos: addSign };
|
return { ...obj, pos: updateXYData };
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
return newUpdateUrl;
|
return updateXYposition;
|
||||||
} else {
|
|
||||||
const getXYdata = xyPostion[index].pos;
|
|
||||||
|
|
||||||
let getPosData = xyPostion[index].pos.filter(
|
|
||||||
(data) => data.key === signKey
|
|
||||||
);
|
|
||||||
|
|
||||||
const addSign = getXYdata.map((url, ind) => {
|
|
||||||
if (url.key === signKey) {
|
|
||||||
return {
|
|
||||||
...url,
|
|
||||||
Width: getIMGWH.newWidth,
|
|
||||||
Height: getIMGWH.newHeight,
|
|
||||||
SignUrl: image.src,
|
|
||||||
ImageType: image.imgType
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateUrl = xyPostion.map((obj, ind) => {
|
|
||||||
if (ind === index) {
|
|
||||||
return { ...obj, pos: addSign };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
return newUpdateUrl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//function for save button to save signature or image url
|
//function for save button to save signature or image url
|
||||||
@@ -172,51 +126,43 @@ export function onSaveSign(
|
|||||||
signatureImg,
|
signatureImg,
|
||||||
imgWH,
|
imgWH,
|
||||||
isDefaultSign,
|
isDefaultSign,
|
||||||
isSign
|
isTypeText
|
||||||
) {
|
) {
|
||||||
let getXYdata = xyPostion[index].pos;
|
|
||||||
let getPosData = xyPostion[index].pos.filter((data) => data.key === signKey);
|
|
||||||
|
|
||||||
let getIMGWH;
|
let getIMGWH;
|
||||||
|
let getXYdata = xyPostion[index].pos;
|
||||||
|
const updateXYData = getXYdata.map((position) => {
|
||||||
|
if (position.key === signKey) {
|
||||||
if (isDefaultSign) {
|
if (isDefaultSign) {
|
||||||
getIMGWH = calculateImgAspectRatio(imgWH);
|
getIMGWH = calculateImgAspectRatio(imgWH, position);
|
||||||
|
} else if (isTypeText) {
|
||||||
|
getIMGWH = { newWidth: imgWH.width, newHeight: imgWH.height };
|
||||||
|
} else {
|
||||||
|
getIMGWH = calculateImgAspectRatio(
|
||||||
|
{ width: 150, height: 60 },
|
||||||
|
position
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const posWidth = isDefaultSign
|
const posWidth = getIMGWH ? getIMGWH.newWidth : 150;
|
||||||
? getIMGWH.newWidth
|
const posHeight = getIMGWH ? getIMGWH.newHeight : 60;
|
||||||
: isSign && getPosData[0].ImageType
|
|
||||||
? 150
|
|
||||||
: getPosData[0].Width
|
|
||||||
? getPosData[0].Width
|
|
||||||
: 150;
|
|
||||||
const posHidth = isDefaultSign
|
|
||||||
? getIMGWH.newHeight
|
|
||||||
: isSign && getPosData[0].ImageType
|
|
||||||
? 60
|
|
||||||
: getPosData[0].Height
|
|
||||||
? getPosData[0].Height
|
|
||||||
: 60;
|
|
||||||
|
|
||||||
const addSign = getXYdata.map((url, ind) => {
|
|
||||||
if (url.key === signKey) {
|
|
||||||
return {
|
return {
|
||||||
...url,
|
...position,
|
||||||
Width: posWidth,
|
Width: posWidth,
|
||||||
Height: posHidth,
|
Height: posHeight,
|
||||||
SignUrl: signatureImg,
|
SignUrl: signatureImg
|
||||||
ImageType: "sign"
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return url;
|
return position;
|
||||||
});
|
});
|
||||||
|
|
||||||
const newUpdateUrl = xyPostion.map((obj, ind) => {
|
const updateXYposition = xyPostion.map((obj, ind) => {
|
||||||
if (ind === index) {
|
if (ind === index) {
|
||||||
return { ...obj, pos: addSign };
|
return { ...obj, pos: updateXYData };
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
return newUpdateUrl;
|
return updateXYposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addZIndex = (signerPos, key, setZIndex) => {
|
export const addZIndex = (signerPos, key, setZIndex) => {
|
||||||
@@ -260,24 +206,26 @@ export const addDefaultSignatureImg = (xyPostion, defaultSignImg) => {
|
|||||||
height: img.height
|
height: img.height
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const getIMGWH = calculateImgAspectRatio(imgWH);
|
|
||||||
let xyDefaultPos = [];
|
let xyDefaultPos = [];
|
||||||
for (let i = 0; i < xyPostion.length; i++) {
|
for (let i = 0; i < xyPostion.length; i++) {
|
||||||
|
let getIMGWH;
|
||||||
const getXYdata = xyPostion[i].pos;
|
const getXYdata = xyPostion[i].pos;
|
||||||
const getPageNo = xyPostion[i].pageNumber;
|
const getPageNo = xyPostion[i].pageNumber;
|
||||||
const getPosData = getXYdata;
|
const getPosData = getXYdata;
|
||||||
|
|
||||||
const addSign = getPosData.map((url, ind) => {
|
const addSign = getPosData.map((position, ind) => {
|
||||||
if (url) {
|
getIMGWH = calculateImgAspectRatio(imgWH, position);
|
||||||
|
if (position && !position.isStamp) {
|
||||||
return {
|
return {
|
||||||
...url,
|
...position,
|
||||||
SignUrl: defaultSignImg,
|
SignUrl: defaultSignImg,
|
||||||
Width: getIMGWH.newWidth,
|
Width: getIMGWH.newWidth,
|
||||||
Height: getIMGWH.newHeight,
|
Height: getIMGWH.newHeight,
|
||||||
ImageType: "default"
|
ImageType: "default"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return url;
|
return position;
|
||||||
});
|
});
|
||||||
|
|
||||||
const newXypos = {
|
const newXypos = {
|
||||||
@@ -449,88 +397,87 @@ export function urlValidator(url) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export function modalAlign() {
|
|
||||||
let modalDialog = $(".modal-dialog").getBoundingClientRect();
|
export const placeholderWidth = (pos, scale, signyourself) => {
|
||||||
let mobileHead = $(".mobileHead").getBoundingClientRect();
|
|
||||||
let modal = $(".modal-dialog");
|
|
||||||
if (modalDialog.left < mobileHead.left) {
|
|
||||||
let leftOffset = mobileHead.left - modalDialog.left;
|
|
||||||
modal.style.left = leftOffset + "px";
|
|
||||||
modal.style.top = window.innerHeight / 3 + "px";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const containerWidth = (pos, scale, signyourself) => {
|
|
||||||
let width;
|
let width;
|
||||||
|
const defaultWidth = 150;
|
||||||
|
const posWidth = pos.Width ? pos.Width : defaultWidth;
|
||||||
|
|
||||||
if (signyourself) {
|
if (signyourself) {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
return pos.Width * scale;
|
return posWidth * scale;
|
||||||
} else {
|
} else {
|
||||||
return pos.Width;
|
return posWidth;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
width = pos.Width ? pos.Width * scale : 150 * scale;
|
width = posWidth ? posWidth * scale : defaultWidth * scale;
|
||||||
return width;
|
return width;
|
||||||
} else {
|
} else {
|
||||||
if (pos.IsResize) {
|
if (pos.IsResize) {
|
||||||
width = pos.Width ? pos.Width * scale : 150 * scale;
|
width = posWidth ? posWidth * scale : defaultWidth * scale;
|
||||||
return width;
|
return width;
|
||||||
} else {
|
} else {
|
||||||
width = pos.Width ? pos.Width : 150;
|
width = posWidth ? posWidth : defaultWidth;
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
if (pos.IsResize) {
|
if (pos.IsResize) {
|
||||||
width = pos.Width ? pos.Width : 150;
|
width = posWidth ? posWidth : defaultWidth;
|
||||||
return width;
|
return width;
|
||||||
} else {
|
} else {
|
||||||
width = pos.Width ? pos.Width * pos.scale : 150 * pos.scale;
|
width = posWidth ? posWidth * pos.scale : defaultWidth * pos.scale;
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
width = pos.Width ? pos.Width : 150;
|
width = posWidth ? posWidth : defaultWidth;
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const containerHeight = (pos, scale, signyourself) => {
|
export const placeholderHeight = (pos, scale, signyourself) => {
|
||||||
let height;
|
let height;
|
||||||
|
const posHeight = pos.Height;
|
||||||
|
const defaultHeight = 60;
|
||||||
if (signyourself) {
|
if (signyourself) {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
return pos.Height * scale;
|
return posHeight * scale;
|
||||||
} else {
|
} else {
|
||||||
return pos.Height;
|
return posHeight;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
height = pos.Height ? pos.Height * scale : 60 * scale;
|
height = posHeight ? posHeight * scale : defaultHeight * scale;
|
||||||
return height;
|
return height;
|
||||||
} else {
|
} else {
|
||||||
if (pos.IsResize) {
|
if (pos.IsResize) {
|
||||||
height = pos.Height ? pos.Height * scale : 60 * scale;
|
height = posHeight ? posHeight * scale : defaultHeight * scale;
|
||||||
return height;
|
return height;
|
||||||
} else {
|
} else {
|
||||||
height = pos.Height ? pos.Height : 60;
|
height = posHeight ? posHeight : defaultHeight;
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
if (pos.IsResize) {
|
if (pos.IsResize) {
|
||||||
height = pos.Height ? pos.Height : 60;
|
height = posHeight ? posHeight : defaultHeight;
|
||||||
return height;
|
return height;
|
||||||
} else {
|
} else {
|
||||||
height = pos.Height ? pos.Height * pos.scale : 60 * pos.scale;
|
height = posHeight
|
||||||
|
? posHeight * pos.scale
|
||||||
|
: defaultHeight * pos.scale;
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
height = pos.Height ? pos.Height : 60;
|
height = posHeight ? posHeight : defaultHeight;
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -578,78 +525,80 @@ export const multiSignEmbed = async (
|
|||||||
} else {
|
} else {
|
||||||
img = await pdfDoc.embedPng(imgData);
|
img = await pdfDoc.embedPng(imgData);
|
||||||
}
|
}
|
||||||
const imgHeight = imgUrlList[id].Height ? imgUrlList[id].Height : 60;
|
|
||||||
const scaleWidth = containerWidth(imgUrlList[id], scale, signyourself);
|
const scaleWidth = placeholderWidth(imgUrlList[id], scale, signyourself);
|
||||||
const scaleHeight = containerHeight(imgUrlList[id], scale, signyourself);
|
const scaleHeight = placeholderHeight(
|
||||||
|
imgUrlList[id],
|
||||||
|
scale,
|
||||||
|
signyourself
|
||||||
|
);
|
||||||
|
|
||||||
const xPos = (pos) => {
|
const xPos = (pos) => {
|
||||||
|
const resizePos = pos.xPosition;
|
||||||
if (signyourself) {
|
if (signyourself) {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
return imgUrlList[id].xPosition * scale;
|
return resizePos * scale;
|
||||||
} else {
|
} else {
|
||||||
return imgUrlList[id].xPosition;
|
return resizePos;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//checking both condition mobile and desktop view
|
//checking both condition mobile and desktop view
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
const x = pos.xPosition * (pos.scale / scale);
|
const x = resizePos * (pos.scale / scale);
|
||||||
return x * scale;
|
return x * scale;
|
||||||
} else {
|
} else {
|
||||||
const x = pos.xPosition / scale;
|
const x = resizePos / scale;
|
||||||
return x * scale;
|
return x * scale;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
const x = pos.xPosition * pos.scale;
|
const x = resizePos * pos.scale;
|
||||||
return x;
|
return x;
|
||||||
} else {
|
} else {
|
||||||
return pos.xPosition;
|
return resizePos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const yPos = (pos) => {
|
const yPos = (pos) => {
|
||||||
|
const resizePos = imgUrlList[id].yPosition;
|
||||||
if (signyourself) {
|
if (signyourself) {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
return (
|
return page.getHeight() - resizePos * scale - scaleHeight;
|
||||||
page.getHeight() -
|
|
||||||
imgUrlList[id].yPosition * scale -
|
|
||||||
imgHeight * scale
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return page.getHeight() - imgUrlList[id].yPosition - imgHeight;
|
return page.getHeight() - resizePos - scaleHeight;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//checking both condition mobile and desktop view
|
//checking both condition mobile and desktop view
|
||||||
const y = pos.yPosition / scale;
|
const y = resizePos / scale;
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
const y = pos.yPosition * (pos.scale / scale);
|
const y = resizePos * (pos.scale / scale);
|
||||||
return page.getHeight() - y * scale - imgHeight * scale;
|
return page.getHeight() - y * scale - scaleHeight;
|
||||||
} else {
|
} else {
|
||||||
if (pos.IsResize) {
|
if (pos.IsResize) {
|
||||||
return page.getHeight() - y * scale - imgHeight * scale;
|
return page.getHeight() - y * scale - scaleHeight;
|
||||||
} else {
|
} else {
|
||||||
return page.getHeight() - y * scale - imgHeight;
|
return page.getHeight() - y * scale - scaleHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||||
if (pos.isMobile) {
|
if (pos.isMobile) {
|
||||||
if (pos.IsResize) {
|
if (pos.IsResize) {
|
||||||
const y = pos.yPosition * pos.scale;
|
const y = resizePos * pos.scale;
|
||||||
return page.getHeight() - y - imgHeight;
|
return page.getHeight() - y - scaleHeight;
|
||||||
} else {
|
} else {
|
||||||
const y = pos.yPosition * pos.scale;
|
const y = resizePos * pos.scale;
|
||||||
return page.getHeight() - y - imgHeight * pos.scale;
|
return page.getHeight() - y - scaleHeight;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return page.getHeight() - pos.yPosition - imgHeight;
|
return page.getHeight() - resizePos - scaleHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -706,9 +655,11 @@ export const handleImageResize = (
|
|||||||
containerWH,
|
containerWH,
|
||||||
showResize
|
showResize
|
||||||
) => {
|
) => {
|
||||||
const filterSignerPos = signerPos.filter(
|
// const filterSignerPos = signerPos.filter(
|
||||||
(data) => data.signerObjId === signerId
|
// (data) => data.signerObjId === signerId
|
||||||
);
|
// );
|
||||||
|
|
||||||
|
const filterSignerPos = signerPos.filter((data) => data.Id === signerId);
|
||||||
|
|
||||||
if (filterSignerPos.length > 0) {
|
if (filterSignerPos.length > 0) {
|
||||||
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
||||||
@@ -716,10 +667,46 @@ export const handleImageResize = (
|
|||||||
(data) => data.pageNumber === pageNumber
|
(data) => data.pageNumber === pageNumber
|
||||||
);
|
);
|
||||||
if (getPageNumer.length > 0) {
|
if (getPageNumer.length > 0) {
|
||||||
const getXYdata = getPageNumer[0].pos.filter(
|
// const getXYdata = getPageNumer[0].pos.filter(
|
||||||
(data, ind) => data.key === key && data.Width && data.Height
|
// (data, ind) => data.key === key && data.Width && data.Height
|
||||||
);
|
// );
|
||||||
if (getXYdata.length > 0) {
|
// if (getXYdata.length > 0) {
|
||||||
|
// const getXYdata = getPageNumer[0].pos;
|
||||||
|
// const getPosData = getXYdata;
|
||||||
|
// const addSignPos = getPosData.map((url, ind) => {
|
||||||
|
// if (url.key === key) {
|
||||||
|
// return {
|
||||||
|
// ...url,
|
||||||
|
// Width: ref.offsetWidth,
|
||||||
|
// Height: ref.offsetHeight,
|
||||||
|
// IsResize: showResize ? true : false
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// return url;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
|
||||||
|
// if (obj.pageNumber === pageNumber) {
|
||||||
|
// return { ...obj, pos: addSignPos };
|
||||||
|
// }
|
||||||
|
// return obj;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // const newUpdateSigner = signerPos.map((obj, ind) => {
|
||||||
|
// // if (obj.signerObjId === signerId) {
|
||||||
|
// // return { ...obj, placeHolder: newUpdateSignPos };
|
||||||
|
// // }
|
||||||
|
// // return obj;
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// const newUpdateSigner = signerPos.map((obj, ind) => {
|
||||||
|
// if (obj.Id === signerId) {
|
||||||
|
// return { ...obj, placeHolder: newUpdateSignPos };
|
||||||
|
// }
|
||||||
|
// return obj;
|
||||||
|
// });
|
||||||
|
// setSignerPos(newUpdateSigner);
|
||||||
|
// } else {
|
||||||
const getXYdata = getPageNumer[0].pos;
|
const getXYdata = getPageNumer[0].pos;
|
||||||
const getPosData = getXYdata;
|
const getPosData = getXYdata;
|
||||||
const addSignPos = getPosData.map((url, ind) => {
|
const addSignPos = getPosData.map((url, ind) => {
|
||||||
@@ -741,38 +728,14 @@ export const handleImageResize = (
|
|||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// const newUpdateSigner = signerPos.map((obj, ind) => {
|
||||||
|
// if (obj.signerObjId === signerId) {
|
||||||
|
// return { ...obj, placeHolder: newUpdateSignPos };
|
||||||
|
// }
|
||||||
|
// return obj;
|
||||||
|
// });
|
||||||
const newUpdateSigner = signerPos.map((obj, ind) => {
|
const newUpdateSigner = signerPos.map((obj, ind) => {
|
||||||
if (obj.signerObjId === signerId) {
|
if (obj.Id === signerId) {
|
||||||
return { ...obj, placeHolder: newUpdateSignPos };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
|
|
||||||
setSignerPos(newUpdateSigner);
|
|
||||||
} else {
|
|
||||||
const getXYdata = getPageNumer[0].pos;
|
|
||||||
const getPosData = getXYdata;
|
|
||||||
const addSignPos = getPosData.map((url, ind) => {
|
|
||||||
if (url.key === key) {
|
|
||||||
return {
|
|
||||||
...url,
|
|
||||||
Width: ref.offsetWidth,
|
|
||||||
Height: ref.offsetHeight,
|
|
||||||
IsResize: showResize ? true : false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
|
|
||||||
if (obj.pageNumber === pageNumber) {
|
|
||||||
return { ...obj, pos: addSignPos };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateSigner = signerPos.map((obj, ind) => {
|
|
||||||
if (obj.signerObjId === signerId) {
|
|
||||||
return { ...obj, placeHolder: newUpdateSignPos };
|
return { ...obj, placeHolder: newUpdateSignPos };
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@@ -780,7 +743,7 @@ export const handleImageResize = (
|
|||||||
|
|
||||||
setSignerPos(newUpdateSigner);
|
setSignerPos(newUpdateSigner);
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -788,42 +751,38 @@ export const handleImageResize = (
|
|||||||
export const handleSignYourselfImageResize = (
|
export const handleSignYourselfImageResize = (
|
||||||
ref,
|
ref,
|
||||||
key,
|
key,
|
||||||
direction,
|
|
||||||
position,
|
|
||||||
xyPostion,
|
xyPostion,
|
||||||
index,
|
index,
|
||||||
setXyPostion,
|
setXyPostion
|
||||||
pdfOriginalWidth,
|
|
||||||
containerWH
|
|
||||||
) => {
|
) => {
|
||||||
const updateFilter = xyPostion[index].pos.filter(
|
// const updateFilter = xyPostion[index].pos.filter(
|
||||||
(data) => data.key === key && data.Width && data.Height
|
// (data) => data.key === key && data.Width && data.Height
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (updateFilter.length > 0) {
|
// if (updateFilter.length > 0) {
|
||||||
const getXYdata = xyPostion[index].pos;
|
// const getXYdata = xyPostion[index].pos;
|
||||||
const getPosData = getXYdata;
|
// const getPosData = getXYdata;
|
||||||
const addSign = getPosData.map((url, ind) => {
|
// const addSign = getPosData.map((url, ind) => {
|
||||||
if (url.key === key) {
|
// if (url.key === key) {
|
||||||
return {
|
// return {
|
||||||
...url,
|
// ...url,
|
||||||
Width: ref.offsetWidth,
|
// Width: ref.offsetWidth,
|
||||||
Height: ref.offsetHeight,
|
// Height: ref.offsetHeight,
|
||||||
IsResize: true
|
// IsResize: true
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
return url;
|
// return url;
|
||||||
});
|
// });
|
||||||
|
|
||||||
const newUpdateUrl = xyPostion.map((obj, ind) => {
|
// const newUpdateUrl = xyPostion.map((obj, ind) => {
|
||||||
if (ind === index) {
|
// if (ind === index) {
|
||||||
return { ...obj, pos: addSign };
|
// return { ...obj, pos: addSign };
|
||||||
}
|
// }
|
||||||
return obj;
|
// return obj;
|
||||||
});
|
// });
|
||||||
|
|
||||||
setXyPostion(newUpdateUrl);
|
// setXyPostion(newUpdateUrl);
|
||||||
} else {
|
// } else {
|
||||||
const getXYdata = xyPostion[index].pos;
|
const getXYdata = xyPostion[index].pos;
|
||||||
|
|
||||||
const getPosData = getXYdata;
|
const getPosData = getXYdata;
|
||||||
@@ -847,7 +806,7 @@ export const handleSignYourselfImageResize = (
|
|||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
setXyPostion(newUpdateUrl);
|
setXyPostion(newUpdateUrl);
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for call cloud function signPdf and generate digital signature
|
//function for call cloud function signPdf and generate digital signature
|
||||||
@@ -865,119 +824,120 @@ export const signPdfFun = async (
|
|||||||
) => {
|
) => {
|
||||||
let singleSign;
|
let singleSign;
|
||||||
|
|
||||||
const newWidth = containerWH.width;
|
// const newWidth = containerWH.width;
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
// const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||||
if (signerData && signerData.length === 1 && signerData[0].pos.length === 1) {
|
// if (signerData && signerData.length === 1 && signerData[0].pos.length === 1) {
|
||||||
const height = xyPosData.Height ? xyPosData.Height : 60;
|
// const height = xyPosData.Height ? xyPosData.Height : 60;
|
||||||
|
|
||||||
const xPos = (pos) => {
|
// const xPos = (pos) => {
|
||||||
//checking both condition mobile and desktop view
|
// const resizePos = pos.xPosition;
|
||||||
if (isMobile) {
|
// //checking both condition mobile and desktop view
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
// if (isMobile) {
|
||||||
if (pos.isMobile) {
|
// //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||||
const x = pos.xPosition * (pos.scale / scale);
|
// if (pos.isMobile) {
|
||||||
return x * scale;
|
// const x = resizePos * (pos.scale / scale);
|
||||||
} else {
|
// return x * scale;
|
||||||
const x = pos.xPosition / scale;
|
// } else {
|
||||||
return x * scale;
|
// const x = resizePos / scale;
|
||||||
}
|
// return x * scale;
|
||||||
} else {
|
// }
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
// } else {
|
||||||
if (pos.isMobile) {
|
// //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||||
const x = pos.xPosition * pos.scale;
|
// if (pos.isMobile) {
|
||||||
return x;
|
// const x = resizePos * pos.scale;
|
||||||
} else {
|
// return x;
|
||||||
return pos.xPosition;
|
// } else {
|
||||||
}
|
// return resizePos;
|
||||||
}
|
// }
|
||||||
};
|
// }
|
||||||
const yBottom = (pos) => {
|
// };
|
||||||
let yPosition;
|
// const yBottom = (pos) => {
|
||||||
//checking both condition mobile and desktop view
|
// const resizePos = pos.yBottom;
|
||||||
|
// let yPosition;
|
||||||
|
// //checking both condition mobile and desktop view
|
||||||
|
|
||||||
if (isMobile) {
|
// if (isMobile) {
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
// //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||||
if (pos.isMobile) {
|
// if (pos.isMobile) {
|
||||||
const y = pos.yBottom * (pos.scale / scale);
|
// const y = resizePos * (pos.scale / scale);
|
||||||
yPosition = pos.isDrag
|
// yPosition = pos.isDrag
|
||||||
? y * scale - height * scale
|
// ? y * scale - height * scale
|
||||||
: pos.firstYPos
|
// : pos.firstYPos
|
||||||
? y * scale - height * scale + pos.firstYPos
|
// ? y * scale - height * scale + pos.firstYPos
|
||||||
: y * scale - height * scale;
|
// : y * scale - height * scale;
|
||||||
return yPosition;
|
// return yPosition;
|
||||||
} else {
|
// } else {
|
||||||
const y = pos.yBottom / scale;
|
// const y = resizePos / scale;
|
||||||
if (pos.IsResize) {
|
// if (pos.IsResize) {
|
||||||
yPosition = pos.isDrag
|
// yPosition = pos.isDrag
|
||||||
? y * scale - height * scale
|
// ? y * scale - height * scale
|
||||||
: pos.firstYPos
|
// : pos.firstYPos
|
||||||
? y * scale - height * scale + pos.firstYPos
|
// ? y * scale - height * scale + pos.firstYPos
|
||||||
: y * scale - height * scale;
|
// : y * scale - height * scale;
|
||||||
return yPosition;
|
// return yPosition;
|
||||||
} else {
|
// } else {
|
||||||
yPosition = pos.isDrag
|
// yPosition = pos.isDrag
|
||||||
? y * scale - height
|
// ? y * scale - height
|
||||||
: pos.firstYPos
|
// : pos.firstYPos
|
||||||
? y * scale - height + pos.firstYPos
|
// ? y * scale - height + pos.firstYPos
|
||||||
: y * scale - height;
|
// : y * scale - height;
|
||||||
return yPosition;
|
// return yPosition;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
// //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||||
if (pos.isMobile) {
|
// if (pos.isMobile) {
|
||||||
const y = pos.yBottom * pos.scale;
|
// const y = resizePos * pos.scale;
|
||||||
if (pos.IsResize) {
|
// if (pos.IsResize) {
|
||||||
yPosition = pos.isDrag
|
// yPosition = pos.isDrag
|
||||||
? y - height
|
// ? y - height
|
||||||
: pos.firstYPos
|
// : pos.firstYPos
|
||||||
? y - height + pos.firstYPos
|
// ? y - height + pos.firstYPos
|
||||||
: y - height;
|
// : y - height;
|
||||||
return yPosition;
|
// return yPosition;
|
||||||
} else {
|
// } else {
|
||||||
yPosition = pos.isDrag
|
// yPosition = pos.isDrag
|
||||||
? y - height * pos.scale
|
// ? y - height * pos.scale
|
||||||
: pos.firstYPos
|
// : pos.firstYPos
|
||||||
? y - height * pos.scale + pos.firstYPos
|
// ? y - height * pos.scale + pos.firstYPos
|
||||||
: y - height * pos.scale;
|
// : y - height * pos.scale;
|
||||||
return yPosition;
|
// return yPosition;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
yPosition = pos.isDrag
|
// yPosition = pos.isDrag
|
||||||
? pos.yBottom - height
|
// ? resizePos - height
|
||||||
: pos.firstYPos
|
// : pos.firstYPos
|
||||||
? pos.yBottom - height + pos.firstYPos
|
// ? resizePos - height + pos.firstYPos
|
||||||
: pos.yBottom - height;
|
// : resizePos - height;
|
||||||
return yPosition;
|
// return yPosition;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
const bottomY = yBottom(xyPosData);
|
// singleSign = {
|
||||||
singleSign = {
|
// pdfFile: pdfBase64Url,
|
||||||
pdfFile: pdfBase64Url,
|
// docId: documentId,
|
||||||
docId: documentId,
|
// userId: signerObjectId,
|
||||||
userId: signerObjectId,
|
// sign: {
|
||||||
sign: {
|
// Base64: base64Url,
|
||||||
Base64: base64Url,
|
// Left: xPos(xyPosData),
|
||||||
Left: xPos(xyPosData),
|
// Bottom: yBottom(xyPosData),
|
||||||
Bottom: bottomY,
|
// Width: placeholderWidth(xyPosData, scale),
|
||||||
Width: containerWidth(xyPosData, scale),
|
// Height: placeholderHeight(xyPosData, scale),
|
||||||
Height: containerHeight(xyPosData, scale),
|
// Page: pageNo
|
||||||
Page: pageNo
|
// }
|
||||||
}
|
// };
|
||||||
};
|
// } else if (
|
||||||
} else if (
|
// signerData &&
|
||||||
signerData &&
|
// signerData.length > 0 &&
|
||||||
signerData.length > 0 &&
|
// signerData[0].pos.length > 0
|
||||||
signerData[0].pos.length > 0
|
// ) {
|
||||||
) {
|
|
||||||
singleSign = {
|
singleSign = {
|
||||||
pdfFile: base64Url,
|
pdfFile: base64Url,
|
||||||
docId: documentId,
|
docId: documentId,
|
||||||
userId: signerObjectId
|
userId: signerObjectId
|
||||||
|
// };
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const response = await axios
|
const response = await axios
|
||||||
.post(`${localStorage.getItem("baseUrl")}functions/signPdf`, singleSign, {
|
.post(`${localStorage.getItem("baseUrl")}functions/signPdf`, singleSign, {
|
||||||
@@ -1001,3 +961,93 @@ export const signPdfFun = async (
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const randomId = () => Math.floor(1000 + Math.random() * 9000);
|
||||||
|
|
||||||
|
export const createDocument = async (template, placeholders, signerData) => {
|
||||||
|
if (template && template.length > 0) {
|
||||||
|
const Doc = template[0];
|
||||||
|
|
||||||
|
let placeholdersArr = [];
|
||||||
|
if (placeholders?.length > 0) {
|
||||||
|
placeholdersArr = placeholders;
|
||||||
|
}
|
||||||
|
let signers = [];
|
||||||
|
if (signerData?.length > 0) {
|
||||||
|
signerData.forEach((x) => {
|
||||||
|
if (x.objectId) {
|
||||||
|
const obj = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Contactbook",
|
||||||
|
objectId: x.objectId
|
||||||
|
};
|
||||||
|
signers.push(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const data = {
|
||||||
|
Name: Doc.Name,
|
||||||
|
URL: Doc.URL,
|
||||||
|
SignedUrl: Doc.SignedUrl,
|
||||||
|
Description: Doc.Description,
|
||||||
|
Note: Doc.Note,
|
||||||
|
Placeholders: placeholdersArr,
|
||||||
|
ExtUserPtr: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Users",
|
||||||
|
objectId: Doc.ExtUserPtr.objectId
|
||||||
|
},
|
||||||
|
CreatedBy: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: Doc.CreatedBy.objectId
|
||||||
|
},
|
||||||
|
Signers: signers
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await axios.post(
|
||||||
|
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||||
|
"_appName"
|
||||||
|
)}_Document`,
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res) {
|
||||||
|
return { status: "success", id: res.data.objectId };
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("axois err ", err);
|
||||||
|
return { status: "error", id: "Something Went Wrong!" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getFirstLetter = (name) => {
|
||||||
|
const firstLetter = name?.charAt(0);
|
||||||
|
return firstLetter;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const darkenColor = (color, factor) => {
|
||||||
|
// Remove '#' from the color code and parse it to get RGB values
|
||||||
|
const hex = color.replace("#", "");
|
||||||
|
const r = parseInt(hex.substring(0, 2), 16);
|
||||||
|
const g = parseInt(hex.substring(2, 4), 16);
|
||||||
|
const b = parseInt(hex.substring(4, 6), 16);
|
||||||
|
|
||||||
|
// Darken the color by reducing each RGB component
|
||||||
|
const darkerR = Math.floor(r * (1 - factor));
|
||||||
|
const darkerG = Math.floor(g * (1 - factor));
|
||||||
|
const darkerB = Math.floor(b * (1 - factor));
|
||||||
|
|
||||||
|
// Convert the darkened RGB components back to hex
|
||||||
|
return `#${((darkerR << 16) | (darkerG << 8) | darkerB)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(6, "0")}`;
|
||||||
|
};
|
||||||
|
|||||||