mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-13 13:17:39 +02:00
Compare commits
54
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3a1c74a45 | ||
|
|
2544651ff1 | ||
|
|
93297b972a | ||
|
|
7165ed82f5 | ||
|
|
17422427a8 | ||
|
|
9ef2bc9ee2 | ||
|
|
12ec1bad0f | ||
|
|
fd552cedec | ||
|
|
5784378073 | ||
|
|
e0448cd4fa | ||
|
|
9ae0334249 | ||
|
|
eb355f562b | ||
|
|
92dc13185b | ||
|
|
65ec4e78ad | ||
|
|
944370134a | ||
|
|
c1621f64e6 | ||
|
|
e8c06d0836 | ||
|
|
a6295a6e56 | ||
|
|
47ae52c881 | ||
|
|
f2f0b55596 | ||
|
|
0c415de598 | ||
|
|
411941d9f7 | ||
|
|
3c54f2287c | ||
|
|
dfa121fe57 | ||
|
|
52b17730ef | ||
|
|
346d69124c | ||
|
|
7f35074acd | ||
|
|
b9e9694d61 | ||
|
|
ee4a787b81 | ||
|
|
d801680846 | ||
|
|
d84ab89a9b | ||
|
|
26d38f4ca2 | ||
|
|
745e519eec | ||
|
|
45b3e739d7 | ||
|
|
5ce50db001 | ||
|
|
a8c7b60c1b | ||
|
|
16860bc7b8 | ||
|
|
57f20ae1c0 | ||
|
|
d3b0c614ff | ||
|
|
e28f929ffc | ||
|
|
9f8f9a0992 | ||
|
|
60857638ba | ||
|
|
8041151243 | ||
|
|
7faed512b8 | ||
|
|
5d99a4a9c8 | ||
|
|
25c50d5387 | ||
|
|
5719dcca79 | ||
|
|
db1e81a249 | ||
|
|
ecd3395453 | ||
|
|
06e8140be4 | ||
|
|
14e9330651 | ||
|
|
636910a78e | ||
|
|
e4f9152de8 | ||
|
|
e0b9df9ba5 |
@@ -178,6 +178,24 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"a11y"
|
"a11y"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Govinda04",
|
||||||
|
"name": "Govinda Kocharekar",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/50038172?v=4",
|
||||||
|
"profile": "https://github.com/Govinda04",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "crediblebilal",
|
||||||
|
"name": "Bilal Ahmad Bhat",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/55330484?v=4",
|
||||||
|
"profile": "https://bilal.cc",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-2
@@ -39,11 +39,18 @@ DO_ACCESS_KEY_ID=
|
|||||||
DO_SECRET_ACCESS_KEY=
|
DO_SECRET_ACCESS_KEY=
|
||||||
# Digital ocean spaces region or AWS s3 region
|
# Digital ocean spaces region or AWS s3 region
|
||||||
DO_REGION=us-west
|
DO_REGION=us-west
|
||||||
|
# Set this to true id you are using local storage instead of s3 compatible storage
|
||||||
|
# USE_LOCAL=TRUE
|
||||||
|
|
||||||
# Email mailgun 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=
|
MAILGUN_API_KEY=XXXXX
|
||||||
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_HOST=
|
||||||
|
SMTP_PORT=
|
||||||
|
SMTP_USER_EMAIL=
|
||||||
|
SMTP_PASS=
|
||||||
|
|
||||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||||
PFX_BASE64=
|
PFX_BASE64=
|
||||||
|
|||||||
+7
-1
@@ -44,10 +44,16 @@ DO_REGION=us-west
|
|||||||
# local storage
|
# local storage
|
||||||
USE_LOCAL=TRUE
|
USE_LOCAL=TRUE
|
||||||
|
|
||||||
# Email mailgun 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=XXXXX
|
||||||
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_HOST=
|
||||||
|
SMTP_PORT=
|
||||||
|
SMTP_USER_EMAIL=
|
||||||
|
SMTP_PASS=
|
||||||
|
|
||||||
|
|
||||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||||
PFX_BASE64='MIIKCQIBAzCCCc8GCSqGSIb3DQEHAaCCCcAEggm8MIIJuDCCBG8GCSqGSIb3DQEH
|
PFX_BASE64='MIIKCQIBAzCCCc8GCSqGSIb3DQEHAaCCCcAEggm8MIIJuDCCBG8GCSqGSIb3DQEH
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
name: "Bug Report"
|
||||||
|
labels: ["bug","up-for-grabs"]
|
||||||
|
title: "[Bug]: "
|
||||||
|
assignees:
|
||||||
|
- andrew-opensignlabs
|
||||||
|
description: Create a bug report to help us make OpenSign™ the world's best document e-signature platform
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Issue Description
|
||||||
|
description: Please provide a clear & concise description of the problem.
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
description: Describe what you expected to happen.
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Current Behavior
|
||||||
|
description: Describe what is happening instead.
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Please provide step-by-step instructions to reproduce the issue. Include code snippets, URLs, error messages and any other relevant information.
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Screenshots of the issue(optional)
|
||||||
|
description: Add screenshots to better explain the issue.
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Operating System [e.g. MacOS Sonoma 14.1, Windows 11]
|
||||||
|
- type: dropdown
|
||||||
|
id: browsers
|
||||||
|
attributes:
|
||||||
|
label: What browsers are you seeing the problem on?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Chrome
|
||||||
|
- Firefox
|
||||||
|
- Safari
|
||||||
|
- Microsoft Edge
|
||||||
|
default: 0
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: What version of OpenSign™ are you seeing this issue on? [e.g. 1.0.6]
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: environment
|
||||||
|
attributes:
|
||||||
|
label: What environment are you seeing the problem on?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Production (app.opensignlabs.com)
|
||||||
|
- Staging (staging-app.opensignlabs.com)
|
||||||
|
- Hosted (app.yourdomain.com)
|
||||||
|
- Dev (localhost or vercel)
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Please check the boxes that apply to this issue report.
|
||||||
|
options:
|
||||||
|
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: checkboxes
|
||||||
|
id: terms
|
||||||
|
attributes:
|
||||||
|
label: Code of Conduct
|
||||||
|
description: By submitting this issue, you agree to follow our [Code of Conduct](https://www.opensignlabs.com)
|
||||||
|
options:
|
||||||
|
- label: I agree to follow this project's Code of Conduct
|
||||||
|
required: true
|
||||||
|
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||||
|
required: true
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: Suggest an idea for OpenSign™
|
||||||
|
title: "Feature Request: [Short Description]"
|
||||||
|
labels: [feature request, needs triage]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
## Thanks for taking the time to fill out this feature request!
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: title
|
||||||
|
attributes:
|
||||||
|
label: Feature Title
|
||||||
|
description: What would you call this feature?
|
||||||
|
placeholder: e.g., Advanced Signature Verification
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: feature-description
|
||||||
|
attributes:
|
||||||
|
label: Feature Description
|
||||||
|
description: |
|
||||||
|
Please provide a detailed description of the feature you're proposing.
|
||||||
|
placeholder: |
|
||||||
|
e.g., I'm proposing an advanced signature verification feature that...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: featuretype
|
||||||
|
attributes:
|
||||||
|
label: What type of feature are you requesting?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- UI/UX Improvement
|
||||||
|
- Security / Compliance
|
||||||
|
- Performance / Optimization
|
||||||
|
- 3rd party integration
|
||||||
|
- Other
|
||||||
|
- type: dropdown
|
||||||
|
id: importance
|
||||||
|
attributes:
|
||||||
|
label: Importance
|
||||||
|
description: How important is this feature to you?
|
||||||
|
options:
|
||||||
|
- Critical
|
||||||
|
- High
|
||||||
|
- Medium
|
||||||
|
- Low
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: Additional Context
|
||||||
|
description: Any other context or screenshots about the feature request here.
|
||||||
|
placeholder: Additional details, examples, or screenshots...
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
id: terms
|
||||||
|
attributes:
|
||||||
|
label: Code of Conduct
|
||||||
|
description: By submitting this issue, you agree to follow our [Code of Conduct](https://www.opensignlabs.com)
|
||||||
|
options:
|
||||||
|
- label: I agree to follow this project's Code of Conduct
|
||||||
|
required: true
|
||||||
|
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||||
|
required: true
|
||||||
+1
-2
@@ -98,8 +98,7 @@ Environment Varaibles:
|
|||||||
| PUBLIC_URL | http://localhost:3000 | Set it to the URL form where the app home page will be accessed |
|
| PUBLIC_URL | http://localhost:3000 | Set it to the URL form where the app home page will be accessed |
|
||||||
| GENERATE_SOURCEMAP | false | Set it to true if you want to generate the Sourcemap for debugging |
|
| GENERATE_SOURCEMAP | false | Set it to true if you want to generate the Sourcemap for debugging |
|
||||||
| REACT_APP_SERVERURL | http://localhost:8080/app | Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead) |
|
| REACT_APP_SERVERURL | http://localhost:8080/app | Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead) |
|
||||||
| REACT_APP_APPID | http://localhost:3000 | Set it to the URL form where the app home page will be accessed |
|
| REACT_APP_APPID | opensignstgn | A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API. |
|
||||||
| PUBLIC_URL | opensignstgn | A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API. |
|
|
||||||
| APP_ID | opensignstgn | A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App. |
|
| APP_ID | opensignstgn | A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App. |
|
||||||
| appName | open_sign_server | Name of the app. It will be visible in the verification emails sent out. |
|
| appName | open_sign_server | Name of the app. It will be visible in the verification emails sent out. |
|
||||||
| MASTER_KEY | XnAadwKxxByMr | A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database. |
|
| MASTER_KEY | XnAadwKxxByMr | A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database. |
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ We would like to thank all our contributors and users for their support and feed
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rishabjasrotia"><img src="https://avatars.githubusercontent.com/u/33950743?v=4?s=100" width="100px;" alt="Rishab"/><br /><sub><b>Rishab</b></sub></a><br /><a href="#code-rishabjasrotia" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rishabjasrotia"><img src="https://avatars.githubusercontent.com/u/33950743?v=4?s=100" width="100px;" alt="Rishab"/><br /><sub><b>Rishab</b></sub></a><br /><a href="#code-rishabjasrotia" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://session.it"><img src="https://avatars.githubusercontent.com/u/327285?v=4?s=100" width="100px;" alt="Maurizio Pillitu"/><br /><sub><b>Maurizio Pillitu</b></sub></a><br /><a href="#bug-maoo" title="Bug reports">🐛</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://session.it"><img src="https://avatars.githubusercontent.com/u/327285?v=4?s=100" width="100px;" alt="Maurizio Pillitu"/><br /><sub><b>Maurizio Pillitu</b></sub></a><br /><a href="#bug-maoo" title="Bug reports">🐛</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://luisparra.dev"><img src="https://avatars.githubusercontent.com/u/16653744?v=4?s=100" width="100px;" alt="Luis Parra"/><br /><sub><b>Luis Parra</b></sub></a><br /><a href="#a11y-lsprr" title="Accessibility">️️️️♿️</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://luisparra.dev"><img src="https://avatars.githubusercontent.com/u/16653744?v=4?s=100" width="100px;" alt="Luis Parra"/><br /><sub><b>Luis Parra</b></sub></a><br /><a href="#a11y-lsprr" title="Accessibility">️️️️♿️</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Govinda04"><img src="https://avatars.githubusercontent.com/u/50038172?v=4?s=100" width="100px;" alt="Govinda Kocharekar"/><br /><sub><b>Govinda Kocharekar</b></sub></a><br /><a href="#code-Govinda04" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://bilal.cc"><img src="https://avatars.githubusercontent.com/u/55330484?v=4?s=100" width="100px;" alt="Bilal Ahmad Bhat"/><br /><sub><b>Bilal Ahmad Bhat</b></sub></a><br /><a href="#code-crediblebilal" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -42,7 +42,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "serve -s build",
|
"start": "serve -s build",
|
||||||
"start-dev": "mf-cra start",
|
"start-dev": "mf-cra start",
|
||||||
"build": "rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
|
||||||
|
"build": "npm run version && rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
||||||
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
|
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
@@ -85,4 +86,4 @@
|
|||||||
"pretty-quick": "^3.1.3",
|
"pretty-quick": "^3.1.3",
|
||||||
"tailwindcss": "^3.3.3"
|
"tailwindcss": "^3.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
|
||||||
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
|
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
|
||||||
|
|
||||||
<title>Open sign</title>
|
<title>OpenSign™</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -50,4 +50,4 @@
|
|||||||
-->
|
-->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
v1.0.5-beta
|
||||||
@@ -32,6 +32,7 @@ const AppendFormInForm = (props) => {
|
|||||||
try {
|
try {
|
||||||
const query = new Parse.Query("contracts_Contactbook");
|
const query = new Parse.Query("contracts_Contactbook");
|
||||||
query.equalTo("CreatedBy", user);
|
query.equalTo("CreatedBy", user);
|
||||||
|
query.notEqualTo("IsDeleted", true);
|
||||||
query.equalTo("Email", user.getEmail());
|
query.equalTo("Email", user.getEmail());
|
||||||
const res = await query.first();
|
const res = await query.first();
|
||||||
// console.log(res);
|
// console.log(res);
|
||||||
|
|||||||
@@ -1,8 +1,20 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Package from "../../package.json";
|
import Package from "../../package.json";
|
||||||
|
import axios from "axios";
|
||||||
const Footer = () => {
|
const Footer = () => {
|
||||||
const [showButton, setShowButton] = useState(false);
|
const [showButton, setShowButton] = useState(false);
|
||||||
|
const [version, setVersion] = useState("");
|
||||||
|
useEffect(() => {
|
||||||
|
axios
|
||||||
|
.get("/version.txt")
|
||||||
|
.then((response) => {
|
||||||
|
setVersion(response.data); // Set the retrieved data to the state variable
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error reading the file:", error);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
if (window.pageYOffset >= 50) {
|
if (window.pageYOffset >= 50) {
|
||||||
setShowButton(true);
|
setShowButton(true);
|
||||||
@@ -25,16 +37,12 @@ const Footer = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const appName = "OpenSign™";
|
const appName = "OpenSign™";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="bg-[#222c3c] text-[#98a6ba] text-center text-[13px] py-3">
|
<div className="bg-[#222c3c] text-[#98a6ba] text-center text-[13px] py-3">
|
||||||
All Rights Reserved © {new Date().getFullYear()}
|
All Rights Reserved © {new Date().getFullYear()}
|
||||||
{appName}{" "}
|
{appName} ( version: {version ? version : `${Package.version} `})
|
||||||
(version:{" "}
|
|
||||||
{localStorage.getItem("appVersion") &&
|
|
||||||
`${Package.version}.${localStorage.getItem("appVersion")}`}
|
|
||||||
)
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
|
|||||||
@@ -43,8 +43,9 @@ const GoogleSignInBtn = ({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
const clearStorage = async () => {
|
const clearStorage = async () => {
|
||||||
await Parse.User.logOut();
|
if (Parse.User.current()) {
|
||||||
|
await Parse.User.logOut();
|
||||||
|
}
|
||||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||||
let appid = localStorage.getItem("AppID12");
|
let appid = localStorage.getItem("AppID12");
|
||||||
let applogo = localStorage.getItem("appLogo");
|
let applogo = localStorage.getItem("appLogo");
|
||||||
@@ -74,7 +75,6 @@ const GoogleSignInBtn = ({
|
|||||||
localStorage.setItem("userSettings", userSettings);
|
localStorage.setItem("userSettings", userSettings);
|
||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
|
|
||||||
};
|
};
|
||||||
const responseGoogle = async (response) => {
|
const responseGoogle = async (response) => {
|
||||||
clearStorage();
|
clearStorage();
|
||||||
|
|||||||
@@ -472,6 +472,8 @@ const TreeWidget = (props) => {
|
|||||||
props.schema.data.FolderTypeField,
|
props.schema.data.FolderTypeField,
|
||||||
props.schema.data.FolderTypeValue
|
props.schema.data.FolderTypeValue
|
||||||
);
|
);
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
folder.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||||
if (tabList.length > 0) {
|
if (tabList.length > 0) {
|
||||||
let len = tabList.length - 1;
|
let len = tabList.length - 1;
|
||||||
folder.set(props.schema.data.ParentFolderField, {
|
folder.set(props.schema.data.ParentFolderField, {
|
||||||
@@ -698,7 +700,7 @@ const TreeWidget = (props) => {
|
|||||||
))}
|
))}
|
||||||
<hr />
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
{editable && (
|
{/* {editable && (
|
||||||
<TreeEditForm
|
<TreeEditForm
|
||||||
FormId={props.schema.data.FormId}
|
FormId={props.schema.data.FormId}
|
||||||
objectId={editId}
|
objectId={editId}
|
||||||
@@ -707,7 +709,7 @@ const TreeWidget = (props) => {
|
|||||||
selectFolderHandle();
|
selectFolderHandle();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)} */}
|
||||||
{isAddField && !loader && !editable && (
|
{isAddField && !loader && !editable && (
|
||||||
<TreeFormComponent
|
<TreeFormComponent
|
||||||
Id={props.schema.data.FormId}
|
Id={props.schema.data.FormId}
|
||||||
@@ -795,7 +797,7 @@ const TreeWidget = (props) => {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{fldr[props.schema.data.FolderTypeField] ===
|
{/* {fldr[props.schema.data.FolderTypeField] ===
|
||||||
props.schema.data.FolderTypeValue && (
|
props.schema.data.FolderTypeValue && (
|
||||||
<a
|
<a
|
||||||
className="float-right"
|
className="float-right"
|
||||||
@@ -815,7 +817,7 @@ const TreeWidget = (props) => {
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</a>
|
</a>
|
||||||
)}
|
)} */}
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ function DashboardReport(props) {
|
|||||||
const [isLoader, setIsLoader] = useState(true);
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
const [reportName, setReportName] = useState("");
|
const [reportName, setReportName] = useState("");
|
||||||
const [actions, setActions] = useState([]);
|
const [actions, setActions] = 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 abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
@@ -43,6 +44,7 @@ function DashboardReport(props) {
|
|||||||
if (json) {
|
if (json) {
|
||||||
setActions(json.actions);
|
setActions(json.actions);
|
||||||
setReportName(json.reportName);
|
setReportName(json.reportName);
|
||||||
|
setHeading(json.heading);
|
||||||
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;
|
||||||
@@ -140,7 +142,9 @@ function DashboardReport(props) {
|
|||||||
<ReportTable
|
<ReportTable
|
||||||
ReportName={reportName}
|
ReportName={reportName}
|
||||||
List={List}
|
List={List}
|
||||||
|
setList={setList}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
|
heading={heading}
|
||||||
setIsNextRecord={setIsNextRecord}
|
setIsNextRecord={setIsNextRecord}
|
||||||
isMoreDocs={isMoreDocs}
|
isMoreDocs={isMoreDocs}
|
||||||
docPerPage={docPerPage}
|
docPerPage={docPerPage}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import React, { useCallback, useMemo } from "react";
|
||||||
|
import { useDropScript } from "../../hook/useScript";
|
||||||
|
|
||||||
|
const DROPBOX_APP_KEY = process.env.REACT_APP_DROPBOX_API_KEY; // App key
|
||||||
|
const DROPBOX_SDK_URL = "https://www.dropbox.com/static/api/2/dropins.js";
|
||||||
|
const DROPBOX_SCRIPT_ID = "dropboxjs";
|
||||||
|
|
||||||
|
export default function DropboxChooser({ children, onSuccess, onCancel }) {
|
||||||
|
useDropScript(DROPBOX_SDK_URL, {
|
||||||
|
attrs: {
|
||||||
|
id: DROPBOX_SCRIPT_ID,
|
||||||
|
"data-app-key": DROPBOX_APP_KEY
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = useMemo(
|
||||||
|
() => ({
|
||||||
|
// Required. Called when a user selects an item in the Chooser.
|
||||||
|
success: (files) => {
|
||||||
|
// console.log("success", files);
|
||||||
|
onSuccess && onSuccess(files);
|
||||||
|
},
|
||||||
|
// Optional. Called when the user closes the dialog without selecting a file
|
||||||
|
// and does not include any parameters.
|
||||||
|
cancel: () => {
|
||||||
|
console.log("cancel");
|
||||||
|
onCancel && onCancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Optional. "preview" (default) is a preview link to the document for sharing,
|
||||||
|
// "direct" is an expiring link to download the contents of the file. For more
|
||||||
|
linkType: "direct", // or "preview"
|
||||||
|
multiselect: false, // 是否支持多选
|
||||||
|
extensions: [".pdf"],
|
||||||
|
|
||||||
|
// Optional. A value of false (default) limits selection to files,
|
||||||
|
// while true allows the user to select both folders and files.
|
||||||
|
// You cannot specify `linkType: "direct"` when using `folderselect: true`.
|
||||||
|
folderselect: false // or true
|
||||||
|
}),
|
||||||
|
[onSuccess, onCancel]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleChoose = useCallback(() => {
|
||||||
|
if (window.Dropbox) {
|
||||||
|
window.Dropbox.choose(options);
|
||||||
|
}
|
||||||
|
}, [options]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div onClick={handleChoose}>
|
||||||
|
{children || (
|
||||||
|
<button className="px-2 py-[2px] text-2xl rounded border-[1px] text-blue-400 border-gray-300 w-full">
|
||||||
|
<i className="fa-brands fa-dropbox"></i>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,14 +2,12 @@ import React, { useState, useEffect } from "react";
|
|||||||
import { SaveFileSize } from "../../constant/saveFileSize";
|
import { SaveFileSize } from "../../constant/saveFileSize";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import sanitizeFileName from "../../primitives/sanitizeFileName";
|
import sanitizeFileName from "../../primitives/sanitizeFileName";
|
||||||
|
import DropboxChooser from "./DropboxChoose";
|
||||||
const FileUpload = (props) => {
|
const FileUpload = (props) => {
|
||||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||||
const [_fileupload, setFileUpload] = useState("");
|
const [_fileupload, setFileUpload] = useState("");
|
||||||
const [fileload, setfileload] = useState(false);
|
const [fileload, setfileload] = useState(false);
|
||||||
|
|
||||||
const [localValue, setLocalValue] = useState("");
|
|
||||||
const [Message] = useState(false);
|
const [Message] = useState(false);
|
||||||
const [percentage, setpercentage] = useState(0);
|
const [percentage, setpercentage] = useState(0);
|
||||||
|
|
||||||
@@ -25,7 +23,6 @@ const FileUpload = (props) => {
|
|||||||
const onChange = (e) => {
|
const onChange = (e) => {
|
||||||
try {
|
try {
|
||||||
let files = e.target.files;
|
let files = e.target.files;
|
||||||
setLocalValue(e.target.files);
|
|
||||||
if (typeof files[0] !== "undefined") {
|
if (typeof files[0] !== "undefined") {
|
||||||
if (props.schema.filetypes && props.schema.filetypes.length > 0) {
|
if (props.schema.filetypes && props.schema.filetypes.length > 0) {
|
||||||
var fileName = files[0].name;
|
var fileName = files[0].name;
|
||||||
@@ -106,6 +103,56 @@ const FileUpload = (props) => {
|
|||||||
console.error("Error uploading file:", error);
|
console.error("Error uploading file:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dropboxSuccess = async (files) => {
|
||||||
|
// console.log("file ", files);
|
||||||
|
setfileload(true);
|
||||||
|
const file = files[0];
|
||||||
|
const url = file.link;
|
||||||
|
const size = file.bytes;
|
||||||
|
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);
|
||||||
|
// console.log("percentCompleted ", percentCompleted);
|
||||||
|
setpercentage(percentCompleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log("response.url() ", response.url());
|
||||||
|
setFileUpload(response.url());
|
||||||
|
props.onChange(response.url());
|
||||||
|
setfileload(false);
|
||||||
|
|
||||||
|
if (response.url()) {
|
||||||
|
SaveFileSize(size, response.url());
|
||||||
|
return response.url();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setfileload(false);
|
||||||
|
setpercentage(0);
|
||||||
|
console.error("Error uploading file:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const dropboxCancel = async () => {
|
||||||
|
console.log("cancel clicked ");
|
||||||
|
};
|
||||||
let fileView =
|
let fileView =
|
||||||
props.formData &&
|
props.formData &&
|
||||||
props.schema.uploadtype === "s3viajw" ? null : props.formData &&
|
props.schema.uploadtype === "s3viajw" ? null : props.formData &&
|
||||||
@@ -207,55 +254,51 @@ const FileUpload = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<>
|
<>
|
||||||
{localValue ? (
|
{props.formData ? (
|
||||||
<input
|
<div className="flex gap-2 justify-center items-center">
|
||||||
type="file"
|
<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]">
|
||||||
id="hashfile"
|
<div className="break-all">
|
||||||
style={{
|
file selected : {props.formData.split("/")[3]}
|
||||||
border: "1px solid #ccc",
|
</div>
|
||||||
color: "gray",
|
<div
|
||||||
backgroundColor: "white",
|
onClick={() => {
|
||||||
padding: "5px 10px",
|
console.log("clicked");
|
||||||
borderRadius: "4px",
|
setFileUpload([]);
|
||||||
fontSize: "13px",
|
props.onChange(undefined);
|
||||||
width: "100%",
|
}}
|
||||||
fontWeight: "bold"
|
className="cursor-pointer px-[10px] text-[20px] font-bold bg-white text-red-500"
|
||||||
}}
|
>
|
||||||
accept="application/pdf,application/vnd.ms-excel"
|
<i className="fa-solid fa-xmark"></i>
|
||||||
onChange={onChange}
|
</div>
|
||||||
/>
|
</div>
|
||||||
) : props.formData ? (
|
<DropboxChooser
|
||||||
<div
|
onSuccess={dropboxSuccess}
|
||||||
style={{
|
onCancel={dropboxCancel}
|
||||||
border: "1px solid #ccc",
|
/>
|
||||||
color: "gray",
|
|
||||||
backgroundColor: "white",
|
|
||||||
padding: "5px 10px",
|
|
||||||
borderRadius: "4px",
|
|
||||||
fontSize: "13px",
|
|
||||||
width: "100%",
|
|
||||||
fontWeight: "bold"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
file selected : {props.formData.split("/")[3]}
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<input
|
<div className="flex gap-2 justify-center items-center">
|
||||||
type="file"
|
<input
|
||||||
id="hashfile"
|
type="file"
|
||||||
style={{
|
id="hashfile"
|
||||||
border: "1px solid #ccc",
|
style={{
|
||||||
color: "gray",
|
border: "1px solid #ccc",
|
||||||
backgroundColor: "white",
|
color: "gray",
|
||||||
padding: "5px 10px",
|
backgroundColor: "white",
|
||||||
borderRadius: "4px",
|
padding: "5px 10px",
|
||||||
fontSize: "13px",
|
borderRadius: "4px",
|
||||||
width: "100%",
|
fontSize: "13px",
|
||||||
fontWeight: "bold"
|
width: "100%",
|
||||||
}}
|
fontWeight: "bold"
|
||||||
accept="application/pdf,application/vnd.ms-excel"
|
}}
|
||||||
onChange={onChange}
|
accept="application/pdf,application/vnd.ms-excel"
|
||||||
/>
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
<DropboxChooser
|
||||||
|
onSuccess={dropboxSuccess}
|
||||||
|
onCancel={dropboxCancel}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|||||||
@@ -42,9 +42,8 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
className={`${isOpen ? "block" : "hidden"
|
className={`bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 md:translate-x-0
|
||||||
} bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 ${isOpen ? "translate-x-0" : "-translate-x-full"
|
${isOpen ? "translate-x-0 block" : "-translate-x-full hidden"}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
|
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
|
||||||
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
|
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
|
||||||
|
|||||||
@@ -15,3 +15,20 @@ export const useScript = (url, onload) => {
|
|||||||
};
|
};
|
||||||
}, [url, onload]);
|
}, [url, onload]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**`useScript` hook is generated scripte for google sign in button */
|
||||||
|
export const useDropScript = (url, onload) => {
|
||||||
|
useEffect(() => {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
//add url parameter to the script src, for load and it will remove after load in return
|
||||||
|
script.src = url;
|
||||||
|
script.async = true;
|
||||||
|
script.defer = true;
|
||||||
|
script.id = "dropboxjs";
|
||||||
|
script.setAttribute("data-app-key", "8k0thg9r1t7asqg");
|
||||||
|
document.head.appendChild(script);
|
||||||
|
return () => {
|
||||||
|
document.head.removeChild(script);
|
||||||
|
};
|
||||||
|
}, [url, onload]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const formJson = (id) => {
|
|||||||
type: "string",
|
type: "string",
|
||||||
title: "Select Document",
|
title: "Select Document",
|
||||||
filetypes: [],
|
filetypes: [],
|
||||||
maxfilesizeKB: "5000",
|
maxfilesizeKB: "10000",
|
||||||
uploadtype: "regular",
|
uploadtype: "regular",
|
||||||
helpbody: "",
|
helpbody: "",
|
||||||
helplink: ""
|
helplink: ""
|
||||||
@@ -147,7 +147,7 @@ export const formJson = (id) => {
|
|||||||
class: "contracts_Contactbook",
|
class: "contracts_Contactbook",
|
||||||
displayKey: "Name",
|
displayKey: "Name",
|
||||||
valueKey: "objectId",
|
valueKey: "objectId",
|
||||||
query: `where={"CreatedBy":${userPtr}}&keys=Name`,
|
query: `where={"CreatedBy":${userPtr},"IsDeleted":{"$ne":true}}&keys=Name`,
|
||||||
isPointer: true,
|
isPointer: true,
|
||||||
helpbody: "",
|
helpbody: "",
|
||||||
helplink: "",
|
helplink: "",
|
||||||
@@ -582,4 +582,3 @@ export const formJson = (id) => {
|
|||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
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 contactbook = ["Sr.No", "Name", "Email", "Phone"];
|
||||||
switch (id) {
|
switch (id) {
|
||||||
// draft documents report
|
// draft documents report
|
||||||
case "ByHuevtCFY":
|
case "ByHuevtCFY":
|
||||||
return {
|
return {
|
||||||
reportName: "Draft Documents",
|
reportName: "Draft Documents",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
@@ -21,6 +23,7 @@ export default function reportJson(id) {
|
|||||||
case "4Hhwbp482K":
|
case "4Hhwbp482K":
|
||||||
return {
|
return {
|
||||||
reportName: "Need your sign",
|
reportName: "Need your sign",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
@@ -36,6 +39,7 @@ export default function reportJson(id) {
|
|||||||
case "1MwEuxLEkF":
|
case "1MwEuxLEkF":
|
||||||
return {
|
return {
|
||||||
reportName: "In-progress documents",
|
reportName: "In-progress documents",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -51,6 +55,7 @@ export default function reportJson(id) {
|
|||||||
case "kQUoW4hUXz":
|
case "kQUoW4hUXz":
|
||||||
return {
|
return {
|
||||||
reportName: "Completed Documents",
|
reportName: "Completed Documents",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -66,6 +71,7 @@ export default function reportJson(id) {
|
|||||||
case "UPr2Fm5WY3":
|
case "UPr2Fm5WY3":
|
||||||
return {
|
return {
|
||||||
reportName: "Declined Documents",
|
reportName: "Declined Documents",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -81,6 +87,7 @@ export default function reportJson(id) {
|
|||||||
case "zNqBHXHsYH":
|
case "zNqBHXHsYH":
|
||||||
return {
|
return {
|
||||||
reportName: "Expired Documents",
|
reportName: "Expired Documents",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -96,6 +103,7 @@ export default function reportJson(id) {
|
|||||||
case "d9k3UfYHBc":
|
case "d9k3UfYHBc":
|
||||||
return {
|
return {
|
||||||
reportName: "Recently sent for signatures",
|
reportName: "Recently sent for signatures",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -111,6 +119,7 @@ export default function reportJson(id) {
|
|||||||
case "5Go51Q7T8r":
|
case "5Go51Q7T8r":
|
||||||
return {
|
return {
|
||||||
reportName: "Recent signature requests",
|
reportName: "Recent signature requests",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "Sign",
|
btnLabel: "Sign",
|
||||||
@@ -126,6 +135,7 @@ export default function reportJson(id) {
|
|||||||
case "kC5mfynCi4":
|
case "kC5mfynCi4":
|
||||||
return {
|
return {
|
||||||
reportName: "Drafts",
|
reportName: "Drafts",
|
||||||
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
@@ -137,6 +147,20 @@ export default function reportJson(id) {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
// contactbook report
|
||||||
|
case "5KhaPr482K":
|
||||||
|
return {
|
||||||
|
reportName: "Contactbook",
|
||||||
|
heading: contactbook,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
btnLabel: "",
|
||||||
|
btnColor: "#f55a42",
|
||||||
|
textColor: "white",
|
||||||
|
btnIcon: "fa-solid fa-trash"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
"subtitle": "Customization available Priority support.",
|
"subtitle": "Customization available Priority support.",
|
||||||
"btnText": "Contact us",
|
"btnText": "Contact us",
|
||||||
"url": "https://www.opensignlabs.com/contact-us",
|
"url": "https://www.opensignlabs.com/contact-us",
|
||||||
"target": "_self",
|
"target": "_blank",
|
||||||
"benefits": [
|
"benefits": [
|
||||||
"All features",
|
"All features",
|
||||||
"Custom domain",
|
"Custom domain",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useSelector } from "react-redux";
|
|||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
const HomeLayout = ({ children }) => {
|
const HomeLayout = ({ children }) => {
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(true);
|
||||||
const arr = useSelector((state) => state.TourSteps);
|
const arr = useSelector((state) => state.TourSteps);
|
||||||
|
|
||||||
// reactour state
|
// reactour state
|
||||||
@@ -19,13 +19,11 @@ const HomeLayout = ({ children }) => {
|
|||||||
const [tourConfigs, setTourConfigs] = useState([]);
|
const [tourConfigs, setTourConfigs] = useState([]);
|
||||||
|
|
||||||
const showSidebar = () => {
|
const showSidebar = () => {
|
||||||
setIsOpen(!isOpen);
|
setIsOpen(value => !value);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (width && width <= 768) {
|
if (width && width <= 768) {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
} else {
|
|
||||||
setIsOpen(true);
|
|
||||||
}
|
}
|
||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
import React, { useState, useEffect, useMemo } from "react";
|
import React, { useState, useEffect, useMemo } from "react";
|
||||||
import pad from "../assets/images/pad.svg";
|
import pad from "../assets/images/pad.svg";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import "../styles/report.css";
|
||||||
const ReportTable = ({
|
const ReportTable = ({
|
||||||
ReportName,
|
ReportName,
|
||||||
List,
|
List,
|
||||||
|
setList,
|
||||||
actions,
|
actions,
|
||||||
|
heading,
|
||||||
setIsNextRecord,
|
setIsNextRecord,
|
||||||
isMoreDocs,
|
isMoreDocs,
|
||||||
docPerPage
|
docPerPage
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
// const pageNumbers = [];
|
const [actLoader, setActLoader] = useState({});
|
||||||
|
const [isAlert, setIsAlert] = useState(false);
|
||||||
|
const [isErr, setIsErr] = useState(false);
|
||||||
// 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(() => {
|
||||||
@@ -57,8 +61,34 @@ const ReportTable = ({
|
|||||||
localStorage.setItem("rowlevel", JSON.stringify(item));
|
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||||
// localStorage.setItem("rowlevelMicro");
|
// localStorage.setItem("rowlevelMicro");
|
||||||
};
|
};
|
||||||
const handlebtn = () => {
|
const handlebtn = async (item) => {
|
||||||
console.log("clicked");
|
if (ReportName === "Contactbook") {
|
||||||
|
setActLoader({ [item.objectId]: true });
|
||||||
|
try {
|
||||||
|
const url =
|
||||||
|
process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/";
|
||||||
|
const body = { IsDeleted: true };
|
||||||
|
const res = await axios.put(url + item.objectId, body, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log("Res ", res.data);
|
||||||
|
if (res.data && res.data.updatedAt) {
|
||||||
|
setActLoader({});
|
||||||
|
setIsAlert(true);
|
||||||
|
const upldatedList = List.filter((x) => x.objectId !== item.objectId);
|
||||||
|
setList(upldatedList);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err", err);
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get current list
|
// Get current list
|
||||||
@@ -73,17 +103,27 @@ const ReportTable = ({
|
|||||||
|
|
||||||
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">
|
||||||
|
{isAlert && (
|
||||||
|
<div
|
||||||
|
className={`alert alert-${isErr ? "danger" : "success"} alertBox`}
|
||||||
|
role="alert"
|
||||||
|
onAnimationEnd={() => setIsAlert(false)}
|
||||||
|
>
|
||||||
|
{isErr
|
||||||
|
? "Something went wrong, Please try again later!"
|
||||||
|
: "Record deleted successfully!"}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
||||||
<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]">
|
||||||
<th className="px-4 py-2 font-thin">Sr.No</th>
|
{heading?.map((item, index) => (
|
||||||
<th className="px-4 py-2 font-thin">Name</th>
|
<React.Fragment key={index}>
|
||||||
<th className="px-4 py-2 font-thin">Note</th>
|
<th className="px-4 py-2 font-thin">{item}</th>
|
||||||
<th className="px-4 py-2 font-thin">Folder</th>
|
</React.Fragment>
|
||||||
<th className="px-4 py-2 font-thin">File</th>
|
))}
|
||||||
<th className="px-4 py-2 font-thin">Owner</th>
|
|
||||||
<th className="px-4 py-2 font-thin">Signers</th>
|
|
||||||
{actions?.length > 0 && (
|
{actions?.length > 0 && (
|
||||||
<th className="px-4 py-2 font-thin">Action</th>
|
<th className="px-4 py-2 font-thin">Action</th>
|
||||||
)}
|
)}
|
||||||
@@ -92,61 +132,115 @@ const ReportTable = ({
|
|||||||
<tbody className="text-[12px]">
|
<tbody className="text-[12px]">
|
||||||
{List?.length > 0 ? (
|
{List?.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
{currentLists.map((item, index) => (
|
{currentLists.map((item, index) =>
|
||||||
<tr className="border-y-[1px]" key={index}>
|
ReportName === "Contactbook" ? (
|
||||||
<td className="px-4 py-2">{index + 1}</td>
|
<tr className="border-y-[1px]" key={index}>
|
||||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
<td className="px-4 py-2">{index + 1}</td>
|
||||||
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2">{item?.Email || "-"}</td>
|
||||||
{item?.Folder?.Name || "OpenSignDrive"}
|
<td className="px-4 py-2">{item?.Phone || "-"}</td>
|
||||||
</td>
|
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
||||||
<td className="px-4 py-2">
|
{actions?.length > 0 &&
|
||||||
<a
|
actions.map((act, index) => (
|
||||||
target="_blank"
|
<button
|
||||||
rel="noopener noreferrer"
|
key={index}
|
||||||
title={item?.URL}
|
onClick={() =>
|
||||||
href={item?.URL}
|
act?.redirectUrl
|
||||||
download={item?.URL}
|
? handlemicroapp(item, act.redirectUrl)
|
||||||
className="text-[blue] hover:text-[blue] hover:underline"
|
: handlebtn(item)
|
||||||
>
|
}
|
||||||
{item?.URL ? "Download" : "-"}
|
className={`flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
||||||
</a>
|
style={{
|
||||||
</td>
|
backgroundColor: act.btnColor
|
||||||
|
? act.btnColor
|
||||||
|
: "#3ac9d6",
|
||||||
|
color: act?.textColor ? act?.textColor : "white"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{act?.btnIcon && (
|
||||||
|
<i
|
||||||
|
className={
|
||||||
|
actLoader[item.objectId]
|
||||||
|
? "fa-solid fa-spinner fa-spin-pulse"
|
||||||
|
: act.btnIcon
|
||||||
|
}
|
||||||
|
></i>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
{act?.btnLabel && (
|
||||||
|
<span className="uppercase">
|
||||||
|
{act?.btnLabel ? act.btnLabel : "View"}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
<tr className="border-y-[1px]" key={index}>
|
||||||
|
<td className="px-4 py-2">{index + 1}</td>
|
||||||
|
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||||
|
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
||||||
|
<td className="px-4 py-2">
|
||||||
|
{item?.Folder?.Name || "OpenSignDrive"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-2">
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
title={item?.URL}
|
||||||
|
href={item?.URL}
|
||||||
|
download={item?.URL}
|
||||||
|
className="text-[blue] hover:text-[blue] hover:underline"
|
||||||
|
>
|
||||||
|
{item?.URL ? "Download" : "-"}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
<td className="px-4 py-2">{formatRow(item?.ExtUserPtr)}</td>
|
<td className="px-4 py-2">{formatRow(item?.ExtUserPtr)}</td>
|
||||||
<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-4 py-2 flex flex-col justify-center items-center gap-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)
|
||||||
: handlebtn(item)
|
: handlebtn(item)
|
||||||
}
|
}
|
||||||
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: act.btnColor
|
backgroundColor: act.btnColor
|
||||||
? act.btnColor
|
? act.btnColor
|
||||||
: "#3ac9d6",
|
: "#3ac9d6",
|
||||||
color: act?.textColor ? act?.textColor : "white"
|
color: act?.textColor ? act?.textColor : "white"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
{act?.btnIcon && <i className={act.btnIcon}></i>}
|
{act?.btnIcon && (
|
||||||
</span>
|
<i
|
||||||
<span className="uppercase">
|
className={
|
||||||
{act?.btnLabel ? act.btnLabel : "view"}
|
actLoader[item.objectId]
|
||||||
</span>
|
? "fa-solid fa-spinner fa-spin-pulse"
|
||||||
</button>
|
: act.btnIcon
|
||||||
// )
|
}
|
||||||
))}
|
></i>
|
||||||
</td>
|
)}
|
||||||
</tr>
|
</span>
|
||||||
))}
|
<span className="uppercase">
|
||||||
|
{act?.btnLabel ? act.btnLabel : "view"}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
// )
|
||||||
|
))}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ import React, { useState, useEffect } from "react";
|
|||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import "../styles/loader.css";
|
import "../styles/loader.css";
|
||||||
import GetDashboard from "../components/dashboard/GetDashboard";
|
import GetDashboard from "../components/dashboard/GetDashboard";
|
||||||
import { Navigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import { save_tourSteps } from "../redux/actions";
|
import { save_tourSteps } from "../redux/actions";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
const Dashboard = (props) => {
|
const Dashboard = (props) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const [dashboard, setdashboard] = useState([]);
|
const [dashboard, setdashboard] = useState([]);
|
||||||
const [classnameArray, setclassnameArray] = useState([]);
|
const [classnameArray, setclassnameArray] = useState([]);
|
||||||
@@ -15,6 +16,19 @@ const Dashboard = (props) => {
|
|||||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||||
const [defaultQuery, setDefaultQuery] = useState("");
|
const [defaultQuery, setDefaultQuery] = useState("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (localStorage.getItem("accesstoken")) {
|
||||||
|
if (id !== undefined) {
|
||||||
|
getDashboard(id);
|
||||||
|
} else {
|
||||||
|
getDashboard(localStorage.getItem("PageLanding"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
navigate("/", { replace: true });
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
const getDashboard = async (id) => {
|
const getDashboard = async (id) => {
|
||||||
setloading(true);
|
setloading(true);
|
||||||
try {
|
try {
|
||||||
@@ -93,20 +107,6 @@ const Dashboard = (props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (id !== undefined) {
|
|
||||||
getDashboard(id);
|
|
||||||
} else {
|
|
||||||
getDashboard(localStorage.getItem("PageLanding"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [id]);
|
|
||||||
|
|
||||||
if (localStorage.getItem("accesstoken") === "" || null) {
|
|
||||||
return <Navigate to="/" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
let _dash = (
|
let _dash = (
|
||||||
<GetDashboard
|
<GetDashboard
|
||||||
dashboard={dashboard}
|
dashboard={dashboard}
|
||||||
|
|||||||
@@ -1183,17 +1183,17 @@ function Login(props) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label
|
<label
|
||||||
htmlFor="Destination"
|
htmlFor="JobTitle"
|
||||||
style={{ display: "flex" }}
|
style={{ display: "flex" }}
|
||||||
className="col-form-label"
|
className="col-form-label"
|
||||||
>
|
>
|
||||||
Destination{" "}
|
Job Title
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="Destination"
|
id="JobTitle"
|
||||||
value={userDetails.Destination}
|
value={userDetails.Destination}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setUserDetails({
|
setUserDetails({
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ const PgSignUp = (props) => {
|
|||||||
});
|
});
|
||||||
const [validationMessage, setValidationMessage] = useState("");
|
const [validationMessage, setValidationMessage] = useState("");
|
||||||
const [isLoader, setIsLoader] = useState(true);
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
|
const [lengthValid, setLengthValid] = useState(false);
|
||||||
|
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||||
|
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||||
|
|
||||||
// below useEffect is used to fetch App data and save to redux state
|
// below useEffect is used to fetch App data and save to redux state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -104,21 +107,23 @@ const PgSignUp = (props) => {
|
|||||||
// "handleSubmit" is used to save user details signup him/her who come from plan-pricing page
|
// "handleSubmit" is used to save user details signup him/her who come from plan-pricing page
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsLoader(true);
|
if (lengthValid && caseDigitValid && specialCharValid) {
|
||||||
if (formData.password === formData.confirmPassword) {
|
setIsLoader(true);
|
||||||
const url = window.location.href;
|
if (formData.password === formData.confirmPassword) {
|
||||||
let paramString = url.split("?")[1];
|
const url = window.location.href;
|
||||||
let queryString = new URLSearchParams(paramString);
|
let paramString = url.split("?")[1];
|
||||||
// console.log("url ", queryString);
|
let queryString = new URLSearchParams(paramString);
|
||||||
|
// console.log("url ", queryString);
|
||||||
|
|
||||||
let obj = { ...formData };
|
let obj = { ...formData };
|
||||||
for (let pair of queryString.entries()) {
|
for (let pair of queryString.entries()) {
|
||||||
// console.log("Key is: " + pair[0]);
|
// console.log("Key is: " + pair[0]);
|
||||||
// console.log("Value is: " + pair[1]);
|
// console.log("Value is: " + pair[1]);
|
||||||
obj = { ...obj, [pair[0]]: pair[1] };
|
obj = { ...obj, [pair[0]]: pair[1] };
|
||||||
|
}
|
||||||
|
saveUser(obj);
|
||||||
|
// console.log("obj ", obj);}
|
||||||
}
|
}
|
||||||
saveUser(obj);
|
|
||||||
// console.log("obj ", obj);}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const saveUser = async (obj) => {
|
const saveUser = async (obj) => {
|
||||||
@@ -194,6 +199,15 @@ const PgSignUp = (props) => {
|
|||||||
const newPassword = e.target.value;
|
const newPassword = e.target.value;
|
||||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
validatePasswords(newPassword, formData.confirmPassword);
|
validatePasswords(newPassword, formData.confirmPassword);
|
||||||
|
|
||||||
|
// Check conditions separately
|
||||||
|
setLengthValid(newPassword.length >= 8);
|
||||||
|
setCaseDigitValid(
|
||||||
|
/[a-z]/.test(newPassword) &&
|
||||||
|
/[A-Z]/.test(newPassword) &&
|
||||||
|
/\d/.test(newPassword)
|
||||||
|
);
|
||||||
|
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
|
||||||
};
|
};
|
||||||
const handleConFirmPassowordChange = (e) => {
|
const handleConFirmPassowordChange = (e) => {
|
||||||
const newConfirmPassword = e.target.value;
|
const newConfirmPassword = e.target.value;
|
||||||
@@ -485,6 +499,33 @@ const PgSignUp = (props) => {
|
|||||||
>
|
>
|
||||||
{validationMessage}
|
{validationMessage}
|
||||||
</div>
|
</div>
|
||||||
|
{formData.password.length > 0 && (
|
||||||
|
<div className="mt-1 text-[11px]">
|
||||||
|
<p
|
||||||
|
className={`${
|
||||||
|
lengthValid ? "text-green-600" : "text-red-600"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{lengthValid ? "✓" : "✗"} Password should be 8 characters long
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className={`${
|
||||||
|
caseDigitValid ? "text-green-600" : "text-red-600"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{caseDigitValid ? "✓" : "✗"} Password should contain uppercase
|
||||||
|
letter, lowercase letter, digit
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className={`${
|
||||||
|
specialCharValid ? "text-green-600" : "text-red-600"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{specialCharValid ? "✓" : "✗"} Password should contain special
|
||||||
|
character
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="clearfix">
|
<div className="clearfix">
|
||||||
<button type="submit" className="signupbtn">
|
<button type="submit" className="signupbtn">
|
||||||
Submit
|
Submit
|
||||||
|
|||||||
@@ -136,8 +136,13 @@ const PlanSubscriptions = () => {
|
|||||||
<p>{item.subtitle}</p>
|
<p>{item.subtitle}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NavLink
|
<NavLink
|
||||||
to={item.url + details}
|
to={
|
||||||
|
item.btnText === "Subscribe"
|
||||||
|
? item.url + details
|
||||||
|
: item.url
|
||||||
|
}
|
||||||
className="bg-[#002862] w-full text-white py-2 rounded uppercase hover:no-underline hover:text-white"
|
className="bg-[#002862] w-full text-white py-2 rounded uppercase hover:no-underline hover:text-white"
|
||||||
target={item.target}
|
target={item.target}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const Report = () => {
|
|||||||
const [isLoader, setIsLoader] = useState(true);
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
const [reportName, setReportName] = useState("");
|
const [reportName, setReportName] = useState("");
|
||||||
const [actions, setActions] = useState([]);
|
const [actions, setActions] = 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 abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
@@ -47,6 +48,7 @@ const Report = () => {
|
|||||||
const json = reportJson(id);
|
const json = reportJson(id);
|
||||||
if (json) {
|
if (json) {
|
||||||
setActions(json.actions);
|
setActions(json.actions);
|
||||||
|
setHeading(json.heading);
|
||||||
setReportName(json.reportName);
|
setReportName(json.reportName);
|
||||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||||
Parse.initialize(localStorage.getItem("AppID12"));
|
Parse.initialize(localStorage.getItem("AppID12"));
|
||||||
@@ -146,7 +148,9 @@ const Report = () => {
|
|||||||
<ReportTable
|
<ReportTable
|
||||||
ReportName={reportName}
|
ReportName={reportName}
|
||||||
List={List}
|
List={List}
|
||||||
|
setList={setList}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
|
heading={heading}
|
||||||
setIsNextRecord={setIsNextRecord}
|
setIsNextRecord={setIsNextRecord}
|
||||||
isMoreDocs={isMoreDocs}
|
isMoreDocs={isMoreDocs}
|
||||||
docPerPage={docPerPage}
|
docPerPage={docPerPage}
|
||||||
|
|||||||
@@ -25,92 +25,138 @@ const Signup = (props) => {
|
|||||||
toastDescription: ""
|
toastDescription: ""
|
||||||
});
|
});
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
const [lengthValid, setLengthValid] = useState(false);
|
||||||
|
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||||
|
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||||
|
|
||||||
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
||||||
const image = props.appInfo.applogo;
|
const image = props.appInfo.applogo;
|
||||||
|
|
||||||
|
const clearStorage = async () => {
|
||||||
|
if (Parse.User.current()) {
|
||||||
|
await Parse.User.logOut();
|
||||||
|
}
|
||||||
|
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||||
|
let appid = localStorage.getItem("AppID12");
|
||||||
|
let applogo = localStorage.getItem("appLogo");
|
||||||
|
let domain = localStorage.getItem("domain");
|
||||||
|
let appversion = localStorage.getItem("appVersion");
|
||||||
|
let appTitle = localStorage.getItem("appTitle");
|
||||||
|
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
|
let PageLanding = localStorage.getItem("PageLanding");
|
||||||
|
let _appName = localStorage.getItem("_appName");
|
||||||
|
let _app_objectId = localStorage.getItem("_app_objectId");
|
||||||
|
let appName = localStorage.getItem("appName");
|
||||||
|
let userSettings = localStorage.getItem("userSettings");
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
localStorage.setItem("BaseUrl12", baseUrl);
|
||||||
|
localStorage.setItem("AppID12", appid);
|
||||||
|
localStorage.setItem("appLogo", applogo);
|
||||||
|
localStorage.setItem("domain", domain);
|
||||||
|
localStorage.setItem("appversion", appversion);
|
||||||
|
localStorage.setItem("appTitle", appTitle);
|
||||||
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
|
localStorage.setItem("_appName", _appName);
|
||||||
|
localStorage.setItem("_app_objectId", _app_objectId);
|
||||||
|
localStorage.setItem("appName", appName);
|
||||||
|
localStorage.setItem("userSettings", userSettings);
|
||||||
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
|
localStorage.setItem("parseAppId", appid);
|
||||||
|
};
|
||||||
const handleSubmit = (event) => {
|
const handleSubmit = (event) => {
|
||||||
setState({ loading: true });
|
event.preventDefault();
|
||||||
const userDetails = {
|
if (lengthValid && caseDigitValid && specialCharValid) {
|
||||||
name: name,
|
clearStorage();
|
||||||
email: email,
|
setState({ loading: true });
|
||||||
phone: phone,
|
const userDetails = {
|
||||||
company: company,
|
name: name,
|
||||||
jobTitle: jobTitle
|
email: email,
|
||||||
};
|
phone: phone,
|
||||||
localStorage.setItem("userDetails", JSON.stringify(userDetails));
|
company: company,
|
||||||
try {
|
jobTitle: jobTitle
|
||||||
event.preventDefault();
|
};
|
||||||
Parse.serverURL = parseBaseUrl;
|
localStorage.setItem("userDetails", JSON.stringify(userDetails));
|
||||||
Parse.initialize(parseAppId);
|
try {
|
||||||
event.preventDefault();
|
Parse.serverURL = parseBaseUrl;
|
||||||
var user = new Parse.User();
|
Parse.initialize(parseAppId);
|
||||||
user.set("name", name);
|
event.preventDefault();
|
||||||
user.set("email", email);
|
var user = new Parse.User();
|
||||||
user.set("password", password);
|
user.set("name", name);
|
||||||
user.set("phone", phone);
|
user.set("email", email);
|
||||||
user.set("username", email);
|
user.set("password", password);
|
||||||
let res = user.save();
|
user.set("phone", phone);
|
||||||
res
|
user.set("username", email);
|
||||||
.then(async (r) => {
|
let res = user.save();
|
||||||
if (r) {
|
res
|
||||||
let roleData = props.appInfo.settings;
|
.then(async (r) => {
|
||||||
if (roleData && roleData.length > 0) {
|
if (r) {
|
||||||
const params = {
|
let roleData = props.appInfo.settings;
|
||||||
userDetails: {
|
if (roleData && roleData.length > 0) {
|
||||||
jobTitle: jobTitle,
|
const params = {
|
||||||
company: company,
|
userDetails: {
|
||||||
name: name,
|
jobTitle: jobTitle,
|
||||||
email: email,
|
company: company,
|
||||||
phone: phone,
|
name: name,
|
||||||
role: props.appInfo.defaultRole
|
email: email,
|
||||||
|
phone: phone,
|
||||||
|
role: props.appInfo.defaultRole
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const usersignup = await Parse.Cloud.run(
|
||||||
|
"usersignup",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
if (usersignup) {
|
||||||
|
handleNavigation(r.getSessionToken());
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
alert(err.message);
|
||||||
|
setState({ loading: false });
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
try {
|
}
|
||||||
const usersignup = await Parse.Cloud.run("usersignup", params);
|
})
|
||||||
if (usersignup) {
|
.catch(async (err) => {
|
||||||
handleNavigation(r.getSessionToken());
|
if (err.code === 202) {
|
||||||
|
const params = { email: email };
|
||||||
|
const res = await Parse.Cloud.run("getUserDetails", params);
|
||||||
|
// console.log("Res ", res);
|
||||||
|
if (res) {
|
||||||
|
alert("User already exists with this username!");
|
||||||
|
setState({ loading: false });
|
||||||
|
} else {
|
||||||
|
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||||
|
let parseAppId = localStorage.getItem("AppID12");
|
||||||
|
// console.log("state.email ", email);
|
||||||
|
try {
|
||||||
|
Parse.serverURL = baseUrl;
|
||||||
|
Parse.initialize(parseAppId);
|
||||||
|
await Parse.User.requestPasswordReset(email).then(
|
||||||
|
async function (res1) {
|
||||||
|
if (res1.data === undefined) {
|
||||||
|
alert(
|
||||||
|
"Verification mail has been sent to your E-mail!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
alert(err.message);
|
|
||||||
setState({ loading: false });
|
setState({ loading: false });
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(async (err) => {
|
|
||||||
if (err.code === 202) {
|
|
||||||
const params = { email: email };
|
|
||||||
const res = await Parse.Cloud.run("getUserDetails", params);
|
|
||||||
// console.log("Res ", res);
|
|
||||||
if (res) {
|
|
||||||
alert("User already exists with this username!");
|
|
||||||
setState({ loading: false });
|
|
||||||
} else {
|
} else {
|
||||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
alert(err.message);
|
||||||
let parseAppId = localStorage.getItem("AppID12");
|
|
||||||
// console.log("state.email ", email);
|
|
||||||
try {
|
|
||||||
Parse.serverURL = baseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
await Parse.User.requestPasswordReset(email).then(
|
|
||||||
async function (res1) {
|
|
||||||
if (res1.data === undefined) {
|
|
||||||
alert("Verification mail has been sent to your E-mail!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
setState({ loading: false });
|
setState({ loading: false });
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
alert(err.message);
|
} catch (error) {
|
||||||
setState({ loading: false });
|
console.log("err ", error);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log("err ", error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -396,6 +442,19 @@ const Signup = (props) => {
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handlePasswordChange = (e) => {
|
||||||
|
const newPassword = e.target.value;
|
||||||
|
setPassword(newPassword);
|
||||||
|
|
||||||
|
// Check conditions separately
|
||||||
|
setLengthValid(newPassword.length >= 8);
|
||||||
|
setCaseDigitValid(
|
||||||
|
/[a-z]/.test(newPassword) &&
|
||||||
|
/[A-Z]/.test(newPassword) &&
|
||||||
|
/\d/.test(newPassword)
|
||||||
|
);
|
||||||
|
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="bg-white">
|
<div className="bg-white">
|
||||||
{state.loading && (
|
{state.loading && (
|
||||||
@@ -508,7 +567,7 @@ const Signup = (props) => {
|
|||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
name="password"
|
name="password"
|
||||||
value={password}
|
value={password}
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
onChange={(e) => handlePasswordChange(e)}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -524,6 +583,38 @@ const Signup = (props) => {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
{password.length > 0 && (
|
||||||
|
<div className="mt-1 text-[11px]">
|
||||||
|
<p
|
||||||
|
className={`${
|
||||||
|
lengthValid ? "text-green-600" : "text-red-600"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{lengthValid ? "✓" : "✗"} Password should be 8
|
||||||
|
characters long
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className={`${
|
||||||
|
caseDigitValid ? "text-green-600" : "text-red-600"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{caseDigitValid ? "✓" : "✗"} Password should contain
|
||||||
|
uppercase letter, lowercase letter, digit
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className={`${
|
||||||
|
specialCharValid
|
||||||
|
? "text-green-600"
|
||||||
|
: "text-red-600"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{specialCharValid ? "✓" : "✗"} Password should
|
||||||
|
contain special character
|
||||||
|
</p>
|
||||||
|
{/* </>
|
||||||
|
)} */}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
.alertBox {
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
top: 10%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
font-size: 13px;
|
||||||
|
animation: inAnimation 2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes inAnimation {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ async function ContactbookAftersave(request) {
|
|||||||
acl.setWriteAccess(object.get('UserId'), true);
|
acl.setWriteAccess(object.get('UserId'), true);
|
||||||
|
|
||||||
object.setACL(acl);
|
object.setACL(acl);
|
||||||
|
object.set('IsDeleted', false)
|
||||||
// Continue saving the object
|
// Continue saving the object
|
||||||
return object.save(null, { useMasterKey: true });
|
return object.save(null, { useMasterKey: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}"},"$or":[{"CreatedBy":{"$exists":false}},{"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}"}}&include=ExtUserPtr,Signers,Folder`;
|
||||||
} else {
|
} else {
|
||||||
url = `${classUrl}?where={"Folder":{"$exists":false},"$or":[{"CreatedBy":{"$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}"}}&include=ExtUserPtr,Signers`;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(url, {
|
const res = await axios.get(url, {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import reportJson from './reportsJson.js';
|
import reportJson from './reportsJson.js';
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
|
|
||||||
export default async function getReport(request) {
|
export default async function getReport(request) {
|
||||||
const reportId = request.params.reportId;
|
const reportId = request.params.reportId;
|
||||||
@@ -19,6 +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';
|
||||||
if (json) {
|
if (json) {
|
||||||
const { params, keys } = json;
|
const { params, keys } = json;
|
||||||
const orderBy = '-updatedAt';
|
const orderBy = '-updatedAt';
|
||||||
@@ -29,7 +30,7 @@ export default async function getReport(request) {
|
|||||||
'X-Parse-Application-Id': appId,
|
'X-Parse-Application-Id': appId,
|
||||||
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
||||||
};
|
};
|
||||||
const url = `${serverUrl}/classes/contracts_Document?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr`;
|
const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr`;
|
||||||
const res = await axios.get(url, { headers: headers });
|
const res = await axios.get(url, { headers: headers });
|
||||||
if (res.data && res.data.results) {
|
if (res.data && res.data.results) {
|
||||||
return res.data.results;
|
return res.data.results;
|
||||||
|
|||||||
@@ -198,6 +198,20 @@ export default function reportJson(id, userId) {
|
|||||||
},
|
},
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
};
|
};
|
||||||
|
// contact book report
|
||||||
|
case '5KhaPr482K':
|
||||||
|
return {
|
||||||
|
reportName: 'Contactbook',
|
||||||
|
params: {
|
||||||
|
CreatedBy: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
IsDeleted: { $ne: true },
|
||||||
|
},
|
||||||
|
keys: ['Name', 'Email', 'Phone'],
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,556 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @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: '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: '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: '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: '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 });
|
||||||
|
};
|
||||||
@@ -18,6 +18,7 @@ import FSFilesAdapter from 'parse-server-fs-adapter';
|
|||||||
import AWS from 'aws-sdk';
|
import AWS from 'aws-sdk';
|
||||||
import { app as customRoute } from './cloud/customRoute/customApp.js';
|
import { app as customRoute } from './cloud/customRoute/customApp.js';
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
|
import { createTransport } from 'nodemailer';
|
||||||
|
|
||||||
const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT);
|
const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT);
|
||||||
// console.log("configuration ", configuration);
|
// console.log("configuration ", configuration);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[{
|
[
|
||||||
|
{
|
||||||
"_id": "H9vRfEYKhT",
|
"_id": "H9vRfEYKhT",
|
||||||
"_created_at": {
|
"_created_at": {
|
||||||
"$date": "2023-09-04T14:04:00.669Z"
|
"$date": "2023-09-04T14:04:00.669Z"
|
||||||
@@ -105,6 +106,14 @@
|
|||||||
"pageType": "report",
|
"pageType": "report",
|
||||||
"description": "",
|
"description": "",
|
||||||
"objectId": "zNqBHXHsYH"
|
"objectId": "zNqBHXHsYH"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fa-solid fa-address-book",
|
||||||
|
"title": "Contactbook",
|
||||||
|
"target": "_self",
|
||||||
|
"pageType": "report",
|
||||||
|
"description": "",
|
||||||
|
"objectId": "5KhaPr482K"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -237,6 +246,14 @@
|
|||||||
"pageType": "report",
|
"pageType": "report",
|
||||||
"description": "",
|
"description": "",
|
||||||
"objectId": "zNqBHXHsYH"
|
"objectId": "zNqBHXHsYH"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fa-solid fa-address-book",
|
||||||
|
"title": "Contactbook",
|
||||||
|
"target": "_self",
|
||||||
|
"pageType": "report",
|
||||||
|
"description": "",
|
||||||
|
"objectId": "5KhaPr482K"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -269,4 +286,5 @@
|
|||||||
],
|
],
|
||||||
"menuTitle": "Admin Menu",
|
"menuTitle": "Admin Menu",
|
||||||
"menuType": "Side Menu"
|
"menuType": "Side Menu"
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
@@ -25,8 +25,15 @@ function PdfFile() {
|
|||||||
});
|
});
|
||||||
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 currentUser =
|
||||||
|
localStorage.getItem(
|
||||||
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||||
|
) &&
|
||||||
|
localStorage.getItem(
|
||||||
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||||
|
);
|
||||||
|
const jsonCurrentUser = JSON.parse(currentUser);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (docId) {
|
if (docId) {
|
||||||
@@ -151,22 +158,32 @@ function PdfFile() {
|
|||||||
setIsFolderLoader(true);
|
setIsFolderLoader(true);
|
||||||
|
|
||||||
const getParentObjId = folderName[folderName.length - 1];
|
const getParentObjId = folderName[folderName.length - 1];
|
||||||
const isParentId = getParentObjId && getParentObjId.objectId;
|
const parentId = getParentObjId && getParentObjId.objectId;
|
||||||
let data;
|
let data;
|
||||||
if (isParentId) {
|
if (parentId) {
|
||||||
data = {
|
data = {
|
||||||
Name: newFolderName,
|
Name: newFolderName,
|
||||||
Type: "Folder",
|
Type: "Folder",
|
||||||
Folder: {
|
Folder: {
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
className: `${localStorage.getItem("_appName")}_Document`,
|
className: `${localStorage.getItem("_appName")}_Document`,
|
||||||
objectId: isParentId
|
objectId: parentId
|
||||||
|
},
|
||||||
|
CreatedBy: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: jsonCurrentUser.objectId
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
data = {
|
data = {
|
||||||
Name: newFolderName,
|
Name: newFolderName,
|
||||||
Type: "Folder"
|
Type: "Folder",
|
||||||
|
CreatedBy: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: jsonCurrentUser.objectId
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useRef, useEffect } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
import { themeColor } from "../utils/ThemeColor/backColor";
|
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||||
import { PDFDocument, rgb } 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 ModalHeader from "react-bootstrap/esm/ModalHeader";
|
||||||
@@ -16,7 +16,10 @@ import {
|
|||||||
contractDocument,
|
contractDocument,
|
||||||
getBase64FromIMG,
|
getBase64FromIMG,
|
||||||
getBase64FromUrl,
|
getBase64FromUrl,
|
||||||
urlValidator
|
urlValidator,
|
||||||
|
multiSignEmbed,
|
||||||
|
embedDocId,
|
||||||
|
pdfNewWidthFun
|
||||||
} 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";
|
||||||
@@ -90,19 +93,14 @@ function PdfRequestFiles() {
|
|||||||
const jsonSender = JSON.parse(senderUser);
|
const jsonSender = JSON.parse(senderUser);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const clientWidth = window.innerWidth;
|
|
||||||
const value = docId ? 80 : 30;
|
|
||||||
const pdfWidth = clientWidth - 160 - 200 - value;
|
|
||||||
|
|
||||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
|
||||||
//pdf from left and right component
|
|
||||||
setPdfNewWidth(pdfWidth);
|
|
||||||
if (documentId) {
|
if (documentId) {
|
||||||
getDocumentDetails();
|
getDocumentDetails();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (divRef.current) {
|
if (divRef.current) {
|
||||||
|
const pdfWidth = pdfNewWidthFun(divRef);
|
||||||
|
setPdfNewWidth(pdfWidth);
|
||||||
setContainerWH({
|
setContainerWH({
|
||||||
width: divRef.current.offsetWidth,
|
width: divRef.current.offsetWidth,
|
||||||
height: divRef.current.offsetHeight
|
height: divRef.current.offsetHeight
|
||||||
@@ -319,29 +317,12 @@ function PdfRequestFiles() {
|
|||||||
if (isDocId) {
|
if (isDocId) {
|
||||||
pdfBase64 = await getBase64FromUrl(url);
|
pdfBase64 = await getBase64FromUrl(url);
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < allPages; i++) {
|
//embed document's object id to all pages in pdf document
|
||||||
const font = await pdfDoc.embedFont("Helvetica");
|
await embedDocId(pdfDoc, documentId, allPages);
|
||||||
|
|
||||||
const fontSize = 10;
|
|
||||||
const textContent =
|
|
||||||
documentId && `OpenSign™ DocumentId: ${documentId}`;
|
|
||||||
|
|
||||||
const pages = pdfDoc.getPages();
|
|
||||||
const page = pages[i];
|
|
||||||
|
|
||||||
page.drawText(textContent, {
|
|
||||||
x: 10,
|
|
||||||
y: page.getHeight() - 10,
|
|
||||||
size: fontSize,
|
|
||||||
font,
|
|
||||||
color: rgb(0.5, 0.5, 0.5)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
pdfBase64 = await pdfDoc.saveAsBase64({
|
pdfBase64 = await pdfDoc.saveAsBase64({
|
||||||
useObjectStreams: false
|
useObjectStreams: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < pngUrl.length; i++) {
|
for (let i = 0; i < pngUrl.length; i++) {
|
||||||
const imgUrlList = pngUrl[i].pos;
|
const imgUrlList = pngUrl[i].pos;
|
||||||
const pageNo = pngUrl[i].pageNumber;
|
const pageNo = pngUrl[i].pageNumber;
|
||||||
@@ -381,112 +362,15 @@ function PdfRequestFiles() {
|
|||||||
}
|
}
|
||||||
//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) {
|
||||||
for (let i = 0; i < allPages; i++) {
|
//embed document's object id to all pages in pdf document
|
||||||
const font = await pdfDoc.embedFont("Helvetica");
|
await embedDocId(pdfDoc, documentId, allPages);
|
||||||
|
//embed multi signature in pdf
|
||||||
const fontSize = 10;
|
const pdfBytes = await multiSignEmbed(
|
||||||
const textContent =
|
pngUrl,
|
||||||
documentId && `OpenSign™ DocumentId: ${documentId} `;
|
pdfDoc,
|
||||||
|
pdfOriginalWidth,
|
||||||
const pages = pdfDoc.getPages();
|
false
|
||||||
const page = pages[i];
|
);
|
||||||
|
|
||||||
page.drawText(textContent, {
|
|
||||||
x: 10,
|
|
||||||
y: page.getHeight() - 10,
|
|
||||||
size: fontSize,
|
|
||||||
font,
|
|
||||||
color: rgb(0.5, 0.5, 0.5)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < pngUrl.length; i++) {
|
|
||||||
const pageNo = pngUrl[i].pageNumber;
|
|
||||||
|
|
||||||
const imgUrlList = pngUrl[i].pos;
|
|
||||||
const pages = pdfDoc.getPages();
|
|
||||||
const page = pages[pageNo - 1];
|
|
||||||
|
|
||||||
const images = await Promise.all(
|
|
||||||
imgUrlList.map(async (url) => {
|
|
||||||
let signUrl = url.SignUrl;
|
|
||||||
if (url.ImageType === "image/png") {
|
|
||||||
//function for convert signature png base64 url to jpeg base64
|
|
||||||
const newUrl = await convertPNGtoJPEG(signUrl);
|
|
||||||
signUrl = newUrl;
|
|
||||||
}
|
|
||||||
const checkUrl = urlValidator(signUrl);
|
|
||||||
if (checkUrl) {
|
|
||||||
signUrl = signUrl + "?get";
|
|
||||||
}
|
|
||||||
const res = await fetch(signUrl);
|
|
||||||
return res.arrayBuffer();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
images.forEach(async (imgData, id) => {
|
|
||||||
let img = await pdfDoc.embedJpg(imgData);
|
|
||||||
const imgHeight = imgUrlList[id].Height
|
|
||||||
? imgUrlList[id].Height
|
|
||||||
: 60;
|
|
||||||
const imgWidth = imgUrlList[id].Width
|
|
||||||
? imgUrlList[id].Width
|
|
||||||
: 150;
|
|
||||||
const isMobile = window.innerWidth < 767;
|
|
||||||
const newWidth = window.innerWidth;
|
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
|
||||||
const xPos = (pos) => {
|
|
||||||
//checking both condition mobile and desktop view
|
|
||||||
if (isMobile) {
|
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const x = pos.xPosition * (pos.scale / scale);
|
|
||||||
return x * scale + 50;
|
|
||||||
} else {
|
|
||||||
const x = pos.xPosition / 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
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const x = pos.xPosition * pos.scale + 50;
|
|
||||||
return x;
|
|
||||||
} else {
|
|
||||||
return pos.xPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const yPos = (pos) => {
|
|
||||||
//checking both condition mobile and desktop view
|
|
||||||
const y = pos.yPosition / scale;
|
|
||||||
if (isMobile) {
|
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const y = pos.yPosition * (pos.scale / scale);
|
|
||||||
return page.getHeight() - y * scale - imgHeight;
|
|
||||||
} else {
|
|
||||||
return page.getHeight() - y * scale - imgHeight;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const y = pos.yPosition * pos.scale;
|
|
||||||
return page.getHeight() - y - imgHeight;
|
|
||||||
} else {
|
|
||||||
return page.getHeight() - pos.yPosition - imgHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
page.drawImage(img, {
|
|
||||||
x: xPos(imgUrlList[id]),
|
|
||||||
y: yPos(imgUrlList[id]),
|
|
||||||
width: imgWidth,
|
|
||||||
height: imgHeight
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const pdfBytes = await pdfDoc.saveAsBase64({
|
|
||||||
useObjectStreams: false
|
|
||||||
});
|
|
||||||
|
|
||||||
signPdfFun(pdfBytes, documentId, pngUrl);
|
signPdfFun(pdfBytes, documentId, pngUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useRef, useEffect } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
import { PDFDocument, rgb } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import "../css/./signature.css";
|
import "../css/./signature.css";
|
||||||
import sign from "../assests/sign3.png";
|
import sign from "../assests/sign3.png";
|
||||||
import stamp from "../assests/stamp2.png";
|
import stamp from "../assests/stamp2.png";
|
||||||
@@ -18,7 +18,10 @@ import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
|||||||
import {
|
import {
|
||||||
convertPNGtoJPEG,
|
convertPNGtoJPEG,
|
||||||
contractDocument,
|
contractDocument,
|
||||||
getBase64FromIMG
|
getBase64FromIMG,
|
||||||
|
embedDocId,
|
||||||
|
multiSignEmbed,
|
||||||
|
pdfNewWidthFun
|
||||||
} from "../utils/Utils";
|
} from "../utils/Utils";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import Tour from "reactour";
|
import Tour from "reactour";
|
||||||
@@ -30,7 +33,7 @@ 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, urlValidator } from "../utils/Utils";
|
||||||
import { modalAlign } from "../utils/Utils";
|
import { modalAlign } from "../utils/Utils";
|
||||||
import { $ } from "select-dom";
|
|
||||||
//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() {
|
||||||
const [pdfDetails, setPdfDetails] = useState([]);
|
const [pdfDetails, setPdfDetails] = useState([]);
|
||||||
@@ -79,7 +82,7 @@ function SignYourSelf() {
|
|||||||
status: false,
|
status: false,
|
||||||
type: "load"
|
type: "load"
|
||||||
});
|
});
|
||||||
|
const divRef = useRef(null);
|
||||||
const nodeRef = useRef(null);
|
const nodeRef = useRef(null);
|
||||||
const [{ isOver }, drop] = useDrop({
|
const [{ isOver }, drop] = useDrop({
|
||||||
accept: "BOX",
|
accept: "BOX",
|
||||||
@@ -166,17 +169,18 @@ function SignYourSelf() {
|
|||||||
const jsonSender = JSON.parse(senderUser);
|
const jsonSender = JSON.parse(senderUser);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const clientWidth = window.innerWidth;
|
|
||||||
const value = docId ? 80 : 80;
|
|
||||||
const pdfWidth = clientWidth - 160 - 200 - value;
|
|
||||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
|
||||||
//pdf from left and right component
|
|
||||||
setPdfNewWidth(pdfWidth);
|
|
||||||
if (documentId) {
|
if (documentId) {
|
||||||
getDocumentDetails(true);
|
getDocumentDetails(true);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (divRef.current) {
|
||||||
|
const pdfWidth = pdfNewWidthFun(divRef);
|
||||||
|
setPdfNewWidth(pdfWidth);
|
||||||
|
}
|
||||||
|
}, [divRef.current]);
|
||||||
|
|
||||||
//function for get document details for perticular signer with signer'object id
|
//function for get document details for perticular signer with signer'object id
|
||||||
const getDocumentDetails = async (showComplete) => {
|
const getDocumentDetails = async (showComplete) => {
|
||||||
//getting document details
|
//getting document details
|
||||||
@@ -186,18 +190,19 @@ function SignYourSelf() {
|
|||||||
setPdfDetails(documentData);
|
setPdfDetails(documentData);
|
||||||
const isCompleted =
|
const isCompleted =
|
||||||
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
||||||
if (isCompleted && showComplete) {
|
if (isCompleted) {
|
||||||
const docStatus = {
|
const docStatus = {
|
||||||
isCompleted: isCompleted
|
isCompleted: isCompleted
|
||||||
};
|
};
|
||||||
|
|
||||||
setDocumentStatus(docStatus);
|
setDocumentStatus(docStatus);
|
||||||
|
setPdfUrl(documentData[0].SignedUrl);
|
||||||
const alreadySign = {
|
const alreadySign = {
|
||||||
status: true,
|
status: true,
|
||||||
mssg: "You have successfully signed the document!"
|
mssg: "You have successfully signed the document!"
|
||||||
};
|
};
|
||||||
setShowAlreadySignDoc(alreadySign);
|
if (showComplete) {
|
||||||
setPdfUrl(documentData[0].SignedUrl);
|
setShowAlreadySignDoc(alreadySign);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
documentData === "Error: Something went wrong!" ||
|
documentData === "Error: Something went wrong!" ||
|
||||||
@@ -422,24 +427,7 @@ function SignYourSelf() {
|
|||||||
//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 (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
||||||
//embed document's object id to all pages in pdf document
|
//embed document's object id to all pages in pdf document
|
||||||
for (let i = 0; i < allPages; i++) {
|
await embedDocId(pdfDoc, documentId, allPages);
|
||||||
const font = await pdfDoc.embedFont("Helvetica");
|
|
||||||
|
|
||||||
const fontSize = 10;
|
|
||||||
const textContent =
|
|
||||||
documentId && `OpenSign™ DocumentId: ${documentId}`;
|
|
||||||
|
|
||||||
const pages = pdfDoc.getPages();
|
|
||||||
const page = pages[i];
|
|
||||||
|
|
||||||
page.drawText(textContent, {
|
|
||||||
x: 10,
|
|
||||||
y: page.getHeight() - 10,
|
|
||||||
size: fontSize,
|
|
||||||
font,
|
|
||||||
color: rgb(0.5, 0.5, 0.5)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const pdfBase64 = await pdfDoc.saveAsBase64({
|
const pdfBase64 = await pdfDoc.saveAsBase64({
|
||||||
useObjectStreams: false
|
useObjectStreams: false
|
||||||
});
|
});
|
||||||
@@ -475,85 +463,15 @@ function SignYourSelf() {
|
|||||||
}
|
}
|
||||||
//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 (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
||||||
for (let i = 0; i < allPages; i++) {
|
//embed document's object id to all pages in pdf document
|
||||||
const font = await pdfDoc.embedFont("Helvetica");
|
await embedDocId(pdfDoc, documentId, allPages);
|
||||||
|
//embed multi signature in pdf
|
||||||
const fontSize = 10;
|
const pdfBytes = await multiSignEmbed(
|
||||||
const textContent =
|
pngUrl,
|
||||||
documentId && `OpenSign™ DocumentId: ${documentId} `;
|
pdfDoc,
|
||||||
|
pdfOriginalWidth,
|
||||||
const pages = pdfDoc.getPages();
|
true
|
||||||
const page = pages[i];
|
);
|
||||||
|
|
||||||
page.drawText(textContent, {
|
|
||||||
x: 10,
|
|
||||||
y: page.getHeight() - 10,
|
|
||||||
size: fontSize,
|
|
||||||
font,
|
|
||||||
color: rgb(0.5, 0.5, 0.5)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (let i = 0; i < pngUrl.length; i++) {
|
|
||||||
const pageNo = pngUrl[i].pageNumber;
|
|
||||||
|
|
||||||
const imgUrlList = pngUrl[i].pos;
|
|
||||||
const pages = pdfDoc.getPages();
|
|
||||||
const page = pages[pageNo - 1];
|
|
||||||
|
|
||||||
const images = await Promise.all(
|
|
||||||
imgUrlList.map(async (url) => {
|
|
||||||
let signUrl = url.SignUrl;
|
|
||||||
|
|
||||||
if (url.ImageType === "image/png") {
|
|
||||||
//function for convert signature png base64 url to jpeg base64
|
|
||||||
const newUrl = await convertPNGtoJPEG(signUrl);
|
|
||||||
signUrl = newUrl;
|
|
||||||
}
|
|
||||||
const checkUrl = urlValidator(signUrl);
|
|
||||||
if (checkUrl) {
|
|
||||||
signUrl = signUrl + "?get";
|
|
||||||
}
|
|
||||||
const res = await fetch(signUrl);
|
|
||||||
|
|
||||||
return res.arrayBuffer();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
images.forEach(async (imgData, id) => {
|
|
||||||
let img = await pdfDoc.embedJpg(imgData);
|
|
||||||
const imgHeight = imgUrlList[id].Height
|
|
||||||
? imgUrlList[id].Height
|
|
||||||
: 60;
|
|
||||||
const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150;
|
|
||||||
const isMobile = window.innerWidth < 767;
|
|
||||||
const newWidth = window.innerWidth;
|
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
|
||||||
|
|
||||||
const posY = () => {
|
|
||||||
if (isMobile) {
|
|
||||||
if (id === 0) {
|
|
||||||
return (
|
|
||||||
page.getHeight() -
|
|
||||||
imgUrlList[id].yPosition * scale -
|
|
||||||
imgHeight
|
|
||||||
);
|
|
||||||
} else if (id > 0) {
|
|
||||||
return page.getHeight() - imgUrlList[id].yPosition * scale;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return page.getHeight() - imgUrlList[id].yPosition - imgHeight;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
page.drawImage(img, {
|
|
||||||
x: isMobile
|
|
||||||
? imgUrlList[id].xPosition * scale + imgWidth / 2
|
|
||||||
: imgUrlList[id].xPosition,
|
|
||||||
y: posY(),
|
|
||||||
width: imgWidth,
|
|
||||||
height: imgHeight
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
|
||||||
signPdfFun(pdfBytes, documentId);
|
signPdfFun(pdfBytes, documentId);
|
||||||
}
|
}
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
@@ -574,16 +492,16 @@ function SignYourSelf() {
|
|||||||
let singleSign;
|
let singleSign;
|
||||||
|
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const newWidth = window.innerWidth;
|
const newWidth = window.innerWidth - 32;
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||||
const imgWidth = xyPosData ? xyPosData.Width : 150;
|
const imgWidth = xyPosData ? xyPosData.Width : 150;
|
||||||
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
||||||
const height = xyPosData.Height ? xyPosData.Height : 60;
|
const height = xyPosData.Height ? xyPosData.Height : 60;
|
||||||
const bottomY = xyPosData.isDrag
|
const bottomY = xyPosData.isDrag
|
||||||
? xyPosData.yBottom * scale - height
|
? xyPosData.yBottom * scale - height * scale
|
||||||
: xyPosData.firstYPos
|
: xyPosData.firstYPos
|
||||||
? xyPosData.yBottom * scale - height + xyPosData.firstYPos
|
? xyPosData.yBottom * scale - height * scale + xyPosData.firstYPos
|
||||||
: xyPosData.yBottom * scale - height;
|
: xyPosData.yBottom * scale - height * scale;
|
||||||
|
|
||||||
singleSign = {
|
singleSign = {
|
||||||
pdfFile: pdfBase64Url,
|
pdfFile: pdfBase64Url,
|
||||||
@@ -591,11 +509,11 @@ function SignYourSelf() {
|
|||||||
sign: {
|
sign: {
|
||||||
Base64: base64Url,
|
Base64: base64Url,
|
||||||
Left: isMobile
|
Left: isMobile
|
||||||
? xyPosData.xPosition * scale + imgWidth / 2
|
? xyPosData.xPosition * scale + 43
|
||||||
: xyPosData.xPosition,
|
: xyPosData.xPosition,
|
||||||
Bottom: bottomY,
|
Bottom: bottomY,
|
||||||
Width: xyPosData.Width ? xyPosData.Width : 150,
|
Width: xyPosData.Width ? xyPosData.Width * scale : 150 * scale,
|
||||||
Height: height,
|
Height: height * scale,
|
||||||
Page: pageNo
|
Page: pageNo
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -959,7 +877,7 @@ function SignYourSelf() {
|
|||||||
) : noData ? (
|
) : noData ? (
|
||||||
<Nodata />
|
<Nodata />
|
||||||
) : (
|
) : (
|
||||||
<div className="signatureContainer">
|
<div className="signatureContainer" ref={divRef}>
|
||||||
{/* this component used for UI interaction and show their functionality */}
|
{/* this component used for UI interaction and show their functionality */}
|
||||||
{pdfLoadFail && !checkTourStatus && (
|
{pdfLoadFail && !checkTourStatus && (
|
||||||
<Tour
|
<Tour
|
||||||
|
|||||||
@@ -274,8 +274,7 @@ function EmailComponent({
|
|||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: "white",
|
color: "white",
|
||||||
fontSize: "13px",
|
fontSize: "13px"
|
||||||
marginTop: "2px"
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{data}
|
{data}
|
||||||
@@ -287,7 +286,8 @@ function EmailComponent({
|
|||||||
src={close}
|
src={close}
|
||||||
width={10}
|
width={10}
|
||||||
height={10}
|
height={10}
|
||||||
style={{ fontWeight: "600", margin: "0 0 10px 2px" }}
|
style={{ fontWeight: "600", marginLeft: "7px" }}
|
||||||
|
className="emailChipClose"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ import Nodata from "./component/Nodata";
|
|||||||
import SignerListPlace from "./component/signerListPlace";
|
import SignerListPlace from "./component/signerListPlace";
|
||||||
import Header from "./component/header";
|
import Header from "./component/header";
|
||||||
import {
|
import {
|
||||||
contactBook,
|
pdfNewWidthFun,
|
||||||
contractDocument,
|
contractDocument,
|
||||||
contractUsers,
|
contractUsers,
|
||||||
getHostUrl
|
getHostUrl
|
||||||
@@ -36,13 +36,10 @@ function PlaceHolderSign() {
|
|||||||
const [pageNumber, setPageNumber] = useState(1);
|
const [pageNumber, setPageNumber] = useState(1);
|
||||||
const [signBtnPosition, setSignBtnPosition] = useState([]);
|
const [signBtnPosition, setSignBtnPosition] = useState([]);
|
||||||
const [xySignature, setXYSignature] = useState({});
|
const [xySignature, setXYSignature] = useState({});
|
||||||
const signRef = useRef(null);
|
|
||||||
const dragRef = useRef(null);
|
|
||||||
const [dragKey, setDragKey] = useState();
|
const [dragKey, setDragKey] = useState();
|
||||||
const [signersdata, setSignersData] = useState();
|
const [signersdata, setSignersData] = useState();
|
||||||
const [signerObjId, setSignerObjId] = useState();
|
const [signerObjId, setSignerObjId] = useState();
|
||||||
const [signerPos, setSignerPos] = useState([]);
|
const [signerPos, setSignerPos] = useState([]);
|
||||||
|
|
||||||
const [isSelectListId, setIsSelectId] = useState();
|
const [isSelectListId, setIsSelectId] = useState();
|
||||||
const [isSendAlert, setIsSendAlert] = useState({});
|
const [isSendAlert, setIsSendAlert] = useState({});
|
||||||
const [isSend, setIsSend] = useState(false);
|
const [isSend, setIsSend] = useState(false);
|
||||||
@@ -61,6 +58,9 @@ function PlaceHolderSign() {
|
|||||||
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
||||||
const [contractName, setContractName] = useState("");
|
const [contractName, setContractName] = useState("");
|
||||||
const { docId } = useParams();
|
const { docId } = useParams();
|
||||||
|
const signRef = useRef(null);
|
||||||
|
const dragRef = useRef(null);
|
||||||
|
const divRef = useRef(null);
|
||||||
const [isShowEmail, setIsShowEmail] = useState(false);
|
const [isShowEmail, setIsShowEmail] = useState(false);
|
||||||
const [selectedEmail, setSelectedEmail] = useState(false);
|
const [selectedEmail, setSelectedEmail] = useState(false);
|
||||||
const [pdfLoadFail, setPdfLoadFail] = useState({
|
const [pdfLoadFail, setPdfLoadFail] = useState({
|
||||||
@@ -161,17 +161,17 @@ function PlaceHolderSign() {
|
|||||||
const jsonSender = JSON.parse(senderUser);
|
const jsonSender = JSON.parse(senderUser);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const clientWidth = window.innerWidth;
|
|
||||||
const value = docId ? 80 : 30;
|
|
||||||
const pdfWidth = clientWidth - 160 - 200 - value;
|
|
||||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
|
||||||
//pdf from left and right component
|
|
||||||
setPdfNewWidth(pdfWidth);
|
|
||||||
if (documentId) {
|
if (documentId) {
|
||||||
getDocumentDetails();
|
getDocumentDetails();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (divRef.current) {
|
||||||
|
const pdfWidth = pdfNewWidthFun(divRef);
|
||||||
|
setPdfNewWidth(pdfWidth);
|
||||||
|
}
|
||||||
|
}, [divRef.current]);
|
||||||
//function for get document details
|
//function for get document details
|
||||||
const getDocumentDetails = async () => {
|
const getDocumentDetails = async () => {
|
||||||
//getting document details
|
//getting document details
|
||||||
@@ -833,7 +833,7 @@ function PlaceHolderSign() {
|
|||||||
) : noData ? (
|
) : noData ? (
|
||||||
<Nodata />
|
<Nodata />
|
||||||
) : (
|
) : (
|
||||||
<div className="signatureContainer">
|
<div className="signatureContainer" ref={divRef}>
|
||||||
{/* this component used for UI interaction and show their functionality */}
|
{/* this component used for UI interaction and show their functionality */}
|
||||||
{!checkTourStatus && (
|
{!checkTourStatus && (
|
||||||
//this tour component used in your html component where you want to put
|
//this tour component used in your html component where you want to put
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useRef, useEffect } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
import { PDFDocument, rgb } 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 Modal from "react-bootstrap/Modal";
|
import Modal from "react-bootstrap/Modal";
|
||||||
@@ -14,12 +14,14 @@ import DefaultSignature from "./component/defaultSignature";
|
|||||||
import {
|
import {
|
||||||
getBase64FromUrl,
|
getBase64FromUrl,
|
||||||
getBase64FromIMG,
|
getBase64FromIMG,
|
||||||
contactBookName,
|
pdfNewWidthFun,
|
||||||
convertPNGtoJPEG,
|
convertPNGtoJPEG,
|
||||||
contractUsers,
|
contractUsers,
|
||||||
contactBook,
|
contactBook,
|
||||||
contractDocument,
|
contractDocument,
|
||||||
urlValidator
|
urlValidator,
|
||||||
|
multiSignEmbed,
|
||||||
|
embedDocId
|
||||||
} from "../utils/Utils";
|
} from "../utils/Utils";
|
||||||
import Tour from "reactour";
|
import Tour from "reactour";
|
||||||
import Signedby from "./component/signedby";
|
import Signedby from "./component/signedby";
|
||||||
@@ -92,15 +94,12 @@ function EmbedPdfImage() {
|
|||||||
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
|
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
|
||||||
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const clientWidth = window.innerWidth;
|
|
||||||
const pdfWidth = clientWidth - 160 - 220 - 30;
|
|
||||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
|
||||||
//pdf from left and right component
|
|
||||||
setPdfNewWidth(pdfWidth);
|
|
||||||
getDocumentDetails();
|
getDocumentDetails();
|
||||||
}, []);
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (divRef.current) {
|
if (divRef.current) {
|
||||||
|
const pdfWidth = pdfNewWidthFun(divRef);
|
||||||
|
setPdfNewWidth(pdfWidth);
|
||||||
setContainerWH({
|
setContainerWH({
|
||||||
width: divRef.current.offsetWidth,
|
width: divRef.current.offsetWidth,
|
||||||
height: divRef.current.offsetHeight
|
height: divRef.current.offsetHeight
|
||||||
@@ -424,23 +423,8 @@ function EmbedPdfImage() {
|
|||||||
if (isDocId) {
|
if (isDocId) {
|
||||||
pdfBase64 = await getBase64FromUrl(url);
|
pdfBase64 = await getBase64FromUrl(url);
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < allPages; i++) {
|
//embed document's object id to all pages in pdf document
|
||||||
const font = await pdfDoc.embedFont("Helvetica");
|
await embedDocId(pdfDoc, docId, allPages);
|
||||||
|
|
||||||
const fontSize = 10;
|
|
||||||
const textContent = docId && `OpenSign™ DocumentId: ${docId} `;
|
|
||||||
|
|
||||||
const pages = pdfDoc.getPages();
|
|
||||||
const page = pages[i];
|
|
||||||
|
|
||||||
page.drawText(textContent, {
|
|
||||||
x: 10,
|
|
||||||
y: page.getHeight() - 10,
|
|
||||||
size: fontSize,
|
|
||||||
font,
|
|
||||||
color: rgb(0.5, 0.5, 0.5)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
pdfBase64 = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
pdfBase64 = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||||
}
|
}
|
||||||
for (let i = 0; i < xyPostion.length; i++) {
|
for (let i = 0; i < xyPostion.length; i++) {
|
||||||
@@ -475,115 +459,18 @@ function EmbedPdfImage() {
|
|||||||
}
|
}
|
||||||
//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 (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
||||||
for (let i = 0; i < allPages; i++) {
|
//embed document's object id to all pages in pdf document
|
||||||
const font = await pdfDoc.embedFont("Helvetica");
|
await embedDocId(pdfDoc, docId, allPages);
|
||||||
|
//embed multi signature in pdf
|
||||||
const fontSize = 10;
|
const pdfBytes = await multiSignEmbed(
|
||||||
const textContent = docId && `OpenSign™ DocumentId: ${docId} `;
|
pngUrl,
|
||||||
|
pdfDoc,
|
||||||
const pages = pdfDoc.getPages();
|
pdfOriginalWidth,
|
||||||
const page = pages[i];
|
false
|
||||||
|
);
|
||||||
page.drawText(textContent, {
|
|
||||||
x: 10,
|
|
||||||
y: page.getHeight() - 10,
|
|
||||||
size: fontSize,
|
|
||||||
font,
|
|
||||||
color: rgb(0.5, 0.5, 0.5)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (let i = 0; i < pngUrl.length; i++) {
|
|
||||||
const pageNo = pngUrl[i].pageNumber;
|
|
||||||
|
|
||||||
const imgUrlList = pngUrl[i].pos;
|
|
||||||
const pages = pdfDoc.getPages();
|
|
||||||
const page = pages[pageNo - 1];
|
|
||||||
|
|
||||||
const images = await Promise.all(
|
|
||||||
imgUrlList.map(async (url) => {
|
|
||||||
let signUrl = url.SignUrl;
|
|
||||||
if (url.ImageType === "image/png") {
|
|
||||||
//function for convert signature png base64 url to jpeg base64
|
|
||||||
const newUrl = await convertPNGtoJPEG(signUrl);
|
|
||||||
signUrl = newUrl;
|
|
||||||
}
|
|
||||||
const checkUrl = urlValidator(signUrl);
|
|
||||||
if (checkUrl) {
|
|
||||||
signUrl = signUrl + "?get";
|
|
||||||
}
|
|
||||||
const res = await fetch(signUrl);
|
|
||||||
|
|
||||||
return res.arrayBuffer();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
images.forEach(async (imgData, id) => {
|
|
||||||
let img = await pdfDoc.embedJpg(imgData);
|
|
||||||
|
|
||||||
const imgHeight = imgUrlList[id].Height
|
|
||||||
? imgUrlList[id].Height
|
|
||||||
: 60;
|
|
||||||
const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150;
|
|
||||||
const isMobile = window.innerWidth < 767;
|
|
||||||
const newWidth = window.innerWidth;
|
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
|
||||||
const xPos = (pos) => {
|
|
||||||
//checking both condition mobile and desktop view
|
|
||||||
if (isMobile) {
|
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const x = pos.xPosition * (pos.scale / scale);
|
|
||||||
return x * scale + 50;
|
|
||||||
} else {
|
|
||||||
const x = pos.xPosition / 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
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const x = pos.xPosition * pos.scale + 50;
|
|
||||||
return x;
|
|
||||||
} else {
|
|
||||||
return pos.xPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const yPos = (pos) => {
|
|
||||||
//checking both condition mobile and desktop view
|
|
||||||
|
|
||||||
if (isMobile) {
|
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const y = pos.yPosition * (pos.scale / scale);
|
|
||||||
return page.getHeight() - y * scale - imgHeight;
|
|
||||||
} else {
|
|
||||||
const y = pos.yPosition / scale;
|
|
||||||
return page.getHeight() - y * scale - imgHeight;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
|
||||||
if (pos.isMobile) {
|
|
||||||
const y = pos.yPosition * pos.scale;
|
|
||||||
return page.getHeight() - y - imgHeight;
|
|
||||||
} else {
|
|
||||||
return page.getHeight() - pos.yPosition - imgHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
page.drawImage(img, {
|
|
||||||
x: xPos(imgUrlList[id]),
|
|
||||||
y: yPos(imgUrlList[id]),
|
|
||||||
width: imgWidth,
|
|
||||||
height: imgHeight
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
|
||||||
signPdfFun(pdfBytes, docId);
|
signPdfFun(pdfBytes, docId);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
|
|
||||||
setXyPostion([]);
|
setXyPostion([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1048,7 +935,7 @@ function EmbedPdfImage() {
|
|||||||
{/* pdf header which contain finish back button */}
|
{/* pdf header which contain finish back button */}
|
||||||
<Header
|
<Header
|
||||||
recipient={true}
|
recipient={true}
|
||||||
pdfDetails={completePdfData}
|
pdfDetails={signedPdfData}
|
||||||
isAlreadySign={isAlreadySign}
|
isAlreadySign={isAlreadySign}
|
||||||
pageNumber={pageNumber}
|
pageNumber={pageNumber}
|
||||||
allPages={allPages}
|
allPages={allPages}
|
||||||
|
|||||||
@@ -80,6 +80,10 @@
|
|||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emailChipClose:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.addEmailInput {
|
.addEmailInput {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -639,6 +643,7 @@ option {
|
|||||||
|
|
||||||
.stickyfooter {
|
.stickyfooter {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
z-index: 32 !important;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
right: 0rem;
|
right: 0rem;
|
||||||
}
|
}
|
||||||
@@ -785,4 +790,4 @@ option {
|
|||||||
|
|
||||||
.signature-backdrop.fade.in {
|
.signature-backdrop.fade.in {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { $ } from 'select-dom';
|
import { $ } from "select-dom";
|
||||||
|
import { rgb } from "pdf-lib";
|
||||||
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();
|
||||||
@@ -327,18 +327,162 @@ export const contactBook = async (objectId) => {
|
|||||||
export function urlValidator(url) {
|
export function urlValidator(url) {
|
||||||
try {
|
try {
|
||||||
const newUrl = new URL(url);
|
const newUrl = new URL(url);
|
||||||
return newUrl.protocol === 'http:' || newUrl.protocol === 'https:';
|
return newUrl.protocol === "http:" || newUrl.protocol === "https:";
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export function modalAlign() {
|
export function modalAlign() {
|
||||||
let modalDialog = $('.modal-dialog').getBoundingClientRect();
|
let modalDialog = $(".modal-dialog").getBoundingClientRect();
|
||||||
let mobileHead = $('.mobileHead').getBoundingClientRect()
|
let mobileHead = $(".mobileHead").getBoundingClientRect();
|
||||||
let modal = $('.modal-dialog');
|
let modal = $(".modal-dialog");
|
||||||
if (modalDialog.left < mobileHead.left) {
|
if (modalDialog.left < mobileHead.left) {
|
||||||
let leftOffset = mobileHead.left - modalDialog.left;
|
let leftOffset = mobileHead.left - modalDialog.left;
|
||||||
modal.style.left = leftOffset + 'px';
|
modal.style.left = leftOffset + "px";
|
||||||
modal.style.top = (window.innerHeight/3) + 'px';
|
modal.style.top = window.innerHeight / 3 + "px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//function for embed multiple signature using pdf-lib
|
||||||
|
export const multiSignEmbed = async (
|
||||||
|
pngUrl,
|
||||||
|
pdfDoc,
|
||||||
|
pdfOriginalWidth,
|
||||||
|
signyourself
|
||||||
|
) => {
|
||||||
|
for (let i = 0; i < pngUrl.length; i++) {
|
||||||
|
const pageNo = pngUrl[i].pageNumber;
|
||||||
|
const imgUrlList = pngUrl[i].pos;
|
||||||
|
const pages = pdfDoc.getPages();
|
||||||
|
const page = pages[pageNo - 1];
|
||||||
|
const images = await Promise.all(
|
||||||
|
imgUrlList.map(async (url) => {
|
||||||
|
let signUrl = url.SignUrl;
|
||||||
|
if (url.ImageType === "image/png") {
|
||||||
|
//function for convert signature png base64 url to jpeg base64
|
||||||
|
const newUrl = await convertPNGtoJPEG(signUrl);
|
||||||
|
signUrl = newUrl;
|
||||||
|
}
|
||||||
|
const checkUrl = urlValidator(signUrl);
|
||||||
|
if (checkUrl) {
|
||||||
|
signUrl = signUrl + "?get";
|
||||||
|
}
|
||||||
|
const res = await fetch(signUrl);
|
||||||
|
return res.arrayBuffer();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
images.forEach(async (imgData, id) => {
|
||||||
|
let img;
|
||||||
|
if (
|
||||||
|
(imgUrlList[id].ImageType &&
|
||||||
|
imgUrlList[id].ImageType === "image/png") ||
|
||||||
|
imgUrlList[id].ImageType === "image/jpeg"
|
||||||
|
) {
|
||||||
|
img = await pdfDoc.embedJpg(imgData);
|
||||||
|
} else {
|
||||||
|
img = await pdfDoc.embedPng(imgData);
|
||||||
|
}
|
||||||
|
const imgHeight = imgUrlList[id].Height ? imgUrlList[id].Height : 60;
|
||||||
|
const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150;
|
||||||
|
const isMobile = window.innerWidth < 767;
|
||||||
|
const newWidth = window.innerWidth - 32;
|
||||||
|
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||||
|
const xPos = (pos) => {
|
||||||
|
if (signyourself) {
|
||||||
|
if (isMobile) {
|
||||||
|
return imgUrlList[id].xPosition * scale + 43;
|
||||||
|
} else {
|
||||||
|
return imgUrlList[id].xPosition;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//checking both condition mobile and desktop view
|
||||||
|
if (isMobile) {
|
||||||
|
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||||
|
if (pos.isMobile) {
|
||||||
|
const x = pos.xPosition * (pos.scale / scale);
|
||||||
|
return x * scale + 50;
|
||||||
|
} else {
|
||||||
|
const x = pos.xPosition / 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
|
||||||
|
if (pos.isMobile) {
|
||||||
|
const x = pos.xPosition * pos.scale + 50;
|
||||||
|
return x;
|
||||||
|
} else {
|
||||||
|
return pos.xPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const yPos = (pos) => {
|
||||||
|
if (signyourself) {
|
||||||
|
if (isMobile) {
|
||||||
|
return (
|
||||||
|
page.getHeight() -
|
||||||
|
imgUrlList[id].yPosition * scale -
|
||||||
|
imgHeight * scale
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return page.getHeight() - imgUrlList[id].yPosition - imgHeight;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//checking both condition mobile and desktop view
|
||||||
|
const y = pos.yPosition / scale;
|
||||||
|
if (isMobile) {
|
||||||
|
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||||
|
if (pos.isMobile) {
|
||||||
|
const y = pos.yPosition * (pos.scale / scale);
|
||||||
|
return page.getHeight() - y * scale - imgHeight;
|
||||||
|
} else {
|
||||||
|
return page.getHeight() - y * scale - imgHeight;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||||
|
if (pos.isMobile) {
|
||||||
|
const y = pos.yPosition * pos.scale;
|
||||||
|
return page.getHeight() - y - imgHeight;
|
||||||
|
} else {
|
||||||
|
return page.getHeight() - pos.yPosition - imgHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
page.drawImage(img, {
|
||||||
|
x: xPos(imgUrlList[id]),
|
||||||
|
y: yPos(imgUrlList[id]),
|
||||||
|
width: signyourself ? imgWidth * scale : imgWidth,
|
||||||
|
height: signyourself ? imgHeight * scale : imgHeight
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||||
|
return pdfBytes;
|
||||||
|
};
|
||||||
|
//function for embed document id
|
||||||
|
export const embedDocId = async (pdfDoc, documentId, allPages) => {
|
||||||
|
for (let i = 0; i < allPages; i++) {
|
||||||
|
const font = await pdfDoc.embedFont("Helvetica");
|
||||||
|
const fontSize = 10;
|
||||||
|
const textContent = documentId && `OpenSign™ DocumentId: ${documentId} `;
|
||||||
|
const pages = pdfDoc.getPages();
|
||||||
|
const page = pages[i];
|
||||||
|
page.drawText(textContent, {
|
||||||
|
x: 10,
|
||||||
|
y: page.getHeight() - 10,
|
||||||
|
size: fontSize,
|
||||||
|
font,
|
||||||
|
color: rgb(0.5, 0.5, 0.5)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const pdfNewWidthFun = (divRef) => {
|
||||||
|
const clientWidth = divRef.current.offsetWidth;
|
||||||
|
const pdfWidth = clientWidth - 160 - 200;
|
||||||
|
//160 is width of left side, 200 is width of right side component
|
||||||
|
return pdfWidth;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user