mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-05 01:07:39 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
375dc86f0a | ||
|
|
d2f187f6c0 | ||
|
|
5393ee9ba9 | ||
|
|
d4d2948455 | ||
|
|
37617c04ad | ||
|
|
10e0153018 | ||
|
|
42cbe94af8 | ||
|
|
8f95e53d9d | ||
|
|
0dae21dcf1 | ||
|
|
912efeb5fd | ||
|
|
3d9307f96d | ||
|
|
873f4b080a | ||
|
|
e337a79e2e | ||
|
|
980ce62bf6 | ||
|
|
dccf757f56 | ||
|
|
4a6b88328e | ||
|
|
779a84cf0b | ||
|
|
aff409ba63 | ||
|
|
275167c0c4 | ||
|
|
19b2af7f57 | ||
|
|
5050b9ee97 | ||
|
|
23da4be6b1 | ||
|
|
299648b8e0 | ||
|
|
86fa0c87ae | ||
|
|
9619eec40f | ||
|
|
886161d65f | ||
|
|
d5d646e6e0 | ||
|
|
494103163c | ||
|
|
72e9e4848b | ||
|
|
1181ba6f90 | ||
|
|
b8d6ec5fe0 | ||
|
|
7335d7df0a | ||
|
|
44754095fb | ||
|
|
0f515bae01 | ||
|
|
76a11f6ee6 | ||
|
|
5fb28feb65 | ||
|
|
e5f1524b10 | ||
|
|
8a875691fb | ||
|
|
0b2710b97d | ||
|
|
57552a32b0 | ||
|
|
572ec3658e | ||
|
|
6d5c791f61 | ||
|
|
168e479c0c | ||
|
|
927e1b7ef9 | ||
|
|
76dccf804e | ||
|
|
4262e0e6eb | ||
|
|
7d487420aa | ||
|
|
c20611b50b | ||
|
|
15d73ee62d | ||
|
|
a334cda9aa | ||
|
|
69d4254b44 | ||
|
|
c422b11e3a | ||
|
|
95d2794754 | ||
|
|
65ce0d430c | ||
|
|
e7a98d55f0 | ||
|
|
d247c6d0e7 | ||
|
|
20e0277113 | ||
|
|
2ed3609c46 | ||
|
|
2e41dc20c1 | ||
|
|
50a8f93014 | ||
|
|
3803b29835 | ||
|
|
e18586887e | ||
|
|
d137c081ee | ||
|
|
62dfe32d32 | ||
|
|
f801192a8c | ||
|
|
13d161e3c8 | ||
|
|
a249baea66 | ||
|
|
f6f5b08d43 | ||
|
|
a1f4e9ea74 | ||
|
|
5eed145f4b | ||
|
|
546a0f8e87 | ||
|
|
975c4b079a | ||
|
|
09e0ac2415 | ||
|
|
6140aea31a | ||
|
|
c59c921a8b | ||
|
|
4b1e13d39a | ||
|
|
e33e0be735 | ||
|
|
2ff4e372d6 | ||
|
|
9cfffe3fbd | ||
|
|
82ef278a0e | ||
|
|
574d2d05a4 | ||
|
|
38f72c7415 | ||
|
|
e00704a43c | ||
|
|
778e28fae0 | ||
|
|
1574f86654 | ||
|
|
df17bdcd68 | ||
|
|
f290fd875f | ||
|
|
caeb055fc2 | ||
|
|
1eafc113e6 | ||
|
|
4e46795e0f | ||
|
|
f7087dfb29 | ||
|
|
e6a7cda3b6 | ||
|
|
db120ecda7 | ||
|
|
9bfe8b0e26 | ||
|
|
c1438be9e0 | ||
|
|
f4d7e33f97 | ||
|
|
4ec7fdb078 | ||
|
|
3413d0914d | ||
|
|
793b6a5550 | ||
|
|
77894f6754 | ||
|
|
812928a6a3 | ||
|
|
bb398d13a2 | ||
|
|
2d7a893424 | ||
|
|
62e943161a | ||
|
|
2604156c7f | ||
|
|
1e04bb4dbe | ||
|
|
0ac3a70a83 | ||
|
|
2f1ad45f92 | ||
|
|
8263e3247e | ||
|
|
9666e41880 | ||
|
|
e50f062a91 | ||
|
|
1c8f401060 | ||
|
|
a8e764a62c | ||
|
|
43bc1f3e17 | ||
|
|
eebed949cd | ||
|
|
c7cd9e56f8 | ||
|
|
1c9fb5ebcb | ||
|
|
1339259c3b | ||
|
|
27a069e1a2 | ||
|
|
7a69537255 | ||
|
|
9569b78e66 | ||
|
|
266b0f27f5 | ||
|
|
00e5c48828 | ||
|
|
c9e010e993 | ||
|
|
5b52825ea6 | ||
|
|
100b97cf1a | ||
|
|
7a3216a81c | ||
|
|
c6412be70d | ||
|
|
954dbb3375 | ||
|
|
c996825665 | ||
|
|
5fc1a58bdb | ||
|
|
5c947181a2 | ||
|
|
2e8b2fa525 | ||
|
|
1e6e5f9dba | ||
|
|
fa2e169df4 | ||
|
|
174023c62f | ||
|
|
1198460c97 | ||
|
|
07954c8bb6 | ||
|
|
d4d9521c31 | ||
|
|
d77477f3d1 | ||
|
|
ff36faa96c | ||
|
|
450de195a7 | ||
|
|
57b23d7f97 | ||
|
|
a246f74e11 | ||
|
|
89c687ed06 | ||
|
|
f7e2fa8aec | ||
|
|
8a2960511c | ||
|
|
832e5c2181 | ||
|
|
00d900c2b2 | ||
|
|
47ef685bcc | ||
|
|
9f4aff65f2 | ||
|
|
2eddb49b8e | ||
|
|
63f1bb9fc7 | ||
|
|
e73b055cc2 | ||
|
|
abd7cf9b71 | ||
|
|
2dbd41ce65 | ||
|
|
25ef7c9f39 | ||
|
|
81a4daa5e8 | ||
|
|
3f9e6d1f81 | ||
|
|
1507f113f4 | ||
|
|
d46ba8f307 | ||
|
|
2426e7484c | ||
|
|
17b9fc772e | ||
|
|
7b2b71fea5 | ||
|
|
70a3adebd7 | ||
|
|
9e012ef6c7 | ||
|
|
948e0d3270 | ||
|
|
6e4f9ba0e9 | ||
|
|
a816ceb04b | ||
|
|
f864f74f14 | ||
|
|
2c715a77a2 | ||
|
|
9b4cdde80a | ||
|
|
de2154e6fe | ||
|
|
76f4ccfcf3 | ||
|
|
af52bb30f5 |
+1
-1
@@ -20,7 +20,7 @@ appName=open_sign_server
|
|||||||
# 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.
|
# 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
|
MASTER_KEY=XnAadwKxxByMr
|
||||||
# Mongodb URI to connect to
|
# Mongodb URI to connect to
|
||||||
MONGODB_URI=mongodb://mongo:27017/OpenSignDB
|
MONGODB_URI=mongodb://mongo-container:27017/OpenSignDB
|
||||||
# Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions.
|
# Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions.
|
||||||
PARSE_MOUNT=/app
|
PARSE_MOUNT=/app
|
||||||
# Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead)
|
# Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'main'
|
- 'staging'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@@ -10,9 +10,9 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- image: amolshejole/OpenSign
|
- image: opensign/opensign
|
||||||
dockerfile: apps/OpenSign/Dockerhubfile
|
dockerfile: apps/OpenSign/Dockerhubfile
|
||||||
- image: amolshejole/OpenSignServer
|
- image: opensign/opensignserver
|
||||||
dockerfile: apps/OpenSignServer/Dockerhubfile
|
dockerfile: apps/OpenSignServer/Dockerhubfile
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
|
|
||||||
<a href="https://www.opensignlabs.com/">Website</a>
|
<a href="https://www.opensignlabs.com/">Website</a>
|
||||||
<span> • </span>
|
<span> • </span>
|
||||||
<a href="https://www.opensignlabs.com">Docs</a>
|
<a href="https://docs.opensignlabs.com">Help Docs</a>
|
||||||
|
<span> • </span>
|
||||||
|
<a href="https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1">API Docs</a>
|
||||||
<span> • </span>
|
<span> • </span>
|
||||||
<a href="https://www.opensignlabs.com/blog">Blog</a>
|
<a href="https://www.opensignlabs.com/blog">Blog</a>
|
||||||
<span> • </span>
|
<span> • </span>
|
||||||
@@ -22,7 +24,7 @@
|
|||||||
<a href="https://www.linkedin.com/company/opensign%E2%84%A2/about/">LinkedIn</a>
|
<a href="https://www.linkedin.com/company/opensign%E2%84%A2/about/">LinkedIn</a>
|
||||||
|
|
||||||
|
|
||||||
## The open-source document e-signing solution
|
## The premier open source document signing solution(DocuSign alternative)
|
||||||
|
|
||||||
---
|
---
|
||||||
</div>
|
</div>
|
||||||
@@ -42,29 +44,32 @@ Please star ⭐ the repo to support us! 😀
|
|||||||
|
|
||||||
### Introduction
|
### Introduction
|
||||||
|
|
||||||
Welcome to OpenSign, the premier open source docusign alternative - document e-signing solution designed to provide a secure, reliable and free alternative to commercial esign platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Our mission is to democratize the e-signing process, making it accessible and straightforward for everyone.
|
Welcome to OpenSign, the premier open source docusign alternative - document e-signing solution designed to provide a secure, reliable and free alternative to commercial esign platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Our mission is to democratize the document signing process, making it accessible and straightforward for everyone.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- **Secure PDF E-Signing:** With the help of robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility.
|
- **Secure PDF E-Signing:** With the help of robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility. Now sign unlimited documents even on the [cloud hosted free version of OpenSign](https://www.opensignlabs.com/).
|
||||||
- **Annotate Documents:** OpenSign™ allows you to annotate PDF documents with an advanced signing pad that allows hand drawn signatures, uploaded images, typed signatures & saved signatures for the simplest signing experience ever.
|
- **Annotate Documents:** OpenSign™ allows you to annotate PDF documents with an advanced signing pad that allows hand drawn signatures, uploaded images, typed signatures & saved signatures for the simplest open source document signing experience ever.
|
||||||
- **User-Friendly Interface:** OpenSign™ was built while keeping Intuitive design in mind for ease of use. Features like "Sign yourself", "Templates", "One click signatures" and "OpenSign™ Drive" makes it stand out of the crowd and even makes it better than a lot of so-called industry leaders.
|
- **User-Friendly Interface:** OpenSign™ was built while keeping Intuitive design in mind for ease of use. Features like "Sign yourself", "Templates", "One click signatures" and "OpenSign™ Drive" makes it stand out of the crowd and even makes it better than a lot of so-called industry leaders. OpenSign intends to provide the best document signing experience in the open source ecosystem.
|
||||||
- **Multi-signer Support:** OpenSign's ability to invite multiple signers for signing along with the ability to invite witnesses & being able to enforce signing in a sequence makes it the only open source solution that is fully loaded and allows it to compete head-to-head with established players in e-signature space.
|
- **Multi-signer Support:** OpenSign's ability to invite multiple signers for signing along with the ability to invite by sharing signing links & being able to enforce signing in a sequence makes it the only open source solution that is fully loaded and allows it to compete head-to-head with established players in e-signature space.
|
||||||
- **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address.
|
- **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address.
|
||||||
- **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign. Not just this, OpenSign™ also allows signers to reject signing a document.
|
- **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign. Not just this, OpenSign™ also allows signers to reject signing a document with a reason that will be promptly shared with the sender.
|
||||||
- **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates.
|
- **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates. Not just this, you are even allowed to customise the email templates making your free document signing invitations look the way you always wanted them to be.
|
||||||
- **PDF Template Creation:** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time & collect e-signatures seamlessly.
|
- **PDF Template Creation:** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time & collect e-signatures seamlessly.
|
||||||
- **OpenSign™ Drive:** It is a centralised secure vault for your digital documents that makes storing, signing, organizing, sharing & achieving your docs a breeze.
|
- **OpenSign™ Drive:** It is a centralised secure vault for your digital documents that makes storing, signing, organizing, sharing & archieving your docs a breeze.
|
||||||
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
|
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
|
||||||
- **API Support:** OpenSign™ API allows seamless integration into existing systems and software. You can generate an API key from the app and refer the [docs](https://docs.opensignlabs.com) to start integrating it in your existing applications.
|
- **API Support:** OpenSign™ API allows seamless integration into existing systems and software. You can generate an API key from the app and refer the [official API docs](https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1) to start integrating it in your existing applications.
|
||||||
- **Integrations:** Seamless integrations with various Cloud storage systems, CRMs & enterprise platforms is available. We also have a Zapier integration that allows you to integrate it with virtually any application.
|
- **Integrations:** The open source document signing experience becomes even more seamless because of integrations with various Cloud storage systems, CRMs & enterprise platforms. We also have a Zapier integration that allows you to integrate it with virtually any application.
|
||||||
|
<img alt="Login page" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/8016edb6-7d6e-4185-ab72-82d2c4a16032" height='200' >
|
||||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
|
<img alt="Dash_board" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/6e7b96f7-3154-4c25-bc1e-caf33925cc47" height='200'>
|
||||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
<img alt="Widgets" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/7edb65bd-c265-4b3d-9758-38e79766c5c2" height='200'>
|
||||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/56835efd-c40e-42de-a206-20202c293876 height='200'>
|
<img alt="Request Signature" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/1697ae46-dcac-41c9-a081-aded25693846" height='200'>
|
||||||
|
<img alt="Create template" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/c2060fda-50f1-4116-a532-51b94b48463a" height='200'>
|
||||||
|
<img alt="Manage_Template" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/90310c74-8271-49bd-8c5f-89daa5a623c4" height='200'>
|
||||||
|
<img alt="Folders" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/a52207e7-3b0e-497c-b5f6-747bc4e67918" height='200'>
|
||||||
|
<img alt="OpenSign_Confetti" src="https://github.com/OpenSignLabs/OpenSign/assets/171803164/8f4c6a6e-4a73-439c-9f34-f426044d0a7f" height='200'>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -88,13 +93,13 @@ We welcome contributions from the open-source community. For more information on
|
|||||||
|
|
||||||
### License
|
### License
|
||||||
|
|
||||||
OpenSign is licensed under the AGPL License. For more details, see the [LICENSE](LICENSE) file.
|
OpenSign is licensed under the AGPL-3 License. For more details, see the [LICENSE](LICENSE) file.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Acknowledgments
|
### Acknowledgments
|
||||||
|
|
||||||
We would like to thank all our contributors and users for their support and feedback. Special thanks to [OpenSignLabs](https://github.com/OpenSignLabs) for spearheading this initiative.
|
We would like to thank all our contributors and users for their support and feedback. Special thanks to [OpenSignLabs](https://www.opensignlabs.com) for spearheading this initiative.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1 @@
|
|||||||
The community is working hard to put together a great usage guide.
|
Please visit the official documentation [here](https://docs.opensignlabs.com).
|
||||||
You will soon see one of the best usage guides here.
|
|
||||||
|
|
||||||
Till then you can view the quick promo video by clicking the link below -
|
|
||||||
|
|
||||||
[<img src="https://i.ytimg.com/vi/szYaBZhXZNo/maxresdefault.jpg" width="50%">](https://www.youtube.com/watch?v=szYaBZhXZNo "OpenSign promo")
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"presets": ["@babel/preset-env", "@babel/preset-react"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: ["@babel/preset-env", "@babel/preset-react"]
|
||||||
|
};
|
||||||
Generated
+3220
-2137
File diff suppressed because it is too large
Load Diff
+37
-23
@@ -4,24 +4,24 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^0.8.2",
|
"@formkit/auto-animate": "^0.8.2",
|
||||||
"@lottiefiles/dotlottie-react": "^0.6.4",
|
"@lottiefiles/dotlottie-react": "^0.8.5",
|
||||||
"@radix-ui/themes": "^3.0.5",
|
"@radix-ui/themes": "^3.1.1",
|
||||||
"@react-pdf/renderer": "^3.4.4",
|
"@react-pdf/renderer": "^3.4.4",
|
||||||
"@reduxjs/toolkit": "^2.2.5",
|
"@reduxjs/toolkit": "^2.2.7",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"nth-check": "^2.1.1",
|
"nth-check": "^2.1.1",
|
||||||
"parse": "^5.1.0",
|
"parse": "^5.3.0",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"radix-ui": "^1.0.1",
|
"radix-ui": "^1.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.10.2",
|
"react-bootstrap": "^2.10.4",
|
||||||
"react-confetti": "^6.1.0",
|
"react-confetti": "^6.1.0",
|
||||||
"react-cookie": "^7.1.4",
|
"react-cookie": "^7.2.0",
|
||||||
"react-datepicker": "^6.9.0",
|
"react-datepicker": "^7.3.0",
|
||||||
"react-dnd": "^16.0.1",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dnd-multi-backend": "^8.0.3",
|
"react-dnd-multi-backend": "^8.0.3",
|
||||||
@@ -30,33 +30,35 @@
|
|||||||
"react-gtm-module": "^2.0.11",
|
"react-gtm-module": "^2.0.11",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-konva": "^18.2.10",
|
"react-konva": "^18.2.10",
|
||||||
"react-pdf": "^9.0.0",
|
"react-pdf": "^9.1.0",
|
||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-redux": "^9.1.2",
|
"react-redux": "^9.1.2",
|
||||||
"react-rnd": "^10.4.11",
|
"react-rnd": "^10.4.11",
|
||||||
"react-router-dom": "^6.22.3",
|
"react-router-dom": "^6.25.1",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-scrollbars-custom": "^4.1.1",
|
"react-scrollbars-custom": "^4.1.1",
|
||||||
"react-select": "^5.8.0",
|
"react-select": "^5.8.0",
|
||||||
"react-signature-canvas": "^1.0.6",
|
"react-signature-canvas": "^1.0.6",
|
||||||
"react-tooltip": "^5.26.4",
|
"react-tooltip": "^5.27.1",
|
||||||
"react-web-share": "^2.0.2",
|
"react-web-share": "^2.0.2",
|
||||||
"reactour": "^1.19.4",
|
"reactour": "^1.19.4",
|
||||||
"redux": "^5.0.1",
|
"redux": "^5.0.1",
|
||||||
"redux-thunk": "^3.1.0",
|
"redux-thunk": "^3.1.0",
|
||||||
"regex-parser": "^2.3.0",
|
"regex-parser": "^2.3.0",
|
||||||
"serve": "^14.2.3",
|
"serve": "^14.2.3",
|
||||||
"styled-components": "^4.4.1",
|
"styled-components": "^5.3.0",
|
||||||
"web-vitals": "^4.0.1",
|
"web-vitals": "^4.2.2",
|
||||||
"ws": "^8.17.1"
|
"ws": "^8.18.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"build-webpack": "webpack --config webpack.config.js",
|
||||||
|
"build": "npm run version && npm run build-webpack && react-scripts build",
|
||||||
|
"build-watch": "webpack --config webpack.config.js --watch",
|
||||||
|
"start-dev": "concurrently \"npm run build-watch\" \"react-scripts start\"",
|
||||||
"start": "serve -s build",
|
"start": "serve -s build",
|
||||||
"start-dev": "react-scripts start",
|
|
||||||
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
|
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
|
||||||
"version-win": "powershell -Command \"Invoke-RestMethod -Uri 'https://api.github.com/repos/opensignlabs/opensign/releases/latest' | Select-Object -ExpandProperty tag_name | Out-File -FilePath ./public/version.txt\"",
|
"version-win": "powershell -Command \"Invoke-RestMethod -Uri 'https://api.github.com/repos/opensignlabs/opensign/releases/latest' | Select-Object -ExpandProperty tag_name | Out-File -FilePath ./public/version.txt\"",
|
||||||
"build": "npm run version && react-scripts build",
|
"build-win": "npm run version-win && npm run build-webpack && react-scripts build",
|
||||||
"build-win": "npm run version-win && react-scripts build",
|
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"release": "standard-version",
|
"release": "standard-version",
|
||||||
@@ -86,21 +88,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/runtime-corejs2": "^7.24.7",
|
"@babel/core": "^7.25.2",
|
||||||
|
"@babel/preset-env": "^7.25.3",
|
||||||
|
"@babel/preset-react": "^7.24.7",
|
||||||
|
"@babel/runtime-corejs2": "^7.25.0",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
|
"babel-loader": "^9.1.3",
|
||||||
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"commitizen": "^4.3.0",
|
"commitizen": "^4.3.0",
|
||||||
"daisyui": "^4.12.2",
|
"concurrently": "^8.2.2",
|
||||||
|
"css-loader": "^7.1.2",
|
||||||
|
"daisyui": "^4.12.10",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"dotenv-webpack": "^8.1.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"eslint-plugin-react": "^7.34.3",
|
"eslint-plugin-react": "^7.34.3",
|
||||||
"lint-staged": "^15.2.7",
|
"lint-staged": "^15.2.7",
|
||||||
"postcss": "^8.4.38",
|
"mini-css-extract-plugin": "^2.9.0",
|
||||||
"prettier": "^3.3.2",
|
"postcss": "^8.4.40",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
"pretty-quick": "^4.0.0",
|
"pretty-quick": "^4.0.0",
|
||||||
"tailwindcss": "^3.4.4"
|
"tailwindcss": "^3.4.7",
|
||||||
|
"terser-webpack-plugin": "^5.3.10",
|
||||||
|
"webpack-cli": "^5.1.4"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"nth-check": "$nth-check",
|
"nth-check": "$nth-check",
|
||||||
"ws":"$ws"
|
"ws": "$ws"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@
|
|||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<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" />
|
||||||
<link rel="stylesheet" href="/css/fonts.css" />
|
<link rel="stylesheet" href="https://cdn.opensignlabs.com/fonts.css" />
|
||||||
<title>OpenSign™</title>
|
<title>OpenSign™</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -18,6 +18,8 @@ import LazyPage from "./primitives/LazyPage";
|
|||||||
import { isEnableSubscription } from "./constant/const";
|
import { isEnableSubscription } from "./constant/const";
|
||||||
import SSOVerify from "./pages/SSOVerify";
|
import SSOVerify from "./pages/SSOVerify";
|
||||||
import Loader from "./primitives/Loader";
|
import Loader from "./primitives/Loader";
|
||||||
|
import TeamList from "./pages/TeamList";
|
||||||
|
import UserList from "./pages/UserList";
|
||||||
const DebugPdf = lazy(() => import("./pages/DebugPdf"));
|
const DebugPdf = lazy(() => import("./pages/DebugPdf"));
|
||||||
const ForgetPassword = lazy(() => import("./pages/ForgetPassword"));
|
const ForgetPassword = lazy(() => import("./pages/ForgetPassword"));
|
||||||
const GuestLogin = lazy(() => import("./pages/GuestLogin"));
|
const GuestLogin = lazy(() => import("./pages/GuestLogin"));
|
||||||
@@ -30,6 +32,8 @@ const Opensigndrive = lazy(() => import("./pages/Opensigndrive"));
|
|||||||
const ManageSign = lazy(() => import("./pages/Managesign"));
|
const ManageSign = lazy(() => import("./pages/Managesign"));
|
||||||
const GenerateToken = lazy(() => import("./pages/GenerateToken"));
|
const GenerateToken = lazy(() => import("./pages/GenerateToken"));
|
||||||
const Webhook = lazy(() => import("./pages/Webhook"));
|
const Webhook = lazy(() => import("./pages/Webhook"));
|
||||||
|
const AddAdmin = lazy(() => import("./pages/AddAdmin"));
|
||||||
|
const UpdateExistUserAdmin = lazy(() => import("./pages/UpdateExistUserAdmin"));
|
||||||
|
|
||||||
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`;
|
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`;
|
||||||
const AppLoader = () => {
|
const AppLoader = () => {
|
||||||
@@ -52,11 +56,9 @@ function App() {
|
|||||||
const baseurl = process.env.REACT_APP_SERVERURL
|
const baseurl = process.env.REACT_APP_SERVERURL
|
||||||
? process.env.REACT_APP_SERVERURL
|
? process.env.REACT_APP_SERVERURL
|
||||||
: window.location.origin + "/api/app";
|
: window.location.origin + "/api/app";
|
||||||
const appName = "contracts";
|
|
||||||
try {
|
try {
|
||||||
localStorage.setItem("baseUrl", `${baseurl}/`);
|
localStorage.setItem("baseUrl", `${baseurl}/`);
|
||||||
localStorage.setItem("parseAppId", appId);
|
localStorage.setItem("parseAppId", appId);
|
||||||
localStorage.setItem("domain", appName);
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("err ", error);
|
console.log("err ", error);
|
||||||
@@ -72,7 +74,21 @@ function App() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route element={<ValidateRoute />}>
|
<Route element={<ValidateRoute />}>
|
||||||
<Route exact path="/" element={<Login />} />
|
<Route exact path="/" element={<Login />} />
|
||||||
<Route path="/signup" element={<LazyPage Page={Signup} />} />
|
{isEnableSubscription && (
|
||||||
|
<Route path="/signup" element={<LazyPage Page={Signup} />} />
|
||||||
|
)}
|
||||||
|
{!isEnableSubscription && (
|
||||||
|
<>
|
||||||
|
<Route
|
||||||
|
path="/addadmin"
|
||||||
|
element={<LazyPage Page={AddAdmin} />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/upgrade-2.1"
|
||||||
|
element={<LazyPage Page={UpdateExistUserAdmin} />}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Route>
|
</Route>
|
||||||
<Route element={<Validate />}>
|
<Route element={<Validate />}>
|
||||||
<Route
|
<Route
|
||||||
@@ -139,11 +155,6 @@ function App() {
|
|||||||
path="/managesign"
|
path="/managesign"
|
||||||
element={<LazyPage Page={ManageSign} />}
|
element={<LazyPage Page={ManageSign} />}
|
||||||
/>
|
/>
|
||||||
<Route
|
|
||||||
path="/generatetoken"
|
|
||||||
element={<LazyPage Page={GenerateToken} />}
|
|
||||||
/>
|
|
||||||
<Route path="/webhook" element={<LazyPage Page={Webhook} />} />
|
|
||||||
<Route
|
<Route
|
||||||
path="/template/:templateId"
|
path="/template/:templateId"
|
||||||
element={<TemplatePlaceholder />}
|
element={<TemplatePlaceholder />}
|
||||||
@@ -164,11 +175,30 @@ function App() {
|
|||||||
path="/pdfRequestFiles/:docId"
|
path="/pdfRequestFiles/:docId"
|
||||||
element={<PdfRequestFiles />}
|
element={<PdfRequestFiles />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* recipient signature route with no rowlevel data using docId from url */}
|
{/* recipient signature route with no rowlevel data using docId from url */}
|
||||||
<Route
|
<Route
|
||||||
path="/recipientSignPdf/:docId/:contactBookId"
|
path="/recipientSignPdf/:docId/:contactBookId"
|
||||||
element={<PdfRequestFiles />}
|
element={<PdfRequestFiles />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/recipientSignPdf/:docId"
|
||||||
|
element={<PdfRequestFiles />}
|
||||||
|
/>
|
||||||
|
{isEnableSubscription && (
|
||||||
|
<>
|
||||||
|
<Route path="/teams" element={<TeamList />} />
|
||||||
|
<Route
|
||||||
|
path="/generatetoken"
|
||||||
|
element={<LazyPage Page={GenerateToken} />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/webhook"
|
||||||
|
element={<LazyPage Page={Webhook} />}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<Route path="/users" element={<UserList />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/sso" element={<SSOVerify />} />
|
<Route path="/sso" element={<SSOVerify />} />
|
||||||
<Route path="*" element={<PageNotFound />} />
|
<Route path="*" element={<PageNotFound />} />
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -1,6 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const AddSigner = (props) => {
|
const AddSigner = (props) => {
|
||||||
@@ -10,8 +9,6 @@ const AddSigner = (props) => {
|
|||||||
const [addYourself, setAddYourself] = useState(false);
|
const [addYourself, setAddYourself] = useState(false);
|
||||||
const [isLoader, setIsLoader] = useState(false);
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
const [isUserExist, setIsUserExist] = useState(false);
|
const [isUserExist, setIsUserExist] = useState(false);
|
||||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
|
||||||
const parseAppId = localStorage.getItem("parseAppId");
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkUserExist();
|
checkUserExist();
|
||||||
@@ -85,18 +82,6 @@ const AddSigner = (props) => {
|
|||||||
}
|
}
|
||||||
const user = await _user.save();
|
const user = await _user.save();
|
||||||
if (user) {
|
if (user) {
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_Guest",
|
|
||||||
userId: user.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
const currentUser = Parse.User.current();
|
||||||
contactQuery.set(
|
contactQuery.set(
|
||||||
"CreatedBy",
|
"CreatedBy",
|
||||||
@@ -140,18 +125,6 @@ const AddSigner = (props) => {
|
|||||||
if (err.code === 202) {
|
if (err.code === 202) {
|
||||||
const params = { email: email };
|
const params = { email: email };
|
||||||
const userRes = await Parse.Cloud.run("getUserId", params);
|
const userRes = await Parse.Cloud.run("getUserId", params);
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_Guest",
|
|
||||||
userId: userRes.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
const currentUser = Parse.User.current();
|
||||||
contactQuery.set(
|
contactQuery.set(
|
||||||
"CreatedBy",
|
"CreatedBy",
|
||||||
|
|||||||
@@ -0,0 +1,194 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import Title from "./Title";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
|
const AddTeam = (props) => {
|
||||||
|
const [formdata, setFormdata] = useState({
|
||||||
|
name: "",
|
||||||
|
team: ""
|
||||||
|
});
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [teamList, setTeamList] = useState([]);
|
||||||
|
useEffect(() => {
|
||||||
|
getTeamList();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getTeamList = async () => {
|
||||||
|
setIsLoader(true);
|
||||||
|
try {
|
||||||
|
const teams = await Parse.Cloud.run("getteams", { active: true });
|
||||||
|
const teamRes = JSON.parse(JSON.stringify(teams));
|
||||||
|
if (teamRes.length > 0) {
|
||||||
|
const _teamRes = JSON.parse(JSON.stringify(teamRes));
|
||||||
|
const allUsersteam = _teamRes.find((x) => x.Name === "All Users");
|
||||||
|
if (allUsersteam) {
|
||||||
|
setFormdata({ team: allUsersteam.objectId });
|
||||||
|
}
|
||||||
|
setTeamList(_teamRes);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in fetch top level teamList", err);
|
||||||
|
} finally {
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDropdown = (e) => {
|
||||||
|
setFormdata((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
||||||
|
};
|
||||||
|
// Define a function to handle form submission
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
// Extracting values except for the 'name' key
|
||||||
|
let updatedAncestors = [];
|
||||||
|
if (formdata.team) {
|
||||||
|
const Ancestors = teamList.find(
|
||||||
|
(x) => x.objectId === formdata.team
|
||||||
|
)?.Ancestors;
|
||||||
|
if (Ancestors && Ancestors.length > 0) {
|
||||||
|
updatedAncestors = Ancestors.map((x) => ({
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Teams",
|
||||||
|
objectId: x.objectId
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
const AllUser = teamList.find((x) => x.objectId === "All Users");
|
||||||
|
updatedAncestors = [
|
||||||
|
AllUser,
|
||||||
|
{
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Teams",
|
||||||
|
objectId: formdata.team
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
setIsLoader(true);
|
||||||
|
let data = { Name: formdata.name };
|
||||||
|
if (updatedAncestors.length > 0) {
|
||||||
|
const ParentId = updatedAncestors[updatedAncestors.length - 1];
|
||||||
|
data["ParentId"] = ParentId?.objectId;
|
||||||
|
data["Ancestors"] = updatedAncestors;
|
||||||
|
}
|
||||||
|
const newTeamRes = await Parse.Cloud.run("addteam", data);
|
||||||
|
// console.log("teamRes ", newTeamRes);
|
||||||
|
if (updatedAncestors.length > 0) {
|
||||||
|
const ParentId = teamList.find((x) => x.objectId === formdata.team);
|
||||||
|
props.handleTeamInfo({
|
||||||
|
objectId: newTeamRes.id,
|
||||||
|
Name: formdata.name,
|
||||||
|
ParentId: ParentId,
|
||||||
|
Ancestors: updatedAncestors,
|
||||||
|
IsActive: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
props.handleTeamInfo({
|
||||||
|
objectId: newTeamRes.id,
|
||||||
|
Name: formdata.name,
|
||||||
|
ParentId: "",
|
||||||
|
Ancestors: "",
|
||||||
|
IsActive: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
setFormdata({ name: "", team: { name: "", objectId: "" } });
|
||||||
|
props.setIsAlert({ type: "success", msg: "Team created successfully." });
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in save team", err);
|
||||||
|
if (err.code === 137) {
|
||||||
|
props.setIsAlert({ type: "danger", msg: "Teams already exists." });
|
||||||
|
} else if (err.code === 102) {
|
||||||
|
props.setIsAlert({ type: "warning", msg: "Provide team name." });
|
||||||
|
} else {
|
||||||
|
props.setIsAlert({ type: "danger", msg: "Something went wrong." });
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => props.setIsAlert({ type: "success", msg: "" }), 1500);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define a function to handle the "add yourself" checkbox
|
||||||
|
const handleReset = () => {
|
||||||
|
setFormdata({
|
||||||
|
name: "",
|
||||||
|
team: { name: "", objectId: "" }
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleChange = (e) => {
|
||||||
|
setFormdata((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="shadow-md rounded-box my-[1px] p-3 bg-[#ffffff]">
|
||||||
|
<Title title="Add Team" />
|
||||||
|
{isLoader && (
|
||||||
|
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30 z-50 rounded-box">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="w-full mx-auto">
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
{/* <h1 className="text-[20px] font-semibold mb-4">Add User</h1> */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="name"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
value={formdata.name}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
required
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="phone"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Parent Team
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={formdata.team}
|
||||||
|
onChange={(e) => handleDropdown(e)}
|
||||||
|
name="team"
|
||||||
|
className="op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
>
|
||||||
|
{teamList.length > 0 &&
|
||||||
|
teamList.map((x) => (
|
||||||
|
<option key={x.objectId} value={x.objectId}>
|
||||||
|
{x.Name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleReset()}
|
||||||
|
className="op-btn op-btn-secondary"
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddTeam;
|
||||||
@@ -1,24 +1,55 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
|
||||||
import Title from "./Title";
|
import Title from "./Title";
|
||||||
import Alert from "../primitives/Alert";
|
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
|
import { copytoData } from "../constant/Utils";
|
||||||
|
import { isEnableSubscription } from "../constant/const";
|
||||||
|
function generatePassword(length) {
|
||||||
|
const characters =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
let result = "";
|
||||||
|
const charactersLength = characters.length;
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
const AddUser = (props) => {
|
const AddUser = (props) => {
|
||||||
const [name, setName] = useState("");
|
const [formdata, setFormdata] = useState({
|
||||||
const [phone, setPhone] = useState("");
|
name: "",
|
||||||
const [email, setEmail] = useState("");
|
phone: "",
|
||||||
|
email: "",
|
||||||
|
team: "",
|
||||||
|
password: "",
|
||||||
|
role: ""
|
||||||
|
});
|
||||||
const [isLoader, setIsLoader] = useState(false);
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
const [isUserExist, setIsUserExist] = useState(false);
|
const [teamList, setTeamList] = useState([]);
|
||||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
const role = ["OrgAdmin", "Editor", "User"];
|
||||||
const parseAppId = localStorage.getItem("parseAppId");
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getTeamList();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getTeamList = async () => {
|
||||||
|
setFormdata((prev) => ({ ...prev, password: generatePassword(12) }));
|
||||||
|
const teamRes = await Parse.Cloud.run("getteams", { active: true });
|
||||||
|
if (teamRes.length > 0) {
|
||||||
|
const _teamRes = JSON.parse(JSON.stringify(teamRes));
|
||||||
|
setTeamList(_teamRes);
|
||||||
|
if (!isEnableSubscription) {
|
||||||
|
const allUserId =
|
||||||
|
_teamRes.find((x) => x.Name === "All Users")?.objectId || "";
|
||||||
|
setFormdata((prev) => ({ ...prev, team: allUserId }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
const checkUserExist = async () => {
|
const checkUserExist = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await Parse.Cloud.run("getUserDetails", {
|
const res = await Parse.Cloud.run("getUserDetails", {
|
||||||
email: email,
|
email: formdata.email
|
||||||
userId: Parse.User.current().id
|
|
||||||
});
|
});
|
||||||
if (res) {
|
if (res) {
|
||||||
return true;
|
return true;
|
||||||
@@ -33,24 +64,46 @@ const AddUser = (props) => {
|
|||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
const localUser = JSON.parse(localStorage.getItem("Extand_Class"))?.[0];
|
||||||
setIsLoader(true);
|
setIsLoader(true);
|
||||||
const res = await checkUserExist();
|
const res = await checkUserExist();
|
||||||
if (res) {
|
if (res) {
|
||||||
setIsUserExist(true);
|
props.setIsAlert({ type: "danger", msg: "User already exist." });
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsUserExist(false);
|
props.setIsAlert({ type: "success", msg: "" });
|
||||||
}, 1000);
|
}, 1000);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const contactQuery = new Parse.Object("contracts_Users");
|
const extUser = new Parse.Object("contracts_Users");
|
||||||
contactQuery.set("Name", name);
|
extUser.set("Name", formdata.name);
|
||||||
contactQuery.set("Phone", phone);
|
if (formdata.phone) {
|
||||||
contactQuery.set("Email", email);
|
extUser.set("Phone", formdata.phone);
|
||||||
contactQuery.set("UserRole", "contracts_User");
|
}
|
||||||
|
extUser.set("Email", formdata.email);
|
||||||
|
extUser.set("UserRole", `contracts_${formdata.role}`);
|
||||||
|
if (formdata?.team) {
|
||||||
|
extUser.set("TeamIds", [
|
||||||
|
{
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Teams",
|
||||||
|
objectId: formdata.team
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (localUser && localUser.OrganizationId) {
|
||||||
|
extUser.set("OrganizationId", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Organizations",
|
||||||
|
objectId: localUser.OrganizationId.objectId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (localUser && localUser.Company) {
|
||||||
|
extUser.set("Company", localUser.Company);
|
||||||
|
}
|
||||||
|
|
||||||
if (localStorage.getItem("TenantId")) {
|
if (localStorage.getItem("TenantId")) {
|
||||||
contactQuery.set("TenantId", {
|
extUser.set("TenantId", {
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
className: "partners_Tenant",
|
className: "partners_Tenant",
|
||||||
objectId: localStorage.getItem("TenantId")
|
objectId: localStorage.getItem("TenantId")
|
||||||
@@ -60,89 +113,69 @@ const AddUser = (props) => {
|
|||||||
try {
|
try {
|
||||||
const _users = Parse.Object.extend("User");
|
const _users = Parse.Object.extend("User");
|
||||||
const _user = new _users();
|
const _user = new _users();
|
||||||
_user.set("name", name);
|
_user.set("name", formdata.name);
|
||||||
_user.set("username", email);
|
_user.set("username", formdata.email);
|
||||||
_user.set("email", email);
|
_user.set("email", formdata.email);
|
||||||
_user.set("password", email);
|
_user.set("password", formdata.password);
|
||||||
if (phone) {
|
if (formdata.phone) {
|
||||||
_user.set("phone", phone);
|
_user.set("phone", formdata.phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await _user.save();
|
const user = await _user.save();
|
||||||
if (user) {
|
if (user) {
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_User",
|
|
||||||
userId: user.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
const currentUser = Parse.User.current();
|
||||||
contactQuery.set(
|
extUser.set(
|
||||||
"CreatedBy",
|
"CreatedBy",
|
||||||
Parse.User.createWithoutData(currentUser.id)
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
contactQuery.set("UserId", user);
|
extUser.set("UserId", user);
|
||||||
const acl = new Parse.ACL();
|
const acl = new Parse.ACL();
|
||||||
acl.setPublicReadAccess(true);
|
acl.setPublicReadAccess(true);
|
||||||
acl.setPublicWriteAccess(true);
|
acl.setPublicWriteAccess(true);
|
||||||
acl.setReadAccess(currentUser.id, true);
|
acl.setReadAccess(currentUser.id, true);
|
||||||
acl.setWriteAccess(currentUser.id, true);
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
contactQuery.setACL(acl);
|
extUser.setACL(acl);
|
||||||
|
|
||||||
const res = await contactQuery.save();
|
const res = await extUser.save();
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
if (props.details) {
|
|
||||||
props.details({
|
|
||||||
value: parseData[props.valueKey],
|
|
||||||
label: parseData[props.displayKey]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
if (props.handleUserData) {
|
if (props.handleUserData) {
|
||||||
|
if (formdata?.team) {
|
||||||
|
const team = teamList.find((x) => x.objectId === formdata.team);
|
||||||
|
parseData.TeamIds = parseData.TeamIds.map((y) =>
|
||||||
|
y.objectId === team.objectId ? team : y
|
||||||
|
);
|
||||||
|
}
|
||||||
props.handleUserData(parseData);
|
props.handleUserData(parseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
|
setFormdata({
|
||||||
setName("");
|
name: "",
|
||||||
setPhone("");
|
email: "",
|
||||||
setEmail("");
|
phone: "",
|
||||||
|
team: "",
|
||||||
|
role: ""
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err ", err);
|
console.log("err ", err);
|
||||||
if (err.code === 202) {
|
if (err.code === 202) {
|
||||||
const params = { email: email };
|
const params = { email: formdata.email };
|
||||||
const userRes = await Parse.Cloud.run("getUserId", params);
|
const userRes = await Parse.Cloud.run("getUserId", params);
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_User",
|
|
||||||
userId: userRes.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
const currentUser = Parse.User.current();
|
||||||
contactQuery.set(
|
extUser.set(
|
||||||
"CreatedBy",
|
"CreatedBy",
|
||||||
Parse.User.createWithoutData(currentUser.id)
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
contactQuery.set("UserId", {
|
extUser.set("UserId", {
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
className: "_User",
|
className: "_User",
|
||||||
objectId: userRes.id
|
objectId: userRes.id
|
||||||
@@ -153,55 +186,75 @@ const AddUser = (props) => {
|
|||||||
acl.setReadAccess(currentUser.id, true);
|
acl.setReadAccess(currentUser.id, true);
|
||||||
acl.setWriteAccess(currentUser.id, true);
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
contactQuery.setACL(acl);
|
extUser.setACL(acl);
|
||||||
const res = await contactQuery.save();
|
const res = await extUser.save();
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
if (props.details) {
|
|
||||||
props.details({
|
|
||||||
value: parseData[props.valueKey],
|
|
||||||
label: parseData[props.displayKey]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
if (props.handleUserData) {
|
if (props.handleUserData) {
|
||||||
|
if (formdata?.team) {
|
||||||
|
const team = teamList.find((x) => x.objectId === formdata.team);
|
||||||
|
parseData.TeamIds = parseData.TeamIds.map((y) =>
|
||||||
|
y.objectId === team.objectId ? team : y
|
||||||
|
);
|
||||||
|
}
|
||||||
props.handleUserData(parseData);
|
props.handleUserData(parseData);
|
||||||
}
|
}
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
setName("");
|
setFormdata({
|
||||||
setPhone("");
|
name: "",
|
||||||
setEmail("");
|
email: "",
|
||||||
|
phone: "",
|
||||||
|
team: "",
|
||||||
|
role: ""
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.log("err", err);
|
console.log("err", err);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert("something went wrong!");
|
props.setIsAlert({ type: "danger", msg: "something went wrong." });
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => props.setIsAlert({ type: "success", msg: "" }), 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define a function to handle the "add yourself" checkbox
|
// Define a function to handle the "add yourself" checkbox
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
setName("");
|
setFormdata({
|
||||||
setPhone("");
|
name: "",
|
||||||
setEmail("");
|
email: "",
|
||||||
|
phone: "",
|
||||||
|
team: "",
|
||||||
|
role: ""
|
||||||
|
});
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleChange = (e) => {
|
||||||
|
setFormdata((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const copytoclipboard = (text) => {
|
||||||
|
copytoData(text);
|
||||||
|
props.setIsAlert({ type: "success", msg: "Copied" });
|
||||||
|
setTimeout(() => props.setIsAlert({ type: "success", msg: "" }), 1500); // Reset copied state after 1.5 seconds
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="shadow-md rounded my-2 p-3 bg-[#ffffff] md:border-[1px] md:border-gray-600/50">
|
<div className="shadow-md rounded-box my-[1px] p-3 bg-[#ffffff]">
|
||||||
<Title title={"Add User"} />
|
<Title title={"Add User"} />
|
||||||
{isUserExist && <Alert type="danger">User already exists!</Alert>}
|
|
||||||
{isLoader && (
|
{isLoader && (
|
||||||
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30 z-50">
|
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30 z-50 rounded-box">
|
||||||
<Loader />
|
<Loader />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="w-full mx-auto">
|
<div className="w-full mx-auto">
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<h1 className="text-[20px] font-semibold mb-4">Add User</h1>
|
{/* <h1 className="text-[20px] font-semibold mb-4">Add User</h1> */}
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label
|
||||||
htmlFor="name"
|
htmlFor="name"
|
||||||
@@ -212,9 +265,9 @@ const AddUser = (props) => {
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="name"
|
name="name"
|
||||||
value={name}
|
value={formdata.name}
|
||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => handleChange(e)}
|
||||||
required
|
required
|
||||||
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
@@ -229,44 +282,111 @@ const AddUser = (props) => {
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
id="email"
|
name="email"
|
||||||
value={email}
|
value={formdata.email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => handleChange(e)}
|
||||||
required
|
required
|
||||||
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="email"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Password
|
||||||
|
</label>
|
||||||
|
<div className="flex justify-between items-center op-input op-input-bordered op-input-sm text-base-content w-full h-full text-[13px]">
|
||||||
|
<div className="break-all">{formdata?.password}</div>
|
||||||
|
<i
|
||||||
|
onClick={() => copytoclipboard(formdata?.password)}
|
||||||
|
className="fa-light fa-copy rounded-full hover:bg-base-300 p-[8px] cursor-pointer "
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
<div className="text-[12px] ml-2 mb-0 text-[red] select-none">
|
||||||
|
Password will only be generated once; make sure to copy it.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label
|
||||||
htmlFor="phone"
|
htmlFor="phone"
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
>
|
>
|
||||||
Phone
|
Phone
|
||||||
<span className="text-[red] text-[13px]"> *</span>
|
{/* <span className="text-[red] text-[13px]"> *</span> */}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="phone"
|
name="phone"
|
||||||
value={phone}
|
placeholder="optional"
|
||||||
onChange={(e) => setPhone(e.target.value)}
|
value={formdata.phone}
|
||||||
required
|
onChange={(e) => handleChange(e)}
|
||||||
|
// required
|
||||||
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{isEnableSubscription && (
|
||||||
<div className="flex items-center mt-3 gap-2 text-white">
|
<div className="mb-3">
|
||||||
<button
|
<label
|
||||||
type="submit"
|
htmlFor="phone"
|
||||||
className="bg-[#1ab6ce] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 focus:outline-none"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Team<span className="text-[red] text-[13px]"> *</span>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={formdata.team}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
name="team"
|
||||||
|
className="op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<option defaultValue={""} value={""}>
|
||||||
|
select
|
||||||
|
</option>
|
||||||
|
{teamList.length > 0 &&
|
||||||
|
teamList.map((x) => (
|
||||||
|
<option key={x.objectId} value={x.objectId}>
|
||||||
|
{x.Name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="phone"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
>
|
>
|
||||||
|
Role<span className="text-[red] text-[13px]"> *</span>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={formdata.role}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
name="role"
|
||||||
|
className="op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<option defaultValue={""} value={""}>
|
||||||
|
select
|
||||||
|
</option>
|
||||||
|
{role.length > 0 &&
|
||||||
|
role.map((x) => (
|
||||||
|
<option key={x} value={x}>
|
||||||
|
{x}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleReset()}
|
onClick={() => handleReset()}
|
||||||
className="bg-[#188ae2] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 text-center ml-[2px] focus:outline-none"
|
className="op-btn op-btn-secondary"
|
||||||
>
|
>
|
||||||
Reset
|
Cancel
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -4,8 +4,13 @@ import FullScreenButton from "./FullScreenButton";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { useWindowSize } from "../hook/useWindowSize";
|
import { useWindowSize } from "../hook/useWindowSize";
|
||||||
import { checkIsSubscribed, getAppLogo, openInNewTab } from "../constant/Utils";
|
import {
|
||||||
import { isEnableSubscription } from "../constant/const";
|
checkIsSubscribed,
|
||||||
|
checkIsSubscribedTeam,
|
||||||
|
getAppLogo,
|
||||||
|
openInNewTab
|
||||||
|
} from "../constant/Utils";
|
||||||
|
import { isEnableSubscription, isStaging } from "../constant/const";
|
||||||
|
|
||||||
const Header = ({ showSidebar }) => {
|
const Header = ({ showSidebar }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -15,6 +20,7 @@ const Header = ({ showSidebar }) => {
|
|||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isSubscribe, setIsSubscribe] = useState(true);
|
const [isSubscribe, setIsSubscribe] = useState(true);
|
||||||
const [isPro, setIsPro] = useState(false);
|
const [isPro, setIsPro] = useState(false);
|
||||||
|
const [isTeam, setIsTeam] = useState(false);
|
||||||
const [applogo, setAppLogo] = useState(
|
const [applogo, setAppLogo] = useState(
|
||||||
localStorage.getItem("appLogo") || " "
|
localStorage.getItem("appLogo") || " "
|
||||||
);
|
);
|
||||||
@@ -29,15 +35,17 @@ const Header = ({ showSidebar }) => {
|
|||||||
async function checkSubscription() {
|
async function checkSubscription() {
|
||||||
if (isEnableSubscription) {
|
if (isEnableSubscription) {
|
||||||
const getIsSubscribe = await checkIsSubscribed();
|
const getIsSubscribe = await checkIsSubscribed();
|
||||||
|
const getIsTeam = await checkIsSubscribedTeam();
|
||||||
if (getIsSubscribe) {
|
if (getIsSubscribe) {
|
||||||
const applogo = await getAppLogo();
|
const applogo = await getAppLogo();
|
||||||
if (applogo) {
|
if (applogo?.logo) {
|
||||||
setAppLogo(applogo);
|
setAppLogo(applogo?.logo);
|
||||||
} else {
|
} else {
|
||||||
setAppLogo(localStorage.getItem("appLogo") || "");
|
setAppLogo(localStorage.getItem("appLogo") || "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setIsPro(getIsSubscribe);
|
setIsPro(getIsSubscribe);
|
||||||
|
setIsTeam(getIsTeam);
|
||||||
setIsSubscribe(getIsSubscribe);
|
setIsSubscribe(getIsSubscribe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,22 +61,16 @@ const Header = ({ showSidebar }) => {
|
|||||||
}
|
}
|
||||||
let appdata = localStorage.getItem("userSettings");
|
let appdata = localStorage.getItem("userSettings");
|
||||||
let applogo = localStorage.getItem("appLogo");
|
let applogo = localStorage.getItem("appLogo");
|
||||||
let appName = localStorage.getItem("appName");
|
|
||||||
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
let PageLanding = localStorage.getItem("PageLanding");
|
let PageLanding = localStorage.getItem("PageLanding");
|
||||||
let domain = localStorage.getItem("domain");
|
|
||||||
let _appName = localStorage.getItem("_appName");
|
|
||||||
let baseUrl = localStorage.getItem("baseUrl");
|
let baseUrl = localStorage.getItem("baseUrl");
|
||||||
let appid = localStorage.getItem("parseAppId");
|
let appid = localStorage.getItem("parseAppId");
|
||||||
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
|
||||||
localStorage.setItem("appLogo", applogo);
|
localStorage.setItem("appLogo", applogo);
|
||||||
localStorage.setItem("appName", appName);
|
|
||||||
localStorage.setItem("_appName", _appName);
|
|
||||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
localStorage.setItem("PageLanding", PageLanding);
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
localStorage.setItem("domain", domain);
|
|
||||||
localStorage.setItem("userSettings", appdata);
|
localStorage.setItem("userSettings", appdata);
|
||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
@@ -91,7 +93,13 @@ const Header = ({ showSidebar }) => {
|
|||||||
document.removeEventListener("click", closeMenuOnOutsideClick);
|
document.removeEventListener("click", closeMenuOnOutsideClick);
|
||||||
};
|
};
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
const handleConsoleRedirect = () => {
|
||||||
|
if (isStaging) {
|
||||||
|
window.open(" https://staging-console.opensignlabs.com/");
|
||||||
|
} else {
|
||||||
|
window.open("https://console.opensignlabs.com/");
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="op-navbar bg-base-100 shadow">
|
<div className="op-navbar bg-base-100 shadow">
|
||||||
<div className="flex-none">
|
<div className="flex-none">
|
||||||
@@ -122,11 +130,16 @@ const Header = ({ showSidebar }) => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isPro && (
|
{!isTeam && isPro && (
|
||||||
<div className="w-[35px] h-[35px] bg-white rounded-full ring-[1px] ring-offset-2 ring-[#002862] text-[#002862] overflow-hidden font-semibold flex items-center justify-center">
|
<div className="w-[35px] h-[35px] bg-white rounded-full ring-[1px] ring-offset-2 ring-[#002862] text-[#002862] overflow-hidden font-semibold flex items-center justify-center">
|
||||||
PRO
|
PRO
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{isTeam && (
|
||||||
|
<div className="w-[35px] h-[35px] bg-white rounded-full ring-[1px] text-[13px] ring-offset-2 ring-[#002862] text-[#002862] overflow-hidden font-semibold flex items-center justify-center">
|
||||||
|
TEAM
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div>
|
<div>
|
||||||
<FullScreenButton />
|
<FullScreenButton />
|
||||||
</div>
|
</div>
|
||||||
@@ -194,7 +207,7 @@ const Header = ({ showSidebar }) => {
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open("https://console.opensignlabs.com/");
|
handleConsoleRedirect();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -51,14 +51,8 @@ const GoogleSignInBtn = ({
|
|||||||
let baseUrl = localStorage.getItem("baseUrl");
|
let baseUrl = localStorage.getItem("baseUrl");
|
||||||
let appid = localStorage.getItem("parseAppId");
|
let appid = localStorage.getItem("parseAppId");
|
||||||
let applogo = localStorage.getItem("appLogo");
|
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 defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
let PageLanding = localStorage.getItem("PageLanding");
|
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");
|
let userSettings = localStorage.getItem("userSettings");
|
||||||
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
@@ -66,14 +60,8 @@ const GoogleSignInBtn = ({
|
|||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
localStorage.setItem("appLogo", applogo);
|
localStorage.setItem("appLogo", applogo);
|
||||||
localStorage.setItem("domain", domain);
|
|
||||||
localStorage.setItem("appversion", appversion);
|
|
||||||
localStorage.setItem("appTitle", appTitle);
|
|
||||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
localStorage.setItem("PageLanding", PageLanding);
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
localStorage.setItem("_appName", _appName);
|
|
||||||
localStorage.setItem("_app_objectId", _app_objectId);
|
|
||||||
localStorage.setItem("appName", appName);
|
|
||||||
localStorage.setItem("userSettings", userSettings);
|
localStorage.setItem("userSettings", userSettings);
|
||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
@@ -186,22 +174,16 @@ const GoogleSignInBtn = ({
|
|||||||
|
|
||||||
let appdata = localStorage.getItem("userSettings");
|
let appdata = localStorage.getItem("userSettings");
|
||||||
let applogo = localStorage.getItem("appLogo");
|
let applogo = localStorage.getItem("appLogo");
|
||||||
let appName = localStorage.getItem("appName");
|
|
||||||
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
let PageLanding = localStorage.getItem("PageLanding");
|
let PageLanding = localStorage.getItem("PageLanding");
|
||||||
let domain = localStorage.getItem("domain");
|
|
||||||
let _appName = localStorage.getItem("_appName");
|
|
||||||
let baseUrl = localStorage.getItem("baseUrl");
|
let baseUrl = localStorage.getItem("baseUrl");
|
||||||
let appid = localStorage.getItem("parseAppId");
|
let appid = localStorage.getItem("parseAppId");
|
||||||
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
|
||||||
localStorage.setItem("appLogo", applogo);
|
localStorage.setItem("appLogo", applogo);
|
||||||
localStorage.setItem("appName", appName);
|
|
||||||
localStorage.setItem("_appName", _appName);
|
|
||||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
localStorage.setItem("PageLanding", PageLanding);
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
localStorage.setItem("domain", domain);
|
|
||||||
localStorage.setItem("userSettings", appdata);
|
localStorage.setItem("userSettings", appdata);
|
||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const GetDashboard = (props) => {
|
|||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
col?.widget?.bgColor ? col.widget.bgColor : "bg-[#2ed8b6]"
|
col?.widget?.bgColor ? col.widget.bgColor : "bg-[#2ed8b6]"
|
||||||
} op-card w-full h-[140px] px-3 pt-4 mb-3 shadow-md"`}
|
} op-card w-full h-[140px] px-3 pt-4 mb-3 shadow-md`}
|
||||||
data-tut={col.widget.data.tourSection}
|
data-tut={col.widget.data.tourSection}
|
||||||
>
|
>
|
||||||
<Suspense
|
<Suspense
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ function DriveBody(props) {
|
|||||||
props.sortingData(null, null, updatedData);
|
props.sortingData(null, null, updatedData);
|
||||||
await axios
|
await axios
|
||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"_appName"
|
"baseUrl"
|
||||||
)}_Document/${docId}`,
|
)}classes/contracts_Document/${docId}`,
|
||||||
updateName,
|
updateName,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@@ -104,7 +104,7 @@ function DriveBody(props) {
|
|||||||
const signedUrl = data.SignedUrl;
|
const signedUrl = data.SignedUrl;
|
||||||
//checking if document has completed and request signature flow
|
//checking if document has completed and request signature flow
|
||||||
if (data?.IsCompleted && signerExist?.length > 0) {
|
if (data?.IsCompleted && signerExist?.length > 0) {
|
||||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
navigate(`/recipientSignPdf/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//checking if document has completed and signyour-self flow
|
//checking if document has completed and signyour-self flow
|
||||||
else if (!signerExist && !isPlaceholder) {
|
else if (!signerExist && !isPlaceholder) {
|
||||||
@@ -112,7 +112,7 @@ function DriveBody(props) {
|
|||||||
}
|
}
|
||||||
//checking if document has declined by someone
|
//checking if document has declined by someone
|
||||||
else if (isDecline) {
|
else if (isDecline) {
|
||||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
navigate(`/recipientSignPdf/${data.objectId}`);
|
||||||
//checking draft type document
|
//checking draft type document
|
||||||
} else if (
|
} else if (
|
||||||
signerExist?.length > 0 &&
|
signerExist?.length > 0 &&
|
||||||
@@ -122,8 +122,8 @@ function DriveBody(props) {
|
|||||||
navigate(`/placeHolderSign/${data.objectId}`);
|
navigate(`/placeHolderSign/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//Inprogress document
|
//Inprogress document
|
||||||
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
|
else if (isPlaceholder?.length > 0 && signedUrl) {
|
||||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
navigate(`/recipientSignPdf/${data.objectId}`);
|
||||||
} //placeholder draft document
|
} //placeholder draft document
|
||||||
else if (
|
else if (
|
||||||
(signerExist?.length > 0 &&
|
(signerExist?.length > 0 &&
|
||||||
@@ -170,9 +170,7 @@ function DriveBody(props) {
|
|||||||
|
|
||||||
await axios
|
await axios
|
||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem("baseUrl")}classes/contracts_Document/${docId}`,
|
||||||
"_appName"
|
|
||||||
)}_Document/${docId}`,
|
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@@ -219,7 +217,7 @@ function DriveBody(props) {
|
|||||||
updateData = {
|
updateData = {
|
||||||
Folder: {
|
Folder: {
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
className: `${localStorage.getItem("_appName")}_Document`,
|
className: "contracts_Document",
|
||||||
objectId: moveFolderId
|
objectId: moveFolderId
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -231,9 +229,9 @@ function DriveBody(props) {
|
|||||||
|
|
||||||
await axios
|
await axios
|
||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"_appName"
|
"baseUrl"
|
||||||
)}_Document/${updateDocId}`,
|
)}classes/contracts_Document/${updateDocId}`,
|
||||||
updateData,
|
updateData,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import LoaderWithMsg from "../../primitives/LoaderWithMsg";
|
import LoaderWithMsg from "../../primitives/LoaderWithMsg";
|
||||||
import { contractDocument } from "../../constant/Utils";
|
import { contractDocument } from "../../constant/Utils";
|
||||||
import HandleError from "../../primitives/HandleError";
|
import HandleError from "../../primitives/HandleError";
|
||||||
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
|
function useQuery() {
|
||||||
|
return new URLSearchParams(useLocation().search);
|
||||||
|
}
|
||||||
function DraftDocument() {
|
function DraftDocument() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const query = useQuery();
|
||||||
|
const docId = query.get("docId");
|
||||||
const [isLoading, setIsLoading] = useState({
|
const [isLoading, setIsLoading] = useState({
|
||||||
isLoader: true,
|
isLoader: true,
|
||||||
message: "This might take some time"
|
message: "This might take some time"
|
||||||
});
|
});
|
||||||
|
|
||||||
const rowLevel =
|
|
||||||
localStorage.getItem("rowlevel") &&
|
|
||||||
JSON.parse(localStorage.getItem("rowlevel"));
|
|
||||||
const docId =
|
|
||||||
rowLevel && rowLevel?.id
|
|
||||||
? rowLevel.id
|
|
||||||
: rowLevel?.objectId && rowLevel.objectId;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getDocumentDetails();
|
getDocumentDetails();
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
@@ -53,7 +49,7 @@ function DraftDocument() {
|
|||||||
const signedUrl = data.SignedUrl;
|
const signedUrl = data.SignedUrl;
|
||||||
//checking if document has completed and request signature flow
|
//checking if document has completed and request signature flow
|
||||||
if (data?.IsCompleted && signerExist?.length > 0) {
|
if (data?.IsCompleted && signerExist?.length > 0) {
|
||||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
navigate(`/recipientSignPdf/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//checking if document has completed and signyour-self flow
|
//checking if document has completed and signyour-self flow
|
||||||
else if (!signerExist && !isPlaceholder) {
|
else if (!signerExist && !isPlaceholder) {
|
||||||
@@ -61,7 +57,7 @@ function DraftDocument() {
|
|||||||
}
|
}
|
||||||
//checking if document has declined by someone
|
//checking if document has declined by someone
|
||||||
else if (isDecline) {
|
else if (isDecline) {
|
||||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
navigate(`/recipientSignPdf/${data.objectId}`);
|
||||||
//checking draft type document
|
//checking draft type document
|
||||||
} else if (
|
} else if (
|
||||||
signerExist?.length > 0 &&
|
signerExist?.length > 0 &&
|
||||||
@@ -71,8 +67,8 @@ function DraftDocument() {
|
|||||||
navigate(`/placeHolderSign/${data.objectId}`);
|
navigate(`/placeHolderSign/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//Inprogress document
|
//Inprogress document
|
||||||
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
|
else if (isPlaceholder?.length > 0 && signedUrl) {
|
||||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
navigate(`/recipientSignPdf/${data.objectId}`);
|
||||||
} //placeholder draft document
|
} //placeholder draft document
|
||||||
else if (
|
else if (
|
||||||
(signerExist?.length > 0 &&
|
(signerExist?.length > 0 &&
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import React, { useEffect, useState } from "react";
|
|||||||
import { isEnableSubscription } from "../../constant/const";
|
import { isEnableSubscription } from "../../constant/const";
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import { radioButtonWidget } from "../../constant/Utils";
|
import { radioButtonWidget } from "../../constant/Utils";
|
||||||
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
|
||||||
import Upgrade from "../../primitives/Upgrade";
|
import Upgrade from "../../primitives/Upgrade";
|
||||||
function DropdownWidgetOption(props) {
|
function DropdownWidgetOption(props) {
|
||||||
const [dropdownOptionList, setDropdownOptionList] = useState([
|
const [dropdownOptionList, setDropdownOptionList] = useState([
|
||||||
@@ -214,55 +213,57 @@ function DropdownWidgetOption(props) {
|
|||||||
onClick={handleAddInput}
|
onClick={handleAddInput}
|
||||||
className="fa-light fa-square-plus text-[25px] ml-[10px] op-text-primary cursor-pointer"
|
className="fa-light fa-square-plus text-[25px] ml-[10px] op-text-primary cursor-pointer"
|
||||||
></i>
|
></i>
|
||||||
<div>
|
{isEnableSubscription && (
|
||||||
{props.type === "checkbox" && !props.isSignYourself && (
|
<div>
|
||||||
<>
|
{props.type === "checkbox" && !props.isSignYourself && (
|
||||||
<label
|
<>
|
||||||
className={`${
|
<label
|
||||||
!props.isSubscribe ? "text-[gray]" : ""
|
className={`${
|
||||||
} text-[13px] font-semibold`}
|
!props.isSubscribe ? "text-[gray]" : ""
|
||||||
>
|
} text-[13px] font-semibold`}
|
||||||
Minimun check
|
>
|
||||||
</label>
|
Minimun check
|
||||||
{!props.isSubscribe && isEnableSubscription && <Upgrade />}
|
</label>
|
||||||
<input
|
{!props.isSubscribe && isEnableSubscription && (
|
||||||
required
|
<Upgrade />
|
||||||
defaultValue={0}
|
)}
|
||||||
value={minCount}
|
<input
|
||||||
onChange={(e) => {
|
required
|
||||||
const count = handleSetMinMax(e);
|
defaultValue={0}
|
||||||
setMinCount(count);
|
value={minCount}
|
||||||
}}
|
disabled={props.isSubscribe ? false : true}
|
||||||
className={`${
|
onChange={(e) => {
|
||||||
props.isSubscribe || !isEnableSubscription
|
const count = handleSetMinMax(e);
|
||||||
? ""
|
setMinCount(count);
|
||||||
: "pointer-events-none bg-opacity-50"
|
}}
|
||||||
} op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs`}
|
className={`${
|
||||||
/>
|
props.isSubscribe ? "" : "pointer-events-none"
|
||||||
<label
|
} op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs`}
|
||||||
className={`${
|
/>
|
||||||
!props.isSubscribe ? "text-[gray]" : ""
|
<label
|
||||||
} text-[13px] font-semibold`}
|
className={`${
|
||||||
>
|
!props.isSubscribe ? "text-[gray]" : ""
|
||||||
Maximum check
|
} text-[13px] font-semibold`}
|
||||||
</label>
|
>
|
||||||
<input
|
Maximum check
|
||||||
required
|
</label>
|
||||||
defaultValue={0}
|
<input
|
||||||
value={maxCount}
|
required
|
||||||
onChange={(e) => {
|
defaultValue={0}
|
||||||
const count = handleSetMinMax(e);
|
value={maxCount}
|
||||||
setMaxCount(count);
|
disabled={props.isSubscribe ? false : true}
|
||||||
}}
|
onChange={(e) => {
|
||||||
className={`${
|
const count = handleSetMinMax(e);
|
||||||
props.isSubscribe || !isEnableSubscription
|
setMaxCount(count);
|
||||||
? ""
|
}}
|
||||||
: "pointer-events-none bg-opacity-50"
|
className={`${
|
||||||
} op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs`}
|
props.isSubscribe ? "" : "pointer-events-none"
|
||||||
/>
|
} op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs`}
|
||||||
</>
|
/>
|
||||||
)}
|
</>
|
||||||
</div>
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{["dropdown", radioButtonWidget].includes(props.type) && (
|
{["dropdown", radioButtonWidget].includes(props.type) && (
|
||||||
<>
|
<>
|
||||||
@@ -344,15 +345,6 @@ function DropdownWidgetOption(props) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{props.type === "checkbox" &&
|
|
||||||
!props.isSignYourself &&
|
|
||||||
!isEnableSubscription && (
|
|
||||||
<PremiumAlertHeader
|
|
||||||
message={
|
|
||||||
"Field validations are free in beta, this feature will incur a fee later."
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
props.type === "checkbox" && !props.isSignYourself
|
props.type === "checkbox" && !props.isSignYourself
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { checkIsSubscribed, getFileName } from "../../constant/Utils";
|
import { checkIsSubscribed, getFileName } from "../../constant/Utils";
|
||||||
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
|
||||||
import Upgrade from "../../primitives/Upgrade";
|
import Upgrade from "../../primitives/Upgrade";
|
||||||
import { isEnableSubscription } from "../../constant/const";
|
import { isEnableSubscription } from "../../constant/const";
|
||||||
// import SelectFolder from "../../premitives/SelectFolder";
|
// import SelectFolder from "../../premitives/SelectFolder";
|
||||||
@@ -134,39 +133,32 @@ const EditTemplate = ({ template, onSuccess }) => {
|
|||||||
<div className="text-[12px]">No</div>
|
<div className="text-[12px]">No</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs mt-2">
|
{isEnableSubscription && (
|
||||||
{!isEnableSubscription && (
|
<div className="text-xs mt-2">
|
||||||
<PremiumAlertHeader
|
<span
|
||||||
message={
|
className={
|
||||||
"Auto reminder is free in beta, this feature will incur a fee later."
|
isSubscribe ? "font-semibold" : "font-semibold text-gray-300"
|
||||||
}
|
}
|
||||||
/>
|
>
|
||||||
)}
|
Auto reminder{" "}
|
||||||
<span
|
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
||||||
className={
|
</span>
|
||||||
isSubscribe || !isEnableSubscription
|
<label
|
||||||
? "font-semibold"
|
className={`${
|
||||||
: "font-semibold text-gray-300"
|
isSubscribe
|
||||||
}
|
? "cursor-pointer "
|
||||||
>
|
: "pointer-events-none opacity-50"
|
||||||
Auto reminder{" "}
|
} relative block items-center mb-0`}
|
||||||
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
>
|
||||||
</span>
|
<input
|
||||||
<label
|
checked={formData.AutomaticReminders}
|
||||||
className={`${
|
onChange={handleAutoReminder}
|
||||||
isSubscribe || !isEnableSubscription
|
type="checkbox"
|
||||||
? "cursor-pointer "
|
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white mt-2"
|
||||||
: "pointer-events-none opacity-50"
|
/>
|
||||||
} relative block items-center mb-0`}
|
</label>
|
||||||
>
|
</div>
|
||||||
<input
|
)}
|
||||||
checked={formData.AutomaticReminders}
|
|
||||||
onChange={handleAutoReminder}
|
|
||||||
type="checkbox"
|
|
||||||
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white mt-2"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{isSubscribe && formData?.AutomaticReminders === true && (
|
{isSubscribe && formData?.AutomaticReminders === true && (
|
||||||
<div className="text-xs mt-2">
|
<div className="text-xs mt-2">
|
||||||
<label className="block">
|
<label className="block">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { useState } from "react";
|
|||||||
import { saveAs } from "file-saver";
|
import { saveAs } from "file-saver";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { getBase64FromUrl } from "../../constant/Utils";
|
import { getBase64FromUrl } from "../../constant/Utils";
|
||||||
import { themeColor } from "../../constant/const";
|
import { themeColor, emailRegex } from "../../constant/const";
|
||||||
import printModule from "print-js";
|
import printModule from "print-js";
|
||||||
import Loader from "../../primitives/Loader";
|
import Loader from "../../primitives/Loader";
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
@@ -19,8 +19,9 @@ function EmailComponent({
|
|||||||
activeMailAdapter
|
activeMailAdapter
|
||||||
}) {
|
}) {
|
||||||
const [emailList, setEmailList] = useState([]);
|
const [emailList, setEmailList] = useState([]);
|
||||||
const [emailValue, setEmailValue] = useState();
|
const [emailValue, setEmailValue] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [emailErr, setEmailErr] = useState(false);
|
||||||
//function for send email
|
//function for send email
|
||||||
const sendEmail = async () => {
|
const sendEmail = async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
@@ -111,17 +112,30 @@ function EmailComponent({
|
|||||||
//function for get email value
|
//function for get email value
|
||||||
const handleEmailValue = (e) => {
|
const handleEmailValue = (e) => {
|
||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
|
setEmailErr(false);
|
||||||
setEmailValue(value);
|
setEmailValue(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for save email in array after press enter
|
//function for save email in array after press enter
|
||||||
const handleEnterPress = (e) => {
|
const handleEnterPress = (e) => {
|
||||||
|
const pattern = emailRegex;
|
||||||
|
const validate = emailValue?.match(pattern);
|
||||||
if (e.key === "Enter" && emailValue) {
|
if (e.key === "Enter" && emailValue) {
|
||||||
setEmailList((prev) => [...prev, emailValue]);
|
if (validate) {
|
||||||
setEmailValue("");
|
const emailLowerCase = emailValue?.toLowerCase();
|
||||||
|
setEmailList((prev) => [...prev, emailLowerCase]);
|
||||||
|
setEmailValue("");
|
||||||
|
} else {
|
||||||
|
setEmailErr(true);
|
||||||
|
}
|
||||||
} else if (e === "add" && emailValue) {
|
} else if (e === "add" && emailValue) {
|
||||||
setEmailList((prev) => [...prev, emailValue]);
|
if (validate) {
|
||||||
setEmailValue("");
|
const emailLowerCase = emailValue?.toLowerCase();
|
||||||
|
setEmailList((prev) => [...prev, emailLowerCase]);
|
||||||
|
setEmailValue("");
|
||||||
|
} else {
|
||||||
|
setEmailErr(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -179,7 +193,6 @@ function EmailComponent({
|
|||||||
Successfully signed!
|
Successfully signed!
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<div></div>
|
|
||||||
{!isAndroid && (
|
{!isAndroid && (
|
||||||
<button
|
<button
|
||||||
onClick={handleToPrint}
|
onClick={handleToPrint}
|
||||||
@@ -203,72 +216,63 @@ function EmailComponent({
|
|||||||
Recipients added here will get a copy of the signed document.
|
Recipients added here will get a copy of the signed document.
|
||||||
</p>
|
</p>
|
||||||
{emailList.length > 0 ? (
|
{emailList.length > 0 ? (
|
||||||
<>
|
<div className="p-0 border-[1.5px] op-border-primary rounded w-full text-[15px]">
|
||||||
<div className="p-0 border-[1.5px] op-border-primary rounded w-full text-[15px]">
|
<div className="flex flex-row flex-wrap">
|
||||||
<div className="flex flex-row flex-wrap">
|
{emailList.map((data, ind) => {
|
||||||
{emailList.map((data, ind) => {
|
return (
|
||||||
return (
|
<div
|
||||||
<div
|
className="flex flex-row items-center op-bg-primary m-[4px] rounded-md py-[5px] px-[10px]"
|
||||||
className="flex flex-row items-center op-bg-primary m-[4px] rounded-md py-[5px] px-[10px]"
|
key={ind}
|
||||||
key={ind}
|
>
|
||||||
|
<span className="text-base-100 text-[13px]">
|
||||||
|
{data}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="text-base-100 text-[13px] font-semibold ml-[7px] cursor-pointer"
|
||||||
|
onClick={() => removeChip(ind)}
|
||||||
>
|
>
|
||||||
<span className="text-base-100 text-[13px]">
|
<i className="fa-light fa-xmark"></i>
|
||||||
{data}
|
</span>
|
||||||
</span>
|
</div>
|
||||||
<span
|
);
|
||||||
className="text-base-100 text-[13px] font-semibold ml-[7px] cursor-pointer"
|
})}
|
||||||
onClick={() => removeChip(ind)}
|
|
||||||
>
|
|
||||||
<i className="fa-light fa-xmark"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
{emailList.length <= 9 && (
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={emailValue}
|
|
||||||
className="p-[10px] pb-[20px] rounded w-full text-[15px] bg-transparent outline-none"
|
|
||||||
onChange={handleEmailValue}
|
|
||||||
onKeyDown={handleEnterPress}
|
|
||||||
onBlur={() => {
|
|
||||||
if (emailValue) {
|
|
||||||
handleEnterPress("add");
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
{emailList.length <= 9 && (
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
value={emailValue}
|
||||||
|
className="p-[10px] pb-[20px] rounded w-full text-[15px] bg-transparent outline-none"
|
||||||
|
onChange={handleEmailValue}
|
||||||
|
onKeyDown={handleEnterPress}
|
||||||
|
onBlur={() => emailValue && handleEnterPress("add")}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="email"
|
||||||
value={emailValue}
|
value={emailValue}
|
||||||
className="p-[10px] pb-[20px] rounded w-full text-[15px] outline-none bg-transparent border-[1.5px] op-border-primary"
|
className="p-[10px] pb-[20px] rounded w-full text-[15px] outline-none bg-transparent border-[1.5px] op-border-primary"
|
||||||
onChange={handleEmailValue}
|
onChange={handleEmailValue}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
placeholder="Add the email addresses"
|
placeholder="Add an email address and hit enter"
|
||||||
onBlur={() => {
|
onBlur={() => emailValue && handleEnterPress("add")}
|
||||||
if (emailValue) {
|
|
||||||
handleEnterPress("add");
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{emailErr && (
|
||||||
|
<p className="text-xs text-[red] ml-1.5 mt-0.5">
|
||||||
|
please provide correct email address
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
emailValue ? "cursor-pointer" : "cursor-default"
|
emailValue ? "cursor-pointer" : "cursor-default"
|
||||||
} op-btn op-btn-primary op-btn-sm m-2 shadow-md`}
|
} op-btn op-btn-primary op-btn-sm m-2 shadow-md`}
|
||||||
onClick={() => {
|
onClick={() => emailValue && handleEnterPress("add")}
|
||||||
if (emailValue) {
|
|
||||||
handleEnterPress("add");
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<i className="fa-light fa-plus" aria-hidden="true"></i>
|
<i className="fa-light fa-plus" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {
|
|||||||
} from "../../constant/Utils";
|
} from "../../constant/Utils";
|
||||||
import "../../styles/signature.css";
|
import "../../styles/signature.css";
|
||||||
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import Loader from "../../primitives/Loader";
|
import Loader from "../../primitives/Loader";
|
||||||
|
|
||||||
@@ -33,21 +32,18 @@ function Header({
|
|||||||
isSignYourself,
|
isSignYourself,
|
||||||
setIsEmail,
|
setIsEmail,
|
||||||
completeBtnTitle,
|
completeBtnTitle,
|
||||||
setIsEditTemplate
|
setIsEditTemplate,
|
||||||
|
isPublicTemplate
|
||||||
}) {
|
}) {
|
||||||
const filterPrefill =
|
const filterPrefill =
|
||||||
signerPos && signerPos?.filter((data) => data.Role !== "prefill");
|
signerPos && signerPos?.filter((data) => data.Role !== "prefill");
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const navigate = useNavigate();
|
|
||||||
const [isDownloading, setIsDownloading] = useState("");
|
const [isDownloading, setIsDownloading] = useState("");
|
||||||
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||||
|
|
||||||
//function for show decline alert
|
//function for show decline alert
|
||||||
const handleDeclinePdfAlert = async () => {
|
const handleDeclinePdfAlert = async () => {
|
||||||
const currentDecline = {
|
const currentDecline = { currnt: "Sure", isDeclined: true };
|
||||||
currnt: "Sure",
|
|
||||||
isDeclined: true
|
|
||||||
};
|
|
||||||
setIsDecline(currentDecline);
|
setIsDecline(currentDecline);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,7 +60,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex justify-between items-center py-[5px] px-[10px] ">
|
<div className="flex justify-between items-center py-[5px] px-[10px] ">
|
||||||
<div onClick={() => navigate(-1)}>
|
<div onClick={() => window.history.go(-2)}>
|
||||||
<i
|
<i
|
||||||
className="fa-light fa-arrow-left text-base-content"
|
className="fa-light fa-arrow-left text-base-content"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -209,7 +205,7 @@ function Header({
|
|||||||
</DropdownMenu.Trigger>
|
</DropdownMenu.Trigger>
|
||||||
<DropdownMenu.Portal>
|
<DropdownMenu.Portal>
|
||||||
<DropdownMenu.Content
|
<DropdownMenu.Content
|
||||||
className="bg-white shadow-md rounded px-2 py-1"
|
className="bg-white shadow-md rounded-full px-3 py-2"
|
||||||
sideOffset={5}
|
sideOffset={5}
|
||||||
>
|
>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
@@ -275,7 +271,7 @@ function Header({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate(-1)}
|
onClick={() => window.history.go(-2)}
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-ghost op-btn-sm mr-[3px]"
|
className="op-btn op-btn-ghost op-btn-sm mr-[3px]"
|
||||||
>
|
>
|
||||||
@@ -298,6 +294,17 @@ function Header({
|
|||||||
) : isPdfRequestFiles ? (
|
) : isPdfRequestFiles ? (
|
||||||
alreadySign ? (
|
alreadySign ? (
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
|
<button
|
||||||
|
onClick={(e) => handleToPrint(e, pdfUrl, setIsDownloading)}
|
||||||
|
type="button"
|
||||||
|
className="op-btn op-btn-neutral op-btn-sm mr-[3px] shadow"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa-light fa-print py-[3px]"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span className="hidden lg:block">Print</span>
|
||||||
|
</button>
|
||||||
{isCompleted && (
|
{isCompleted && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -313,19 +320,6 @@ function Header({
|
|||||||
<span className="hidden lg:block">Certificate</span>
|
<span className="hidden lg:block">Certificate</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={(e) => handleToPrint(e, pdfUrl, setIsDownloading)}
|
|
||||||
type="button"
|
|
||||||
className="op-btn op-btn-neutral op-btn-sm mr-[3px] shadow"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa-light fa-print py-[3px]"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
<span className="hidden lg:block">Print</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-primary op-btn-sm mr-[3px] shadow"
|
className="op-btn op-btn-primary op-btn-sm mr-[3px] shadow"
|
||||||
@@ -343,7 +337,7 @@ function Header({
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex" data-tut="reactourFifth">
|
<div className="flex" data-tut="reactourFifth">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate(-1)}
|
onClick={() => window.history.go(-2)}
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-ghost op-btn-sm mr-[3px]"
|
className="op-btn op-btn-ghost op-btn-sm mr-[3px]"
|
||||||
>
|
>
|
||||||
@@ -364,40 +358,16 @@ function Header({
|
|||||||
>
|
>
|
||||||
Finish
|
Finish
|
||||||
</button>
|
</button>
|
||||||
<div className="op-dropdown op-dropdown-end">
|
<button
|
||||||
<div
|
type="button"
|
||||||
tabIndex={0}
|
className="op-btn op-btn-neutral op-btn-sm mr-[3px] shadow"
|
||||||
role="button"
|
onClick={() =>
|
||||||
className="op-btn op-btn-info op-btn-sm shadow"
|
handleDownloadPdf(pdfDetails, pdfUrl, setIsDownloading)
|
||||||
>
|
}
|
||||||
<i
|
>
|
||||||
className="fa-light fa-ellipsis-v"
|
<i className="fa-light fa-arrow-down font-semibold lg:hidden"></i>
|
||||||
aria-hidden="true"
|
<span className="hidden lg:block">Download</span>
|
||||||
></i>
|
</button>
|
||||||
</div>
|
|
||||||
<ul
|
|
||||||
tabIndex={0}
|
|
||||||
className="op-dropdown-content z-[1] op-menu op-menu-sm p-1 shadow bg-base-100 rounded-box mt-1"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
onClick={() =>
|
|
||||||
handleDownloadPdf(
|
|
||||||
pdfDetails,
|
|
||||||
pdfUrl,
|
|
||||||
setIsDownloading
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span className="font-semibold text-[12px]">
|
|
||||||
<i
|
|
||||||
className="fa-light fa-arrow-down"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>{" "}
|
|
||||||
Download
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -443,10 +413,24 @@ function Header({
|
|||||||
<span className="hidden lg:block ml-1">Mail</span>
|
<span className="hidden lg:block ml-1">Mail</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
) : isPublicTemplate ? (
|
||||||
|
<>
|
||||||
|
<div className="flex">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="op-btn op-btn-primary op-btn-sm shadow"
|
||||||
|
onClick={() => {
|
||||||
|
embedWidgetsData();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign Now
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate(-1)}
|
onClick={() => window.history.go(-2)}
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-ghost op-btn-sm mr-[3px]"
|
className="op-btn op-btn-ghost op-btn-sm mr-[3px]"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import PlaceholderBorder from "./PlaceholderBorder";
|
|||||||
import { Rnd } from "react-rnd";
|
import { Rnd } from "react-rnd";
|
||||||
import {
|
import {
|
||||||
defaultWidthHeight,
|
defaultWidthHeight,
|
||||||
|
getContainerScale,
|
||||||
handleCopyNextToWidget,
|
handleCopyNextToWidget,
|
||||||
isTabAndMobile,
|
isTabAndMobile,
|
||||||
onChangeInput,
|
onChangeInput,
|
||||||
@@ -234,25 +235,29 @@ function Placeholder(props) {
|
|||||||
setDraggingEnabled(false);
|
setDraggingEnabled(false);
|
||||||
}
|
}
|
||||||
if ((props.isNeedSign || props.isSignYourself) && !props.isDragging) {
|
if ((props.isNeedSign || props.isSignYourself) && !props.isDragging) {
|
||||||
if (props.pos.type) {
|
if (props?.ispublicTemplate) {
|
||||||
if (
|
props.handleUserDetails();
|
||||||
props.pos.type === "signature" ||
|
|
||||||
props.pos.type === "stamp" ||
|
|
||||||
props.pos.type === "image"
|
|
||||||
) {
|
|
||||||
props.setIsSignPad(true);
|
|
||||||
props.setSignKey(props.pos.key);
|
|
||||||
props.setIsStamp(props.pos.isStamp);
|
|
||||||
} else if (props.pos.type === "initials") {
|
|
||||||
props.setIsSignPad(true);
|
|
||||||
props.setSignKey(props.pos.key);
|
|
||||||
props.setIsStamp(props.pos.isStamp);
|
|
||||||
props.setIsInitial(true);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
props.setIsSignPad(true);
|
if (props.pos.type) {
|
||||||
props.setSignKey(props.pos.key);
|
if (
|
||||||
props.setIsStamp(props.pos?.isStamp ? props.pos.isStamp : false);
|
props.pos.type === "signature" ||
|
||||||
|
props.pos.type === "stamp" ||
|
||||||
|
props.pos.type === "image"
|
||||||
|
) {
|
||||||
|
props.setIsSignPad(true);
|
||||||
|
props.setSignKey(props.pos.key);
|
||||||
|
props.setIsStamp(props.pos.isStamp);
|
||||||
|
} else if (props.pos.type === "initials") {
|
||||||
|
props.setIsSignPad(true);
|
||||||
|
props.setSignKey(props.pos.key);
|
||||||
|
props.setIsStamp(props.pos.isStamp);
|
||||||
|
props.setIsInitial(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
props.setIsSignPad(true);
|
||||||
|
props.setSignKey(props.pos.key);
|
||||||
|
props.setIsStamp(props.pos?.isStamp ? props.pos.isStamp : false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
props.isPlaceholder &&
|
props.isPlaceholder &&
|
||||||
@@ -262,6 +267,10 @@ function Placeholder(props) {
|
|||||||
if (props.pos.key === props.selectWidgetId) {
|
if (props.pos.key === props.selectWidgetId) {
|
||||||
props.handleLinkUser(props.data.Id);
|
props.handleLinkUser(props.data.Id);
|
||||||
props.setUniqueId(props.data.Id);
|
props.setUniqueId(props.data.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
}
|
}
|
||||||
} else if (!props.pos.type) {
|
} else if (!props.pos.type) {
|
||||||
if (
|
if (
|
||||||
@@ -291,6 +300,12 @@ function Placeholder(props) {
|
|||||||
}
|
}
|
||||||
if (props.isNeedSign && props.data?.signerObjId === props.signerObjId) {
|
if (props.isNeedSign && props.data?.signerObjId === props.signerObjId) {
|
||||||
handleWidgetIdandPopup();
|
handleWidgetIdandPopup();
|
||||||
|
} else if (
|
||||||
|
props?.isNeedSign &&
|
||||||
|
props?.uniqueId &&
|
||||||
|
props.data?.Id === props?.uniqueId
|
||||||
|
) {
|
||||||
|
handleWidgetIdandPopup();
|
||||||
} else if (props.isPlaceholder || props.isSignYourself) {
|
} else if (props.isPlaceholder || props.isSignYourself) {
|
||||||
handleWidgetIdandPopup();
|
handleWidgetIdandPopup();
|
||||||
}
|
}
|
||||||
@@ -303,7 +318,9 @@ function Placeholder(props) {
|
|||||||
props?.setShowDropdown(true);
|
props?.setShowDropdown(true);
|
||||||
} else if (props.pos.type === "checkbox") {
|
} else if (props.pos.type === "checkbox") {
|
||||||
props?.setIsCheckbox(true);
|
props?.setIsCheckbox(true);
|
||||||
} else if (
|
}
|
||||||
|
//condition to handle setting icon for signyour-self flow for all type text widgets
|
||||||
|
else if (
|
||||||
[
|
[
|
||||||
textInputWidget,
|
textInputWidget,
|
||||||
textWidget,
|
textWidget,
|
||||||
@@ -311,19 +328,33 @@ function Placeholder(props) {
|
|||||||
"company",
|
"company",
|
||||||
"job title",
|
"job title",
|
||||||
"email"
|
"email"
|
||||||
].includes(props.pos.type)
|
].includes(props.pos.type) &&
|
||||||
|
props.isSignYourself
|
||||||
) {
|
) {
|
||||||
props.handleTextSettingModal(true);
|
props.handleTextSettingModal(true);
|
||||||
} else {
|
} else {
|
||||||
props?.handleNameModal && props?.handleNameModal(true);
|
props?.handleNameModal && props?.handleNameModal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//condition for only placeholder and template flow
|
||||||
if (props.data && props?.pos?.type !== textWidget) {
|
if (props.data && props?.pos?.type !== textWidget) {
|
||||||
props.setSignerObjId(props?.data?.signerObjId);
|
props.setSignerObjId(props?.data?.signerObjId);
|
||||||
props.setUniqueId(props?.data?.Id);
|
props.setUniqueId(props?.data?.Id);
|
||||||
} else if (props.data && props.pos.type === textWidget) {
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
|
}
|
||||||
|
//condition to handle in placeholder and template flow for text widget signerId for text widgets i have to set uniqueId in tempSignerId because
|
||||||
|
//it does not have any signer user and any signerobjId
|
||||||
|
else if (props.data && props.pos.type === textWidget) {
|
||||||
props.setTempSignerId(props.uniqueId);
|
props.setTempSignerId(props.uniqueId);
|
||||||
props.setUniqueId(props?.data?.Id);
|
props.setUniqueId(props?.data?.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
}
|
}
|
||||||
props.setSignKey(props.pos.key);
|
props.setSignKey(props.pos.key);
|
||||||
props.setWidgetType(props.pos.type);
|
props.setWidgetType(props.pos.type);
|
||||||
@@ -340,10 +371,19 @@ function Placeholder(props) {
|
|||||||
if (props.data && props?.pos?.type !== textWidget) {
|
if (props.data && props?.pos?.type !== textWidget) {
|
||||||
props.setSignerObjId(props?.data?.signerObjId);
|
props.setSignerObjId(props?.data?.signerObjId);
|
||||||
props.setUniqueId(props?.data?.Id);
|
props.setUniqueId(props?.data?.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
} else if (props.data && props.pos.type === textWidget) {
|
} else if (props.data && props.pos.type === textWidget) {
|
||||||
props.setTempSignerId(props.uniqueId);
|
props.setTempSignerId(props.uniqueId);
|
||||||
props.setSignerObjId(props?.data?.signerObjId);
|
props.setSignerObjId(props?.data?.signerObjId);
|
||||||
props.setUniqueId(props?.data?.Id);
|
props.setUniqueId(props?.data?.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//checking widget's type and open widget copy modal for required widgets
|
//checking widget's type and open widget copy modal for required widgets
|
||||||
@@ -400,6 +440,9 @@ function Placeholder(props) {
|
|||||||
<>
|
<>
|
||||||
{(props.isPlaceholder || props.isSignYourself) && (
|
{(props.isPlaceholder || props.isSignYourself) && (
|
||||||
<>
|
<>
|
||||||
|
{/* condition to add setting icon for signyour-self flow for particular text widgets
|
||||||
|
and also it have diffrent position
|
||||||
|
*/}
|
||||||
{[
|
{[
|
||||||
"checkbox",
|
"checkbox",
|
||||||
textInputWidget,
|
textInputWidget,
|
||||||
@@ -426,6 +469,7 @@ function Placeholder(props) {
|
|||||||
}}
|
}}
|
||||||
></i>
|
></i>
|
||||||
) : (
|
) : (
|
||||||
|
/* condition to add setting icon for placeholder & template flow for all widgets except signature and date */
|
||||||
((!props?.pos?.type && props.pos.isStamp) ||
|
((!props?.pos?.type && props.pos.isStamp) ||
|
||||||
(props?.pos?.type &&
|
(props?.pos?.type &&
|
||||||
!["date", "signature"].includes(props.pos.type) &&
|
!["date", "signature"].includes(props.pos.type) &&
|
||||||
@@ -448,7 +492,7 @@ function Placeholder(props) {
|
|||||||
></i>
|
></i>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
{/* condition for usericon for all widgets except text widgets and signyour-self flow */}
|
||||||
{props.pos.type !== textWidget && !props.isSignYourself && (
|
{props.pos.type !== textWidget && !props.isSignYourself && (
|
||||||
<i
|
<i
|
||||||
data-tut="assignSigner"
|
data-tut="assignSigner"
|
||||||
@@ -457,17 +501,26 @@ function Placeholder(props) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
props.handleLinkUser(props.data.Id);
|
props.handleLinkUser(props.data.Id);
|
||||||
props.setUniqueId(props.data.Id);
|
props.setUniqueId(props.data.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
}}
|
}}
|
||||||
onTouchEnd={(e) => {
|
onTouchEnd={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
props.handleLinkUser(props.data.Id);
|
props.handleLinkUser(props.data.Id);
|
||||||
props.setUniqueId(props.data.Id);
|
props.setUniqueId(props.data.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
}}
|
}}
|
||||||
style={{ color: "#188ae2", right: "32px", top: "-18px" }}
|
style={{ color: "#188ae2", right: "32px", top: "-18px" }}
|
||||||
></i>
|
></i>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{/* setting icon only for date widgets */}
|
||||||
{props.pos.type === "date" && selectDate && (
|
{props.pos.type === "date" && selectDate && (
|
||||||
<div
|
<div
|
||||||
id="menu-container"
|
id="menu-container"
|
||||||
@@ -483,6 +536,10 @@ function Placeholder(props) {
|
|||||||
if (props.data) {
|
if (props.data) {
|
||||||
props.setSignKey(props.pos.key);
|
props.setSignKey(props.pos.key);
|
||||||
props.setUniqueId(props.data.Id);
|
props.setUniqueId(props.data.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onTouchEnd={(e) => {
|
onTouchEnd={(e) => {
|
||||||
@@ -491,6 +548,10 @@ function Placeholder(props) {
|
|||||||
if (props.data) {
|
if (props.data) {
|
||||||
props.setSignKey(props.pos.key);
|
props.setSignKey(props.pos.key);
|
||||||
props.setUniqueId(props.data.Id);
|
props.setUniqueId(props.data.Id);
|
||||||
|
const checkIndex = props.xyPostion.findIndex(
|
||||||
|
(data) => data.Id === props.data.Id
|
||||||
|
);
|
||||||
|
props.setIsSelectId(checkIndex || 0);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -532,29 +593,37 @@ function Placeholder(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{/* copy icon for all widgets */}
|
||||||
<i
|
<i
|
||||||
className="fa-light fa-copy icon"
|
className="fa-light fa-copy icon"
|
||||||
onClick={(e) => handleCopyPlaceholder(e)}
|
onClick={(e) => handleCopyPlaceholder(e)}
|
||||||
onTouchEnd={(e) => handleCopyPlaceholder(e)}
|
onTouchEnd={(e) => handleCopyPlaceholder(e)}
|
||||||
style={{ color: "#188ae2", right: "12px", top: "-18px" }}
|
style={{ color: "#188ae2", right: "12px", top: "-18px" }}
|
||||||
></i>
|
></i>
|
||||||
|
{/* delete icon for all widgets */}
|
||||||
<i
|
<i
|
||||||
className="fa-light fa-circle-xmark icon"
|
className="fa-light fa-circle-xmark icon"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
//condition for template and placeholder flow
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
props.handleDeleteSign(props.pos.key, props.data.Id);
|
props.handleDeleteSign(props.pos.key, props.data.Id);
|
||||||
} else {
|
}
|
||||||
|
//condition for signyour-self flow
|
||||||
|
else {
|
||||||
props.handleDeleteSign(props.pos.key);
|
props.handleDeleteSign(props.pos.key);
|
||||||
props.setIsStamp(false);
|
props.setIsStamp(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
//for mobile and tablet touch event
|
||||||
onTouchEnd={(e) => {
|
onTouchEnd={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
//condition for template and placeholder flow
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
props.handleDeleteSign(props.pos.key, props.data?.Id);
|
props.handleDeleteSign(props.pos.key, props.data?.Id);
|
||||||
} else {
|
}
|
||||||
|
//condition for signyour-self flow
|
||||||
|
else {
|
||||||
props.handleDeleteSign(props.pos.key);
|
props.handleDeleteSign(props.pos.key);
|
||||||
props.setIsStamp(false);
|
props.setIsStamp(false);
|
||||||
}
|
}
|
||||||
@@ -566,10 +635,11 @@ function Placeholder(props) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
const xPos = (pos, signYourself) => {
|
const xPos = (pos, signYourself) => {
|
||||||
const getPdfPageWidth = props.pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === props.pageNumber
|
props.pdfOriginalWH,
|
||||||
|
props.pageNumber,
|
||||||
|
props.containerWH
|
||||||
);
|
);
|
||||||
const containerScale = props.containerWH.width / getPdfPageWidth?.width;
|
|
||||||
const resizePos = pos.xPosition;
|
const resizePos = pos.xPosition;
|
||||||
if (signYourself) {
|
if (signYourself) {
|
||||||
return resizePos * containerScale * props.scale;
|
return resizePos * containerScale * props.scale;
|
||||||
@@ -591,10 +661,11 @@ function Placeholder(props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const yPos = (pos, signYourself) => {
|
const yPos = (pos, signYourself) => {
|
||||||
const getPdfPageWidth = props.pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === props.pageNumber
|
props.pdfOriginalWH,
|
||||||
|
props.pageNumber,
|
||||||
|
props.containerWH
|
||||||
);
|
);
|
||||||
const containerScale = props.containerWH.width / getPdfPageWidth.width;
|
|
||||||
const resizePos = pos.yPosition;
|
const resizePos = pos.yPosition;
|
||||||
|
|
||||||
if (signYourself) {
|
if (signYourself) {
|
||||||
@@ -621,13 +692,25 @@ function Placeholder(props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getCursor = () => {
|
||||||
|
if (props.data && props.isNeedSign) {
|
||||||
|
if (props?.signerObjId && props.data?.signerObjId === props.signerObjId) {
|
||||||
|
return "pointer";
|
||||||
|
} else if (props?.uniqueId && props.data?.Id === props.uniqueId) {
|
||||||
|
return "pointer";
|
||||||
|
} else {
|
||||||
|
return "not-allowed";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "all-scroll";
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<Rnd
|
<Rnd
|
||||||
id={props.pos.key}
|
id={props.pos.key}
|
||||||
data-tut={props.pos.key === props.unSignedWidgetId ? "IsSigned" : ""}
|
data-tut={props.pos.key === props.unSignedWidgetId ? "IsSigned" : ""}
|
||||||
key={props.pos.key}
|
key={props.pos.key}
|
||||||
lockAspectRatio={
|
lockAspectRatio={
|
||||||
// props.pos.type !== textWidget
|
|
||||||
![
|
![
|
||||||
textWidget,
|
textWidget,
|
||||||
"email",
|
"email",
|
||||||
@@ -671,12 +754,7 @@ function Placeholder(props) {
|
|||||||
props.pos.type !== "company" &&
|
props.pos.type !== "company" &&
|
||||||
props.pos.type !== "job title" &&
|
props.pos.type !== "job title" &&
|
||||||
"center",
|
"center",
|
||||||
cursor:
|
cursor: getCursor(),
|
||||||
props.data && props.isNeedSign
|
|
||||||
? props.data?.signerObjId === props.signerObjId
|
|
||||||
? "pointer"
|
|
||||||
: "not-allowed"
|
|
||||||
: "all-scroll",
|
|
||||||
zIndex:
|
zIndex:
|
||||||
props.pos.type === "date"
|
props.pos.type === "date"
|
||||||
? props.pos.key === props.selectWidgetId
|
? props.pos.key === props.selectWidgetId
|
||||||
@@ -775,7 +853,6 @@ function Placeholder(props) {
|
|||||||
)}
|
)}
|
||||||
{isTabAndMobile ? (
|
{isTabAndMobile ? (
|
||||||
<div
|
<div
|
||||||
// className="sm:inline-block md:inline-block lg:hidden "
|
|
||||||
className="flex items-stretch"
|
className="flex items-stretch"
|
||||||
style={{
|
style={{
|
||||||
left: xPos(props.pos, props.isSignYourself),
|
left: xPos(props.pos, props.isSignYourself),
|
||||||
|
|||||||
@@ -47,14 +47,11 @@ function PlaceholderBorder(props) {
|
|||||||
onTouchEnd={() =>
|
onTouchEnd={() =>
|
||||||
props.pos.type === textWidget && props?.setDraggingEnabled(true)
|
props.pos.type === textWidget && props?.setDraggingEnabled(true)
|
||||||
}
|
}
|
||||||
className="absolute inline-block w-[14px] h-[14px] hover:cursor-sw-resize"
|
className="absolute inline-block w-[14px] h-[14px] border-[0.2px] overflow-hidden border-dashed"
|
||||||
style={{
|
style={{
|
||||||
borderColor: themeColor,
|
borderColor: themeColor,
|
||||||
borderStyle: "dashed",
|
minWidth: handleMinWidth() || 0,
|
||||||
minWidth: handleMinWidth(),
|
minHeight: handleMinHeight() || 0
|
||||||
minHeight: handleMinHeight(),
|
|
||||||
borderWidth: "0.2px",
|
|
||||||
overflow: "hidden"
|
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -189,9 +189,7 @@ function PlaceholderCopy(props) {
|
|||||||
<ModalUi
|
<ModalUi
|
||||||
isOpen={props.isPageCopy}
|
isOpen={props.isPageCopy}
|
||||||
title={"Copy to all pages"}
|
title={"Copy to all pages"}
|
||||||
handleClose={() => {
|
handleClose={() => handleUniqueId()}
|
||||||
props.setIsPageCopy(false);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className="h-full p-[20px] text-base-content">
|
<div className="h-full p-[20px] text-base-content">
|
||||||
{copyType.map((data, key) => {
|
{copyType.map((data, key) => {
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ import DatePicker from "react-datepicker";
|
|||||||
import "react-datepicker/dist/react-datepicker.css";
|
import "react-datepicker/dist/react-datepicker.css";
|
||||||
import "../../styles/signature.css";
|
import "../../styles/signature.css";
|
||||||
import RegexParser from "regex-parser";
|
import RegexParser from "regex-parser";
|
||||||
|
import { emailRegex } from "../../constant/const";
|
||||||
const textWidgetCls =
|
const textWidgetCls =
|
||||||
"w-full h-full md:min-w-full md:min-h-full z-[999] text-[12px] rounded-[2px] border-[1px] border-[#007bff] overflow-hidden resize-none outline-none text-base-content item-center bg-base-100 whitespace-pre-wrap";
|
"w-full h-full md:min-w-full md:min-h-full z-[999] text-[12px] rounded-[2px] border-[1px] border-[#007bff] overflow-hidden resize-none outline-none text-base-content item-center whitespace-pre-wrap bg-white";
|
||||||
const selectWidgetCls =
|
const selectWidgetCls =
|
||||||
"w-full h-full absolute left-0 top-0 border-[1px] border-[#007bff] rounded-[2px] focus:outline-none bg-base-100 text-base-content";
|
"w-full h-full absolute left-0 top-0 border-[1px] border-[#007bff] rounded-[2px] focus:outline-none text-base-content";
|
||||||
function PlaceholderType(props) {
|
function PlaceholderType(props) {
|
||||||
const type = props?.pos?.type;
|
const type = props?.pos?.type;
|
||||||
const [selectOption, setSelectOption] = useState("");
|
const [selectOption, setSelectOption] = useState("");
|
||||||
@@ -61,7 +62,7 @@ function PlaceholderType(props) {
|
|||||||
if (validateType && validateType !== "text") {
|
if (validateType && validateType !== "text") {
|
||||||
switch (validateType) {
|
switch (validateType) {
|
||||||
case "email":
|
case "email":
|
||||||
regexValidation = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
regexValidation = emailRegex;
|
||||||
validateExpression(regexValidation);
|
validateExpression(regexValidation);
|
||||||
break;
|
break;
|
||||||
case "number":
|
case "number":
|
||||||
@@ -139,8 +140,7 @@ function PlaceholderType(props) {
|
|||||||
|
|
||||||
const ExampleCustomInput = forwardRef(({ value, onClick }, ref) => (
|
const ExampleCustomInput = forwardRef(({ value, onClick }, ref) => (
|
||||||
<div
|
<div
|
||||||
className={`${selectWidgetCls} overflow-hidden`}
|
className={`${selectWidgetCls} text-[12px] overflow-hidden`}
|
||||||
style={{ fontSize: calculateFontSize() }}
|
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
>
|
>
|
||||||
@@ -171,12 +171,6 @@ function PlaceholderType(props) {
|
|||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [type]);
|
}, [type]);
|
||||||
|
|
||||||
const calculateFontSize = () => {
|
|
||||||
const fontSize = 10 + Math.min(props.pos.Width, props.pos.Height) * 0.1;
|
|
||||||
const size = fontSize ? fontSize : 12;
|
|
||||||
return size + "px";
|
|
||||||
};
|
|
||||||
//function for show checked checkbox
|
//function for show checked checkbox
|
||||||
const selectCheckbox = (ind) => {
|
const selectCheckbox = (ind) => {
|
||||||
const res = props.pos.options?.response;
|
const res = props.pos.options?.response;
|
||||||
@@ -423,8 +417,11 @@ function PlaceholderType(props) {
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
color: "black",
|
fontSize: props.pos.options?.fontSize
|
||||||
fontSize: "12px"
|
? props.pos.options?.fontSize + "px"
|
||||||
|
: "12px",
|
||||||
|
color: props.pos.options?.fontColor || "black",
|
||||||
|
overflow: "hidden"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{type}</span>
|
<span>{type}</span>
|
||||||
@@ -433,7 +430,7 @@ function PlaceholderType(props) {
|
|||||||
case "dropdown":
|
case "dropdown":
|
||||||
return props.data?.signerObjId === props.signerObjId ? (
|
return props.data?.signerObjId === props.signerObjId ? (
|
||||||
<select
|
<select
|
||||||
className={`${selectWidgetCls} text-[12px]`}
|
className={`${selectWidgetCls} text-[12px] bg-inherit`}
|
||||||
id="myDropdown"
|
id="myDropdown"
|
||||||
value={selectOption}
|
value={selectOption}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
@@ -463,10 +460,7 @@ function PlaceholderType(props) {
|
|||||||
})}
|
})}
|
||||||
</select>
|
</select>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div className="text-[12px] overflow-hidden">
|
||||||
className={selectWidgetCls}
|
|
||||||
style={{ fontSize: calculateFontSize() }}
|
|
||||||
>
|
|
||||||
{props.pos?.options?.name ? props.pos.options.name : type}
|
{props.pos?.options?.name ? props.pos.options.name : type}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -522,8 +516,12 @@ function PlaceholderType(props) {
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
color: "black",
|
fontSize: props.pos.options?.fontSize
|
||||||
fontSize: "12px"
|
? props.pos.options?.fontSize + "px"
|
||||||
|
: "12px",
|
||||||
|
color: props.pos.options?.fontColor || "black",
|
||||||
|
fontFamily: "Arial, sans-serif",
|
||||||
|
overflow: "hidden"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{type}</span>
|
<span>{type}</span>
|
||||||
@@ -562,8 +560,12 @@ function PlaceholderType(props) {
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
color: "black",
|
fontSize: props.pos.options?.fontSize
|
||||||
fontSize: "12px"
|
? props.pos.options?.fontSize + "px"
|
||||||
|
: "12px",
|
||||||
|
color: props.pos.options?.fontColor || "black",
|
||||||
|
overflow: "hidden",
|
||||||
|
fontFamily: "Arial, sans-serif"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{type}</span>
|
<span>{type}</span>
|
||||||
@@ -602,15 +604,20 @@ function PlaceholderType(props) {
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
color: "black",
|
fontSize: props.pos.options?.fontSize
|
||||||
fontSize: "12px"
|
? props.pos.options?.fontSize + "px"
|
||||||
|
: "12px",
|
||||||
|
color: props.pos.options?.fontColor || "black",
|
||||||
|
fontFamily: "Arial, sans-serif",
|
||||||
|
overflow: "hidden"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{type}</span>
|
<span>{type}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
case "date":
|
case "date":
|
||||||
return (
|
return props.isSignYourself ||
|
||||||
|
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
|
||||||
<div>
|
<div>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
renderCustomHeader={({ date, changeYear, changeMonth }) => (
|
renderCustomHeader={({ date, changeYear, changeMonth }) => (
|
||||||
@@ -667,6 +674,16 @@ function PlaceholderType(props) {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="text-[12px] text-black items-center overflow-hidden">
|
||||||
|
<span>
|
||||||
|
{props.selectDate
|
||||||
|
? props.selectDate?.format
|
||||||
|
: props.pos?.options?.validation?.format
|
||||||
|
? props.pos?.options?.validation?.format
|
||||||
|
: "MM/dd/yyyy"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
case "image":
|
case "image":
|
||||||
return props.pos.SignUrl ? (
|
return props.pos.SignUrl ? (
|
||||||
@@ -713,15 +730,20 @@ function PlaceholderType(props) {
|
|||||||
fontSize: props.pos.options?.fontSize
|
fontSize: props.pos.options?.fontSize
|
||||||
? props.pos.options?.fontSize + "px"
|
? props.pos.options?.fontSize + "px"
|
||||||
: "12px",
|
: "12px",
|
||||||
color: props.pos.options?.fontColor || "black"
|
color: props.pos.options?.fontColor || "black",
|
||||||
|
fontFamily: "Arial, sans-serif"
|
||||||
}}
|
}}
|
||||||
cols="50"
|
cols="50"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
color: "black",
|
fontSize: props.pos.options?.fontSize
|
||||||
fontSize: "12px"
|
? props.pos.options?.fontSize + "px"
|
||||||
|
: "12px",
|
||||||
|
color: props.pos.options?.fontColor || "black",
|
||||||
|
fontFamily: "Arial, sans-serif",
|
||||||
|
overflow: "hidden"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{type}</span>
|
<span>{type}</span>
|
||||||
@@ -780,6 +802,7 @@ function PlaceholderType(props) {
|
|||||||
}}
|
}}
|
||||||
className={textWidgetCls}
|
className={textWidgetCls}
|
||||||
style={{
|
style={{
|
||||||
|
fontFamily: "Arial, sans-serif",
|
||||||
fontSize: props.pos.options?.fontSize
|
fontSize: props.pos.options?.fontSize
|
||||||
? props.pos.options?.fontSize + "px"
|
? props.pos.options?.fontSize + "px"
|
||||||
: "12px",
|
: "12px",
|
||||||
|
|||||||
@@ -61,15 +61,27 @@ const RecipientList = (props) => {
|
|||||||
);
|
);
|
||||||
//splice method is used to replace or add new value in array at specific index
|
//splice method is used to replace or add new value in array at specific index
|
||||||
remainingItems.splice(index, 0, ...draggedItem);
|
remainingItems.splice(index, 0, ...draggedItem);
|
||||||
|
|
||||||
//set current draggable recipient details,objectId,index,contract_className ... after replace recipient list
|
//set current draggable recipient details,objectId,index,contract_className ... after replace recipient list
|
||||||
props.setSignersData(remainingItems);
|
props?.setSignersData(remainingItems);
|
||||||
props.setSignerObjId(remainingItems[index]?.objectId || "");
|
props?.setSignerObjId(remainingItems[index]?.objectId || "");
|
||||||
props.setIsSelectId(index);
|
props?.setIsSelectId(index);
|
||||||
props.setContractName(remainingItems[index]?.className || "");
|
props?.setContractName(remainingItems[index]?.className || "");
|
||||||
props.setUniqueId(remainingItems[index]?.Id);
|
props?.setUniqueId(remainingItems[index]?.Id);
|
||||||
props.setRoleName(remainingItems[index]?.Role);
|
props?.setRoleName(remainingItems[index]?.Role);
|
||||||
props.setBlockColor(remainingItems[index]?.blockColor);
|
props?.setBlockColor(remainingItems[index]?.blockColor);
|
||||||
|
|
||||||
|
//change order of placeholder's list using sorting method
|
||||||
|
//`remainingItems` is correct order of signers after change order
|
||||||
|
const changeOrderSignerList = props?.signerPos.sort((a, b) => {
|
||||||
|
//`indexA` and `indexB` is to get element position using index in correct order array
|
||||||
|
const indexA = remainingItems.findIndex((item) => item.Id === a.Id);
|
||||||
|
const indexB = remainingItems.findIndex((item) => item.Id === b.Id);
|
||||||
|
//and then compare `indexA - indexB` value
|
||||||
|
//if positive it means indexB element comes before indexA then need to sorting
|
||||||
|
//if negative it means indexA element is on correct position do not need to sorting
|
||||||
|
return indexA - indexB;
|
||||||
|
});
|
||||||
|
props?.setSignerPos(changeOrderSignerList);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -101,7 +113,7 @@ const RecipientList = (props) => {
|
|||||||
} flex flex-row rounded-xl px-2 py-[10px] mt-1 mx-1 items-center last:mb-0.5`}
|
} flex flex-row rounded-xl px-2 py-[10px] mt-1 mx-1 items-center last:mb-0.5`}
|
||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
(!isMobile && isHover === ind) || props.isSelectListId === ind
|
(!isMobile && isHover === ind) || props.uniqueId === obj.Id
|
||||||
? obj?.blockColor
|
? obj?.blockColor
|
||||||
? obj?.blockColor
|
? obj?.blockColor
|
||||||
: color[ind % color.length]
|
: color[ind % color.length]
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ function RenderAllPdfPage({
|
|||||||
setSignBtnPosition,
|
setSignBtnPosition,
|
||||||
pageNumber,
|
pageNumber,
|
||||||
signerPos,
|
signerPos,
|
||||||
signerObjectId
|
signerObjectId,
|
||||||
|
containerWH
|
||||||
}) {
|
}) {
|
||||||
const [signPageNumber, setSignPageNumber] = useState([]);
|
const [signPageNumber, setSignPageNumber] = useState([]);
|
||||||
const [bookmarkColor, setBookmarkColor] = useState("");
|
const [bookmarkColor, setBookmarkColor] = useState("");
|
||||||
@@ -48,7 +49,7 @@ function RenderAllPdfPage({
|
|||||||
const timer = setTimeout(updateSize, 100); // match the transition duration
|
const timer = setTimeout(updateSize, 100); // match the transition duration
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [isHeader, pageContainer]);
|
}, [isHeader, pageContainer, containerWH]);
|
||||||
//'function `addSignatureBookmark` is used to display the page where the user's signature is located.
|
//'function `addSignatureBookmark` is used to display the page where the user's signature is located.
|
||||||
const addSignatureBookmark = (index) => {
|
const addSignatureBookmark = (index) => {
|
||||||
const ispageNumber = signPageNumber.includes(index + 1);
|
const ispageNumber = signPageNumber.includes(index + 1);
|
||||||
@@ -57,13 +58,12 @@ function RenderAllPdfPage({
|
|||||||
<div className="absolute z-20 top-[1px] -right-[13px] -translate-x-1/2 -translate-y-1/2">
|
<div className="absolute z-20 top-[1px] -right-[13px] -translate-x-1/2 -translate-y-1/2">
|
||||||
<i
|
<i
|
||||||
style={{ color: bookmarkColor || "red" }}
|
style={{ color: bookmarkColor || "red" }}
|
||||||
className="fa-light fa-bookmark"
|
className="fa-solid fa-bookmark"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={pageContainer} className="hidden w-[20%] bg-base-100 md:block">
|
<div ref={pageContainer} className="hidden w-[20%] bg-base-100 md:block">
|
||||||
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
|
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import RSC from "react-scrollbars-custom";
|
|||||||
import { Document, Page } from "react-pdf";
|
import { Document, Page } from "react-pdf";
|
||||||
import {
|
import {
|
||||||
defaultWidthHeight,
|
defaultWidthHeight,
|
||||||
|
getContainerScale,
|
||||||
handleImageResize,
|
handleImageResize,
|
||||||
handleSignYourselfImageResize
|
handleSignYourselfImageResize
|
||||||
} from "../../constant/Utils";
|
} from "../../constant/Utils";
|
||||||
@@ -57,7 +58,10 @@ function RenderPdf({
|
|||||||
setTempSignerId,
|
setTempSignerId,
|
||||||
uniqueId,
|
uniqueId,
|
||||||
pdfOriginalWH,
|
pdfOriginalWH,
|
||||||
scale
|
scale,
|
||||||
|
setIsSelectId,
|
||||||
|
ispublicTemplate,
|
||||||
|
handleUserDetails
|
||||||
}) {
|
}) {
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
//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
|
||||||
@@ -65,10 +69,11 @@ function RenderPdf({
|
|||||||
|
|
||||||
// handle signature block width and height according to screen
|
// handle signature block width and height according to screen
|
||||||
const posWidth = (pos, signYourself) => {
|
const posWidth = (pos, signYourself) => {
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH.width / getPdfPageWidth.width || 1;
|
|
||||||
const defaultWidth = defaultWidthHeight(pos.type).width;
|
const defaultWidth = defaultWidthHeight(pos.type).width;
|
||||||
const posWidth = pos.Width ? pos.Width : defaultWidth;
|
const posWidth = pos.Width ? pos.Width : defaultWidth;
|
||||||
if (signYourself) {
|
if (signYourself) {
|
||||||
@@ -94,11 +99,11 @@ function RenderPdf({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const posHeight = (pos, signYourself) => {
|
const posHeight = (pos, signYourself) => {
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH.width / getPdfPageWidth?.width || 1;
|
|
||||||
|
|
||||||
const posHeight = pos.Height || defaultWidthHeight(pos.type).height;
|
const posHeight = pos.Height || defaultWidthHeight(pos.type).height;
|
||||||
if (signYourself) {
|
if (signYourself) {
|
||||||
return posHeight * scale * containerScale;
|
return posHeight * scale * containerScale;
|
||||||
@@ -194,6 +199,8 @@ function RenderPdf({
|
|||||||
containerWH={containerWH}
|
containerWH={containerWH}
|
||||||
pdfOriginalWH={pdfOriginalWH}
|
pdfOriginalWH={pdfOriginalWH}
|
||||||
pageNumber={pageNumber}
|
pageNumber={pageNumber}
|
||||||
|
ispublicTemplate={ispublicTemplate}
|
||||||
|
handleUserDetails={handleUserDetails}
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
@@ -319,6 +326,7 @@ function RenderPdf({
|
|||||||
containerWH={containerWH}
|
containerWH={containerWH}
|
||||||
pdfOriginalWH={pdfOriginalWH}
|
pdfOriginalWH={pdfOriginalWH}
|
||||||
pageNumber={pageNumber}
|
pageNumber={pageNumber}
|
||||||
|
setIsSelectId={setIsSelectId}
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
@@ -428,7 +436,7 @@ function RenderPdf({
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
width: containerWH.width * scale
|
width: containerWH?.width && containerWH?.width * scale
|
||||||
}}
|
}}
|
||||||
ref={drop}
|
ref={drop}
|
||||||
id="container"
|
id="container"
|
||||||
@@ -501,6 +509,7 @@ function RenderPdf({
|
|||||||
containerWH={containerWH}
|
containerWH={containerWH}
|
||||||
pdfOriginalWH={pdfOriginalWH}
|
pdfOriginalWH={pdfOriginalWH}
|
||||||
pageNumber={pageNumber}
|
pageNumber={pageNumber}
|
||||||
|
setIsSelectId={setIsSelectId}
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
@@ -570,7 +579,7 @@ function RenderPdf({
|
|||||||
{/* this component for render pdf document is in middle of the component */}
|
{/* this component for render pdf document is in middle of the component */}
|
||||||
<Document
|
<Document
|
||||||
onLoadError={() => {
|
onLoadError={() => {
|
||||||
pdfLoad(false);
|
setPdfLoad(false);
|
||||||
}}
|
}}
|
||||||
loading={"Loading Document.."}
|
loading={"Loading Document.."}
|
||||||
onLoadSuccess={pageDetails}
|
onLoadSuccess={pageDetails}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React, { useRef, useState, useEffect } from "react";
|
import React, { useRef, useState, useEffect } from "react";
|
||||||
import SignatureCanvas from "react-signature-canvas";
|
import SignatureCanvas from "react-signature-canvas";
|
||||||
|
|
||||||
function SignPad({
|
function SignPad({
|
||||||
isSignPad,
|
isSignPad,
|
||||||
isStamp,
|
isStamp,
|
||||||
@@ -99,7 +98,12 @@ function SignPad({
|
|||||||
} else {
|
} else {
|
||||||
if (isTab === "type") {
|
if (isTab === "type") {
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
onSaveSign(null, false, textWidth, textHeight);
|
onSaveSign(
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
!isInitial && textWidth > 150 ? 150 : textWidth,
|
||||||
|
!isInitial && textHeight > 35 ? 35 : textHeight
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
canvasRef.current.clear();
|
canvasRef.current.clear();
|
||||||
@@ -149,7 +153,6 @@ function SignPad({
|
|||||||
const isWidgetType = currWidgetsDetails?.type;
|
const isWidgetType = currWidgetsDetails?.type;
|
||||||
const signatureType = currWidgetsDetails?.signatureType;
|
const signatureType = currWidgetsDetails?.signatureType;
|
||||||
const url = currWidgetsDetails?.SignUrl;
|
const url = currWidgetsDetails?.SignUrl;
|
||||||
|
|
||||||
//checking widget type and draw type signature url
|
//checking widget type and draw type signature url
|
||||||
if (isInitial) {
|
if (isInitial) {
|
||||||
if (isWidgetType === "initials" && signatureType === "draw" && url) {
|
if (isWidgetType === "initials" && signatureType === "draw" && url) {
|
||||||
@@ -164,8 +167,8 @@ function SignPad({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const trimmedName = currentUserName.trim();
|
const trimmedName = currentUserName && currentUserName.trim();
|
||||||
const firstCharacter = trimmedName.charAt(0);
|
const firstCharacter = trimmedName?.charAt(0);
|
||||||
const userName = isInitial ? firstCharacter : currentUserName;
|
const userName = isInitial ? firstCharacter : currentUserName;
|
||||||
setSignValue(userName);
|
setSignValue(userName);
|
||||||
setFontSelect("Fasthand");
|
setFontSelect("Fasthand");
|
||||||
@@ -212,11 +215,11 @@ function SignPad({
|
|||||||
: fontSelect
|
: fontSelect
|
||||||
? fontSelect
|
? fontSelect
|
||||||
: "Fasthand";
|
: "Fasthand";
|
||||||
|
const fontSizeValue = "40px";
|
||||||
//creating span for getting text content width
|
//creating span for getting text content width
|
||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
span.textContent = textContent;
|
span.textContent = textContent;
|
||||||
span.style.font = `20px ${fontfamily}`; // here put your text size and font family
|
span.style.font = `${fontSizeValue} ${fontfamily}`; // here put your text size and font family
|
||||||
span.style.color = color ? color : penColor;
|
span.style.color = color ? color : penColor;
|
||||||
span.style.display = "hidden";
|
span.style.display = "hidden";
|
||||||
document.body.appendChild(span); // Replace 'container' with the ID of the container element
|
document.body.appendChild(span); // Replace 'container' with the ID of the container element
|
||||||
@@ -226,7 +229,8 @@ function SignPad({
|
|||||||
// Draw the text content on the canvas
|
// Draw the text content on the canvas
|
||||||
const ctx = canvasElement.getContext("2d");
|
const ctx = canvasElement.getContext("2d");
|
||||||
const pixelRatio = window.devicePixelRatio || 1;
|
const pixelRatio = window.devicePixelRatio || 1;
|
||||||
const width = span.offsetWidth;
|
const addExtraWidth = isInitial ? 10 : 50;
|
||||||
|
const width = span.offsetWidth + addExtraWidth;
|
||||||
const height = span.offsetHeight;
|
const height = span.offsetHeight;
|
||||||
setTextWidth(width);
|
setTextWidth(width);
|
||||||
setTextHeight(height);
|
setTextHeight(height);
|
||||||
@@ -299,8 +303,9 @@ function SignPad({
|
|||||||
<div className="flex flex-row justify-between mt-[3px]">
|
<div className="flex flex-row justify-between mt-[3px]">
|
||||||
<div className="flex flex-row justify-between gap-[5px] md:gap-[8px] text-[11px] md:text-base">
|
<div className="flex flex-row justify-between gap-[5px] md:gap-[8px] text-[11px] md:text-base">
|
||||||
{isStamp ? (
|
{isStamp ? (
|
||||||
<span className="op-link-primary op-link">
|
<span className="text-base-content font-bold text-lg">
|
||||||
{widgetType === "image"
|
{widgetType === "image" ||
|
||||||
|
currWidgetsDetails?.type === "image"
|
||||||
? "Upload image"
|
? "Upload image"
|
||||||
: "Upload stamp image"}
|
: "Upload stamp image"}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ function SignerListComponent(props) {
|
|||||||
className="flex w-[30px] h-[30px] rounded-full justify-center items-center mx-1"
|
className="flex w-[30px] h-[30px] rounded-full justify-center items-center mx-1"
|
||||||
>
|
>
|
||||||
<span className="text-[12px] text-center font-bold text-black uppercase">
|
<span className="text-[12px] text-center font-bold text-black uppercase">
|
||||||
{getFirstLetter(props?.obj?.Name || props?.obj?.Role)}
|
{getFirstLetter(
|
||||||
|
props.obj?.Name || props.obj?.email || props.obj?.Role
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ function TextFontSetting(props) {
|
|||||||
isOpen={props.isTextSetting}
|
isOpen={props.isTextSetting}
|
||||||
reduceWidth={"max-w-[350px]"}
|
reduceWidth={"max-w-[350px]"}
|
||||||
title={"Text field"}
|
title={"Text field"}
|
||||||
handleClose={() => {
|
handleClose={() => props.setIsTextSetting(false)}
|
||||||
props.setIsTextSetting(false);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className="h-full p-[20px]">
|
<div className="h-full p-[20px]">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
@@ -19,7 +17,9 @@ function TextFontSetting(props) {
|
|||||||
<select
|
<select
|
||||||
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
value={
|
value={
|
||||||
props.fontSize || props.currWidgetsDetails?.options?.fontSize
|
props.fontSize ||
|
||||||
|
props.currWidgetsDetails?.options?.fontSize ||
|
||||||
|
"12"
|
||||||
}
|
}
|
||||||
onChange={(e) => props.setFontSize(e.target.value)}
|
onChange={(e) => props.setFontSize(e.target.value)}
|
||||||
>
|
>
|
||||||
@@ -35,7 +35,9 @@ function TextFontSetting(props) {
|
|||||||
<span>color: </span>
|
<span>color: </span>
|
||||||
<select
|
<select
|
||||||
value={
|
value={
|
||||||
props.fontColor || props.currWidgetsDetails?.options?.fontColor
|
props.fontColor ||
|
||||||
|
props.currWidgetsDetails?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
}
|
}
|
||||||
onChange={(e) => props.setFontColor(e.target.value)}
|
onChange={(e) => props.setFontColor(e.target.value)}
|
||||||
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
|
|||||||
@@ -37,11 +37,10 @@ function WidgetComponent({
|
|||||||
sendInOrder,
|
sendInOrder,
|
||||||
isTemplateFlow,
|
isTemplateFlow,
|
||||||
setBlockColor,
|
setBlockColor,
|
||||||
blockColor,
|
setIsAddSigner,
|
||||||
setIsAddSigner
|
uniqueId
|
||||||
}) {
|
}) {
|
||||||
const [isSignersModal, setIsSignersModal] = useState(false);
|
const [isSignersModal, setIsSignersModal] = useState(false);
|
||||||
|
|
||||||
const [, dropdown] = useDrag({
|
const [, dropdown] = useDrag({
|
||||||
type: "BOX",
|
type: "BOX",
|
||||||
item: {
|
item: {
|
||||||
@@ -187,7 +186,6 @@ function WidgetComponent({
|
|||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const scrollContainerRef = useRef(null);
|
const scrollContainerRef = useRef(null);
|
||||||
const [widget, setWidget] = useState([]);
|
const [widget, setWidget] = useState([]);
|
||||||
|
|
||||||
const color = [
|
const color = [
|
||||||
"#93a3db",
|
"#93a3db",
|
||||||
"#e6c3db",
|
"#e6c3db",
|
||||||
@@ -245,86 +243,66 @@ function WidgetComponent({
|
|||||||
? textWidgetData
|
? textWidgetData
|
||||||
: widget;
|
: widget;
|
||||||
|
|
||||||
|
const handleSelectRecipient = () => {
|
||||||
|
if (
|
||||||
|
signersdata[isSelectListId]?.Email ||
|
||||||
|
signersdata[isSelectListId]?.Role
|
||||||
|
) {
|
||||||
|
const userData =
|
||||||
|
signersdata[isSelectListId]?.Name || signersdata[isSelectListId]?.Role;
|
||||||
|
const name =
|
||||||
|
userData?.length > 20 ? `${userData.slice(0, 20)}...` : userData;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isMobile ? (
|
{isMobile ? (
|
||||||
!isMailSend && (
|
!isMailSend && (
|
||||||
<div
|
<div id="navbar" className="fixed z-[99] bottom-0 right-0 w-full">
|
||||||
id="navbar"
|
{isSigners && (
|
||||||
className="fixed z-[99] bottom-0 right-0"
|
<div className="w-full mb-[5px] flex justify-center items-center gap-1">
|
||||||
style={{ width: window.innerWidth + "px" }}
|
<div className="w-full ml-[5px]" onClick={() => handleModal()}>
|
||||||
>
|
<select
|
||||||
<div className="mx-1">
|
data-tut="recipientArea"
|
||||||
{isSigners && (
|
className="w-full op-select op-select-bordered pointer-events-none"
|
||||||
<div
|
value={handleSelectRecipient()}
|
||||||
data-tut="recipientArea"
|
style={{
|
||||||
className="py-[10px] flex justify-center items-center op-card"
|
backgroundColor: isSelectListId
|
||||||
style={{
|
|
||||||
background: blockColor
|
|
||||||
? blockColor
|
|
||||||
: isSelectListId
|
|
||||||
? color[isSelectListId % color.length]
|
? color[isSelectListId % color.length]
|
||||||
: color[0]
|
: color[0]
|
||||||
}}
|
}}
|
||||||
onClick={() => handleModal()}
|
|
||||||
>
|
|
||||||
<span className="text-[13px] font-bold flex items-center">
|
|
||||||
{title ? title : "Recipient"}
|
|
||||||
{signersdata[isSelectListId]?.Role && (
|
|
||||||
<div>
|
|
||||||
{signersdata[isSelectListId]?.Name ? (
|
|
||||||
<>
|
|
||||||
:{" "}
|
|
||||||
{signersdata[isSelectListId]?.Name?.length > 12
|
|
||||||
? `${signersdata[isSelectListId].Name.slice(
|
|
||||||
0,
|
|
||||||
12
|
|
||||||
)}...`
|
|
||||||
: signersdata[isSelectListId]?.Name}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
:{" "}
|
|
||||||
{signersdata[isSelectListId]?.Role?.length > 12
|
|
||||||
? `${signersdata[isSelectListId].Role.slice(
|
|
||||||
0,
|
|
||||||
12
|
|
||||||
)}...`
|
|
||||||
: signersdata[isSelectListId]?.Role}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="ml-[6px] text-[16px]">
|
|
||||||
<i className="fa-light fa-angle-down"></i>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="mx-1">
|
|
||||||
{handleAddSigner ? (
|
|
||||||
<div
|
|
||||||
data-tut="reactourAddbtn"
|
|
||||||
className="op-btn op-btn-accent w-full my-[2px]"
|
|
||||||
onClick={() => handleAddSigner()}
|
|
||||||
>
|
|
||||||
<i className="fa-light fa-plus"></i>
|
|
||||||
<span>Add role</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
setIsAddSigner && (
|
|
||||||
<div
|
|
||||||
data-tut="addRecipient"
|
|
||||||
className="op-btn op-btn-accent w-full my-[2px]"
|
|
||||||
onClick={() => setIsAddSigner(true)}
|
|
||||||
>
|
>
|
||||||
<i className="fa-light fa-plus"></i>
|
<option value={handleSelectRecipient()}>
|
||||||
<span>Add recipients</span>
|
{handleSelectRecipient()}
|
||||||
</div>
|
</option>
|
||||||
)
|
</select>
|
||||||
)}
|
</div>
|
||||||
</div>
|
|
||||||
|
<div className="w-[18%]">
|
||||||
|
{handleAddSigner ? (
|
||||||
|
<button
|
||||||
|
data-tut="reactourAddbtn"
|
||||||
|
onClick={() => handleAddSigner()}
|
||||||
|
className="op-btn op-btn-accent"
|
||||||
|
>
|
||||||
|
<i className="fa-light fa-plus "></i>
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
setIsAddSigner && (
|
||||||
|
<button
|
||||||
|
data-tut="addRecipient"
|
||||||
|
onClick={() => setIsAddSigner(true)}
|
||||||
|
className="op-btn op-btn-accent"
|
||||||
|
>
|
||||||
|
<i className="fa-light fa-plus"></i>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
data-tut="addWidgets"
|
data-tut="addWidgets"
|
||||||
ref={scrollContainerRef}
|
ref={scrollContainerRef}
|
||||||
@@ -392,6 +370,7 @@ function WidgetComponent({
|
|||||||
sendInOrder={sendInOrder}
|
sendInOrder={sendInOrder}
|
||||||
setSignersData={setSignersData}
|
setSignersData={setSignersData}
|
||||||
setBlockColor={setBlockColor}
|
setBlockColor={setBlockColor}
|
||||||
|
uniqueId={uniqueId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import React, { useEffect, useState } from "react";
|
|||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import "../../styles/AddUser.css";
|
import "../../styles/AddUser.css";
|
||||||
import RegexParser from "regex-parser";
|
import RegexParser from "regex-parser";
|
||||||
import { textInputWidget } from "../../constant/Utils";
|
import { textInputWidget, textWidget } from "../../constant/Utils";
|
||||||
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
|
||||||
import Upgrade from "../../primitives/Upgrade";
|
import Upgrade from "../../primitives/Upgrade";
|
||||||
import { isEnableSubscription } from "../../constant/const";
|
import { isEnableSubscription } from "../../constant/const";
|
||||||
import Tooltip from "../../primitives/Tooltip";
|
import Tooltip from "../../primitives/Tooltip";
|
||||||
|
import { fontColorArr, fontsizeArr } from "../../constant/Utils";
|
||||||
|
|
||||||
const WidgetNameModal = (props) => {
|
const WidgetNameModal = (props) => {
|
||||||
const [formdata, setFormdata] = useState({
|
const [formdata, setFormdata] = useState({
|
||||||
@@ -23,7 +23,7 @@ const WidgetNameModal = (props) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.defaultdata) {
|
if (props.defaultdata) {
|
||||||
setFormdata({
|
setFormdata({
|
||||||
name: props.defaultdata?.options?.name || props?.widgetName || "",
|
name: props.defaultdata?.options?.name || "",
|
||||||
defaultValue: props.defaultdata?.options?.defaultValue || "",
|
defaultValue: props.defaultdata?.options?.defaultValue || "",
|
||||||
status: props.defaultdata?.options?.status || "required",
|
status: props.defaultdata?.options?.status || "required",
|
||||||
hint: props.defaultdata?.options?.hint || "",
|
hint: props.defaultdata?.options?.hint || "",
|
||||||
@@ -35,11 +35,11 @@ const WidgetNameModal = (props) => {
|
|||||||
} else {
|
} else {
|
||||||
setFormdata({
|
setFormdata({
|
||||||
...formdata,
|
...formdata,
|
||||||
name: props.defaultdata?.options?.name || props?.widgetName || ""
|
name: props.defaultdata?.options?.name || ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [props.defaultdata, props.widgetName]);
|
}, [props.defaultdata]);
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (props.handleData) {
|
if (props.handleData) {
|
||||||
@@ -106,22 +106,10 @@ const WidgetNameModal = (props) => {
|
|||||||
handleClose={props.handleClose && props.handleClose}
|
handleClose={props.handleClose && props.handleClose}
|
||||||
title={"Widget info"}
|
title={"Widget info"}
|
||||||
>
|
>
|
||||||
{(props.defaultdata?.type === textInputWidget ||
|
|
||||||
props.widgetName === textInputWidget) &&
|
|
||||||
!isEnableSubscription && (
|
|
||||||
<PremiumAlertHeader
|
|
||||||
message={
|
|
||||||
"Field validations are free in beta, this feature will incur a fee later."
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className={`${
|
className={`${
|
||||||
props.defaultdata?.type === textInputWidget ||
|
props.defaultdata?.type === textInputWidget ? "pt-0" : ""
|
||||||
props.widgetName === textInputWidget
|
|
||||||
? "pt-0"
|
|
||||||
: ""
|
|
||||||
} p-[20px] text-base-content`}
|
} p-[20px] text-base-content`}
|
||||||
>
|
>
|
||||||
<div className="mb-[0.75rem] text-[13px]">
|
<div className="mb-[0.75rem] text-[13px]">
|
||||||
@@ -137,67 +125,71 @@ const WidgetNameModal = (props) => {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{(props.defaultdata?.type === textInputWidget ||
|
{props.defaultdata?.type === textInputWidget && (
|
||||||
props.widgetName === textInputWidget) && (
|
|
||||||
<>
|
<>
|
||||||
<div className="mb-[0.75rem]">
|
{isEnableSubscription && (
|
||||||
<div className="flex items-center gap-1">
|
<div className="mb-[0.75rem]">
|
||||||
<label
|
<div className="flex items-center gap-1">
|
||||||
htmlFor="textvalidate"
|
<label
|
||||||
|
htmlFor="textvalidate"
|
||||||
|
className={`${
|
||||||
|
!props.isSubscribe && isEnableSubscription
|
||||||
|
? "bg-opacity-50 pointer-events-none"
|
||||||
|
: ""
|
||||||
|
} text-[13px]`}
|
||||||
|
>
|
||||||
|
Validation
|
||||||
|
</label>
|
||||||
|
<Tooltip
|
||||||
|
url={"https://www.w3schools.com/jsref/jsref_obj_regexp.asp"}
|
||||||
|
/>
|
||||||
|
{!props.isSubscribe && isEnableSubscription && <Upgrade />}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
!props.isSubscribe && isEnableSubscription
|
!props.isSubscribe && isEnableSubscription
|
||||||
? "bg-opacity-50 pointer-events-none"
|
? "bg-opacity-50 pointer-events-none"
|
||||||
: ""
|
: ""
|
||||||
} text-[13px]`}
|
} flex flex-row gap-[10px] mb-[0.5rem]`}
|
||||||
>
|
>
|
||||||
Validation
|
<div className="w-full relative group">
|
||||||
</label>
|
<input
|
||||||
<Tooltip
|
className="z-20 relative op-input op-input-bordered rounded-r-none op-input-sm focus:outline-none group-hover:border-base-content w-[87%] md:w-[92%] text-xs"
|
||||||
url={"https://www.w3schools.com/jsref/jsref_obj_regexp.asp"}
|
name="textvalidate"
|
||||||
/>
|
placeholder="Enter custom regular expression"
|
||||||
{!props.isSubscribe && isEnableSubscription && <Upgrade />}
|
value={formdata.textvalidate}
|
||||||
</div>
|
onChange={(e) => handleChange(e)}
|
||||||
<div
|
// onBlur={() => handleBlurRegex()}
|
||||||
className={`${
|
/>
|
||||||
!props.isSubscribe && isEnableSubscription
|
<select
|
||||||
? "bg-opacity-50 pointer-events-none"
|
className="validationlist op-input op-input-bordered op-input-sm focus:outline-none group-hover:border-base-content w-full text-xs"
|
||||||
: ""
|
name="textvalidate"
|
||||||
} flex flex-row gap-[10px] mb-[0.5rem]`}
|
value={formdata.textvalidate}
|
||||||
>
|
onChange={(e) => handleChange(e)}
|
||||||
<div className="w-full relative group">
|
onBlur={() => handleBlurRegex()}
|
||||||
<input
|
|
||||||
className="z-20 relative op-input op-input-bordered rounded-r-none op-input-sm focus:outline-none group-hover:border-base-content w-[87%] md:w-[92%] text-xs"
|
|
||||||
name="textvalidate"
|
|
||||||
placeholder="Enter custom regular expression"
|
|
||||||
value={formdata.textvalidate}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
// onBlur={() => handleBlurRegex()}
|
|
||||||
/>
|
|
||||||
<select
|
|
||||||
className="validationlist op-input op-input-bordered op-input-sm focus:outline-none group-hover:border-base-content w-full text-xs"
|
|
||||||
name="textvalidate"
|
|
||||||
value={formdata.textvalidate}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
onBlur={() => handleBlurRegex()}
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
disabled={formdata?.textvalidate}
|
|
||||||
className="text-[13px]"
|
|
||||||
>
|
>
|
||||||
Select...
|
<option
|
||||||
</option>
|
disabled={formdata?.textvalidate}
|
||||||
{inputOpt.map((data, ind) => {
|
className="text-[13px]"
|
||||||
return (
|
>
|
||||||
<option className="text-[13px]" key={ind} value={data}>
|
Select...
|
||||||
{data}
|
</option>
|
||||||
</option>
|
{inputOpt.map((data, ind) => {
|
||||||
);
|
return (
|
||||||
})}
|
<option
|
||||||
</select>
|
className="text-[13px]"
|
||||||
|
key={ind}
|
||||||
|
value={data}
|
||||||
|
>
|
||||||
|
{data}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
<div className="mb-[0.75rem]">
|
<div className="mb-[0.75rem]">
|
||||||
<label htmlFor="name" className="text-[13px]">
|
<label htmlFor="name" className="text-[13px]">
|
||||||
Default value
|
Default value
|
||||||
@@ -252,8 +244,7 @@ const WidgetNameModal = (props) => {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(props.defaultdata?.type === textInputWidget ||
|
{props.defaultdata?.type === textInputWidget && (
|
||||||
props?.widgetName === textInputWidget) && (
|
|
||||||
<div className="mb-[0.75rem]">
|
<div className="mb-[0.75rem]">
|
||||||
<label htmlFor="hint" className="text-[13px]">
|
<label htmlFor="hint" className="text-[13px]">
|
||||||
Hint
|
Hint
|
||||||
@@ -266,6 +257,63 @@ const WidgetNameModal = (props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{[
|
||||||
|
textInputWidget,
|
||||||
|
textWidget,
|
||||||
|
"name",
|
||||||
|
"company",
|
||||||
|
"job title",
|
||||||
|
"email"
|
||||||
|
].includes(props.defaultdata?.type) && (
|
||||||
|
<div className="flex items-center mb-[0.75rem]">
|
||||||
|
<span>Font size:</span>
|
||||||
|
<select
|
||||||
|
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
|
value={
|
||||||
|
props.fontSize || props.defaultdata?.options?.fontSize || "12"
|
||||||
|
}
|
||||||
|
onChange={(e) => props.setFontSize(e.target.value)}
|
||||||
|
>
|
||||||
|
{fontsizeArr.map((size, ind) => {
|
||||||
|
return (
|
||||||
|
<option className="text-[13px]" value={size} key={ind}>
|
||||||
|
{size}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
<div className="flex flex-row gap-1 items-center ml-4">
|
||||||
|
<span>color: </span>
|
||||||
|
<select
|
||||||
|
value={
|
||||||
|
props.fontColor ||
|
||||||
|
props.defaultdata?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
|
}
|
||||||
|
onChange={(e) => props.setFontColor(e.target.value)}
|
||||||
|
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
|
>
|
||||||
|
{fontColorArr.map((color, ind) => {
|
||||||
|
return (
|
||||||
|
<option value={color} key={ind}>
|
||||||
|
{color}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
props.fontColor ||
|
||||||
|
props.defaultdata?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
|
}}
|
||||||
|
className="w-5 h-[19px] ml-1"
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="h-[1px] w-full mb-[16px] bg-[#b7b3b3]"></div>
|
<div className="h-[1px] w-full mb-[16px] bg-[#b7b3b3]"></div>
|
||||||
<button type="submit" className="op-btn op-btn-primary">
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
Save
|
Save
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export default function DropboxChooser({ children, onSuccess, onCancel }) {
|
|||||||
return (
|
return (
|
||||||
<div onClick={handleChoose}>
|
<div onClick={handleChoose}>
|
||||||
{children || (
|
{children || (
|
||||||
<button className="px-2 py-[2px] text-2xl rounded border-[1px] text-blue-400 border-gray-300 w-full">
|
<button className="cursor-pointer op-input op-input-bordered focus:outline-none hover:border-base-content max-h-[35px] max-w-[45px] flex justify-center items-center">
|
||||||
<i className="fa-brands fa-dropbox"></i>
|
<i className="fa-brands fa-dropbox"></i>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ import Submenu from "./SubMenu";
|
|||||||
import SocialMedia from "./SocialMedia";
|
import SocialMedia from "./SocialMedia";
|
||||||
import dp from "../../assets/images/dp.png";
|
import dp from "../../assets/images/dp.png";
|
||||||
import sidebarList from "../../json/menuJson";
|
import sidebarList from "../../json/menuJson";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { isEnableSubscription } from "../../constant/const";
|
||||||
|
|
||||||
const Sidebar = ({ isOpen, closeSidebar }) => {
|
const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const [menuList, setmenuList] = useState([]);
|
const [menuList, setmenuList] = useState([]);
|
||||||
const [submenuOpen, setSubmenuOpen] = useState(false);
|
const [submenuOpen, setSubmenuOpen] = useState(false);
|
||||||
let username = localStorage.getItem("username");
|
const username = localStorage.getItem("username");
|
||||||
const image = localStorage.getItem("profileImg") || dp;
|
const image = localStorage.getItem("profileImg") || dp;
|
||||||
const tenantname = localStorage.getItem("Extand_Class")
|
const tenantname = localStorage.getItem("Extand_Class")
|
||||||
? JSON.parse(localStorage.getItem("Extand_Class"))?.[0]?.Company
|
? JSON.parse(localStorage.getItem("Extand_Class"))?.[0]?.Company
|
||||||
@@ -23,29 +26,76 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
const menuItem = async () => {
|
const menuItem = async () => {
|
||||||
try {
|
try {
|
||||||
if (localStorage.getItem("defaultmenuid")) {
|
if (localStorage.getItem("defaultmenuid")) {
|
||||||
const menuId = localStorage.getItem("defaultmenuid") !== "VPh91h0ZHk";
|
const Extand_Class = localStorage.getItem("Extand_Class");
|
||||||
if (menuId) {
|
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
||||||
setmenuList(sidebarList);
|
// console.log("extClass ", extClass);
|
||||||
} else {
|
let userRole = "contracts_User";
|
||||||
const addUserForm = {
|
if (extClass && extClass.length > 0) {
|
||||||
icon: "fa-light fa-user",
|
userRole = extClass[0].UserRole;
|
||||||
title: "Add User",
|
}
|
||||||
target: "_self",
|
if (
|
||||||
pageType: "form",
|
userRole === "contracts_Admin" ||
|
||||||
description: "",
|
userRole === "contracts_OrgAdmin"
|
||||||
objectId: "lM0xRnM3iE"
|
) {
|
||||||
};
|
|
||||||
const newSidebarList = sidebarList.map((item) => {
|
const newSidebarList = sidebarList.map((item) => {
|
||||||
if (item.title === "Settings") {
|
if (item.title === "Settings") {
|
||||||
// Make a shallow copy of the item
|
// Make a shallow copy of the item
|
||||||
const newItem = { ...item };
|
const newItem = { ...item };
|
||||||
// Insert addUserForm at the second position
|
if (isEnableSubscription) {
|
||||||
newItem.children.splice(1, 0, addUserForm);
|
newItem.children = [
|
||||||
|
...newItem.children,
|
||||||
|
{
|
||||||
|
icon: "fa-light fa-building-memo",
|
||||||
|
title: "Teams",
|
||||||
|
target: "_self",
|
||||||
|
pageType: "",
|
||||||
|
description: "",
|
||||||
|
objectId: "teams"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "fa-light fa-users fa-fw",
|
||||||
|
title: "Users",
|
||||||
|
target: "_self",
|
||||||
|
pageType: "",
|
||||||
|
description: "",
|
||||||
|
objectId: "users"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
const arr = newItem.children.slice(0, 1);
|
||||||
|
newItem.children = [
|
||||||
|
...arr,
|
||||||
|
{
|
||||||
|
icon: "fa-light fa-users fa-fw",
|
||||||
|
title: "Users",
|
||||||
|
target: "_self",
|
||||||
|
pageType: "",
|
||||||
|
description: "",
|
||||||
|
objectId: "users"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
setmenuList(newSidebarList);
|
setmenuList(newSidebarList);
|
||||||
|
} else {
|
||||||
|
if (!isEnableSubscription) {
|
||||||
|
const newSidebarList = sidebarList.map((item) => {
|
||||||
|
if (item.title === "Settings") {
|
||||||
|
// Make a shallow copy of the item
|
||||||
|
const newItem = { ...item };
|
||||||
|
const arr = newItem.children.slice(0, 1);
|
||||||
|
newItem.children = arr;
|
||||||
|
return newItem;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
setmenuList(newSidebarList);
|
||||||
|
} else {
|
||||||
|
setmenuList(sidebarList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -61,13 +111,19 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
closeSidebar();
|
closeSidebar();
|
||||||
setSubmenuOpen({});
|
setSubmenuOpen({});
|
||||||
};
|
};
|
||||||
|
const handleProfile = () => {
|
||||||
|
navigate("/profile");
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
className={`absolute lg:relative bg-base-100 h-screen overflow-y-auto transition-all z-[999] shadow-lg hide-scrollbar
|
className={`absolute lg:relative bg-base-100 h-screen overflow-y-auto transition-all z-[500] shadow-lg hide-scrollbar
|
||||||
${isOpen ? "w-full md:w-[300px]" : "w-0"}`}
|
${isOpen ? "w-full md:w-[300px]" : "w-0"}`}
|
||||||
>
|
>
|
||||||
<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
|
||||||
|
onClick={() => handleProfile()}
|
||||||
|
className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden cursor-pointer"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
className="w-full h-full object-contain"
|
className="w-full h-full object-contain"
|
||||||
src={image}
|
src={image}
|
||||||
@@ -75,9 +131,15 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-[14px] font-bold text-base-content">{username}</p>
|
|
||||||
<p
|
<p
|
||||||
className={`text-[12px] text-base-content ${
|
onClick={handleProfile}
|
||||||
|
className="text-[14px] font-bold text-base-content cursor-pointer"
|
||||||
|
>
|
||||||
|
{username}
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
onClick={handleProfile}
|
||||||
|
className={`cursor-pointer text-[12px] text-base-content ${
|
||||||
tenantname ? "mt-2" : ""
|
tenantname ? "mt-2" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { isEnableSubscription } from "./const";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { rgb } from "pdf-lib";
|
import { rgb } from "pdf-lib";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
@@ -8,7 +7,7 @@ import { appInfo } from "./appinfo";
|
|||||||
import { saveAs } from "file-saver";
|
import { saveAs } from "file-saver";
|
||||||
import printModule from "print-js";
|
import printModule from "print-js";
|
||||||
|
|
||||||
export const fontsizeArr = [7, 8, 9, 10, 11, 12, 13, 14, 15, 18];
|
export const fontsizeArr = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28];
|
||||||
export const fontColorArr = ["red", "black", "blue", "yellow"];
|
export const fontColorArr = ["red", "black", "blue", "yellow"];
|
||||||
export const isMobile = window.innerWidth < 767;
|
export const isMobile = window.innerWidth < 767;
|
||||||
export const isTabAndMobile = window.innerWidth < 1023;
|
export const isTabAndMobile = window.innerWidth < 1023;
|
||||||
@@ -63,7 +62,7 @@ export async function fetchSubscription(
|
|||||||
return { plan: "", billingDate: "" };
|
return { plan: "", billingDate: "" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//function to get subcripition details from Extand user class
|
//function to get subcripition details from subscription class
|
||||||
export async function checkIsSubscribed() {
|
export async function checkIsSubscribed() {
|
||||||
try {
|
try {
|
||||||
const res = await fetchSubscription();
|
const res = await fetchSubscription();
|
||||||
@@ -84,6 +83,34 @@ export async function checkIsSubscribed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//function to get subcripition details from subscription class
|
||||||
|
export async function checkIsSubscribedTeam() {
|
||||||
|
try {
|
||||||
|
const res = await fetchSubscription();
|
||||||
|
if (res.plan === "freeplan") {
|
||||||
|
return false;
|
||||||
|
} else if (res.billingDate) {
|
||||||
|
const plan =
|
||||||
|
res.plan === "team-weekly" ||
|
||||||
|
res.plan === "team-yearly" ||
|
||||||
|
res.plan === "teams-monthly" ||
|
||||||
|
res.plan === "teams-yearly" ||
|
||||||
|
res.plan === "enterprise-monthly" ||
|
||||||
|
res.plan === "enterprise-yearly";
|
||||||
|
if (plan && new Date(res.billingDate) > new Date()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in fetch subscription", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const color = [
|
export const color = [
|
||||||
"#93a3db",
|
"#93a3db",
|
||||||
"#e6c3db",
|
"#e6c3db",
|
||||||
@@ -151,7 +178,7 @@ export const getDrive = async (documentId, skip = 0, limit = 100) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("Err ", err);
|
console.log("Err in getDrive cloud function", err);
|
||||||
return "Error: Something went wrong!";
|
return "Error: Something went wrong!";
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -186,7 +213,7 @@ export const contractUsers = async (email) => {
|
|||||||
return data;
|
return data;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("Err ", err);
|
console.log("Err in getUserDetails cloud function", err);
|
||||||
return "Error: Something went wrong!";
|
return "Error: Something went wrong!";
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -326,7 +353,7 @@ export const getDate = () => {
|
|||||||
};
|
};
|
||||||
export const addWidgetOptions = (type) => {
|
export const addWidgetOptions = (type) => {
|
||||||
const defaultOpt = {
|
const defaultOpt = {
|
||||||
name: "",
|
name: type,
|
||||||
status: "required"
|
status: "required"
|
||||||
};
|
};
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -541,7 +568,7 @@ export const signPdfFun = async (
|
|||||||
if (
|
if (
|
||||||
tenantDetails?.CompletionBody &&
|
tenantDetails?.CompletionBody &&
|
||||||
tenantDetails?.CompletionSubject &&
|
tenantDetails?.CompletionSubject &&
|
||||||
(!isEnableSubscription || isSubscribed)
|
isSubscribed
|
||||||
) {
|
) {
|
||||||
isCustomCompletionMail = true;
|
isCustomCompletionMail = true;
|
||||||
}
|
}
|
||||||
@@ -571,7 +598,7 @@ export const signPdfFun = async (
|
|||||||
console.log("error", e);
|
console.log("error", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//change image width and height to 104/44 in png base64
|
//change image width and height to 100/40 in png base64
|
||||||
const getNewse64 = await changeImageWH(base64Sign);
|
const getNewse64 = await changeImageWH(base64Sign);
|
||||||
//remove suffiix of base64
|
//remove suffiix of base64
|
||||||
const suffixbase64 = getNewse64 && getNewse64.split(",").pop();
|
const suffixbase64 = getNewse64 && getNewse64.split(",").pop();
|
||||||
@@ -599,7 +626,7 @@ export const signPdfFun = async (
|
|||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("Err ", err);
|
console.log("Err in signPdf cloud function ", err);
|
||||||
setIsAlert({
|
setIsAlert({
|
||||||
isShow: true,
|
isShow: true,
|
||||||
alertMessage: "something went wrong"
|
alertMessage: "something went wrong"
|
||||||
@@ -669,9 +696,7 @@ export const createDocument = async (template, placeholders, signerData) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axios.post(
|
const res = await axios.post(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem("baseUrl")}classes/contracts_Document`,
|
||||||
"_appName"
|
|
||||||
)}_Document`,
|
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@@ -1213,9 +1238,8 @@ export const changeImageWH = async (base64Image) => {
|
|||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
canvas.width = newWidth;
|
canvas.width = newWidth;
|
||||||
canvas.height = newHeight;
|
canvas.height = newHeight;
|
||||||
ctx.imageSmoothingEnabled = false;
|
|
||||||
ctx.drawImage(img, 0, 0, newWidth, newHeight);
|
ctx.drawImage(img, 0, 0, newWidth, newHeight);
|
||||||
const resizedBase64 = canvas.toDataURL("image/png", 1);
|
const resizedBase64 = canvas.toDataURL("image/png", 1.0);
|
||||||
resolve(resizedBase64);
|
resolve(resizedBase64);
|
||||||
};
|
};
|
||||||
img.onerror = (error) => {
|
img.onerror = (error) => {
|
||||||
@@ -1224,14 +1248,30 @@ export const changeImageWH = async (base64Image) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//function to calculate font size of text area widgets
|
||||||
|
const calculateFontSize = (position, containerScale, signyourself) => {
|
||||||
|
const font = position?.options?.fontSize || 12;
|
||||||
|
if (!signyourself && position?.isMobile && position?.scale) {
|
||||||
|
return font / position?.scale / containerScale;
|
||||||
|
} else {
|
||||||
|
return font / containerScale;
|
||||||
|
}
|
||||||
|
};
|
||||||
//function for embed multiple signature using pdf-lib
|
//function for embed multiple signature using pdf-lib
|
||||||
export const multiSignEmbed = async (
|
export const multiSignEmbed = async (
|
||||||
xyPositionArray,
|
xyPositionArray,
|
||||||
pdfDoc,
|
pdfDoc,
|
||||||
signyourself,
|
signyourself,
|
||||||
scale
|
scale,
|
||||||
|
pdfOriginalWH,
|
||||||
|
containerWH
|
||||||
) => {
|
) => {
|
||||||
for (let item of xyPositionArray) {
|
for (let item of xyPositionArray) {
|
||||||
|
const containerScale = getContainerScale(
|
||||||
|
pdfOriginalWH,
|
||||||
|
item?.pageNumber,
|
||||||
|
containerWH
|
||||||
|
);
|
||||||
const typeExist = item.pos.some((data) => data?.type);
|
const typeExist = item.pos.some((data) => data?.type);
|
||||||
let updateItem;
|
let updateItem;
|
||||||
|
|
||||||
@@ -1391,7 +1431,13 @@ export const multiSignEmbed = async (
|
|||||||
}
|
}
|
||||||
} else if (widgetTypeExist) {
|
} else if (widgetTypeExist) {
|
||||||
const font = await pdfDoc.embedFont("Helvetica");
|
const font = await pdfDoc.embedFont("Helvetica");
|
||||||
const fontSize = parseInt(position?.options?.fontSize) || 12;
|
const fontSize = calculateFontSize(
|
||||||
|
position,
|
||||||
|
containerScale,
|
||||||
|
signyourself
|
||||||
|
);
|
||||||
|
parseInt(fontSize);
|
||||||
|
|
||||||
const color = position?.options?.fontColor;
|
const color = position?.options?.fontColor;
|
||||||
let updateColorInRgb;
|
let updateColorInRgb;
|
||||||
if (color === "red") {
|
if (color === "red") {
|
||||||
@@ -1566,7 +1612,7 @@ export const multiSignEmbed = async (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||||
// console.log("pdf", pdfBytes);
|
//console.log("pdf", pdfBytes);
|
||||||
return pdfBytes;
|
return pdfBytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1618,9 +1664,9 @@ export const placeholderHeight = (pos) => {
|
|||||||
export const contactBook = async (objectId) => {
|
export const contactBook = async (objectId) => {
|
||||||
const result = await axios
|
const result = await axios
|
||||||
.get(
|
.get(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"_appName"
|
"baseUrl"
|
||||||
)}_Contactbook?where={"objectId":"${objectId}"}`,
|
)}classes/contracts_Contactbook?where={"objectId":"${objectId}"}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -1636,7 +1682,7 @@ export const contactBook = async (objectId) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("Err ", err);
|
console.log("Err in contracts_Contactbook class ", err);
|
||||||
return "Error: Something went wrong!";
|
return "Error: Something went wrong!";
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
@@ -1668,7 +1714,7 @@ export const contractDocument = async (documentId) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("Err ", err);
|
console.log("Err in getDocument cloud function ", err);
|
||||||
return "Error: Something went wrong!";
|
return "Error: Something went wrong!";
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1830,18 +1876,21 @@ export const getFileName = (fileUrl) => {
|
|||||||
|
|
||||||
//fetch tenant app logo from `partners_Tenant` class by domain name
|
//fetch tenant app logo from `partners_Tenant` class by domain name
|
||||||
export const getAppLogo = async () => {
|
export const getAppLogo = async () => {
|
||||||
const domainName = window.location.host;
|
if (window.location.host === "app.opensignlabs.com") {
|
||||||
try {
|
return { logo: appInfo.applogo, user: "exist" };
|
||||||
const tenantCreditsQuery = new Parse.Query("partners_Tenant");
|
} else {
|
||||||
tenantCreditsQuery.equalTo("Domain", domainName);
|
const domain = window.location.host;
|
||||||
const res = await tenantCreditsQuery.first();
|
try {
|
||||||
|
const tenant = await Parse.Cloud.run("getlogobydomain", {
|
||||||
if (res) {
|
domain: domain
|
||||||
const updateRes = JSON.parse(JSON.stringify(res));
|
});
|
||||||
return updateRes?.Logo;
|
if (tenant) {
|
||||||
|
return { logo: tenant?.logo, user: tenant?.user };
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in getlogo ", err);
|
||||||
|
return { logo: appInfo.applogo, user: "exist" };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1929,6 +1978,20 @@ export const handleSendOTP = async (email) => {
|
|||||||
alert(error.message);
|
alert(error.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
export const fetchUrl = async (url, pdfName) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
if (!response.ok) {
|
||||||
|
alert("something went wrong, please try again later.");
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
const blob = await response.blob();
|
||||||
|
saveAs(blob, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||||
|
} catch (error) {
|
||||||
|
alert("something went wrong, please try again later.");
|
||||||
|
console.error("Error downloading the file:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
//handle download signed pdf
|
//handle download signed pdf
|
||||||
export const handleDownloadPdf = async (
|
export const handleDownloadPdf = async (
|
||||||
pdfDetails,
|
pdfDetails,
|
||||||
@@ -1940,18 +2003,18 @@ export const handleDownloadPdf = async (
|
|||||||
try {
|
try {
|
||||||
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||||
const axiosRes = await axios.post(
|
const axiosRes = await axios.post(
|
||||||
`${appInfo.baseUrl}/functions/getsignedurl`,
|
`${localStorage.getItem("baseUrl")}/functions/getsignedurl`,
|
||||||
{ url: pdfUrl },
|
{ url: pdfUrl },
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"content-type": "Application/json",
|
"content-type": "Application/json",
|
||||||
"X-Parse-Application-Id": appInfo.appId,
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const url = axiosRes.data.result;
|
const url = axiosRes.data.result;
|
||||||
saveAs(url, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
await fetchUrl(url, pdfName);
|
||||||
setIsDownloading("");
|
setIsDownloading("");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err in getsignedurl", err);
|
console.log("err in getsignedurl", err);
|
||||||
@@ -1970,13 +2033,15 @@ export const handleToPrint = async (event, pdfUrl, setIsDownloading) => {
|
|||||||
setIsDownloading("pdf");
|
setIsDownloading("pdf");
|
||||||
try {
|
try {
|
||||||
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||||
|
//`localStorage.getItem("baseUrl")` is also use in public-profile flow for public-sign
|
||||||
|
//if we give this `appInfo.baseUrl` as a base url then in public-profile it will create base url of it's window.location.origin ex- opensign.me which is not base url
|
||||||
const axiosRes = await axios.post(
|
const axiosRes = await axios.post(
|
||||||
`${appInfo.baseUrl}/functions/getsignedurl`,
|
`${localStorage.getItem("baseUrl")}/functions/getsignedurl`,
|
||||||
{ url: pdfUrl },
|
{ url: pdfUrl },
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"content-type": "Application/json",
|
"content-type": "Application/json",
|
||||||
"X-Parse-Application-Id": appInfo.appId,
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2181,3 +2246,11 @@ function getImagePosition(page, image, sizeRatio) {
|
|||||||
rotate: page.getRotation()
|
rotate: page.getRotation()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
//function to use calculate pdf rendering scale in the container
|
||||||
|
export const getContainerScale = (pdfOriginalWH, pageNumber, containerWH) => {
|
||||||
|
const getPdfPageWidth = pdfOriginalWH.find(
|
||||||
|
(data) => data.pageNumber === pageNumber
|
||||||
|
);
|
||||||
|
const containerScale = containerWH?.width / getPdfPageWidth?.width || 1;
|
||||||
|
return containerScale;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import logo from "../assets/images/logo.png";
|
import logo from "../assets/images/logo.png";
|
||||||
export const appInfo = {
|
export const appInfo = {
|
||||||
appTitle: "contracts",
|
|
||||||
applogo: logo,
|
applogo: logo,
|
||||||
appname: "contracts",
|
|
||||||
appId: process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign",
|
appId: process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign",
|
||||||
baseUrl: process.env.REACT_APP_SERVERURL
|
baseUrl: process.env.REACT_APP_SERVERURL
|
||||||
? process.env.REACT_APP_SERVERURL
|
? process.env.REACT_APP_SERVERURL
|
||||||
@@ -18,22 +16,34 @@ export const appInfo = {
|
|||||||
: "",
|
: "",
|
||||||
metaDescription:
|
metaDescription:
|
||||||
"The fastest way to sign PDFs & request signatures from others.",
|
"The fastest way to sign PDFs & request signatures from others.",
|
||||||
objectId: "aIPmIvMzGM",
|
|
||||||
settings: [
|
settings: [
|
||||||
{
|
|
||||||
role: "contracts_User",
|
|
||||||
menuId: "H9vRfEYKhT",
|
|
||||||
pageType: "dashboard",
|
|
||||||
pageId: "35KBoSgoAK",
|
|
||||||
extended_class: "contracts_Users"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
role: "contracts_Admin",
|
role: "contracts_Admin",
|
||||||
menuId: "VPh91h0ZHk",
|
menuId: "VPh91h0ZHk",
|
||||||
pageType: "dashboard",
|
pageType: "dashboard",
|
||||||
pageId: "35KBoSgoAK",
|
pageId: "35KBoSgoAK",
|
||||||
extended_class: "contracts_Users"
|
extended_class: "contracts_Users"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "contracts_OrgAdmin",
|
||||||
|
menuId: "VPh91h0ZHk",
|
||||||
|
pageType: "dashboard",
|
||||||
|
pageId: "35KBoSgoAK",
|
||||||
|
extended_class: "contracts_Users"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "contracts_Editor",
|
||||||
|
menuId: "H9vRfEYKhT",
|
||||||
|
pageType: "dashboard",
|
||||||
|
pageId: "35KBoSgoAK",
|
||||||
|
extended_class: "contracts_Users"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "contracts_User",
|
||||||
|
menuId: "H9vRfEYKhT",
|
||||||
|
pageType: "dashboard",
|
||||||
|
pageId: "35KBoSgoAK",
|
||||||
|
extended_class: "contracts_Users"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
version: "0.1"
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,4 +3,11 @@ export const templateCls = "contracts_Template";
|
|||||||
export const documentCls = "contracts_Document";
|
export const documentCls = "contracts_Document";
|
||||||
export const themeColor = "#47a3ad";
|
export const themeColor = "#47a3ad";
|
||||||
export const iconColor = "#686968";
|
export const iconColor = "#686968";
|
||||||
export const isEnableSubscription = process.env.REACT_APP_ENABLE_SUBSCRIPTION;
|
export const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||||
|
export const isEnableSubscription =
|
||||||
|
process.env.REACT_APP_ENABLE_SUBSCRIPTION &&
|
||||||
|
process.env.REACT_APP_ENABLE_SUBSCRIPTION?.toLowerCase() === "true"
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
export const isStaging =
|
||||||
|
window.location.origin === "https://staging-app.opensignlabs.com";
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
export default function reportJson(id) {
|
export default function reportJson(id) {
|
||||||
// console.log("json ", json);
|
// console.log("json ", json);
|
||||||
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
||||||
|
const declineHead = [
|
||||||
|
"Sr.No",
|
||||||
|
"Title",
|
||||||
|
"Reason",
|
||||||
|
"Folder",
|
||||||
|
"File",
|
||||||
|
"Owner",
|
||||||
|
"Signers"
|
||||||
|
];
|
||||||
const contactbook = ["Sr.No", "Title", "Email", "Phone"];
|
const contactbook = ["Sr.No", "Title", "Email", "Phone"];
|
||||||
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
||||||
const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"];
|
const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"];
|
||||||
@@ -43,7 +52,7 @@ export default function reportJson(id) {
|
|||||||
hoverLabel: "Sign",
|
hoverLabel: "Sign",
|
||||||
btnColor: "op-btn-primary",
|
btnColor: "op-btn-primary",
|
||||||
btnIcon: "fa-light fa-signature",
|
btnIcon: "fa-light fa-signature",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -69,7 +78,7 @@ export default function reportJson(id) {
|
|||||||
hoverLabel: "View",
|
hoverLabel: "View",
|
||||||
btnColor: "op-btn-secondary",
|
btnColor: "op-btn-secondary",
|
||||||
btnIcon: "fa-light fa-eye",
|
btnIcon: "fa-light fa-eye",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -140,7 +149,7 @@ export default function reportJson(id) {
|
|||||||
case "UPr2Fm5WY3":
|
case "UPr2Fm5WY3":
|
||||||
return {
|
return {
|
||||||
reportName: "Declined Documents",
|
reportName: "Declined Documents",
|
||||||
heading: head,
|
heading: declineHead,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnId: "1458",
|
btnId: "1458",
|
||||||
@@ -207,7 +216,7 @@ export default function reportJson(id) {
|
|||||||
hoverLabel: "View",
|
hoverLabel: "View",
|
||||||
btnColor: "op-btn-secondary",
|
btnColor: "op-btn-secondary",
|
||||||
btnIcon: "fa-light fa-eye",
|
btnIcon: "fa-light fa-eye",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -258,7 +267,7 @@ export default function reportJson(id) {
|
|||||||
hoverLabel: "Sign",
|
hoverLabel: "Sign",
|
||||||
btnColor: "op-btn-primary",
|
btnColor: "op-btn-primary",
|
||||||
btnIcon: "fa-light fa-signature",
|
btnIcon: "fa-light fa-signature",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -306,68 +315,99 @@ export default function reportJson(id) {
|
|||||||
"This is a list of contacts/signers added by you. These will appear as suggestions when you try to add signers to a new document."
|
"This is a list of contacts/signers added by you. These will appear as suggestions when you try to add signers to a new document."
|
||||||
};
|
};
|
||||||
// template report
|
// template report
|
||||||
case "6TeaPr321t":
|
case "6TeaPr321t": {
|
||||||
|
const templateAct = [
|
||||||
|
{
|
||||||
|
btnId: "2234",
|
||||||
|
btnLabel: "Use",
|
||||||
|
hoverLabel: "Use",
|
||||||
|
btnColor: "op-btn-primary",
|
||||||
|
btnIcon: "fa-light fa-plus",
|
||||||
|
redirectUrl: "placeHolderSign",
|
||||||
|
action: "redirect",
|
||||||
|
selector: "reactourSecond",
|
||||||
|
message:
|
||||||
|
"Click the 'Use' button to create a new document from an existing template. "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
btnId: "1631",
|
||||||
|
btnLabel: "Quick send",
|
||||||
|
hoverLabel: "Quick send",
|
||||||
|
btnColor: "op-btn-secondary",
|
||||||
|
btnIcon: "fa-light fa-envelope",
|
||||||
|
redirectUrl: "",
|
||||||
|
action: "bulksend",
|
||||||
|
selector: "tourbulksend",
|
||||||
|
message:
|
||||||
|
"To quickly create and send multiple documents using an existing template, click the 'Quick Send' button."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
btnId: "2234",
|
||||||
|
hoverLabel: "option",
|
||||||
|
btnColor: "",
|
||||||
|
textColor: "black",
|
||||||
|
btnIcon: "fa-light fa-ellipsis-vertical fa-lg",
|
||||||
|
action: "option",
|
||||||
|
selector: "reactourThird",
|
||||||
|
message:
|
||||||
|
"This menu reveals more options such as Edit & Delete. Use the 'Edit' button to add signer roles, modify fields, and update your template. Changes will apply to all future documents created from this template but won’t affect existing documents.Use the Delete button you can delete template. ",
|
||||||
|
subaction: [
|
||||||
|
{
|
||||||
|
btnId: "2434",
|
||||||
|
btnLabel: "Edit",
|
||||||
|
hoverLabel: "Edit",
|
||||||
|
btnIcon: "fa-light fa-pen",
|
||||||
|
redirectUrl: "template",
|
||||||
|
action: "redirect"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
btnId: "1834",
|
||||||
|
btnLabel: "Delete",
|
||||||
|
hoverLabel: "Delete",
|
||||||
|
btnIcon: "fa-light fa-trash",
|
||||||
|
redirectUrl: "",
|
||||||
|
action: "delete"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const Extand_Class = localStorage.getItem("Extand_Class");
|
||||||
|
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
||||||
|
// console.log("extClass ", extClass);
|
||||||
|
let templateActions = templateAct;
|
||||||
|
if (extClass && extClass.length > 0) {
|
||||||
|
if (extClass?.[0]?.UserRole !== "contracts_User") {
|
||||||
|
templateActions = templateAct.map((item) => {
|
||||||
|
if (item.action === "option") {
|
||||||
|
// Make a shallow copy of the item
|
||||||
|
const newItem = { ...item };
|
||||||
|
newItem.subaction = [
|
||||||
|
{
|
||||||
|
btnId: "1873",
|
||||||
|
btnLabel: "Share with team",
|
||||||
|
hoverLabel: "Share with team",
|
||||||
|
btnIcon: "fa-light fa-share-nodes",
|
||||||
|
redirectUrl: "",
|
||||||
|
action: "sharewith"
|
||||||
|
},
|
||||||
|
...newItem.subaction
|
||||||
|
];
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reportName: "Templates",
|
reportName: "Templates",
|
||||||
heading: templateReport,
|
heading: templateReport,
|
||||||
actions: [
|
actions: templateActions,
|
||||||
{
|
|
||||||
btnId: "2234",
|
|
||||||
btnLabel: "Use",
|
|
||||||
hoverLabel: "Use",
|
|
||||||
btnColor: "op-btn-primary",
|
|
||||||
btnIcon: "fa-light fa-plus",
|
|
||||||
redirectUrl: "placeHolderSign",
|
|
||||||
action: "redirect",
|
|
||||||
selector: "reactourSecond",
|
|
||||||
message:
|
|
||||||
"Click the 'Use' button to create a new document from an existing template. "
|
|
||||||
},
|
|
||||||
{
|
|
||||||
btnId: "1631",
|
|
||||||
btnLabel: "Quick send",
|
|
||||||
hoverLabel: "Quick send",
|
|
||||||
btnColor: "op-btn-secondary",
|
|
||||||
btnIcon: "fa-light fa-envelope",
|
|
||||||
redirectUrl: "",
|
|
||||||
action: "bulksend",
|
|
||||||
selector: "tourbulksend",
|
|
||||||
message:
|
|
||||||
"To quickly create and send multiple documents using an existing template, click the 'Quick Send' button."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
btnId: "2234",
|
|
||||||
hoverLabel: "option",
|
|
||||||
btnColor: "",
|
|
||||||
textColor: "black",
|
|
||||||
btnIcon: "fa-light fa-ellipsis-vertical fa-lg",
|
|
||||||
action: "option",
|
|
||||||
selector: "reactourThird",
|
|
||||||
message:
|
|
||||||
"This menu reveals more options such as Edit & Delete. Use the 'Edit' button to add signer roles, modify fields, and update your template. Changes will apply to all future documents created from this template but won’t affect existing documents.Use the Delete button you can delete template. ",
|
|
||||||
subaction: [
|
|
||||||
{
|
|
||||||
btnId: "2434",
|
|
||||||
btnLabel: "Edit",
|
|
||||||
hoverLabel: "Edit",
|
|
||||||
btnIcon: "fa-light fa-pen",
|
|
||||||
redirectUrl: "template",
|
|
||||||
action: "redirect"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
btnId: "1834",
|
|
||||||
btnLabel: "Delete",
|
|
||||||
hoverLabel: "Delete",
|
|
||||||
btnIcon: "fa-light fa-trash",
|
|
||||||
redirectUrl: "",
|
|
||||||
action: "delete"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
helpMsg:
|
helpMsg:
|
||||||
"This is a list of templates that are available to you for creating documents. You can click the 'use' button to create a new document using a template, modify the document & add signers in the next step."
|
"This is a list of templates that are available to you for creating documents. You can click the 'use' button to create a new document using a template, modify the document & add signers in the next step."
|
||||||
};
|
};
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,17 +143,17 @@ const sidebarList = [
|
|||||||
icon: "fa-light fa-key",
|
icon: "fa-light fa-key",
|
||||||
title: "API Token",
|
title: "API Token",
|
||||||
target: "_self",
|
target: "_self",
|
||||||
pageType: "generatetoken",
|
pageType: "",
|
||||||
description: "",
|
description: "",
|
||||||
objectId: ""
|
objectId: "generatetoken"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "fa-light fa-globe",
|
icon: "fa-light fa-globe",
|
||||||
title: "Webhook",
|
title: "Webhook",
|
||||||
target: "_self",
|
target: "_self",
|
||||||
pageType: "webhook",
|
pageType: "",
|
||||||
description: "",
|
description: "",
|
||||||
objectId: ""
|
objectId: "webhook"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
|
import { isStaging } from "../constant/const";
|
||||||
|
|
||||||
const plans = [
|
const plans = [
|
||||||
{
|
{
|
||||||
planName: "OPENSIGN™ FREE",
|
planName: "OPENSIGN™ FREE",
|
||||||
|
img: "free.png",
|
||||||
currency: "",
|
currency: "",
|
||||||
monthlyPrice: "Free",
|
monthlyPrice: "Free",
|
||||||
yearlyPrice: "Free",
|
yearlyPrice: "Free",
|
||||||
subtitle: "Free Unlimited E-signatures, Forever.",
|
subtitle: "Free Unlimited E-signatures, Forever.",
|
||||||
btnText: "Subscribe",
|
btn: { text: "Subscribe", color: "op-btn-primary" },
|
||||||
url: "",
|
url: "",
|
||||||
target: "_blank",
|
target: "_blank",
|
||||||
benefits: [
|
benefits: [
|
||||||
@@ -23,24 +26,44 @@ const plans = [
|
|||||||
"Decline document support",
|
"Decline document support",
|
||||||
"Email notifications",
|
"Email notifications",
|
||||||
"Recipient authentication using OTP",
|
"Recipient authentication using OTP",
|
||||||
|
"Bulk send (upto 5 docs)",
|
||||||
|
"Public profiles",
|
||||||
|
"And much more"
|
||||||
|
],
|
||||||
|
yearlyBenefits: [
|
||||||
|
"Unlimited envelopes",
|
||||||
|
"Sign documents yourself",
|
||||||
|
"Request signatures from others",
|
||||||
|
"14 field types",
|
||||||
|
"Automatic e-signatures",
|
||||||
|
"Completion certificates",
|
||||||
|
"Send in order",
|
||||||
|
"Document templates",
|
||||||
|
"Import from Dropbox",
|
||||||
|
"Contact book",
|
||||||
|
"Document expiry support",
|
||||||
|
"Decline document support",
|
||||||
|
"Email notifications",
|
||||||
|
"Recipient authentication using OTP",
|
||||||
|
"Bulk send (upto 5 docs)",
|
||||||
|
"Public profiles",
|
||||||
"And much more"
|
"And much more"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
planName: "OPENSIGN™ PROFESSIONAL",
|
planName: "OPENSIGN™ PROFESSIONAL",
|
||||||
|
img: "professional.png",
|
||||||
currency: "$",
|
currency: "$",
|
||||||
monthlyPrice: "29.99",
|
monthlyPrice: "29.99",
|
||||||
yearlyPrice: "329.99",
|
yearlyPrice: `9.99<sup style="font-size: 17px;">/month</sup>`,
|
||||||
subtitle: "Exclusive Access to advanced features.",
|
subtitle: "Exclusive Access to advanced features.",
|
||||||
btnText: "Subscribe",
|
btn: { text: "Subscribe", color: "op-btn-primary" },
|
||||||
url:
|
url: isStaging
|
||||||
window.location.origin === "https://staging-app.opensignlabs.com"
|
? "https://billing.zoho.in/subscribe/9627f62a09df1c8ce500f2f4dc8328dd84ecda20eeae13878ce581d60240f206/pro-weekly"
|
||||||
? "https://billing.zoho.in/subscribe/9627f62a09df1c8ce500f2f4dc8328dd84ecda20eeae13878ce581d60240f206/pro-weekly"
|
: "https://billing.opensignlabs.com/subscribe/ef798486e6a0a11ea65f2bae8f2af901d1a09dfa8085585cdd4ec4d7f32137f3/professional-monthly",
|
||||||
: "https://billing.opensignlabs.com/subscribe/ef798486e6a0a11ea65f2bae8f2af901d1a09dfa8085585cdd4ec4d7f32137f3/professional-monthly",
|
yearlyUrl: isStaging
|
||||||
yearlyUrl:
|
? "https://billing.zoho.in/subscribe/9627f62a09df1c8ce500f2f4dc8328ddc184411129224f1f29ed84f6cef3b862/pro-yearly"
|
||||||
window.location.origin === "https://staging-app.opensignlabs.com"
|
: "https://billing.opensignlabs.com/subscribe/ef798486e6a0a11ea65f2bae8f2af901d8ad1135190dff951330360e47585a71/professional-yearly",
|
||||||
? "https://billing.zoho.in/subscribe/9627f62a09df1c8ce500f2f4dc8328ddc184411129224f1f29ed84f6cef3b862/pro-yearly"
|
|
||||||
: "https://billing.opensignlabs.com/subscribe/ef798486e6a0a11ea65f2bae8f2af901d8ad1135190dff951330360e47585a71/professional-yearly",
|
|
||||||
target: "_self",
|
target: "_self",
|
||||||
benefits: [
|
benefits: [
|
||||||
"Everything in OpenSign™ free",
|
"Everything in OpenSign™ free",
|
||||||
@@ -51,18 +74,74 @@ const plans = [
|
|||||||
"Zapier integration",
|
"Zapier integration",
|
||||||
"API Access",
|
"API Access",
|
||||||
"100 API signatures included",
|
"100 API signatures included",
|
||||||
"DocumentId removal from signed docs",
|
|
||||||
"Custom email templates",
|
"Custom email templates",
|
||||||
"Auto reminders"
|
"Auto reminders",
|
||||||
|
"Bulk send (upto 20 docs)",
|
||||||
|
"Premium Public profile usernames",
|
||||||
|
"Embedding (coming soon)"
|
||||||
|
],
|
||||||
|
yearlyBenefits: [
|
||||||
|
"Everything in OpenSign™ free",
|
||||||
|
"Field validations",
|
||||||
|
"Regular expression validations",
|
||||||
|
"Organize docs in OpenSign™ Drive",
|
||||||
|
"Webhooks",
|
||||||
|
"Zapier integration",
|
||||||
|
"API Access",
|
||||||
|
"240 API signatures included",
|
||||||
|
"Custom email templates",
|
||||||
|
"Auto reminders",
|
||||||
|
"Bulk send (upto 20 docs)",
|
||||||
|
"Premium Public profile usernames",
|
||||||
|
"Embedding (coming soon)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
planName: "OPENSIGN™ TEAMS",
|
||||||
|
img: "teams.png",
|
||||||
|
currency: "$",
|
||||||
|
monthlyPrice: `39.99<sup style="font-size: 17px;">/user</sup>`,
|
||||||
|
yearlyPrice: `19.99<sup style="font-size: 17px;">/user/month</sup>`,
|
||||||
|
subtitle: "Exclusive Access to advanced features.",
|
||||||
|
btn: { text: "Subscribe", color: "op-btn-accent" },
|
||||||
|
url: isStaging
|
||||||
|
? "https://billing.zoho.in/subscribe/ed8097273a82b6bf39892c11a3bb3c381eb2705736014cfbdbde1ccf1c7a189d/team-weekly"
|
||||||
|
: "https://billing.opensignlabs.com/subscribe/ef798486e6a0a11ea65f2bae8f2af901237d0702bfaa959406306635d80f138c/teams-monthly",
|
||||||
|
yearlyUrl: isStaging
|
||||||
|
? "https://billing.zoho.in/subscribe/ed8097273a82b6bf39892c11a3bb3c381eb2705736014cfbdbde1ccf1c7a189d/team-weekly"
|
||||||
|
: "https://billing.opensignlabs.com/subscribe/ef798486e6a0a11ea65f2bae8f2af9011a864994bbeeec71fcf106188630199d/teams-yearly",
|
||||||
|
target: "_self",
|
||||||
|
benefits: [
|
||||||
|
"Everything in OpenSign™ professional",
|
||||||
|
"100 API signatures included",
|
||||||
|
"Teams and Organizations",
|
||||||
|
"Share Templates with teams",
|
||||||
|
"Share Templates with individuals",
|
||||||
|
"DocumentId removal from signed docs",
|
||||||
|
"Bulk send (upto 50 docs)",
|
||||||
|
"Request Payments (coming soon)",
|
||||||
|
"Mobile app (coming soon)"
|
||||||
|
],
|
||||||
|
yearlyBenefits: [
|
||||||
|
"Everything in OpenSign™ professional",
|
||||||
|
"500 API signatures included",
|
||||||
|
"Teams and Organizations",
|
||||||
|
"Share Templates with teams",
|
||||||
|
"Share Templates with individuals",
|
||||||
|
"DocumentId removal from signed docs",
|
||||||
|
"Bulk send (upto 50 docs)",
|
||||||
|
"Request Payments (coming soon)",
|
||||||
|
"Mobile app (coming soon)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
planName: "OPENSIGN™ ENTERPRISE",
|
planName: "OPENSIGN™ ENTERPRISE",
|
||||||
|
img: "enterprise.png",
|
||||||
currency: "",
|
currency: "",
|
||||||
monthlyPrice: "Request Price",
|
monthlyPrice: `<p style="font-size: 22px;">Request Price</p>`,
|
||||||
yearlyPrice: "Request Price",
|
yearlyPrice: `<p style="font-size: 22px;">Request Price</p>`,
|
||||||
subtitle: "Scalable Features with priority support.",
|
subtitle: "Scalable Features with priority support.",
|
||||||
btnText: "Contact us",
|
btn: { text: "Contact us", color: "op-btn-primary" },
|
||||||
url: "https://www.opensignlabs.com/contact-us",
|
url: "https://www.opensignlabs.com/contact-us",
|
||||||
target: "_blank",
|
target: "_blank",
|
||||||
benefits: [
|
benefits: [
|
||||||
@@ -72,6 +151,14 @@ const plans = [
|
|||||||
"Uptime SLA",
|
"Uptime SLA",
|
||||||
"SSO support",
|
"SSO support",
|
||||||
"Priority support"
|
"Priority support"
|
||||||
|
],
|
||||||
|
yearlyBenefits: [
|
||||||
|
"All features",
|
||||||
|
"Custom domain",
|
||||||
|
"Custom branding",
|
||||||
|
"Uptime SLA",
|
||||||
|
"SSO support",
|
||||||
|
"Priority support"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ const HomeLayout = () => {
|
|||||||
try {
|
try {
|
||||||
// Use the session token to validate the user
|
// Use the session token to validate the user
|
||||||
const userQuery = new Parse.Query(Parse.User);
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
const user = await userQuery.get(Parse.User.current().id, {
|
const user = await userQuery.get(Parse?.User?.current()?.id, {
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
});
|
});
|
||||||
if (user) {
|
if (user) {
|
||||||
@@ -67,6 +67,8 @@ const HomeLayout = () => {
|
|||||||
const indexOfFirstDot = domainName.indexOf(".");
|
const indexOfFirstDot = domainName.indexOf(".");
|
||||||
// Remove the first dot and get the substring starting from the next character
|
// Remove the first dot and get the substring starting from the next character
|
||||||
const updateDomain = domainName.substring(indexOfFirstDot); //.opensignlabs.com
|
const updateDomain = domainName.substring(indexOfFirstDot); //.opensignlabs.com
|
||||||
|
const serverUrl = localStorage.getItem("baseUrl");
|
||||||
|
const parseAppId = localStorage.getItem("parseAppId");
|
||||||
setCookie("accesstoken", localStorage.getItem("accesstoken"), {
|
setCookie("accesstoken", localStorage.getItem("accesstoken"), {
|
||||||
secure: true,
|
secure: true,
|
||||||
domain: updateDomain
|
domain: updateDomain
|
||||||
@@ -75,6 +77,14 @@ const HomeLayout = () => {
|
|||||||
secure: true,
|
secure: true,
|
||||||
domain: updateDomain
|
domain: updateDomain
|
||||||
});
|
});
|
||||||
|
setCookie("server_url", serverUrl, {
|
||||||
|
secure: true,
|
||||||
|
domain: updateDomain
|
||||||
|
});
|
||||||
|
setCookie("parse_app_id", parseAppId, {
|
||||||
|
secure: true,
|
||||||
|
domain: updateDomain
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
async function checkIsSubscribed() {
|
async function checkIsSubscribed() {
|
||||||
@@ -109,11 +119,7 @@ const HomeLayout = () => {
|
|||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (arr && arr.length > 0) {
|
||||||
localStorage.getItem("domain") === "contracts" &&
|
|
||||||
arr &&
|
|
||||||
arr.length > 0
|
|
||||||
) {
|
|
||||||
handleDynamicSteps();
|
handleDynamicSteps();
|
||||||
} else {
|
} else {
|
||||||
setIsTour(false);
|
setIsTour(false);
|
||||||
@@ -171,7 +177,6 @@ const HomeLayout = () => {
|
|||||||
setIsTour(false);
|
setIsTour(false);
|
||||||
const serverUrl = localStorage.getItem("baseUrl");
|
const serverUrl = localStorage.getItem("baseUrl");
|
||||||
const appId = localStorage.getItem("parseAppId");
|
const appId = localStorage.getItem("parseAppId");
|
||||||
const extUserClass = localStorage.getItem("extended_class");
|
|
||||||
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||||
const extUserId = json && json.length > 0 && json[0].objectId;
|
const extUserId = json && json.length > 0 && json[0].objectId;
|
||||||
// console.log("extUserId ", extUserId)
|
// console.log("extUserId ", extUserId)
|
||||||
@@ -193,7 +198,7 @@ const HomeLayout = () => {
|
|||||||
|
|
||||||
// console.log("updatedTourStatus ", updatedTourStatus);
|
// console.log("updatedTourStatus ", updatedTourStatus);
|
||||||
await axios.put(
|
await axios.put(
|
||||||
serverUrl + "classes/" + extUserClass + "/" + extUserId,
|
serverUrl + "classes/contracts_Users/" + extUserId,
|
||||||
{
|
{
|
||||||
TourStatus: updatedTourStatus
|
TourStatus: updatedTourStatus
|
||||||
},
|
},
|
||||||
@@ -241,7 +246,7 @@ const HomeLayout = () => {
|
|||||||
|
|
||||||
const handleLoginBtn = () => {
|
const handleLoginBtn = () => {
|
||||||
try {
|
try {
|
||||||
Parse.User.logOut();
|
Parse?.User?.logOut();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err ", err);
|
console.log("err ", err);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -251,7 +256,7 @@ const HomeLayout = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="sticky top-0 z-[101]">
|
<div className="sticky top-0 z-[501]">
|
||||||
{!isLoader && <Header showSidebar={showSidebar} />}
|
{!isLoader && <Header showSidebar={showSidebar} />}
|
||||||
</div>
|
</div>
|
||||||
{isUserValid ? (
|
{isUserValid ? (
|
||||||
|
|||||||
@@ -0,0 +1,454 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import { appInfo } from "../constant/appinfo";
|
||||||
|
import { NavLink, useNavigate } from "react-router-dom";
|
||||||
|
import { getAppLogo, openInNewTab } from "../constant/Utils";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { showTenant } from "../redux/reducers/ShowTenant";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
|
||||||
|
const AddAdmin = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [phone, setPhone] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [company, setCompany] = useState("");
|
||||||
|
const [jobTitle, setJobTitle] = useState("");
|
||||||
|
const [lengthValid, setLengthValid] = useState(false);
|
||||||
|
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||||
|
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||||
|
const [isAuthorize, setIsAuthorize] = useState(false);
|
||||||
|
const [isSubscribeNews, setIsSubscribeNews] = useState(false);
|
||||||
|
const [errMsg, setErrMsg] = useState("");
|
||||||
|
const [state, setState] = useState({
|
||||||
|
loading: false,
|
||||||
|
alertType: "success",
|
||||||
|
alertMsg: ""
|
||||||
|
});
|
||||||
|
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
checkUserExist();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
const checkUserExist = async () => {
|
||||||
|
setState((prev) => ({ ...prev, loading: true }));
|
||||||
|
try {
|
||||||
|
const app = await getAppLogo();
|
||||||
|
if (app?.user === "exist") {
|
||||||
|
setErrMsg("Admin already exist.");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setErrMsg("Something went wrong.");
|
||||||
|
console.log("err in check user exist", err);
|
||||||
|
} finally {
|
||||||
|
setState((prev) => ({ ...prev, loading: false }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const clearStorage = async () => {
|
||||||
|
if (Parse.User.current()) {
|
||||||
|
await Parse.User.logOut();
|
||||||
|
}
|
||||||
|
const baseUrl = localStorage.getItem("baseUrl");
|
||||||
|
const appid = localStorage.getItem("parseAppId");
|
||||||
|
const applogo = localStorage.getItem("appLogo");
|
||||||
|
const defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
|
const PageLanding = localStorage.getItem("PageLanding");
|
||||||
|
const userSettings = localStorage.getItem("userSettings");
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
|
localStorage.setItem("parseAppId", appid);
|
||||||
|
localStorage.setItem("appLogo", applogo);
|
||||||
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
|
localStorage.setItem("userSettings", userSettings);
|
||||||
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
|
localStorage.setItem("parseAppId", appid);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (lengthValid && caseDigitValid && specialCharValid) {
|
||||||
|
clearStorage();
|
||||||
|
setState({ loading: true });
|
||||||
|
const userDetails = {
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
phone: phone,
|
||||||
|
company: company,
|
||||||
|
jobTitle: jobTitle
|
||||||
|
};
|
||||||
|
localStorage.setItem("userDetails", JSON.stringify(userDetails));
|
||||||
|
try {
|
||||||
|
event.preventDefault();
|
||||||
|
const user = new Parse.User();
|
||||||
|
user.set("name", name);
|
||||||
|
user.set("email", email);
|
||||||
|
user.set("password", password);
|
||||||
|
user.set("phone", phone);
|
||||||
|
user.set("username", email);
|
||||||
|
const userRes = await user.save();
|
||||||
|
if (userRes) {
|
||||||
|
const params = {
|
||||||
|
userDetails: {
|
||||||
|
jobTitle: jobTitle,
|
||||||
|
company: company,
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
phone: phone,
|
||||||
|
role: "contracts_Admin"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const usersignup = await Parse.Cloud.run("addadmin", params);
|
||||||
|
if (usersignup) {
|
||||||
|
if (isSubscribeNews) {
|
||||||
|
subscribeNewsletter();
|
||||||
|
}
|
||||||
|
handleNavigation(userRes.getSessionToken());
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
alert(err.message);
|
||||||
|
setState({ loading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("err ", error);
|
||||||
|
if (error.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 {
|
||||||
|
// console.log("state.email ", email);
|
||||||
|
try {
|
||||||
|
await Parse.User.requestPasswordReset(email).then(
|
||||||
|
async function (res) {
|
||||||
|
if (res.data === undefined) {
|
||||||
|
alert("Verification mail has been sent to your E-mail!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
setState({ loading: false });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert(error.message);
|
||||||
|
setState({ loading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleNavigation = async (sessionToken) => {
|
||||||
|
const res = await Parse.User.become(sessionToken);
|
||||||
|
if (res) {
|
||||||
|
const _user = JSON.parse(JSON.stringify(res));
|
||||||
|
// console.log("_user ", _user);
|
||||||
|
localStorage.setItem("accesstoken", sessionToken);
|
||||||
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
|
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||||
|
localStorage.setItem("scriptId", true);
|
||||||
|
if (_user.ProfilePic) {
|
||||||
|
localStorage.setItem("profileImg", _user.ProfilePic);
|
||||||
|
} else {
|
||||||
|
localStorage.setItem("profileImg", "");
|
||||||
|
}
|
||||||
|
// Check extended class user role and tenentId
|
||||||
|
try {
|
||||||
|
const userSettings = appInfo.settings;
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const extUser = await Parse.Cloud.run("getUserDetails", {
|
||||||
|
email: currentUser.get("email")
|
||||||
|
});
|
||||||
|
if (extUser) {
|
||||||
|
const IsDisabled = extUser?.get("IsDisabled") || false;
|
||||||
|
if (!IsDisabled) {
|
||||||
|
const userRole = extUser?.get("UserRole");
|
||||||
|
const menu =
|
||||||
|
userRole && userSettings.find((menu) => menu.role === userRole);
|
||||||
|
if (menu) {
|
||||||
|
const _currentRole = userRole;
|
||||||
|
const _role = _currentRole.replace("contracts_", "");
|
||||||
|
localStorage.setItem("_user_role", _role);
|
||||||
|
const extInfo_stringify = JSON.stringify([extUser]);
|
||||||
|
localStorage.setItem("Extand_Class", extInfo_stringify);
|
||||||
|
const extInfo = JSON.parse(JSON.stringify(extUser));
|
||||||
|
localStorage.setItem("userEmail", extInfo?.Email);
|
||||||
|
localStorage.setItem("username", extInfo?.Name);
|
||||||
|
if (extInfo?.TenantId) {
|
||||||
|
const tenant = {
|
||||||
|
Id: extInfo?.TenantId?.objectId || "",
|
||||||
|
Name: extInfo?.TenantId?.TenantName || ""
|
||||||
|
};
|
||||||
|
localStorage.setItem("TenantId", tenant?.Id);
|
||||||
|
dispatch(showTenant(tenant?.Name));
|
||||||
|
localStorage.setItem("TenantName", tenant?.Name);
|
||||||
|
}
|
||||||
|
localStorage.setItem("PageLanding", menu.pageId);
|
||||||
|
localStorage.setItem("defaultmenuid", menu.menuId);
|
||||||
|
localStorage.setItem("pageType", menu.pageType);
|
||||||
|
setState({
|
||||||
|
loading: false,
|
||||||
|
alertType: "success",
|
||||||
|
alertMsg: "Registered user successfully."
|
||||||
|
});
|
||||||
|
navigate(`/${menu.pageType}/${menu.pageId}`);
|
||||||
|
} else {
|
||||||
|
setState({
|
||||||
|
loading: false,
|
||||||
|
alertType: "danger",
|
||||||
|
alertMsg: "Role not found."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setState({
|
||||||
|
loading: false,
|
||||||
|
alertType: "danger",
|
||||||
|
alertMsg: "You don't have access, please contact the admin."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("error in fetch extuser", error);
|
||||||
|
const msg = error.message || "Something went wrong.";
|
||||||
|
setState({ loading: false, alertType: "danger", alertMsg: msg });
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => setState({ loading: false, alertMsg: "" }), 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
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));
|
||||||
|
};
|
||||||
|
const subscribeNewsletter = async () => {
|
||||||
|
try {
|
||||||
|
const params = { name: name, email: email, domain: window.location.host };
|
||||||
|
await Parse.Cloud.run("newsletter", params);
|
||||||
|
// console.log("newsletter ", newsletter);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in subscribeNewsletter", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="h-screen flex justify-center">
|
||||||
|
<Title title={"Add admin"} />
|
||||||
|
{state.loading ? (
|
||||||
|
<div className="text-[grey] flex justify-center items-center text-lg md:text-2xl">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{errMsg ? (
|
||||||
|
<div className="text-[grey] flex justify-center items-center text-lg md:text-2xl">
|
||||||
|
{errMsg}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="w-[95%] md:w-[500px]">
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div className="w-full my-4 op-card bg-base-100 shadow-md outline outline-1 outline-slate-300/50">
|
||||||
|
<h2 className="text-[30px] text-center mt-3 font-medium">
|
||||||
|
Opensign Setup
|
||||||
|
</h2>
|
||||||
|
<NavLink
|
||||||
|
to="https://discord.com/invite/xe9TDuyAyj"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-center text-sm mt-1 text-[blue] cursor-pointer"
|
||||||
|
>
|
||||||
|
Join our discord server
|
||||||
|
<i
|
||||||
|
aria-hidden="true"
|
||||||
|
className="fa-brands fa-discord ml-1"
|
||||||
|
></i>
|
||||||
|
{/* <span className="fa-sr-only">OpenSign's Discord</span> */}
|
||||||
|
</NavLink>
|
||||||
|
<div className="px-6 py-3 text-xs">
|
||||||
|
<label className="block ">
|
||||||
|
Name <span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<hr className="my-2 border-none" />
|
||||||
|
<label>
|
||||||
|
Email <span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="email"
|
||||||
|
type="email"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value?.toLowerCase())}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<hr className="my-2 border-none" />
|
||||||
|
<label>
|
||||||
|
Phone <span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={phone}
|
||||||
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<hr className="my-2 border-none" />
|
||||||
|
<label>
|
||||||
|
Company <span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={company}
|
||||||
|
onChange={(e) => setCompany(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<hr className="my-2 border-none" />
|
||||||
|
<label>
|
||||||
|
Job Title{" "}
|
||||||
|
<span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={jobTitle}
|
||||||
|
onChange={(e) => setJobTitle(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<hr className="my-2 border-none" />
|
||||||
|
<label>
|
||||||
|
Password <span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
type={showPassword ? "text" : "password"}
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
name="password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => handlePasswordChange(e)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer text-base-content`}
|
||||||
|
onClick={togglePasswordVisibility}
|
||||||
|
>
|
||||||
|
{showPassword ? (
|
||||||
|
<i className="fa fa-eye-slash" /> // Close eye icon
|
||||||
|
) : (
|
||||||
|
<i className="fa fa-eye" /> // Open eye icon
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</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 className="mt-2.5 ml-1 flex flex-row items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="op-checkbox op-checkbox-sm"
|
||||||
|
id="termsandcondition"
|
||||||
|
checked={isAuthorize}
|
||||||
|
onChange={(e) => setIsAuthorize(e.target.checked)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="text-xs cursor-pointer ml-1 mb-0"
|
||||||
|
htmlFor="termsandcondition"
|
||||||
|
>
|
||||||
|
I agree to the
|
||||||
|
</label>
|
||||||
|
<span
|
||||||
|
className="underline cursor-pointer ml-1"
|
||||||
|
onClick={() =>
|
||||||
|
openInNewTab(
|
||||||
|
"https://www.opensignlabs.com/terms-and-conditions"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Terms of Service
|
||||||
|
</span>
|
||||||
|
<span>.</span>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2.5 ml-1 flex flex-row items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="op-checkbox op-checkbox-sm"
|
||||||
|
id="termsandcondition"
|
||||||
|
checked={isSubscribeNews}
|
||||||
|
onChange={(e) => setIsSubscribeNews(e.target.checked)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="text-xs cursor-pointer ml-1 mb-0"
|
||||||
|
htmlFor="termsandcondition"
|
||||||
|
>
|
||||||
|
Subscribe to OpenSign newsletter
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mx-4 text-center text-xs font-bold mb-3">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="op-btn op-btn-primary w-full"
|
||||||
|
disabled={state.loading}
|
||||||
|
>
|
||||||
|
{state.loading ? "Loading..." : "Next"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddAdmin;
|
||||||
@@ -21,7 +21,12 @@ function ChangePassword() {
|
|||||||
user.set("password", newpassword);
|
user.set("password", newpassword);
|
||||||
user
|
user
|
||||||
.save()
|
.save()
|
||||||
.then(() => {
|
.then(async () => {
|
||||||
|
let _user = user.toJSON();
|
||||||
|
if (_user) {
|
||||||
|
await Parse.User.become(_user.sessionToken);
|
||||||
|
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||||
|
}
|
||||||
alert("Password updated successfully.");
|
alert("Password updated successfully.");
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@@ -32,7 +37,6 @@ function ChangePassword() {
|
|||||||
} else {
|
} else {
|
||||||
alert("Your current password is missing or incorrect.");
|
alert("Your current password is missing or incorrect.");
|
||||||
}
|
}
|
||||||
console.log("Logged in user", user);
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
alert("Your current password is missing or incorrect.");
|
alert("Your current password is missing or incorrect.");
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ function ForgotPassword() {
|
|||||||
const handleSubmit = async (event) => {
|
const handleSubmit = async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
localStorage.setItem("appLogo", appInfo.applogo);
|
localStorage.setItem("appLogo", appInfo.applogo);
|
||||||
localStorage.setItem("appName", appInfo.appname);
|
|
||||||
// localStorage.setItem("defaultmenuid", props.appInfo.defaultmenuid);
|
|
||||||
// localStorage.setItem("PageLanding", props.appInfo.LandingPageId);
|
|
||||||
localStorage.setItem("userSettings", JSON.stringify(appInfo.settings));
|
localStorage.setItem("userSettings", JSON.stringify(appInfo.settings));
|
||||||
if (state.email) {
|
if (state.email) {
|
||||||
const username = state.email;
|
const username = state.email;
|
||||||
@@ -64,9 +61,9 @@ function ForgotPassword() {
|
|||||||
}, []);
|
}, []);
|
||||||
const saveLogo = async () => {
|
const saveLogo = async () => {
|
||||||
if (isEnableSubscription) {
|
if (isEnableSubscription) {
|
||||||
const logo = await getAppLogo();
|
const app = await getAppLogo();
|
||||||
if (logo) {
|
if (app?.logo) {
|
||||||
setImage(logo);
|
setImage(app?.logo);
|
||||||
} else {
|
} else {
|
||||||
setImage(appInfo?.applogo || undefined);
|
setImage(appInfo?.applogo || undefined);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import { isEnableSubscription } from "../constant/const";
|
|||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import Upgrade from "../primitives/Upgrade";
|
import Upgrade from "../primitives/Upgrade";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
// `Form` render all type of Form on this basis of their provided in path
|
// `Form` render all type of Form on this basis of their provided in path
|
||||||
@@ -644,9 +643,9 @@ const Forms = (props) => {
|
|||||||
<span className="text-red-500 text-[13px]">*</span>
|
<span className="text-red-500 text-[13px]">*</span>
|
||||||
</label>
|
</label>
|
||||||
{fileupload.length > 0 ? (
|
{fileupload.length > 0 ? (
|
||||||
<div className="flex gap-2 justify-center items-center">
|
<div className="flex gap-1 justify-center items-center">
|
||||||
<div className="flex justify-between items-center op-input op-input-bordered op-input-sm w-full h-full text-x text-[13px]">
|
<div className="flex justify-between items-center op-input op-input-bordered op-input-sm w-full h-full text-[13px]">
|
||||||
<div className="break-all ">
|
<div className="break-all cursor-default">
|
||||||
file selected: {getFileName(fileupload)}
|
file selected: {getFileName(fileupload)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -664,7 +663,7 @@ const Forms = (props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex gap-2 justify-center items-center ">
|
<div className="flex gap-1 justify-center items-center">
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
className="op-file-input op-file-input-bordered op-file-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
className="op-file-input op-file-input-bordered op-file-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
@@ -830,39 +829,34 @@ const Forms = (props) => {
|
|||||||
<div className="text-center">No</div>
|
<div className="text-center">No</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs mt-2">
|
{isEnableSubscription && (
|
||||||
{!isEnableSubscription && (
|
<div className="text-xs mt-2">
|
||||||
<PremiumAlertHeader
|
<span
|
||||||
message={
|
className={
|
||||||
"Auto reminder is free in beta, this feature will incur a fee later."
|
isSubscribe
|
||||||
|
? "font-semibold"
|
||||||
|
: "font-semibold text-gray-300"
|
||||||
}
|
}
|
||||||
/>
|
>
|
||||||
)}
|
Auto reminder{" "}
|
||||||
<span
|
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
||||||
className={
|
</span>
|
||||||
isSubscribe || !isEnableSubscription
|
<label
|
||||||
? "font-semibold"
|
className={`${
|
||||||
: "font-semibold text-gray-300"
|
isSubscribe
|
||||||
}
|
? "cursor-pointer "
|
||||||
>
|
: "pointer-events-none opacity-50"
|
||||||
Auto reminder{" "}
|
} relative block items-center mb-0`}
|
||||||
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
>
|
||||||
</span>
|
<input
|
||||||
<label
|
type="checkbox"
|
||||||
className={`${
|
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white"
|
||||||
isSubscribe || !isEnableSubscription
|
checked={formData.autoreminder}
|
||||||
? "cursor-pointer "
|
onChange={handleAutoReminder}
|
||||||
: "pointer-events-none opacity-50"
|
/>
|
||||||
} relative block items-center mb-0`}
|
</label>
|
||||||
>
|
</div>
|
||||||
<input
|
)}
|
||||||
type="checkbox"
|
|
||||||
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white"
|
|
||||||
checked={formData.autoreminder}
|
|
||||||
onChange={handleAutoReminder}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{formData?.autoreminder === true && (
|
{formData?.autoreminder === true && (
|
||||||
<div className="text-xs mt-2">
|
<div className="text-xs mt-2">
|
||||||
<label className="block">
|
<label className="block">
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import Alert from "../primitives/Alert";
|
|||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import { isEnableSubscription } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { checkIsSubscribed, copytoData, openInNewTab } from "../constant/Utils";
|
import { checkIsSubscribed, copytoData, openInNewTab } from "../constant/Utils";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
|
||||||
import Tooltip from "../primitives/Tooltip";
|
import Tooltip from "../primitives/Tooltip";
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
import SubscribeCard from "../primitives/SubscribeCard";
|
import SubscribeCard from "../primitives/SubscribeCard";
|
||||||
@@ -45,7 +44,7 @@ function GenerateToken() {
|
|||||||
};
|
};
|
||||||
const res = await axios.post(url, {}, { headers: headers });
|
const res = await axios.post(url, {}, { headers: headers });
|
||||||
if (res) {
|
if (res) {
|
||||||
SetApiToken(res.data.result.result);
|
SetApiToken(res.data?.result?.result);
|
||||||
}
|
}
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -112,7 +111,6 @@ function GenerateToken() {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow-md rounded-box mb-3">
|
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow-md rounded-box mb-3">
|
||||||
{!isEnableSubscription && <PremiumAlertHeader />}
|
|
||||||
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
||||||
OpenSign™ API{" "}
|
OpenSign™ API{" "}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@@ -122,19 +120,14 @@ function GenerateToken() {
|
|||||||
isSubscribe={true}
|
isSubscribe={true}
|
||||||
/>
|
/>
|
||||||
</h1>
|
</h1>
|
||||||
<ul
|
<ul className="w-full flex flex-col p-2 text-sm">
|
||||||
className={"w-full flex flex-col p-2 text-sm"}
|
|
||||||
// isSubscribe || !isEnableSubscription
|
|
||||||
// ? "w-full flex flex-col p-2 text-sm "
|
|
||||||
// : "w-full flex flex-col p-2 text-sm opacity-20 pointer-events-none select-none"
|
|
||||||
>
|
|
||||||
<li className="flex flex-col md:flex-row justify-between items-center border-y-[1px] border-gray-300 break-all py-2">
|
<li className="flex flex-col md:flex-row justify-between items-center border-y-[1px] border-gray-300 break-all py-2">
|
||||||
<div className="w-full md:w-[70%] flex-col md:flex-row text-xs md:text-[15px] flex items-center gap-x-5">
|
<div className="w-full md:w-[70%] flex-col md:flex-row text-xs md:text-[15px] flex items-center gap-x-5">
|
||||||
<span className="ml-1">API Token:</span>{" "}
|
<span className="ml-1">API Token:</span>{" "}
|
||||||
<span
|
<span
|
||||||
id="token"
|
id="token"
|
||||||
className={`${
|
className={`${
|
||||||
isSubscribe || !isEnableSubscription
|
isSubscribe
|
||||||
? ""
|
? ""
|
||||||
: "bg-white/20 pointer-events-none select-none"
|
: "bg-white/20 pointer-events-none select-none"
|
||||||
} md:text-end py-2 md:py-0`}
|
} md:text-end py-2 md:py-0`}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ function GuestLogin() {
|
|||||||
//function generate serverUrl and parseAppId from url and save it in local storage
|
//function generate serverUrl and parseAppId from url and save it in local storage
|
||||||
const handleServerUrl = async () => {
|
const handleServerUrl = async () => {
|
||||||
if (isEnableSubscription) {
|
if (isEnableSubscription) {
|
||||||
const applogo = await getAppLogo();
|
const app = await getAppLogo();
|
||||||
if (applogo) {
|
if (app?.logo) {
|
||||||
setAppLogo(applogo);
|
setAppLogo(app?.logo);
|
||||||
} else {
|
} else {
|
||||||
setAppLogo(logo);
|
setAppLogo(logo);
|
||||||
}
|
}
|
||||||
@@ -42,10 +42,8 @@ function GuestLogin() {
|
|||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
const parseId = appInfo.appId;
|
const parseId = appInfo.appId;
|
||||||
const newServer = `${appInfo.baseUrl}/`;
|
const newServer = `${appInfo.baseUrl}/`;
|
||||||
const appName = appInfo.appname;
|
|
||||||
localStorage.setItem("baseUrl", newServer);
|
localStorage.setItem("baseUrl", newServer);
|
||||||
localStorage.setItem("parseAppId", parseId);
|
localStorage.setItem("parseAppId", parseId);
|
||||||
localStorage.setItem("_appName", appName);
|
|
||||||
//this condition is used decode base64 to string and get userEmail,documentId, contactBoookId data.
|
//this condition is used decode base64 to string and get userEmail,documentId, contactBoookId data.
|
||||||
if (!id) {
|
if (!id) {
|
||||||
//`atob` function is used to decode base64
|
//`atob` function is used to decode base64
|
||||||
|
|||||||
+352
-801
File diff suppressed because it is too large
Load Diff
@@ -4,12 +4,10 @@ import "../styles/managesign.css";
|
|||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import { toDataUrl } from "../constant/Utils";
|
import { toDataUrl } from "../constant/Utils";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { appInfo } from "../constant/appinfo";
|
|
||||||
import { SaveFileSize } from "../constant/saveFileSize";
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
const ManageSign = () => {
|
const ManageSign = () => {
|
||||||
const appName = appInfo.appname;
|
|
||||||
const [penColor, setPenColor] = useState("blue");
|
const [penColor, setPenColor] = useState("blue");
|
||||||
const [initialPen, setInitialPen] = useState("blue");
|
const [initialPen, setInitialPen] = useState("blue");
|
||||||
const [image, setImage] = useState();
|
const [image, setImage] = useState();
|
||||||
@@ -39,7 +37,7 @@ const ManageSign = () => {
|
|||||||
objectId: User.id
|
objectId: User.id
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const signCls = `${appName}_Signature`;
|
const signCls = "contracts_Signature";
|
||||||
const signQuery = new Parse.Query(signCls);
|
const signQuery = new Parse.Query(signCls);
|
||||||
signQuery.equalTo("UserId", userId);
|
signQuery.equalTo("UserId", userId);
|
||||||
const signRes = await signQuery.first();
|
const signRes = await signQuery.first();
|
||||||
@@ -174,7 +172,7 @@ const ManageSign = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const saveEntry = async (obj) => {
|
const saveEntry = async (obj) => {
|
||||||
const signCls = `${appName}_Signature`;
|
const signCls = "contracts_Signature";
|
||||||
const User = Parse.User.current().id;
|
const User = Parse.User.current().id;
|
||||||
const userId = { __type: "Pointer", className: "_User", objectId: User };
|
const userId = { __type: "Pointer", className: "_User", objectId: User };
|
||||||
if (id) {
|
if (id) {
|
||||||
@@ -265,7 +263,7 @@ const ManageSign = () => {
|
|||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div>
|
<div>
|
||||||
{image ? (
|
{image ? (
|
||||||
<div className="signatureCanvas relative border-[2px] border-[#888] rounded-box">
|
<div className="signatureCanvas relative border-[2px] border-[#888] rounded-box overflow-hidden">
|
||||||
<img
|
<img
|
||||||
alt="signature"
|
alt="signature"
|
||||||
src={image}
|
src={image}
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ function Opensigndrive() {
|
|||||||
setIsFolderLoader(true);
|
setIsFolderLoader(true);
|
||||||
const getParentObjId = folderName[folderName.length - 1];
|
const getParentObjId = folderName[folderName.length - 1];
|
||||||
const parentId = getParentObjId && getParentObjId.objectId;
|
const parentId = getParentObjId && getParentObjId.objectId;
|
||||||
const foldercls = `${localStorage.getItem("_appName")}_Document`;
|
const foldercls = "contracts_Document";
|
||||||
const folderPtr = {
|
const folderPtr = {
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
className: foldercls,
|
className: foldercls,
|
||||||
@@ -465,7 +465,6 @@ function Opensigndrive() {
|
|||||||
if (isDontShow) {
|
if (isDontShow) {
|
||||||
const serverUrl = localStorage.getItem("baseUrl");
|
const serverUrl = localStorage.getItem("baseUrl");
|
||||||
const appId = localStorage.getItem("parseAppId");
|
const appId = localStorage.getItem("parseAppId");
|
||||||
const extUserClass = localStorage.getItem("extended_class");
|
|
||||||
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||||
const extUserId = json && json.length > 0 && json[0].objectId;
|
const extUserId = json && json.length > 0 && json[0].objectId;
|
||||||
let updatedTourStatus = [];
|
let updatedTourStatus = [];
|
||||||
@@ -483,7 +482,7 @@ function Opensigndrive() {
|
|||||||
updatedTourStatus = [{ driveTour: true }];
|
updatedTourStatus = [{ driveTour: true }];
|
||||||
}
|
}
|
||||||
await axios.put(
|
await axios.put(
|
||||||
serverUrl + "classes/" + extUserClass + "/" + extUserId,
|
serverUrl + "classes/contracts_Users/" + extUserId,
|
||||||
{
|
{
|
||||||
TourStatus: updatedTourStatus
|
TourStatus: updatedTourStatus
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -70,6 +70,19 @@ const PgSignUp = () => {
|
|||||||
});
|
});
|
||||||
if (res) {
|
if (res) {
|
||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
|
try {
|
||||||
|
const extUser = await Parse.Cloud.run("getUserDetails", {
|
||||||
|
email: userDetails.email
|
||||||
|
});
|
||||||
|
const userRole = extUser?.get("UserRole");
|
||||||
|
const _currentRole = userRole;
|
||||||
|
const _role = _currentRole.replace("contracts_", "");
|
||||||
|
localStorage.setItem("_user_role", _role);
|
||||||
|
const extInfo_stringify = JSON.stringify([extUser]);
|
||||||
|
localStorage.setItem("Extand_Class", extInfo_stringify);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in fetching extuser", err);
|
||||||
|
}
|
||||||
navigate(
|
navigate(
|
||||||
"/" + userSettings[0].pageType + "/" + userSettings[0].pageId
|
"/" + userSettings[0].pageType + "/" + userSettings[0].pageId
|
||||||
);
|
);
|
||||||
@@ -107,8 +120,6 @@ const PgSignUp = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const saveUser = async (obj) => {
|
const saveUser = async (obj) => {
|
||||||
// const domain = localStorage.getItem("domain");
|
|
||||||
// console.log("domain", domain)
|
|
||||||
try {
|
try {
|
||||||
const zohoRes = await axios.post(
|
const zohoRes = await axios.post(
|
||||||
parseBaseUrl + "functions/zohodetails",
|
parseBaseUrl + "functions/zohodetails",
|
||||||
@@ -209,8 +220,6 @@ const PgSignUp = () => {
|
|||||||
if (res.data) {
|
if (res.data) {
|
||||||
let _user = res.data;
|
let _user = res.data;
|
||||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
localStorage.setItem("userEmail", _user.email);
|
|
||||||
localStorage.setItem("username", _user.name);
|
|
||||||
localStorage.setItem("accesstoken", _user.sessionToken);
|
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||||
localStorage.setItem("scriptId", true);
|
localStorage.setItem("scriptId", true);
|
||||||
if (_user.ProfilePic) {
|
if (_user.ProfilePic) {
|
||||||
@@ -220,190 +229,52 @@ const PgSignUp = () => {
|
|||||||
}
|
}
|
||||||
// Check extended class user role and tenentId
|
// Check extended class user role and tenentId
|
||||||
try {
|
try {
|
||||||
let userRoles = [];
|
const userSettings = appInfo.settings;
|
||||||
if (appInfo.settings) {
|
const currentUser = Parse.User.current();
|
||||||
let userSettings = appInfo.settings;
|
const extUser = await Parse.Cloud.run("getUserDetails", {
|
||||||
|
email: currentUser.get("email")
|
||||||
//Get Current user roles
|
});
|
||||||
let url = `${baseUrl}functions/UserGroups`;
|
if (extUser) {
|
||||||
const headers = {
|
const IsDisabled = extUser?.get("IsDisabled") || false;
|
||||||
"Content-Type": "application/json",
|
if (!IsDisabled) {
|
||||||
"X-Parse-Application-Id": parseAppId,
|
const userRole = extUser?.get("UserRole");
|
||||||
sessionToken: _user.sessionToken
|
const menu =
|
||||||
};
|
userRole && userSettings.find((menu) => menu.role === userRole);
|
||||||
|
if (menu) {
|
||||||
let body = {
|
const _currentRole = userRole;
|
||||||
appname: localStorage.getItem("_appName")
|
const _role = _currentRole.replace("contracts_", "");
|
||||||
};
|
localStorage.setItem("_user_role", _role);
|
||||||
await axios
|
const extInfo_stringify = JSON.stringify([extUser]);
|
||||||
.post(url, JSON.stringify(body), { headers: headers })
|
localStorage.setItem("Extand_Class", extInfo_stringify);
|
||||||
.then((roles) => {
|
const extInfo = JSON.parse(JSON.stringify(extUser));
|
||||||
if (roles) {
|
localStorage.setItem("userEmail", extInfo?.Email);
|
||||||
userRoles = roles.data.result;
|
localStorage.setItem("username", extInfo?.Name);
|
||||||
let _currentRole = "";
|
if (extInfo?.TenantId) {
|
||||||
if (userRoles.length > 1) {
|
const tenant = {
|
||||||
if (
|
Id: extInfo?.TenantId?.objectId || "",
|
||||||
userRoles[0] ===
|
Name: extInfo?.TenantId?.TenantName || ""
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
};
|
||||||
) {
|
localStorage.setItem("TenantId", tenant?.Id);
|
||||||
_currentRole = userRoles[1];
|
dispatch(showTenant(tenant?.Name));
|
||||||
} else {
|
localStorage.setItem("TenantName", tenant?.Name);
|
||||||
_currentRole = userRoles[0];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_currentRole = userRoles[0];
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
_currentRole !==
|
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
|
||||||
) {
|
|
||||||
userSettings.forEach(async (element) => {
|
|
||||||
if (element.role === _currentRole) {
|
|
||||||
let _role = _currentRole.replace(
|
|
||||||
`${localStorage.getItem("_appName")}_`,
|
|
||||||
""
|
|
||||||
);
|
|
||||||
localStorage.setItem("_user_role", _role);
|
|
||||||
// Get TenentID from Extendend Class
|
|
||||||
localStorage.setItem(
|
|
||||||
"extended_class",
|
|
||||||
element.extended_class
|
|
||||||
);
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: currentUser.get("email")
|
|
||||||
}).then(
|
|
||||||
(result) => {
|
|
||||||
const results = [result];
|
|
||||||
let tenentInfo = [];
|
|
||||||
if (results) {
|
|
||||||
let extendedInfo_stringify =
|
|
||||||
JSON.stringify(results);
|
|
||||||
localStorage.setItem(
|
|
||||||
"Extand_Class",
|
|
||||||
extendedInfo_stringify
|
|
||||||
);
|
|
||||||
let extendedInfo = JSON.parse(
|
|
||||||
extendedInfo_stringify
|
|
||||||
);
|
|
||||||
if (extendedInfo.length > 1) {
|
|
||||||
extendedInfo.forEach((x) => {
|
|
||||||
if (x.TenantId) {
|
|
||||||
let obj = {
|
|
||||||
tenentId: x.TenantId.objectId,
|
|
||||||
tenentName: x.TenantId.TenantName || ""
|
|
||||||
};
|
|
||||||
tenentInfo.push(obj);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (tenentInfo.length) {
|
|
||||||
dispatch(
|
|
||||||
showTenant(tenentInfo[0].tenentName || "")
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"TenantName",
|
|
||||||
tenentInfo[0].tenentName || ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem("showpopup", true);
|
|
||||||
localStorage.setItem(
|
|
||||||
"PageLanding",
|
|
||||||
element.pageId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"defaultmenuid",
|
|
||||||
element.menuId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"pageType",
|
|
||||||
element.pageType
|
|
||||||
);
|
|
||||||
setIsLoader(false);
|
|
||||||
navigate("/", { replace: true });
|
|
||||||
} else {
|
|
||||||
extendedInfo.forEach((x) => {
|
|
||||||
if (x.TenantId) {
|
|
||||||
let obj = {
|
|
||||||
tenentId: x.TenantId.objectId,
|
|
||||||
tenentName: x.TenantId.TenantName || ""
|
|
||||||
};
|
|
||||||
localStorage.setItem(
|
|
||||||
"TenantId",
|
|
||||||
x.TenantId.objectId
|
|
||||||
);
|
|
||||||
tenentInfo.push(obj);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (tenentInfo.length) {
|
|
||||||
dispatch(
|
|
||||||
showTenant(tenentInfo[0].tenentName || "")
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"TenantName",
|
|
||||||
tenentInfo[0].tenentName || ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
localStorage.setItem(
|
|
||||||
"PageLanding",
|
|
||||||
element.pageId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"defaultmenuid",
|
|
||||||
element.menuId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"pageType",
|
|
||||||
element.pageType
|
|
||||||
);
|
|
||||||
setIsLoader(false);
|
|
||||||
alert("Registered user successfully");
|
|
||||||
const redirectUrl =
|
|
||||||
location?.state?.from ||
|
|
||||||
`/${element.pageType}/${element.pageId}`;
|
|
||||||
|
|
||||||
// Redirect to the appropriate URL after successful login
|
|
||||||
navigate(redirectUrl);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert("Registered user successfully");
|
|
||||||
localStorage.setItem("PageLanding", element.pageId);
|
|
||||||
localStorage.setItem(
|
|
||||||
"defaultmenuid",
|
|
||||||
element.menuId
|
|
||||||
);
|
|
||||||
localStorage.setItem("pageType", element.pageType);
|
|
||||||
setIsLoader(false);
|
|
||||||
const redirectUrl =
|
|
||||||
location?.state?.from ||
|
|
||||||
`/${element.pageType}/${element.pageId}`;
|
|
||||||
|
|
||||||
// Redirect to the appropriate URL after successful login
|
|
||||||
navigate(redirectUrl);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
setIsLoader(false);
|
|
||||||
console.error("Error while fetching Follow", error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setIsLoader(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setIsLoader(false);
|
|
||||||
}
|
}
|
||||||
})
|
localStorage.setItem("PageLanding", menu.pageId);
|
||||||
.catch((err) => {
|
localStorage.setItem("defaultmenuid", menu.menuId);
|
||||||
console.log("err", err);
|
localStorage.setItem("pageType", menu.pageType);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
});
|
alert("Registered user successfully");
|
||||||
|
const redirectUrl =
|
||||||
|
location?.state?.from || `/${menu.pageType}/${menu.pageId}`;
|
||||||
|
// Redirect to the appropriate URL after successful login
|
||||||
|
navigate(redirectUrl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
console.log(error);
|
console.log("Err in fetch extuser", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ import {
|
|||||||
replaceMailVaribles,
|
replaceMailVaribles,
|
||||||
copytoData,
|
copytoData,
|
||||||
fetchSubscription,
|
fetchSubscription,
|
||||||
convertPdfArrayBuffer
|
convertPdfArrayBuffer,
|
||||||
|
getContainerScale
|
||||||
} from "../constant/Utils";
|
} from "../constant/Utils";
|
||||||
import RenderPdf from "../components/pdf/RenderPdf";
|
import RenderPdf from "../components/pdf/RenderPdf";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@@ -50,7 +51,6 @@ import Upgrade from "../primitives/Upgrade";
|
|||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import TextFontSetting from "../components/pdf/TextFontSetting";
|
|
||||||
import PdfZoom from "../components/pdf/PdfZoom";
|
import PdfZoom from "../components/pdf/PdfZoom";
|
||||||
import LottieWithLoader from "../primitives/DotLottieReact";
|
import LottieWithLoader from "../primitives/DotLottieReact";
|
||||||
|
|
||||||
@@ -170,16 +170,7 @@ function PlaceHolderSign() {
|
|||||||
isDragStamp: !!monitor.isDragging()
|
isDragStamp: !!monitor.isDragging()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
const documentId = docId;
|
||||||
const rowLevel =
|
|
||||||
localStorage.getItem("rowlevel") &&
|
|
||||||
JSON.parse(localStorage.getItem("rowlevel"));
|
|
||||||
const objectId =
|
|
||||||
rowLevel && rowLevel.id
|
|
||||||
? rowLevel.id
|
|
||||||
: rowLevel?.objectId && rowLevel.objectId;
|
|
||||||
|
|
||||||
const documentId = docId ? docId : objectId && objectId;
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (documentId) {
|
if (documentId) {
|
||||||
getDocumentDetails();
|
getDocumentDetails();
|
||||||
@@ -454,7 +445,6 @@ function PlaceHolderSign() {
|
|||||||
const addPositionOfSignature = (item, monitor) => {
|
const addPositionOfSignature = (item, monitor) => {
|
||||||
getSignerPos(item, monitor);
|
getSignerPos(item, monitor);
|
||||||
};
|
};
|
||||||
// console.log("signerpos", signerPos);
|
|
||||||
const getSignerPos = (item, monitor) => {
|
const getSignerPos = (item, monitor) => {
|
||||||
// setSignerObjId("");
|
// setSignerObjId("");
|
||||||
// setContractName("");
|
// setContractName("");
|
||||||
@@ -463,10 +453,11 @@ function PlaceHolderSign() {
|
|||||||
setZIndex(posZIndex);
|
setZIndex(posZIndex);
|
||||||
const signer = signersdata.find((x) => x.Id === uniqueId);
|
const signer = signersdata.find((x) => x.Id === uniqueId);
|
||||||
const key = randomId();
|
const key = randomId();
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH?.width / getPdfPageWidth?.width || 1;
|
|
||||||
let dropData = [];
|
let dropData = [];
|
||||||
let placeHolder;
|
let placeHolder;
|
||||||
const dragTypeValue = item?.text ? item.text : monitor.type;
|
const dragTypeValue = item?.text ? item.text : monitor.type;
|
||||||
@@ -679,17 +670,19 @@ function PlaceHolderSign() {
|
|||||||
|
|
||||||
//function for set and update x and y postion after drag and drop signature tab
|
//function for set and update x and y postion after drag and drop signature tab
|
||||||
const handleStop = (event, dragElement, signerId, key) => {
|
const handleStop = (event, dragElement, signerId, key) => {
|
||||||
|
setFontColor();
|
||||||
|
setFontSize();
|
||||||
if (!isResize && isDragging) {
|
if (!isResize && isDragging) {
|
||||||
const dataNewPlace = addZIndex(signerPos, key, setZIndex);
|
const dataNewPlace = addZIndex(signerPos, key, setZIndex);
|
||||||
let updateSignPos = [...signerPos];
|
let updateSignPos = [...signerPos];
|
||||||
updateSignPos.splice(0, updateSignPos.length, ...dataNewPlace);
|
updateSignPos.splice(0, updateSignPos.length, ...dataNewPlace);
|
||||||
const signId = signerId ? signerId : uniqueId; //? signerId : signerObjId;
|
const signId = signerId ? signerId : uniqueId; //? signerId : signerObjId;
|
||||||
const keyValue = key ? key : dragKey;
|
const keyValue = key ? key : dragKey;
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH.width / getPdfPageWidth?.width;
|
|
||||||
|
|
||||||
if (keyValue >= 0) {
|
if (keyValue >= 0) {
|
||||||
let filterSignerPos;
|
let filterSignerPos;
|
||||||
if (signId) {
|
if (signId) {
|
||||||
@@ -751,7 +744,6 @@ function PlaceHolderSign() {
|
|||||||
setIsDragging(false);
|
setIsDragging(false);
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for delete signature block
|
//function for delete signature block
|
||||||
const handleDeleteSign = (key, Id) => {
|
const handleDeleteSign = (key, Id) => {
|
||||||
const updateData = [];
|
const updateData = [];
|
||||||
@@ -861,13 +853,14 @@ function PlaceHolderSign() {
|
|||||||
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
||||||
ignoreEncryption: true
|
ignoreEncryption: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const isSignYourSelfFlow = false;
|
const isSignYourSelfFlow = false;
|
||||||
try {
|
try {
|
||||||
const pdfBytes = await multiSignEmbed(
|
const pdfBytes = await multiSignEmbed(
|
||||||
placeholder,
|
placeholder,
|
||||||
pdfDoc,
|
pdfDoc,
|
||||||
isSignYourSelfFlow,
|
isSignYourSelfFlow,
|
||||||
|
scale,
|
||||||
|
pdfOriginalWH,
|
||||||
containerWH
|
containerWH
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1007,9 +1000,9 @@ function PlaceHolderSign() {
|
|||||||
}
|
}
|
||||||
await axios
|
await axios
|
||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"_appName"
|
"baseUrl"
|
||||||
)}_Document/${documentId}`,
|
)}classes/contracts_Document/${documentId}`,
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@@ -1145,12 +1138,7 @@ function PlaceHolderSign() {
|
|||||||
const senderName = `${pdfDetails?.[0].ExtUserPtr.Name}`;
|
const senderName = `${pdfDetails?.[0].ExtUserPtr.Name}`;
|
||||||
const documentName = `${pdfDetails?.[0].Name}`;
|
const documentName = `${pdfDetails?.[0].Name}`;
|
||||||
let replaceVar;
|
let replaceVar;
|
||||||
if (
|
if (requestBody && requestSubject && isCustomize && isSubscribe) {
|
||||||
requestBody &&
|
|
||||||
requestSubject &&
|
|
||||||
isCustomize &&
|
|
||||||
(isSubscribe || !isEnableSubscription)
|
|
||||||
) {
|
|
||||||
const replacedRequestBody = requestBody.replace(/"/g, "'");
|
const replacedRequestBody = requestBody.replace(/"/g, "'");
|
||||||
htmlReqBody =
|
htmlReqBody =
|
||||||
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body>" +
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body>" +
|
||||||
@@ -1218,12 +1206,7 @@ function PlaceHolderSign() {
|
|||||||
setMailStatus("success");
|
setMailStatus("success");
|
||||||
try {
|
try {
|
||||||
let data;
|
let data;
|
||||||
if (
|
if (requestBody && requestSubject && isCustomize && isSubscribe) {
|
||||||
requestBody &&
|
|
||||||
requestSubject &&
|
|
||||||
isCustomize &&
|
|
||||||
(isSubscribe || !isEnableSubscription)
|
|
||||||
) {
|
|
||||||
data = {
|
data = {
|
||||||
RequestBody: htmlReqBody,
|
RequestBody: htmlReqBody,
|
||||||
RequestSubject: requestSubject,
|
RequestSubject: requestSubject,
|
||||||
@@ -1237,9 +1220,9 @@ function PlaceHolderSign() {
|
|||||||
|
|
||||||
await axios
|
await axios
|
||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"_appName"
|
"baseUrl"
|
||||||
)}_Document/${documentId}`,
|
)}classes/contracts_Document/${documentId}`,
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@@ -1488,13 +1471,19 @@ function PlaceHolderSign() {
|
|||||||
hint: defaultdata?.hint || "",
|
hint: defaultdata?.hint || "",
|
||||||
defaultValue: defaultdata?.defaultValue || "",
|
defaultValue: defaultdata?.defaultValue || "",
|
||||||
validation:
|
validation:
|
||||||
(isSubscribe || !isEnableSubscription) && inputype
|
isSubscribe && inputype
|
||||||
? {
|
? {
|
||||||
type: inputype,
|
type: inputype,
|
||||||
pattern:
|
pattern:
|
||||||
inputype === "regex" ? defaultdata.textvalidate : ""
|
inputype === "regex" ? defaultdata.textvalidate : ""
|
||||||
}
|
}
|
||||||
: {}
|
: {},
|
||||||
|
fontSize:
|
||||||
|
fontSize || currWidgetsDetails?.options?.fontSize || "12",
|
||||||
|
fontColor:
|
||||||
|
fontColor ||
|
||||||
|
currWidgetsDetails?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@@ -1504,7 +1493,13 @@ function PlaceHolderSign() {
|
|||||||
...position.options,
|
...position.options,
|
||||||
name: defaultdata.name,
|
name: defaultdata.name,
|
||||||
status: defaultdata.status,
|
status: defaultdata.status,
|
||||||
defaultValue: defaultdata.defaultValue
|
defaultValue: defaultdata.defaultValue,
|
||||||
|
fontSize:
|
||||||
|
fontSize || currWidgetsDetails?.options?.fontSize || "12",
|
||||||
|
fontColor:
|
||||||
|
fontColor ||
|
||||||
|
currWidgetsDetails?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1528,6 +1523,8 @@ function PlaceHolderSign() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCurrWidgetsDetails({});
|
setCurrWidgetsDetails({});
|
||||||
|
setFontSize();
|
||||||
|
setFontColor();
|
||||||
handleNameModal();
|
handleNameModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1537,12 +1534,19 @@ function PlaceHolderSign() {
|
|||||||
setShowDropdown(false);
|
setShowDropdown(false);
|
||||||
setIsRadio(false);
|
setIsRadio(false);
|
||||||
setIsCheckbox(false);
|
setIsCheckbox(false);
|
||||||
|
setIsPageCopy(false);
|
||||||
|
//condition for text widget type after set all values for text widget
|
||||||
|
//change setUniqueId which is set in tempsignerId
|
||||||
|
//because textwidget do not have signer user so for selected signers we have to do
|
||||||
|
if (currWidgetsDetails.type === textWidget) {
|
||||||
|
setUniqueId(tempSignerId);
|
||||||
|
setTempSignerId("");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
//function for update TourStatus
|
//function for update TourStatus
|
||||||
const closeTour = async () => {
|
const closeTour = async () => {
|
||||||
setPlaceholderTour(false);
|
setPlaceholderTour(false);
|
||||||
if (isDontShow) {
|
if (isDontShow) {
|
||||||
const extUserClass = localStorage.getItem("extended_class");
|
|
||||||
let updatedTourStatus = [];
|
let updatedTourStatus = [];
|
||||||
if (tourStatus.length > 0) {
|
if (tourStatus.length > 0) {
|
||||||
updatedTourStatus = [...tourStatus];
|
updatedTourStatus = [...tourStatus];
|
||||||
@@ -1561,7 +1565,7 @@ function PlaceHolderSign() {
|
|||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"baseUrl"
|
"baseUrl"
|
||||||
)}classes/${extUserClass}/${signerUserId}`,
|
)}classes/contracts_Users/${signerUserId}`,
|
||||||
{
|
{
|
||||||
TourStatus: updatedTourStatus
|
TourStatus: updatedTourStatus
|
||||||
},
|
},
|
||||||
@@ -1620,13 +1624,11 @@ function PlaceHolderSign() {
|
|||||||
setCurrentId(getCurrentUserDeatils[0].Email);
|
setCurrentId(getCurrentUserDeatils[0].Email);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setSignersData(updateSigner);
|
setSignersData(updateSigner);
|
||||||
const index = signersdata.findIndex((x) => x.Id === uniqueId);
|
const index = signersdata.findIndex((x) => x.Id === uniqueId);
|
||||||
setIsSelectId(index);
|
setIsSelectId(index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//function to add new signer in document signers list
|
//function to add new signer in document signers list
|
||||||
const handleAddNewRecipients = (data) => {
|
const handleAddNewRecipients = (data) => {
|
||||||
const newId = randomId();
|
const newId = randomId();
|
||||||
@@ -1689,60 +1691,6 @@ function PlaceHolderSign() {
|
|||||||
setSignerPos(updatePlaceholderUser);
|
setSignerPos(updatePlaceholderUser);
|
||||||
setIsMailSend(false);
|
setIsMailSend(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveFontSize = () => {
|
|
||||||
const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
|
||||||
if (filterSignerPos.length > 0) {
|
|
||||||
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
|
||||||
|
|
||||||
const getPageNumer = getPlaceHolder.filter(
|
|
||||||
(data) => data.pageNumber === pageNumber
|
|
||||||
);
|
|
||||||
|
|
||||||
if (getPageNumer.length > 0) {
|
|
||||||
const getXYdata = getPageNumer[0].pos;
|
|
||||||
const getPosData = getXYdata;
|
|
||||||
const addSignPos = getPosData.map((position) => {
|
|
||||||
if (position.key === signKey) {
|
|
||||||
return {
|
|
||||||
...position,
|
|
||||||
options: {
|
|
||||||
...position.options,
|
|
||||||
fontSize: fontSize,
|
|
||||||
fontColor: fontColor
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return position;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateSignPos = getPlaceHolder.map((obj) => {
|
|
||||||
if (obj.pageNumber === pageNumber) {
|
|
||||||
return { ...obj, pos: addSignPos };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
const newUpdateSigner = signerPos.map((obj) => {
|
|
||||||
if (obj.Id === uniqueId) {
|
|
||||||
return { ...obj, placeHolder: newUpdateSignPos };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
setSignerPos(newUpdateSigner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setFontSize();
|
|
||||||
setFontColor();
|
|
||||||
if (currWidgetsDetails.type === textWidget) {
|
|
||||||
setUniqueId(tempSignerId);
|
|
||||||
setTempSignerId("");
|
|
||||||
}
|
|
||||||
|
|
||||||
handleTextSettingModal(false);
|
|
||||||
};
|
|
||||||
const handleTextSettingModal = (value) => {
|
|
||||||
setIsTextSetting(value);
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Title title={state?.title ? state.title : "New Document"} />
|
<Title title={state?.title ? state.title : "New Document"} />
|
||||||
@@ -1813,7 +1761,6 @@ function PlaceHolderSign() {
|
|||||||
: isSendAlert.mssg === "confirm" && "Send Mail"
|
: isSendAlert.mssg === "confirm" && "Send Mail"
|
||||||
}
|
}
|
||||||
handleClose={() => setIsSendAlert({})}
|
handleClose={() => setIsSendAlert({})}
|
||||||
showHeaderMessage={isSendAlert.mssg === "confirm"}
|
|
||||||
>
|
>
|
||||||
<div className="max-h-96 overflow-y-scroll scroll-hide p-[20px] text-base-content">
|
<div className="max-h-96 overflow-y-scroll scroll-hide p-[20px] text-base-content">
|
||||||
{isSendAlert.mssg === "sure" ? (
|
{isSendAlert.mssg === "sure" ? (
|
||||||
@@ -1828,86 +1775,69 @@ function PlaceHolderSign() {
|
|||||||
) : (
|
) : (
|
||||||
isSendAlert.mssg === "confirm" && (
|
isSendAlert.mssg === "confirm" && (
|
||||||
<>
|
<>
|
||||||
<>
|
{!isCustomize && (
|
||||||
{!isCustomize && (
|
<span>
|
||||||
<span>
|
Are you sure you want to send out this document
|
||||||
Are you sure you want to send out this
|
for signatures?
|
||||||
document for signatures?
|
</span>
|
||||||
</span>
|
)}
|
||||||
)}
|
{isCustomize && isSubscribe && (
|
||||||
{isCustomize &&
|
<>
|
||||||
(!isEnableSubscription || isSubscribe) && (
|
<EmailBody
|
||||||
<>
|
editorRef={editorRef}
|
||||||
<EmailBody
|
requestBody={requestBody}
|
||||||
editorRef={editorRef}
|
requestSubject={requestSubject}
|
||||||
requestBody={requestBody}
|
handleOnchangeRequest={handleOnchangeRequest}
|
||||||
requestSubject={requestSubject}
|
setRequestSubject={setRequestSubject}
|
||||||
handleOnchangeRequest={
|
/>
|
||||||
handleOnchangeRequest
|
<div
|
||||||
}
|
className="flex justify-end items-center gap-1 mt-2 op-link op-link-primary"
|
||||||
setRequestSubject={setRequestSubject}
|
onClick={() => {
|
||||||
/>
|
setRequestBody(defaultBody);
|
||||||
<div
|
setRequestSubject(defaultSubject);
|
||||||
className="flex justify-end items-center gap-1 mt-2 op-link op-link-primary"
|
}}
|
||||||
onClick={() => {
|
>
|
||||||
setRequestBody(defaultBody);
|
<span>Reset to default</span>
|
||||||
setRequestSubject(defaultSubject);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>Reset to default</span>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
"flex flex-row md:items-center gap-2 md:gap-6 mt-2 "
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="flex flex-row gap-2">
|
|
||||||
<button
|
|
||||||
onClick={() => sendEmailToSigners()}
|
|
||||||
className="op-btn op-btn-primary font-[500] text-sm shadow"
|
|
||||||
>
|
|
||||||
Send
|
|
||||||
</button>
|
|
||||||
{isCustomize && (
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setIsCustomize(false);
|
|
||||||
}}
|
|
||||||
className="op-btn op-btn-ghost font-[500] text-sm"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
{!isCustomize &&
|
)}
|
||||||
(isSubscribe || !isEnableSubscription) && (
|
<div className="flex flex-row md:items-center gap-2 md:gap-6 mt-2">
|
||||||
<span
|
<div className="flex flex-row gap-2">
|
||||||
className="op-link op-link-accent text-sm"
|
<button
|
||||||
onClick={() => {
|
onClick={() => sendEmailToSigners()}
|
||||||
setIsCustomize(!isCustomize);
|
className="op-btn op-btn-primary font-[500] text-sm shadow"
|
||||||
}}
|
>
|
||||||
>
|
Send
|
||||||
Cutomize Email
|
</button>
|
||||||
</span>
|
{isCustomize && (
|
||||||
)}
|
<button
|
||||||
|
onClick={() => setIsCustomize(false)}
|
||||||
{!isSubscribe && isEnableSubscription && (
|
className="op-btn op-btn-ghost font-[500] text-sm"
|
||||||
<div className="mt-2">
|
>
|
||||||
<Upgrade
|
Close
|
||||||
message="Upgrade to customize Email"
|
</button>
|
||||||
newWindow={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
{!isCustomize && isSubscribe && (
|
||||||
|
<span
|
||||||
|
className="op-link op-link-accent text-sm"
|
||||||
|
onClick={() => setIsCustomize(!isCustomize)}
|
||||||
|
>
|
||||||
|
Cutomize Email
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{!isSubscribe && isEnableSubscription && (
|
||||||
|
<div className="mt-2">
|
||||||
|
<Upgrade
|
||||||
|
message="Upgrade to customize Email"
|
||||||
|
newWindow={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isSendAlert.mssg === "confirm" && (
|
{isSendAlert.mssg === "confirm" && (
|
||||||
<>
|
<>
|
||||||
<div className="flex justify-center items-center mt-3">
|
<div className="flex justify-center items-center mt-3">
|
||||||
@@ -1948,29 +1878,37 @@ function PlaceHolderSign() {
|
|||||||
{!mailStatus && (
|
{!mailStatus && (
|
||||||
<div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div>
|
<div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div>
|
||||||
)}
|
)}
|
||||||
{isCurrUser && (
|
<div
|
||||||
|
className={
|
||||||
|
mailStatus === "success"
|
||||||
|
? "flex justify-center mt-1"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{isCurrUser && (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
handleRecipientSign();
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="op-btn op-btn-primary mr-1"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleRecipientSign();
|
setIsSend(false);
|
||||||
|
setSignerPos([]);
|
||||||
|
navigate("/report/1MwEuxLEkF");
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-primary mr-1"
|
className="op-btn op-btn-ghost"
|
||||||
>
|
>
|
||||||
Yes
|
{isCurrUser ? "No" : "Close"}
|
||||||
</button>
|
</button>
|
||||||
)}
|
</div>
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setIsSend(false);
|
|
||||||
setSignerPos([]);
|
|
||||||
navigate("/report/1MwEuxLEkF");
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="op-btn op-btn-ghost"
|
|
||||||
>
|
|
||||||
{isCurrUser ? "No" : "Close"}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
<ModalUi
|
<ModalUi
|
||||||
@@ -2095,10 +2033,10 @@ function PlaceHolderSign() {
|
|||||||
handleNameModal={setIsNameModal}
|
handleNameModal={setIsNameModal}
|
||||||
setTempSignerId={setTempSignerId}
|
setTempSignerId={setTempSignerId}
|
||||||
uniqueId={uniqueId}
|
uniqueId={uniqueId}
|
||||||
handleTextSettingModal={handleTextSettingModal}
|
|
||||||
pdfOriginalWH={pdfOriginalWH}
|
pdfOriginalWH={pdfOriginalWH}
|
||||||
setScale={setScale}
|
setScale={setScale}
|
||||||
scale={scale}
|
scale={scale}
|
||||||
|
setIsSelectId={setIsSelectId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -2142,6 +2080,7 @@ function PlaceHolderSign() {
|
|||||||
setBlockColor={setBlockColor}
|
setBlockColor={setBlockColor}
|
||||||
setIsAddSigner={setIsAddSigner}
|
setIsAddSigner={setIsAddSigner}
|
||||||
handleDeleteUser={handleDeleteUser}
|
handleDeleteUser={handleDeleteUser}
|
||||||
|
uniqueId={uniqueId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -2151,6 +2090,7 @@ function PlaceHolderSign() {
|
|||||||
aria-disabled
|
aria-disabled
|
||||||
>
|
>
|
||||||
<SignerListPlace
|
<SignerListPlace
|
||||||
|
setSignerPos={setSignerPos}
|
||||||
signerPos={signerPos}
|
signerPos={signerPos}
|
||||||
signersdata={signersdata}
|
signersdata={signersdata}
|
||||||
isSelectListId={isSelectListId}
|
isSelectListId={isSelectListId}
|
||||||
@@ -2167,6 +2107,7 @@ function PlaceHolderSign() {
|
|||||||
setIsAddSigner={setIsAddSigner}
|
setIsAddSigner={setIsAddSigner}
|
||||||
handleDeleteUser={handleDeleteUser}
|
handleDeleteUser={handleDeleteUser}
|
||||||
roleName={roleName}
|
roleName={roleName}
|
||||||
|
uniqueId={uniqueId}
|
||||||
// handleAddSigner={handleAddSigner}
|
// handleAddSigner={handleAddSigner}
|
||||||
/>
|
/>
|
||||||
<div data-tut="addWidgets">
|
<div data-tut="addWidgets">
|
||||||
@@ -2211,17 +2152,6 @@ function PlaceHolderSign() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
<TextFontSetting
|
|
||||||
isTextSetting={isTextSetting}
|
|
||||||
setIsTextSetting={setIsTextSetting}
|
|
||||||
fontSize={fontSize}
|
|
||||||
setFontSize={setFontSize}
|
|
||||||
fontColor={fontColor}
|
|
||||||
setFontColor={setFontColor}
|
|
||||||
handleSaveFontSize={handleSaveFontSize}
|
|
||||||
currWidgetsDetails={currWidgetsDetails}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<LinkUserModal
|
<LinkUserModal
|
||||||
handleAddUser={handleAddUser}
|
handleAddUser={handleAddUser}
|
||||||
isAddUser={isAddUser}
|
isAddUser={isAddUser}
|
||||||
@@ -2242,6 +2172,12 @@ function PlaceHolderSign() {
|
|||||||
handleClose={handleNameModal}
|
handleClose={handleNameModal}
|
||||||
handleData={handleWidgetdefaultdata}
|
handleData={handleWidgetdefaultdata}
|
||||||
isSubscribe={isSubscribe}
|
isSubscribe={isSubscribe}
|
||||||
|
isTextSetting={isTextSetting}
|
||||||
|
setIsTextSetting={setIsTextSetting}
|
||||||
|
fontSize={fontSize}
|
||||||
|
setFontSize={setFontSize}
|
||||||
|
fontColor={fontColor}
|
||||||
|
setFontColor={setFontColor}
|
||||||
/>
|
/>
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { NavLink, useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import checkmark from "../assets/images/checkmark.png";
|
import checkmark from "../assets/images/checkmark.png";
|
||||||
import plansArr from "../json/plansArr";
|
import plansArr from "../json/plansArr";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
@@ -16,7 +16,7 @@ const listItemStyle = {
|
|||||||
|
|
||||||
const PlanSubscriptions = () => {
|
const PlanSubscriptions = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [yearlyVisible, setYearlyVisible] = useState(false);
|
const [yearlyVisible, setYearlyVisible] = useState(true);
|
||||||
const [isLoader, setIsLoader] = useState(true);
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
const extUser =
|
const extUser =
|
||||||
localStorage.getItem("Extand_Class") &&
|
localStorage.getItem("Extand_Class") &&
|
||||||
@@ -29,10 +29,15 @@ const PlanSubscriptions = () => {
|
|||||||
};
|
};
|
||||||
const userDetails = JSON.parse(localStorage.getItem("userDetails")) || user;
|
const userDetails = JSON.parse(localStorage.getItem("userDetails")) || user;
|
||||||
// console.log("userDetails ", userDetails);
|
// console.log("userDetails ", userDetails);
|
||||||
const name =
|
const fullname =
|
||||||
userDetails && userDetails.name
|
userDetails && userDetails.name ? userDetails.name.split(" ") : "";
|
||||||
? "first_name=" + encodeURIComponent(userDetails.name)
|
const firstname = fullname?.[0]
|
||||||
: "";
|
? "first_name=" + encodeURIComponent(fullname?.[0])
|
||||||
|
: "";
|
||||||
|
const lastname = fullname?.[1]
|
||||||
|
? "&last_name=" + encodeURIComponent(fullname?.[1])
|
||||||
|
: "";
|
||||||
|
const name = firstname ? firstname + lastname : "";
|
||||||
const email =
|
const email =
|
||||||
userDetails && userDetails.email
|
userDetails && userDetails.email
|
||||||
? "&email=" + encodeURIComponent(userDetails.email)
|
? "&email=" + encodeURIComponent(userDetails.email)
|
||||||
@@ -53,33 +58,37 @@ const PlanSubscriptions = () => {
|
|||||||
company +
|
company +
|
||||||
phone;
|
phone;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if (localStorage.getItem("accesstoken")) {
|
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
// } else {
|
|
||||||
// navigate("/", { replace: true });
|
|
||||||
// }
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleFreePlan = async () => {
|
const handleFreePlan = async (item) => {
|
||||||
setIsLoader(true);
|
if (item.url) {
|
||||||
try {
|
const url = yearlyVisible ? item.yearlyUrl + details : item.url + details;
|
||||||
const params = { userId: Parse.User.current().id };
|
if (user) {
|
||||||
const res = await Parse.Cloud.run("freesubscription", params);
|
localStorage.setItem("userDetails", JSON.stringify(user));
|
||||||
if (res.status === "success" && res.result === "already subscribed!") {
|
}
|
||||||
setIsLoader(false);
|
openInNewTab(url, item?.target);
|
||||||
alert("You have already subscribed to plan!");
|
} else {
|
||||||
} else if (res.status === "success") {
|
setIsLoader(true);
|
||||||
setIsLoader(false);
|
try {
|
||||||
navigate("/");
|
const params = { userId: Parse.User.current().id };
|
||||||
} else if (res.status === "error") {
|
const res = await Parse.Cloud.run("freesubscription", params);
|
||||||
setIsLoader(false);
|
if (res.status === "success" && res.result === "already subscribed!") {
|
||||||
alert(res.result);
|
setIsLoader(false);
|
||||||
|
alert("You have already subscribed to plan!");
|
||||||
|
} else if (res.status === "success") {
|
||||||
|
setIsLoader(false);
|
||||||
|
navigate("/");
|
||||||
|
} else if (res.status === "error") {
|
||||||
|
setIsLoader(false);
|
||||||
|
alert(res.result);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setIsLoader(false);
|
||||||
|
console.log("err in free subscribe", err.message);
|
||||||
|
alert("Somenthing went wrong, please try again later!");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
setIsLoader(false);
|
|
||||||
console.log("err in free subscribe", err.message);
|
|
||||||
alert("Somenthing went wrong, please try again later!");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@@ -109,7 +118,7 @@ const PlanSubscriptions = () => {
|
|||||||
role="tab"
|
role="tab"
|
||||||
className={`${yearlyVisible ? "op-tab-active" : ""} op-tab`}
|
className={`${yearlyVisible ? "op-tab-active" : ""} op-tab`}
|
||||||
>
|
>
|
||||||
Yearly (10% off)
|
Yearly (upto 66% off)
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ul className="op-card flex flex-col md:flex-row h-full bg-base-100 justify-center shadow-lg">
|
<ul className="op-card flex flex-col md:flex-row h-full bg-base-100 justify-center shadow-lg">
|
||||||
@@ -122,19 +131,43 @@ const PlanSubscriptions = () => {
|
|||||||
<h3 className="text-[#002862] uppercase">
|
<h3 className="text-[#002862] uppercase">
|
||||||
{item.planName}
|
{item.planName}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="w-[150px] h-[150px]">
|
<div className="w-[120px] h-[120px] overflow-hidden">
|
||||||
<img
|
<img
|
||||||
className="icon-basic mx-auto"
|
className="w-full h-full object-contain"
|
||||||
src="https://js.zohostatic.com/books/zfwidgets/assets/images/plan.png"
|
src={require(`../assets/images/${item?.img}`)}
|
||||||
alt="freeimg"
|
alt="img"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span className="text-3xl">
|
<span className="text-3xl">
|
||||||
{item.currency && <small>{item.currency}</small>}
|
{item.currency && <small>{item.currency}</small>}
|
||||||
{yearlyVisible
|
{yearlyVisible ? (
|
||||||
? item?.yearlyPrice
|
<>
|
||||||
: item.monthlyPrice}
|
{item?.yearlyPrice.includes("<") ? (
|
||||||
|
<div
|
||||||
|
className="inline-block"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: item?.yearlyPrice
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<span>{item?.yearlyPrice}</span>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{item?.monthlyPrice.includes("<") ? (
|
||||||
|
<div
|
||||||
|
className="inline-block"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: item?.monthlyPrice
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<span>{item?.monthlyPrice}</span>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<p className="font-semibold pt-2 text-sm">
|
<p className="font-semibold pt-2 text-sm">
|
||||||
{yearlyVisible ? "Billed Yearly" : "Billed Monthly"}
|
{yearlyVisible ? "Billed Yearly" : "Billed Monthly"}
|
||||||
@@ -160,36 +193,29 @@ const PlanSubscriptions = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{item.url ? (
|
<button
|
||||||
<NavLink
|
className={`${
|
||||||
to={
|
item?.btn?.color ? item?.btn?.color : "op-btn-primary"
|
||||||
item.btnText === "Subscribe"
|
} w-full text-white py-2 op-btn uppercase hover:text-white cursor-pointer`}
|
||||||
? yearlyVisible
|
onClick={() => handleFreePlan(item)}
|
||||||
? item.yearlyUrl + details
|
>
|
||||||
: item.url + details
|
{item?.btn?.text}
|
||||||
: item.url
|
</button>
|
||||||
}
|
|
||||||
className="bg-[#002862] w-full text-white py-2 rounded uppercase hover:no-underline hover:text-white cursor-pointer"
|
|
||||||
target={item.target}
|
|
||||||
>
|
|
||||||
{item.btnText}
|
|
||||||
</NavLink>
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
className="bg-[#002862] w-full text-white py-2 rounded uppercase hover:text-white cursor-pointer"
|
|
||||||
onClick={() => handleFreePlan()}
|
|
||||||
>
|
|
||||||
{item.btnText}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<hr className="w-full bg-gray-300 h-[0.5px]" />
|
<hr className="w-full bg-gray-300 h-[0.5px]" />
|
||||||
<ul className="mx-1 p-3 text-left break-words text-sm list-none">
|
<ul className="mx-1 p-3 text-left break-words text-sm list-none">
|
||||||
{item.benefits.map((subitem, index) => (
|
{!yearlyVisible &&
|
||||||
<li style={listItemStyle} key={index} className="m-1">
|
item.benefits.map((subitem, index) => (
|
||||||
<span className="relative">{subitem}</span>
|
<li style={listItemStyle} key={index} className="m-1">
|
||||||
</li>
|
<span className="relative">{subitem}</span>
|
||||||
))}
|
</li>
|
||||||
|
))}
|
||||||
|
{yearlyVisible &&
|
||||||
|
item?.yearlyBenefits?.map((subitem, index) => (
|
||||||
|
<li style={listItemStyle} key={index} className="m-1">
|
||||||
|
<span className="relative">{subitem}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const Report = () => {
|
|||||||
const [form, setForm] = useState("");
|
const [form, setForm] = useState("");
|
||||||
const [tourData, setTourData] = useState([]);
|
const [tourData, setTourData] = useState([]);
|
||||||
const [isDontShow, setIsDontShow] = useState(false);
|
const [isDontShow, setIsDontShow] = useState(false);
|
||||||
|
const [isPublic, setIsPublic] = useState({});
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const docPerPage = 10;
|
const docPerPage = 10;
|
||||||
|
|
||||||
@@ -156,6 +157,13 @@ const Report = () => {
|
|||||||
? [...prevRecord, ...res.data.result]
|
? [...prevRecord, ...res.data.result]
|
||||||
: res.data.result
|
: res.data.result
|
||||||
);
|
);
|
||||||
|
const listData = res.data.result;
|
||||||
|
setIsPublic(
|
||||||
|
listData.reduce((acc, item) => {
|
||||||
|
acc[item.objectId] = item?.IsPublic || false;
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
@@ -193,6 +201,8 @@ const Report = () => {
|
|||||||
report_help={reporthelp}
|
report_help={reporthelp}
|
||||||
tourData={tourData}
|
tourData={tourData}
|
||||||
isDontShow={isDontShow}
|
isDontShow={isDontShow}
|
||||||
|
setIsPublic={setIsPublic}
|
||||||
|
isPublic={isPublic}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<PageNotFound prefix={"Report"} />
|
<PageNotFound prefix={"Report"} />
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
|
||||||
import { appInfo } from "../constant/appinfo";
|
import { appInfo } from "../constant/appinfo";
|
||||||
import { isEnableSubscription } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { fetchSubscription } from "../constant/Utils";
|
import { fetchSubscription } from "../constant/Utils";
|
||||||
@@ -136,8 +135,6 @@ const SSOVerify = () => {
|
|||||||
};
|
};
|
||||||
// `thirdpartyLoginfn` is used to save necessary parameters locally for the logged-in user
|
// `thirdpartyLoginfn` is used to save necessary parameters locally for the logged-in user
|
||||||
const thirdpartyLoginfn = async (sessionToken) => {
|
const thirdpartyLoginfn = async (sessionToken) => {
|
||||||
const baseUrl = localStorage.getItem("baseUrl");
|
|
||||||
const parseAppId = localStorage.getItem("parseAppId");
|
|
||||||
try {
|
try {
|
||||||
const validUser = await Parse.User.become(sessionToken);
|
const validUser = await Parse.User.become(sessionToken);
|
||||||
if (validUser) {
|
if (validUser) {
|
||||||
@@ -151,76 +148,44 @@ const SSOVerify = () => {
|
|||||||
}
|
}
|
||||||
// Check extended class user role and tenentId
|
// Check extended class user role and tenentId
|
||||||
try {
|
try {
|
||||||
let userRoles = [];
|
|
||||||
const userSettings = appInfo.settings;
|
const userSettings = appInfo.settings;
|
||||||
//Get Current user roles
|
const currentUser = Parse.User.current();
|
||||||
const url = `${baseUrl}functions/UserGroups`;
|
await Parse.Cloud.run("getUserDetails", {
|
||||||
const headers = {
|
email: currentUser.get("email")
|
||||||
"Content-Type": "application/json",
|
})
|
||||||
"X-Parse-Application-Id": parseAppId,
|
.then(async (extUser) => {
|
||||||
sessionToken: _user.sessionToken
|
if (extUser) {
|
||||||
};
|
const IsDisabled = extUser?.get("IsDisabled") || false;
|
||||||
const body = { appname: appInfo.appname };
|
if (!IsDisabled) {
|
||||||
const UserGroupsRes = await axios.post(url, JSON.stringify(body), {
|
const userRole = extUser?.get("UserRole");
|
||||||
headers: headers
|
const menu =
|
||||||
});
|
userRole &&
|
||||||
userRoles = (UserGroupsRes.data && UserGroupsRes.data.result) || [];
|
userSettings.find((menu) => menu.role === userRole);
|
||||||
if (userRoles) {
|
if (menu) {
|
||||||
let _currentRole = "";
|
const _currentRole = userRole;
|
||||||
const excludeRoles = ["contracts_Guest", `contracts_appeditor`];
|
const redirectUrl =
|
||||||
const filteredRole = userRoles.filter(
|
location?.state?.from ||
|
||||||
(x) => !excludeRoles.includes(x)
|
`/${menu.pageType}/${menu.pageId}`;
|
||||||
);
|
const _role = _currentRole.replace("contracts_", "");
|
||||||
if (filteredRole?.length > 1) {
|
localStorage.setItem("_user_role", _role);
|
||||||
console.log("user has two roles");
|
const extUser_stringify = JSON.stringify([extUser]);
|
||||||
// _currentRole = filteredRole.filter((x) => x === "contracts_User");
|
localStorage.setItem("Extand_Class", extUser_stringify);
|
||||||
} else {
|
const _extUser = JSON.parse(JSON.stringify(extUser));
|
||||||
_currentRole = filteredRole?.[0] || "";
|
localStorage.setItem("userEmail", _extUser.Email);
|
||||||
}
|
localStorage.setItem("username", _extUser.Name);
|
||||||
if (_currentRole) {
|
localStorage.setItem("scriptId", true);
|
||||||
const roleSetting = userSettings?.find(
|
|
||||||
(setting) => setting.role === _currentRole
|
|
||||||
);
|
|
||||||
const redirectUrl =
|
|
||||||
location?.state?.from ||
|
|
||||||
`/${roleSetting.pageType}/${roleSetting.pageId}`;
|
|
||||||
const _role = _currentRole.replace(`${appInfo.appname}_`, "");
|
|
||||||
localStorage.setItem("_user_role", _role);
|
|
||||||
// Get TenentID from Extendend Class
|
|
||||||
localStorage.setItem(
|
|
||||||
"extended_class",
|
|
||||||
roleSetting.extended_class
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
const extUser = await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: _user.email
|
|
||||||
});
|
|
||||||
if (extUser) {
|
|
||||||
const _extUser = JSON.parse(JSON.stringify(extUser));
|
|
||||||
localStorage.setItem("userEmail", _extUser.Email);
|
|
||||||
localStorage.setItem("username", _extUser.Name);
|
|
||||||
localStorage.setItem("scriptId", true);
|
|
||||||
let tenentInfo = [];
|
|
||||||
const results = [extUser];
|
|
||||||
if (results) {
|
|
||||||
let extendedInfo_stringify = JSON.stringify(results);
|
|
||||||
localStorage.setItem(
|
|
||||||
"Extand_Class",
|
|
||||||
extendedInfo_stringify
|
|
||||||
);
|
|
||||||
if (_extUser.TenantId) {
|
if (_extUser.TenantId) {
|
||||||
const obj = {
|
const tenant = {
|
||||||
tenentId: _extUser.TenantId.objectId,
|
Id: _extUser?.TenantId?.objectId || "",
|
||||||
tenentName: _extUser.TenantId.TenantName || ""
|
Name: _extUser?.TenantId?.TenantName || ""
|
||||||
};
|
};
|
||||||
localStorage.setItem("TenantId", obj.tenentId);
|
localStorage.setItem("TenantId", tenant?.Id);
|
||||||
tenentInfo.push(obj);
|
dispatch(showTenant(tenant?.Name));
|
||||||
dispatch(showTenant(obj.tenentName || ""));
|
localStorage.setItem("TenantName", tenant?.Name);
|
||||||
localStorage.setItem("TenantName", obj.tenentName || "");
|
|
||||||
}
|
}
|
||||||
localStorage.setItem("PageLanding", roleSetting.pageId);
|
localStorage.setItem("PageLanding", menu.pageId);
|
||||||
localStorage.setItem("defaultmenuid", roleSetting.menuId);
|
localStorage.setItem("defaultmenuid", menu.menuId);
|
||||||
localStorage.setItem("pageType", roleSetting.pageType);
|
localStorage.setItem("pageType", menu.pageType);
|
||||||
if (isEnableSubscription) {
|
if (isEnableSubscription) {
|
||||||
const res = await fetchSubscription();
|
const res = await fetchSubscription();
|
||||||
const plan = res.plan;
|
const plan = res.plan;
|
||||||
@@ -232,35 +197,32 @@ const SSOVerify = () => {
|
|||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
navigate(redirectUrl);
|
navigate(redirectUrl);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, {
|
navigate(`/subscription`, { replace: true });
|
||||||
replace: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, {
|
navigate(`/subscription`, { replace: true });
|
||||||
replace: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(redirectUrl);
|
navigate(redirectUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
alert(
|
||||||
|
"Error: You don't have access, please contact the admin."
|
||||||
|
);
|
||||||
|
setMessage(
|
||||||
|
"Error: You don't have access, please contact the admin."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
alert("user not exist.");
|
|
||||||
setMessage("Error: User not exist.");
|
|
||||||
console.log("err in get extUser", err);
|
|
||||||
}
|
}
|
||||||
} else {
|
})
|
||||||
alert("Role does not exists.");
|
.catch((error) => {
|
||||||
setMessage("Error: Role does not exists.");
|
console.error("Err in fetch extuser", error);
|
||||||
}
|
alert("user not exist.");
|
||||||
} else {
|
setMessage("Error: User not exist.");
|
||||||
alert("Role does not exists.");
|
});
|
||||||
setMessage("Error: Role does not exists.");
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err in usergroups", err);
|
console.log("err in getuserdetails", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -44,14 +44,8 @@ const Signup = () => {
|
|||||||
let baseUrl = localStorage.getItem("baseUrl");
|
let baseUrl = localStorage.getItem("baseUrl");
|
||||||
let appid = localStorage.getItem("parseAppId");
|
let appid = localStorage.getItem("parseAppId");
|
||||||
let applogo = localStorage.getItem("appLogo");
|
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 defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
let PageLanding = localStorage.getItem("PageLanding");
|
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");
|
let userSettings = localStorage.getItem("userSettings");
|
||||||
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
@@ -59,14 +53,8 @@ const Signup = () => {
|
|||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
localStorage.setItem("appLogo", applogo);
|
localStorage.setItem("appLogo", applogo);
|
||||||
localStorage.setItem("domain", domain);
|
|
||||||
localStorage.setItem("appversion", appversion);
|
|
||||||
localStorage.setItem("appTitle", appTitle);
|
|
||||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
localStorage.setItem("PageLanding", PageLanding);
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
localStorage.setItem("_appName", _appName);
|
|
||||||
localStorage.setItem("_app_objectId", _app_objectId);
|
|
||||||
localStorage.setItem("appName", appName);
|
|
||||||
localStorage.setItem("userSettings", userSettings);
|
localStorage.setItem("userSettings", userSettings);
|
||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
@@ -194,8 +182,6 @@ const Signup = () => {
|
|||||||
if (res.data) {
|
if (res.data) {
|
||||||
let _user = res.data;
|
let _user = res.data;
|
||||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
localStorage.setItem("userEmail", _user.email);
|
|
||||||
localStorage.setItem("username", _user.name);
|
|
||||||
localStorage.setItem("accesstoken", _user.sessionToken);
|
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||||
localStorage.setItem("scriptId", true);
|
localStorage.setItem("scriptId", true);
|
||||||
if (_user.ProfilePic) {
|
if (_user.ProfilePic) {
|
||||||
@@ -205,252 +191,84 @@ const Signup = () => {
|
|||||||
}
|
}
|
||||||
// Check extended class user role and tenentId
|
// Check extended class user role and tenentId
|
||||||
try {
|
try {
|
||||||
let userRoles = [];
|
const userSettings = appInfo.settings;
|
||||||
if (appInfo.settings) {
|
const currentUser = Parse.User.current();
|
||||||
let userSettings = appInfo.settings;
|
await Parse.Cloud.run("getUserDetails", {
|
||||||
|
email: currentUser.get("email")
|
||||||
//Get Current user roles
|
})
|
||||||
let url = `${baseUrl}functions/UserGroups`;
|
.then(async (extUser) => {
|
||||||
const headers = {
|
if (extUser) {
|
||||||
"Content-Type": "application/json",
|
const IsDisabled = extUser?.get("IsDisabled") || false;
|
||||||
"X-Parse-Application-Id": parseAppId,
|
if (!IsDisabled) {
|
||||||
sessionToken: _user.sessionToken
|
const userRole = extUser?.get("UserRole");
|
||||||
};
|
const menu =
|
||||||
|
userRole &&
|
||||||
let body = {
|
userSettings.find((menu) => menu.role === userRole);
|
||||||
appname: localStorage.getItem("_appName")
|
if (menu) {
|
||||||
};
|
const _currentRole = userRole;
|
||||||
await axios
|
const _role = _currentRole.replace("contracts_", "");
|
||||||
.post(url, JSON.stringify(body), { headers: headers })
|
localStorage.setItem("_user_role", _role);
|
||||||
.then((roles) => {
|
const extInfo_stringify = JSON.stringify([extUser]);
|
||||||
if (roles) {
|
localStorage.setItem("Extand_Class", extInfo_stringify);
|
||||||
userRoles = roles.data.result;
|
const extInfo = JSON.parse(JSON.stringify(extUser));
|
||||||
let _currentRole = "";
|
localStorage.setItem("userEmail", extInfo?.Email);
|
||||||
if (userRoles.length > 1) {
|
localStorage.setItem("username", extInfo?.Name);
|
||||||
if (
|
if (extInfo?.TenantId) {
|
||||||
userRoles[0] ===
|
const tenant = {
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
Id: extInfo?.TenantId?.objectId || "",
|
||||||
) {
|
Name: extInfo?.TenantId?.TenantName || ""
|
||||||
_currentRole = userRoles[1];
|
};
|
||||||
} else {
|
localStorage.setItem("TenantId", tenant?.Id);
|
||||||
_currentRole = userRoles[0];
|
dispatch(showTenant(tenant?.Name));
|
||||||
|
localStorage.setItem("TenantName", tenant?.Name);
|
||||||
}
|
}
|
||||||
} else {
|
localStorage.setItem("PageLanding", menu.pageId);
|
||||||
_currentRole = userRoles[0];
|
localStorage.setItem("defaultmenuid", menu.menuId);
|
||||||
}
|
localStorage.setItem("pageType", menu.pageType);
|
||||||
if (
|
setState({ loading: false });
|
||||||
_currentRole !==
|
if (isEnableSubscription) {
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
if (isFreeplan) {
|
||||||
) {
|
navigate(`/${menu.pageType}/${menu.pageId}`);
|
||||||
userSettings.forEach(async (element) => {
|
} else {
|
||||||
if (element.role === _currentRole) {
|
navigate(`/subscription`, { replace: true });
|
||||||
let _role = _currentRole.replace(
|
|
||||||
`${localStorage.getItem("_appName")}_`,
|
|
||||||
""
|
|
||||||
);
|
|
||||||
localStorage.setItem("_user_role", _role);
|
|
||||||
// Get TenentID from Extendend Class
|
|
||||||
localStorage.setItem(
|
|
||||||
"extended_class",
|
|
||||||
element.extended_class
|
|
||||||
);
|
|
||||||
await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: email
|
|
||||||
}).then(
|
|
||||||
(result) => {
|
|
||||||
let tenentInfo = [];
|
|
||||||
const results = [result];
|
|
||||||
if (results) {
|
|
||||||
let extendedInfo_stringify =
|
|
||||||
JSON.stringify(results);
|
|
||||||
localStorage.setItem(
|
|
||||||
"Extand_Class",
|
|
||||||
extendedInfo_stringify
|
|
||||||
);
|
|
||||||
let extendedInfo = JSON.parse(
|
|
||||||
extendedInfo_stringify
|
|
||||||
);
|
|
||||||
if (extendedInfo.length > 1) {
|
|
||||||
extendedInfo.forEach((x) => {
|
|
||||||
if (x.TenantId) {
|
|
||||||
let obj = {
|
|
||||||
tenentId: x.TenantId.objectId,
|
|
||||||
tenentName: x.TenantId.TenantName || ""
|
|
||||||
};
|
|
||||||
tenentInfo.push(obj);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (tenentInfo.length) {
|
|
||||||
dispatch(
|
|
||||||
showTenant(tenentInfo[0].tenentName || "")
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"TenantName",
|
|
||||||
tenentInfo[0].tenentName || ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem("showpopup", true);
|
|
||||||
localStorage.setItem(
|
|
||||||
"IncludedApps",
|
|
||||||
JSON.stringify(tenentInfo)
|
|
||||||
);
|
|
||||||
|
|
||||||
localStorage.setItem(
|
|
||||||
"PageLanding",
|
|
||||||
element.pageId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"defaultmenuid",
|
|
||||||
element.menuId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"pageType",
|
|
||||||
element.pageType
|
|
||||||
);
|
|
||||||
setState({ loading: false });
|
|
||||||
navigate("/");
|
|
||||||
} else {
|
|
||||||
extendedInfo.forEach((x) => {
|
|
||||||
if (x.TenantId) {
|
|
||||||
let obj = {
|
|
||||||
tenentId: x.TenantId.objectId,
|
|
||||||
tenentName: x.TenantId.TenantName || ""
|
|
||||||
};
|
|
||||||
localStorage.setItem(
|
|
||||||
"TenantId",
|
|
||||||
x.TenantId.objectId
|
|
||||||
);
|
|
||||||
tenentInfo.push(obj);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (tenentInfo.length) {
|
|
||||||
dispatch(
|
|
||||||
showTenant(tenentInfo[0].tenentName || "")
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"TenantName",
|
|
||||||
tenentInfo[0].tenentName || ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
localStorage.setItem(
|
|
||||||
"PageLanding",
|
|
||||||
element.pageId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"defaultmenuid",
|
|
||||||
element.menuId
|
|
||||||
);
|
|
||||||
localStorage.setItem(
|
|
||||||
"pageType",
|
|
||||||
element.pageType
|
|
||||||
);
|
|
||||||
setState({ loading: false });
|
|
||||||
if (isEnableSubscription) {
|
|
||||||
if (isFreeplan) {
|
|
||||||
navigate(
|
|
||||||
`/${element.pageType}/${element.pageId}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
navigate(`/subscription`, { replace: true });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert("Registered user successfully");
|
|
||||||
navigate(
|
|
||||||
`/${element.pageType}/${element.pageId}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert("Registered user successfully");
|
|
||||||
localStorage.setItem("PageLanding", element.pageId);
|
|
||||||
localStorage.setItem(
|
|
||||||
"defaultmenuid",
|
|
||||||
element.menuId
|
|
||||||
);
|
|
||||||
localStorage.setItem("pageType", element.pageType);
|
|
||||||
setState({ loading: false });
|
|
||||||
if (isEnableSubscription) {
|
|
||||||
if (isFreeplan) {
|
|
||||||
navigate(
|
|
||||||
`/${element.pageType}/${element.pageId}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
navigate(`/subscription`, { replace: true });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
navigate(
|
|
||||||
`/${element.pageType}/${element.pageId}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
setState({
|
|
||||||
loading: false,
|
|
||||||
alertType: "danger",
|
|
||||||
alertMsg:
|
|
||||||
"You dont have access to this application!"
|
|
||||||
});
|
|
||||||
setTimeout(function () {
|
|
||||||
setState({
|
|
||||||
loading: false,
|
|
||||||
alertType: "danger",
|
|
||||||
alertMsg: ""
|
|
||||||
});
|
|
||||||
}, 2000);
|
|
||||||
localStorage.setItem("accesstoken", null);
|
|
||||||
console.error("Error while fetching Follow", error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
alert("Registered user successfully");
|
||||||
|
navigate(`/${menu.pageType}/${menu.pageId}`);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
alertType: "danger",
|
alertType: "danger",
|
||||||
alertMsg: "User Role Not Found!"
|
alertMsg: "Role not found."
|
||||||
});
|
});
|
||||||
setTimeout(function () {
|
setTimeout(() => {
|
||||||
setState({
|
setState({ loading: false, alertMsg: "" });
|
||||||
loading: false,
|
|
||||||
alertType: "danger",
|
|
||||||
alertMsg: ""
|
|
||||||
});
|
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
alertType: "danger",
|
alertType: "danger",
|
||||||
alertMsg: "User Role Not Found!"
|
alertMsg: "You don't have access, please contact the admin."
|
||||||
});
|
});
|
||||||
setTimeout(function () {
|
setTimeout(() => {
|
||||||
setState({
|
setState({ loading: false, alertMsg: "" });
|
||||||
loading: false,
|
|
||||||
alertType: "danger",
|
|
||||||
alertMsg: ""
|
|
||||||
});
|
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.catch((err) => {
|
})
|
||||||
console.log("err", err);
|
.catch((error) => {
|
||||||
setState({
|
console.log("error in fetch extuser", error);
|
||||||
loading: false,
|
setState({
|
||||||
alertType: "danger",
|
loading: false,
|
||||||
alertMsg:
|
alertType: "danger",
|
||||||
"Does not have permissions to access this application!"
|
alertMsg: "You don't have access, please contact the admin."
|
||||||
});
|
|
||||||
setTimeout(function () {
|
|
||||||
setState({
|
|
||||||
loading: false,
|
|
||||||
alertType: "danger",
|
|
||||||
alertMsg: ""
|
|
||||||
});
|
|
||||||
}, 2000);
|
|
||||||
});
|
});
|
||||||
}
|
setTimeout(() => {
|
||||||
|
setState({ loading: false, alertMsg: "" });
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// alert(`${error.message}`);
|
// alert(`${error.message}`);
|
||||||
setState({
|
setState({
|
||||||
@@ -458,12 +276,8 @@ const Signup = () => {
|
|||||||
alertType: "danger",
|
alertType: "danger",
|
||||||
alertMsg: `${error.message}`
|
alertMsg: `${error.message}`
|
||||||
});
|
});
|
||||||
setTimeout(function () {
|
setTimeout(() => {
|
||||||
setState({
|
setState({ loading: false, alertMsg: "" });
|
||||||
loading: false,
|
|
||||||
alertType: "danger",
|
|
||||||
alertMsg: ""
|
|
||||||
});
|
|
||||||
}, 2000);
|
}, 2000);
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
@@ -477,9 +291,9 @@ const Signup = () => {
|
|||||||
|
|
||||||
const saveLogo = async () => {
|
const saveLogo = async () => {
|
||||||
if (isEnableSubscription) {
|
if (isEnableSubscription) {
|
||||||
const logo = await getAppLogo();
|
const app = await getAppLogo();
|
||||||
if (logo) {
|
if (app?.logo) {
|
||||||
setImage(logo);
|
setImage(app?.logo);
|
||||||
} else {
|
} else {
|
||||||
setImage(appInfo?.applogo || undefined);
|
setImage(appInfo?.applogo || undefined);
|
||||||
}
|
}
|
||||||
@@ -601,9 +415,9 @@ const Signup = () => {
|
|||||||
onClick={togglePasswordVisibility}
|
onClick={togglePasswordVisibility}
|
||||||
>
|
>
|
||||||
{showPassword ? (
|
{showPassword ? (
|
||||||
<i className="fa fa-eye-slash" /> // Close eye icon
|
<i className="fa-light fa-eye-slash" /> // Close eye icon
|
||||||
) : (
|
) : (
|
||||||
<i className="fa fa-eye" /> // Open eye icon
|
<i className="fa-light fa-eye" /> // Open eye icon
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import React, { useState, useRef, useEffect } from "react";
|
|||||||
import { PDFDocument } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { isEnableSubscription } from "../constant/const";
|
|
||||||
import Confetti from "react-confetti";
|
import Confetti from "react-confetti";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import LoaderWithMsg from "../primitives/LoaderWithMsg";
|
import LoaderWithMsg from "../primitives/LoaderWithMsg";
|
||||||
@@ -33,7 +32,8 @@ import {
|
|||||||
textInputWidget,
|
textInputWidget,
|
||||||
fetchImageBase64,
|
fetchImageBase64,
|
||||||
changeImageWH,
|
changeImageWH,
|
||||||
handleSendOTP
|
handleSendOTP,
|
||||||
|
getContainerScale
|
||||||
} from "../constant/Utils";
|
} from "../constant/Utils";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import Tour from "reactour";
|
import Tour from "reactour";
|
||||||
@@ -71,8 +71,8 @@ function SignYourSelf() {
|
|||||||
const signRef = useRef(null);
|
const signRef = useRef(null);
|
||||||
const dragRef = useRef(null);
|
const dragRef = useRef(null);
|
||||||
const [dragKey, setDragKey] = useState();
|
const [dragKey, setDragKey] = useState();
|
||||||
const [fontSize, setFontSize] = useState(11);
|
const [fontSize, setFontSize] = useState();
|
||||||
const [fontColor, setFontColor] = useState("black");
|
const [fontColor, setFontColor] = useState();
|
||||||
const [signKey, setSignKey] = useState();
|
const [signKey, setSignKey] = useState();
|
||||||
const [imgWH, setImgWH] = useState({});
|
const [imgWH, setImgWH] = useState({});
|
||||||
const [pdfNewWidth, setPdfNewWidth] = useState();
|
const [pdfNewWidth, setPdfNewWidth] = useState();
|
||||||
@@ -264,9 +264,9 @@ function SignYourSelf() {
|
|||||||
}
|
}
|
||||||
await axios
|
await axios
|
||||||
.get(
|
.get(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"_appName"
|
"baseUrl"
|
||||||
)}_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${
|
)}classes/contracts_Signature?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${
|
||||||
jsonSender.objectId
|
jsonSender.objectId
|
||||||
}"}}`,
|
}"}}`,
|
||||||
{
|
{
|
||||||
@@ -443,6 +443,7 @@ function SignYourSelf() {
|
|||||||
};
|
};
|
||||||
//function for setting position after drop signature button over pdf
|
//function for setting position after drop signature button over pdf
|
||||||
const addPositionOfSignature = (item, monitor) => {
|
const addPositionOfSignature = (item, monitor) => {
|
||||||
|
setCurrWidgetsDetails({});
|
||||||
const key = randomId();
|
const key = randomId();
|
||||||
let dropData = [];
|
let dropData = [];
|
||||||
let dropObj = {};
|
let dropObj = {};
|
||||||
@@ -454,10 +455,11 @@ function SignYourSelf() {
|
|||||||
const widgetTypeExist = ["name", "company", "job title", "email"].includes(
|
const widgetTypeExist = ["name", "company", "job title", "email"].includes(
|
||||||
dragTypeValue
|
dragTypeValue
|
||||||
);
|
);
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH?.width / getPdfPageWidth?.width || 1;
|
|
||||||
//adding and updating drop position in array when user drop signature button in div
|
//adding and updating drop position in array when user drop signature button in div
|
||||||
if (item === "onclick") {
|
if (item === "onclick") {
|
||||||
const getWidth = widgetTypeExist
|
const getWidth = widgetTypeExist
|
||||||
@@ -695,7 +697,9 @@ function SignYourSelf() {
|
|||||||
xyPostion,
|
xyPostion,
|
||||||
pdfDoc,
|
pdfDoc,
|
||||||
isSignYourSelfFlow,
|
isSignYourSelfFlow,
|
||||||
scale
|
scale,
|
||||||
|
pdfOriginalWH,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
// console.log("pdf", pdfBytes);
|
// console.log("pdf", pdfBytes);
|
||||||
//function for call to embed signature in pdf and get digital signature pdf
|
//function for call to embed signature in pdf and get digital signature pdf
|
||||||
@@ -739,7 +743,7 @@ function SignYourSelf() {
|
|||||||
if (
|
if (
|
||||||
tenantDetails?.CompletionBody &&
|
tenantDetails?.CompletionBody &&
|
||||||
tenantDetails?.CompletionSubject &&
|
tenantDetails?.CompletionSubject &&
|
||||||
(!isEnableSubscription || getIsSubscribe)
|
getIsSubscribe
|
||||||
) {
|
) {
|
||||||
isCustomCompletionMail = true;
|
isCustomCompletionMail = true;
|
||||||
}
|
}
|
||||||
@@ -767,7 +771,7 @@ function SignYourSelf() {
|
|||||||
console.log("error", e);
|
console.log("error", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//change image width and height to 104/44 in png base64
|
//change image width and height to 100/40 in png base64
|
||||||
const getNewse64 = await changeImageWH(base64Sign);
|
const getNewse64 = await changeImageWH(base64Sign);
|
||||||
//remove suffiix of base64
|
//remove suffiix of base64
|
||||||
const suffixbase64 = getNewse64 && getNewse64.split(",").pop();
|
const suffixbase64 = getNewse64 && getNewse64.split(",").pop();
|
||||||
@@ -809,12 +813,15 @@ function SignYourSelf() {
|
|||||||
};
|
};
|
||||||
//function for set and update x and y postion after drag and drop signature tab
|
//function for set and update x and y postion after drag and drop signature tab
|
||||||
const handleStop = (event, dragElement) => {
|
const handleStop = (event, dragElement) => {
|
||||||
|
setFontSize();
|
||||||
|
setFontColor();
|
||||||
if (isDragging && dragElement) {
|
if (isDragging && dragElement) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH.width / getPdfPageWidth?.width || 1;
|
|
||||||
if (dragKey >= 0) {
|
if (dragKey >= 0) {
|
||||||
const filterDropPos = xyPostion.filter(
|
const filterDropPos = xyPostion.filter(
|
||||||
(data) => data.pageNumber === pageNumber
|
(data) => data.pageNumber === pageNumber
|
||||||
@@ -1028,9 +1035,9 @@ function SignYourSelf() {
|
|||||||
}
|
}
|
||||||
await axios
|
await axios
|
||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"_appName"
|
"baseUrl"
|
||||||
)}${contractName}/${signerUserId}`,
|
)}classes/contracts${contractName}/${signerUserId}`,
|
||||||
{
|
{
|
||||||
TourStatus: updatedTourStatus
|
TourStatus: updatedTourStatus
|
||||||
},
|
},
|
||||||
@@ -1134,8 +1141,10 @@ function SignYourSelf() {
|
|||||||
...position,
|
...position,
|
||||||
options: {
|
options: {
|
||||||
...position.options,
|
...position.options,
|
||||||
fontSize: fontSize || currWidgetsDetails?.options?.fontSize,
|
fontSize:
|
||||||
fontColor: fontColor || currWidgetsDetails?.options?.fontColor
|
fontSize || currWidgetsDetails?.options?.fontSize || "12",
|
||||||
|
fontColor:
|
||||||
|
fontColor || currWidgetsDetails?.options?.fontColor || "black"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1153,7 +1162,6 @@ function SignYourSelf() {
|
|||||||
handleTextSettingModal(false);
|
handleTextSettingModal(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
<Title title={"Self Sign"} />
|
<Title title={"Self Sign"} />
|
||||||
|
|||||||
@@ -0,0 +1,465 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import Tooltip from "../primitives/Tooltip";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import pad from "../assets/images/pad.svg";
|
||||||
|
import AddTeam from "../components/AddTeam";
|
||||||
|
import { isEnableSubscription } from "../constant/const";
|
||||||
|
import { checkIsSubscribedTeam } from "../constant/Utils";
|
||||||
|
import SubscribeCard from "../primitives/SubscribeCard";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
|
||||||
|
const heading = ["Sr.No", "Name", "Parent Team", "Active"];
|
||||||
|
const actions = [
|
||||||
|
{
|
||||||
|
btnId: "1231",
|
||||||
|
hoverLabel: "Edit",
|
||||||
|
btnColor: "op-btn-primary",
|
||||||
|
btnIcon: "fa-light fa-pen",
|
||||||
|
redirectUrl: "",
|
||||||
|
action: "edit"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const TeamList = () => {
|
||||||
|
const recordperPage = 10;
|
||||||
|
const [teamList, setTeamList] = useState([]);
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [isModal, setIsModal] = useState(false);
|
||||||
|
const location = useLocation();
|
||||||
|
const isDashboard =
|
||||||
|
location?.pathname === "/dashboard/35KBoSgoAK" ? true : false;
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [isActiveModal, setIsActiveModal] = useState({});
|
||||||
|
const [isAlert, setIsAlert] = useState({ type: "success", msg: "" });
|
||||||
|
const [isActLoader, setIsActLoader] = useState({});
|
||||||
|
const [isSubscribe, setIsSubscribe] = useState(false);
|
||||||
|
const [isEditModal, setIsEditModal] = useState({});
|
||||||
|
const [isAdmin, setIsAdmin] = useState(false);
|
||||||
|
const startIndex = (currentPage - 1) * recordperPage; // user per page
|
||||||
|
|
||||||
|
const getPaginationRange = () => {
|
||||||
|
const totalPageNumbers = 7; // Adjust this value to show more/less page numbers
|
||||||
|
const pages = [];
|
||||||
|
const totalPages = Math.ceil(teamList.length / recordperPage);
|
||||||
|
if (totalPages <= totalPageNumbers) {
|
||||||
|
for (let i = 1; i <= totalPages; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const leftSiblingIndex = Math.max(currentPage - 1, 1);
|
||||||
|
const rightSiblingIndex = Math.min(currentPage + 1, totalPages);
|
||||||
|
|
||||||
|
const showLeftDots = leftSiblingIndex > 2;
|
||||||
|
const showRightDots = rightSiblingIndex < totalPages - 2;
|
||||||
|
|
||||||
|
const firstPageIndex = 1;
|
||||||
|
const lastPageIndex = totalPages;
|
||||||
|
|
||||||
|
if (!showLeftDots && showRightDots) {
|
||||||
|
let leftItemCount = 3;
|
||||||
|
let leftRange = Array.from({ length: leftItemCount }, (_, i) => i + 1);
|
||||||
|
|
||||||
|
pages.push(...leftRange);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(totalPages);
|
||||||
|
} else if (showLeftDots && !showRightDots) {
|
||||||
|
let rightItemCount = 3;
|
||||||
|
let rightRange = Array.from(
|
||||||
|
{ length: rightItemCount },
|
||||||
|
(_, i) => totalPages - rightItemCount + i + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
pages.push(firstPageIndex);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(...rightRange);
|
||||||
|
} else if (showLeftDots && showRightDots) {
|
||||||
|
let middleRange = Array.from(
|
||||||
|
{ length: 3 },
|
||||||
|
(_, i) => leftSiblingIndex + i
|
||||||
|
);
|
||||||
|
|
||||||
|
pages.push(firstPageIndex);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(...middleRange);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(lastPageIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages;
|
||||||
|
};
|
||||||
|
const pageNumbers = getPaginationRange();
|
||||||
|
useEffect(() => {
|
||||||
|
fetchTeamList();
|
||||||
|
}, []);
|
||||||
|
async function fetchTeamList() {
|
||||||
|
try {
|
||||||
|
setIsLoader(true);
|
||||||
|
if (isEnableSubscription) {
|
||||||
|
const getIsSubscribe = await checkIsSubscribedTeam();
|
||||||
|
setIsSubscribe(getIsSubscribe);
|
||||||
|
}
|
||||||
|
const extUser = JSON.parse(localStorage.getItem("Extand_Class"))?.[0];
|
||||||
|
if (extUser) {
|
||||||
|
const admin =
|
||||||
|
extUser?.UserRole &&
|
||||||
|
(extUser?.UserRole === "contracts_Admin" ||
|
||||||
|
extUser?.UserRole === "contracts_OrgAdmin")
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
setIsAdmin(admin);
|
||||||
|
}
|
||||||
|
const teams = await Parse.Cloud.run("getteams");
|
||||||
|
if (teams.length > 0) {
|
||||||
|
const _teamRes = JSON.parse(JSON.stringify(teams));
|
||||||
|
setTeamList(_teamRes);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in fetch teamlist", err);
|
||||||
|
setIsAlert({ type: "danger", msg: "Something went wrong." });
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert({ type: "success", msg: "" });
|
||||||
|
}, 1500);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const handleFormModal = () => {
|
||||||
|
setIsModal(!isModal);
|
||||||
|
};
|
||||||
|
// Get current list
|
||||||
|
const indexOfLastDoc = currentPage * recordperPage;
|
||||||
|
const indexOfFirstDoc = indexOfLastDoc - recordperPage;
|
||||||
|
const currentList = teamList?.slice(indexOfFirstDoc, indexOfLastDoc);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setIsActiveModal({});
|
||||||
|
setIsEditModal({});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Change page
|
||||||
|
const paginateFront = () => setCurrentPage(currentPage + 1);
|
||||||
|
const paginateBack = () => setCurrentPage(currentPage - 1);
|
||||||
|
const handleActionBtn = (act, item) => {
|
||||||
|
if (act.action === "edit") {
|
||||||
|
setIsEditModal({ [item.objectId]: true });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleToggleBtn = (team) => {
|
||||||
|
setIsActiveModal({ [team.objectId]: true });
|
||||||
|
};
|
||||||
|
const handleToggleSubmit = async (team) => {
|
||||||
|
const index = teamList.findIndex((obj) => obj.objectId === team.objectId);
|
||||||
|
if (index !== -1) {
|
||||||
|
setIsActiveModal({});
|
||||||
|
setIsActLoader({ [team.objectId]: true });
|
||||||
|
const newArray = [...teamList];
|
||||||
|
const IsActive = newArray[index].IsActive;
|
||||||
|
newArray[index] = { ...newArray[index], IsActive: !IsActive };
|
||||||
|
setTeamList(newArray);
|
||||||
|
try {
|
||||||
|
await Parse.Cloud.run("updateteam", {
|
||||||
|
IsActive: !IsActive === false ? "false" : "true",
|
||||||
|
TeamId: team.objectId
|
||||||
|
});
|
||||||
|
// console.log("teamRes ", teamRes);
|
||||||
|
setIsAlert({
|
||||||
|
type: !IsActive === false ? "danger" : "success",
|
||||||
|
msg: !IsActive === false ? "Team disabled." : "Team enabled."
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
setIsAlert({ type: "danger", msg: "something went wrong." });
|
||||||
|
console.log("err in disable team", err);
|
||||||
|
} finally {
|
||||||
|
setIsActLoader({});
|
||||||
|
setTimeout(() => setIsAlert({ type: "success", msg: "" }), 1500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleTeamInfo = (team) => {
|
||||||
|
setTeamList((prev) => [team, ...prev]);
|
||||||
|
};
|
||||||
|
const handleEditChange = (e, team) => {
|
||||||
|
const index = teamList.findIndex((obj) => obj.objectId === team.objectId);
|
||||||
|
if (index !== -1) {
|
||||||
|
const newArray = [...teamList];
|
||||||
|
newArray[index] = { ...newArray[index], Name: e.target.value };
|
||||||
|
setTeamList(newArray);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const updateTeamName = async (e, team) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsActLoader({ [team.objectId]: true });
|
||||||
|
setIsEditModal({});
|
||||||
|
try {
|
||||||
|
const data = { Name: team.Name, TeamId: team.objectId };
|
||||||
|
await Parse.Cloud.run("updateteam", data);
|
||||||
|
// console.log("updateTeamRes ", updateTeamRes);
|
||||||
|
setIsAlert({ type: "success", msg: "Team Update successfully." });
|
||||||
|
} catch (Err) {
|
||||||
|
console.log("Err in update team name"), Err;
|
||||||
|
setIsAlert({ type: "danger", msg: "Something went wrong." });
|
||||||
|
} finally {
|
||||||
|
setIsActLoader({});
|
||||||
|
setTimeout(() => setIsAlert({ type: "success", msg: "" }), 1500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<Title title={"Teams"} />
|
||||||
|
{isLoader && (
|
||||||
|
<div className="absolute w-full h-[300px] md:h-[400px] flex justify-center items-center z-30 rounded-box">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{Object.keys(isActLoader)?.length > 0 && (
|
||||||
|
<div className="absolute w-full h-full flex justify-center items-center bg-black bg-opacity-30 z-30 rounded-box">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isSubscribe && isEnableSubscription && !isLoader && (
|
||||||
|
<>
|
||||||
|
{isAdmin ? (
|
||||||
|
<div className="p-2 w-full bg-base-100 text-base-content op-card shadow-lg">
|
||||||
|
{isAlert.msg && (
|
||||||
|
<Alert type={isAlert.type}>
|
||||||
|
<div className="ml-3">{isAlert.msg}</div>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
||||||
|
<div className="font-light">
|
||||||
|
Teams{" "}
|
||||||
|
<span className="text-xs md:text-[13px] font-normal">
|
||||||
|
<Tooltip message={"Teams"} />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="cursor-pointer"
|
||||||
|
onClick={() => handleFormModal()}
|
||||||
|
>
|
||||||
|
<i className="fa-light fa-square-plus text-accent text-[40px]"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={` overflow-x-auto w-full`}>
|
||||||
|
<table className="op-table border-collapse w-full">
|
||||||
|
<thead className="text-[14px]">
|
||||||
|
<tr className="border-y-[1px]">
|
||||||
|
{heading?.map((item, index) => (
|
||||||
|
<React.Fragment key={index}>
|
||||||
|
<th className="px-4 py-2">{item}</th>
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="text-[12px]">
|
||||||
|
{teamList?.length > 0 && (
|
||||||
|
<>
|
||||||
|
{currentList.map((item, index) => (
|
||||||
|
<tr className="border-y-[1px]" key={index}>
|
||||||
|
{heading.includes("Sr.No") && (
|
||||||
|
<th className="px-4 py-2">
|
||||||
|
{startIndex + index + 1}
|
||||||
|
</th>
|
||||||
|
)}
|
||||||
|
<td className="px-4 py-2 font-semibold">
|
||||||
|
{item?.Name}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-2 font-semibold">
|
||||||
|
{item?.ParentId?.Name || "-"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-2 font-semibold">
|
||||||
|
{item?.Name !== "All Users" && (
|
||||||
|
<>
|
||||||
|
<label className="cursor-pointer relative block items-center mb-0">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="op-toggle transition-all op-toggle-secondary"
|
||||||
|
checked={item?.IsActive}
|
||||||
|
onChange={() => handleToggleBtn(item)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
{isActiveModal[item.objectId] && (
|
||||||
|
<ModalUi
|
||||||
|
isOpen
|
||||||
|
title={"Team status"}
|
||||||
|
handleClose={handleClose}
|
||||||
|
>
|
||||||
|
<div className="m-[20px]">
|
||||||
|
<div className="text-lg font-normal text-black">
|
||||||
|
Are you sure you want to{" "}
|
||||||
|
{item?.IsActive
|
||||||
|
? "disable"
|
||||||
|
: "enable"}{" "}
|
||||||
|
this team?
|
||||||
|
</div>
|
||||||
|
<hr className="bg-[#ccc] mt-4 " />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleToggleSubmit(item)
|
||||||
|
}
|
||||||
|
className="op-btn op-btn-primary"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleClose}
|
||||||
|
className="op-btn op-btn-secondary"
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="px-3 py-2 text-white flex flex-wrap gap-1">
|
||||||
|
{item?.Name !== "All Users" && (
|
||||||
|
<>
|
||||||
|
{actions?.length > 0 &&
|
||||||
|
actions.map((act, index) => (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={() =>
|
||||||
|
handleActionBtn(act, item)
|
||||||
|
}
|
||||||
|
title={act.hoverLabel}
|
||||||
|
className={`${
|
||||||
|
act?.btnColor ? act.btnColor : ""
|
||||||
|
} op-btn op-btn-sm w-[50px]`}
|
||||||
|
>
|
||||||
|
<i className={act.btnIcon}></i>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
{isEditModal[item.objectId] && (
|
||||||
|
<ModalUi
|
||||||
|
isOpen
|
||||||
|
title={"Edit Team"}
|
||||||
|
handleClose={handleClose}
|
||||||
|
>
|
||||||
|
<form
|
||||||
|
className="m-[20px]"
|
||||||
|
onSubmit={(e) =>
|
||||||
|
updateTeamName(e, item)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<label className="text-xs font-semibold text-base-content ml-1">
|
||||||
|
Name of Team{" "}
|
||||||
|
<span className="text-[red] text-[13px]">
|
||||||
|
*
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-base-content w-full text-xs"
|
||||||
|
value={item.Name}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleEditChange(e, item)
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="op-btn op-btn-primary mt-3"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="op-join flex flex-wrap items-center p-2">
|
||||||
|
{teamList.length > recordperPage && (
|
||||||
|
<button
|
||||||
|
onClick={() => paginateBack()}
|
||||||
|
className="op-join-item op-btn op-btn-sm"
|
||||||
|
>
|
||||||
|
Prev
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{pageNumbers.map((x, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCurrentPage(x)}
|
||||||
|
disabled={x === "..."}
|
||||||
|
className={`${
|
||||||
|
x === currentPage ? "op-btn-active" : ""
|
||||||
|
} op-join-item op-btn op-btn-sm`}
|
||||||
|
>
|
||||||
|
{x}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
{teamList.length > recordperPage && (
|
||||||
|
<button
|
||||||
|
onClick={() => paginateFront()}
|
||||||
|
className="op-join-item op-btn op-btn-sm"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{teamList?.length <= 0 && (
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
isDashboard ? "h-[317px]" : ""
|
||||||
|
} flex flex-col items-center justify-center w-ful bg-base-100 text-base-content rounded-xl py-4`}
|
||||||
|
>
|
||||||
|
<div className="w-[60px] h-[60px] overflow-hidden">
|
||||||
|
<img
|
||||||
|
className="w-full h-full object-contain"
|
||||||
|
src={pad}
|
||||||
|
alt="img"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm font-semibold">No Data Available</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ModalUi
|
||||||
|
title={"Add Team"}
|
||||||
|
isOpen={isModal}
|
||||||
|
handleClose={handleFormModal}
|
||||||
|
>
|
||||||
|
<AddTeam
|
||||||
|
setIsAlert={setIsAlert}
|
||||||
|
handleTeamInfo={handleTeamInfo}
|
||||||
|
closePopup={handleFormModal}
|
||||||
|
/>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center justify-center h-screen w-full bg-base-100 text-base-content rounded-box">
|
||||||
|
<div className="text-center">
|
||||||
|
<h1 className="text-[60px] lg:text-[120px] font-semibold">
|
||||||
|
404
|
||||||
|
</h1>
|
||||||
|
<p className="text-[30px] lg:text-[50px]">Page Not Found</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!isSubscribe && isEnableSubscription && !isLoader && (
|
||||||
|
<div data-tut="apisubscribe">
|
||||||
|
<SubscribeCard plan={"TEAMS"} price={"20"} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TeamList;
|
||||||
@@ -24,7 +24,8 @@ import {
|
|||||||
addWidgetOptions,
|
addWidgetOptions,
|
||||||
textInputWidget,
|
textInputWidget,
|
||||||
radioButtonWidget,
|
radioButtonWidget,
|
||||||
fetchSubscription
|
fetchSubscription,
|
||||||
|
getContainerScale
|
||||||
} from "../constant/Utils";
|
} from "../constant/Utils";
|
||||||
import RenderPdf from "../components/pdf/RenderPdf";
|
import RenderPdf from "../components/pdf/RenderPdf";
|
||||||
import "../styles/AddUser.css";
|
import "../styles/AddUser.css";
|
||||||
@@ -38,7 +39,6 @@ import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
|||||||
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
|
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import TextFontSetting from "../components/pdf/TextFontSetting";
|
|
||||||
import PdfZoom from "../components/pdf/PdfZoom";
|
import PdfZoom from "../components/pdf/PdfZoom";
|
||||||
const TemplatePlaceholder = () => {
|
const TemplatePlaceholder = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -365,10 +365,11 @@ const TemplatePlaceholder = () => {
|
|||||||
if (signer) {
|
if (signer) {
|
||||||
const posZIndex = zIndex + 1;
|
const posZIndex = zIndex + 1;
|
||||||
setZIndex(posZIndex);
|
setZIndex(posZIndex);
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH.width / getPdfPageWidth?.width || 1;
|
|
||||||
const key = randomId();
|
const key = randomId();
|
||||||
let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
||||||
const dragTypeValue = item?.text ? item.text : monitor.type;
|
const dragTypeValue = item?.text ? item.text : monitor.type;
|
||||||
@@ -389,7 +390,6 @@ const TemplatePlaceholder = () => {
|
|||||||
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
|
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
|
||||||
key: key,
|
key: key,
|
||||||
scale: containerScale,
|
scale: containerScale,
|
||||||
// isMobile: isMobile,
|
|
||||||
zIndex: posZIndex,
|
zIndex: posZIndex,
|
||||||
type: dragTypeValue,
|
type: dragTypeValue,
|
||||||
options: addWidgetOptions(dragTypeValue),
|
options: addWidgetOptions(dragTypeValue),
|
||||||
@@ -501,6 +501,8 @@ const TemplatePlaceholder = () => {
|
|||||||
setShowDropdown(true);
|
setShowDropdown(true);
|
||||||
} else if (dragTypeValue === "checkbox") {
|
} else if (dragTypeValue === "checkbox") {
|
||||||
setIsCheckbox(true);
|
setIsCheckbox(true);
|
||||||
|
} else if (dragTypeValue === radioButtonWidget) {
|
||||||
|
setIsRadio(true);
|
||||||
} else if (
|
} else if (
|
||||||
[textInputWidget, "name", "company", "job title", "email"].includes(
|
[textInputWidget, "name", "company", "job title", "email"].includes(
|
||||||
dragTypeValue
|
dragTypeValue
|
||||||
@@ -508,8 +510,6 @@ const TemplatePlaceholder = () => {
|
|||||||
) {
|
) {
|
||||||
setFontSize(12);
|
setFontSize(12);
|
||||||
setFontColor("black");
|
setFontColor("black");
|
||||||
} else if (dragTypeValue === radioButtonWidget) {
|
|
||||||
setIsRadio(true);
|
|
||||||
}
|
}
|
||||||
setCurrWidgetsDetails({});
|
setCurrWidgetsDetails({});
|
||||||
setWidgetType(dragTypeValue);
|
setWidgetType(dragTypeValue);
|
||||||
@@ -555,16 +555,19 @@ const TemplatePlaceholder = () => {
|
|||||||
|
|
||||||
//function for set and update x and y postion after drag and drop signature tab
|
//function for set and update x and y postion after drag and drop signature tab
|
||||||
const handleStop = (event, dragElement, signerId, key) => {
|
const handleStop = (event, dragElement, signerId, key) => {
|
||||||
|
setFontColor();
|
||||||
|
setFontSize();
|
||||||
if (!isResize && isDragging) {
|
if (!isResize && isDragging) {
|
||||||
const dataNewPlace = addZIndex(signerPos, key, setZIndex);
|
const dataNewPlace = addZIndex(signerPos, key, setZIndex);
|
||||||
let updateSignPos = [...signerPos];
|
let updateSignPos = [...signerPos];
|
||||||
updateSignPos.splice(0, updateSignPos.length, ...dataNewPlace);
|
updateSignPos.splice(0, updateSignPos.length, ...dataNewPlace);
|
||||||
const signId = signerId; //? signerId : signerObjId;
|
const signId = signerId; //? signerId : signerObjId;
|
||||||
const keyValue = key ? key : dragKey;
|
const keyValue = key ? key : dragKey;
|
||||||
const getPdfPageWidth = pdfOriginalWH.find(
|
const containerScale = getContainerScale(
|
||||||
(data) => data.pageNumber === pageNumber
|
pdfOriginalWH,
|
||||||
|
pageNumber,
|
||||||
|
containerWH
|
||||||
);
|
);
|
||||||
const containerScale = containerWH.width / getPdfPageWidth?.width || 1;
|
|
||||||
if (keyValue >= 0) {
|
if (keyValue >= 0) {
|
||||||
const filterSignerPos = updateSignPos.filter(
|
const filterSignerPos = updateSignPos.filter(
|
||||||
(data) => data.Id === signId
|
(data) => data.Id === signId
|
||||||
@@ -615,7 +618,6 @@ const TemplatePlaceholder = () => {
|
|||||||
setIsDragging(false);
|
setIsDragging(false);
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for delete signature block
|
//function for delete signature block
|
||||||
const handleDeleteSign = (key, Id) => {
|
const handleDeleteSign = (key, Id) => {
|
||||||
const updateData = [];
|
const updateData = [];
|
||||||
@@ -851,7 +853,6 @@ const TemplatePlaceholder = () => {
|
|||||||
const closeTour = async () => {
|
const closeTour = async () => {
|
||||||
setTemplateTour(false);
|
setTemplateTour(false);
|
||||||
if (isDontShow) {
|
if (isDontShow) {
|
||||||
const extUserClass = localStorage.getItem("extended_class");
|
|
||||||
let updatedTourStatus = [];
|
let updatedTourStatus = [];
|
||||||
if (tourStatus.length > 0) {
|
if (tourStatus.length > 0) {
|
||||||
updatedTourStatus = [...tourStatus];
|
updatedTourStatus = [...tourStatus];
|
||||||
@@ -870,7 +871,7 @@ const TemplatePlaceholder = () => {
|
|||||||
.put(
|
.put(
|
||||||
`${localStorage.getItem(
|
`${localStorage.getItem(
|
||||||
"baseUrl"
|
"baseUrl"
|
||||||
)}classes/${extUserClass}/${signerUserId}`,
|
)}classes/contracts_Users/${signerUserId}`,
|
||||||
{
|
{
|
||||||
TourStatus: updatedTourStatus
|
TourStatus: updatedTourStatus
|
||||||
},
|
},
|
||||||
@@ -1199,13 +1200,19 @@ const TemplatePlaceholder = () => {
|
|||||||
hint: defaultdata?.hint || "",
|
hint: defaultdata?.hint || "",
|
||||||
defaultValue: defaultdata?.defaultValue || "",
|
defaultValue: defaultdata?.defaultValue || "",
|
||||||
validation:
|
validation:
|
||||||
(isSubscribe || !isEnableSubscription) && inputype
|
isSubscribe && inputype
|
||||||
? {
|
? {
|
||||||
type: inputype,
|
type: inputype,
|
||||||
pattern:
|
pattern:
|
||||||
inputype === "regex" ? defaultdata.textvalidate : ""
|
inputype === "regex" ? defaultdata.textvalidate : ""
|
||||||
}
|
}
|
||||||
: {}
|
: {},
|
||||||
|
fontSize:
|
||||||
|
fontSize || currWidgetsDetails?.options?.fontSize || "12",
|
||||||
|
fontColor:
|
||||||
|
fontColor ||
|
||||||
|
currWidgetsDetails?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@@ -1215,7 +1222,13 @@ const TemplatePlaceholder = () => {
|
|||||||
...position.options,
|
...position.options,
|
||||||
name: defaultdata.name,
|
name: defaultdata.name,
|
||||||
status: defaultdata.status,
|
status: defaultdata.status,
|
||||||
defaultValue: defaultdata.defaultValue
|
defaultValue: defaultdata.defaultValue,
|
||||||
|
fontSize:
|
||||||
|
fontSize || currWidgetsDetails?.options?.fontSize || "12",
|
||||||
|
fontColor:
|
||||||
|
fontColor ||
|
||||||
|
currWidgetsDetails?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1238,6 +1251,8 @@ const TemplatePlaceholder = () => {
|
|||||||
setSignerPos(newUpdateSigner);
|
setSignerPos(newUpdateSigner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setFontSize();
|
||||||
|
setFontColor();
|
||||||
setCurrWidgetsDetails({});
|
setCurrWidgetsDetails({});
|
||||||
handleNameModal();
|
handleNameModal();
|
||||||
};
|
};
|
||||||
@@ -1249,55 +1264,6 @@ const TemplatePlaceholder = () => {
|
|||||||
setIsCheckbox(false);
|
setIsCheckbox(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveFontSize = () => {
|
|
||||||
const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
|
||||||
if (filterSignerPos.length > 0) {
|
|
||||||
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
|
||||||
|
|
||||||
const getPageNumer = getPlaceHolder.filter(
|
|
||||||
(data) => data.pageNumber === pageNumber
|
|
||||||
);
|
|
||||||
|
|
||||||
if (getPageNumer.length > 0) {
|
|
||||||
const getXYdata = getPageNumer[0].pos;
|
|
||||||
const getPosData = getXYdata;
|
|
||||||
const addSignPos = getPosData.map((position) => {
|
|
||||||
if (position.key === signKey) {
|
|
||||||
return {
|
|
||||||
...position,
|
|
||||||
options: {
|
|
||||||
...position.options,
|
|
||||||
fontSize: fontSize,
|
|
||||||
fontColor: fontColor
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return position;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newUpdateSignPos = getPlaceHolder.map((obj) => {
|
|
||||||
if (obj.pageNumber === pageNumber) {
|
|
||||||
return { ...obj, pos: addSignPos };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
const newUpdateSigner = signerPos.map((obj) => {
|
|
||||||
if (obj.Id === uniqueId) {
|
|
||||||
return { ...obj, placeHolder: newUpdateSignPos };
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
setSignerPos(newUpdateSigner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setFontSize();
|
|
||||||
setFontColor();
|
|
||||||
|
|
||||||
handleTextSettingModal(false);
|
|
||||||
};
|
|
||||||
const handleTextSettingModal = (value) => {
|
|
||||||
setIsTextSetting(value);
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Title title={"Template"} />
|
<Title title={"Template"} />
|
||||||
@@ -1399,6 +1365,7 @@ const TemplatePlaceholder = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsCreateDocModal(false);
|
setIsCreateDocModal(false);
|
||||||
|
navigate("/report/6TeaPr321t");
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-secondary ml-2"
|
className="op-btn op-btn-secondary ml-2"
|
||||||
@@ -1532,10 +1499,10 @@ const TemplatePlaceholder = () => {
|
|||||||
selectWidgetId={selectWidgetId}
|
selectWidgetId={selectWidgetId}
|
||||||
setIsCheckbox={setIsCheckbox}
|
setIsCheckbox={setIsCheckbox}
|
||||||
handleNameModal={setIsNameModal}
|
handleNameModal={setIsNameModal}
|
||||||
handleTextSettingModal={handleTextSettingModal}
|
|
||||||
pdfOriginalWH={pdfOriginalWH}
|
pdfOriginalWH={pdfOriginalWH}
|
||||||
setScale={setScale}
|
setScale={setScale}
|
||||||
scale={scale}
|
scale={scale}
|
||||||
|
setIsSelectId={setIsSelectId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -1591,6 +1558,7 @@ const TemplatePlaceholder = () => {
|
|||||||
<SignerListPlace
|
<SignerListPlace
|
||||||
isMailSend={isMailSend}
|
isMailSend={isMailSend}
|
||||||
signerPos={signerPos}
|
signerPos={signerPos}
|
||||||
|
setSignerPos={setSignerPos}
|
||||||
signersdata={signersdata}
|
signersdata={signersdata}
|
||||||
isSelectListId={isSelectListId}
|
isSelectListId={isSelectListId}
|
||||||
setSignerObjId={setSignerObjId}
|
setSignerObjId={setSignerObjId}
|
||||||
@@ -1607,6 +1575,7 @@ const TemplatePlaceholder = () => {
|
|||||||
setSignersData={setSignersData}
|
setSignersData={setSignersData}
|
||||||
blockColor={blockColor}
|
blockColor={blockColor}
|
||||||
setBlockColor={setBlockColor}
|
setBlockColor={setBlockColor}
|
||||||
|
uniqueId={uniqueId}
|
||||||
/>
|
/>
|
||||||
<div data-tut="addWidgets">
|
<div data-tut="addWidgets">
|
||||||
<WidgetComponent
|
<WidgetComponent
|
||||||
@@ -1669,16 +1638,12 @@ const TemplatePlaceholder = () => {
|
|||||||
handleClose={handleNameModal}
|
handleClose={handleNameModal}
|
||||||
handleData={handleWidgetdefaultdata}
|
handleData={handleWidgetdefaultdata}
|
||||||
isSubscribe={isSubscribe}
|
isSubscribe={isSubscribe}
|
||||||
/>
|
|
||||||
<TextFontSetting
|
|
||||||
isTextSetting={isTextSetting}
|
isTextSetting={isTextSetting}
|
||||||
setIsTextSetting={setIsTextSetting}
|
setIsTextSetting={setIsTextSetting}
|
||||||
fontSize={fontSize}
|
fontSize={fontSize}
|
||||||
setFontSize={setFontSize}
|
setFontSize={setFontSize}
|
||||||
fontColor={fontColor}
|
fontColor={fontColor}
|
||||||
setFontColor={setFontColor}
|
setFontColor={setFontColor}
|
||||||
handleSaveFontSize={handleSaveFontSize}
|
|
||||||
currWidgetsDetails={currWidgetsDetails}
|
|
||||||
/>
|
/>
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
import Parse from "parse";
|
||||||
|
import { NavLink, useNavigate } from "react-router-dom";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
|
||||||
|
const UpdateExistUserAdmin = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [formdata, setFormdata] = useState({ email: "", masterkey: "" });
|
||||||
|
const [loader, setLoader] = useState(true);
|
||||||
|
const [errMsg, setErrMsg] = useState("");
|
||||||
|
const [isSubmitLoading, setIsSubmitLoading] = useState(false);
|
||||||
|
const [isAlert, setIsAlert] = useState({ type: "danger", msg: "" });
|
||||||
|
useEffect(() => {
|
||||||
|
checkIsAdminExist();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const checkIsAdminExist = async () => {
|
||||||
|
try {
|
||||||
|
const isAdminExist = await Parse.Cloud.run("checkadminexist");
|
||||||
|
if (isAdminExist !== "not_exist") {
|
||||||
|
console.log("isAdminExist ", isAdminExist);
|
||||||
|
setErrMsg("Admin already exists.");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in checkadminexist", err);
|
||||||
|
setErrMsg("Something went wrong.");
|
||||||
|
} finally {
|
||||||
|
setLoader(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsSubmitLoading(true);
|
||||||
|
try {
|
||||||
|
const updateUserAsAdmin = await Parse.Cloud.run(
|
||||||
|
"updateuserasadmin",
|
||||||
|
formdata
|
||||||
|
);
|
||||||
|
// console.log("updateUserAsAdmin ", updateUserAsAdmin);
|
||||||
|
if (updateUserAsAdmin === "admin_created") {
|
||||||
|
setIsAlert({ type: "success", msg: "Admin created" });
|
||||||
|
navigate("/");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in updateuserasadmin", err.code);
|
||||||
|
if (err.code === 404) {
|
||||||
|
setIsAlert((prev) => ({ ...prev, msg: "Invalid masterkey" }));
|
||||||
|
} else if (err.code === 101) {
|
||||||
|
setIsAlert((prev) => ({ ...prev, msg: "User not found" }));
|
||||||
|
} else if (err.code === 137) {
|
||||||
|
setIsAlert((prev) => ({ ...prev, msg: "Admin already exist" }));
|
||||||
|
} else {
|
||||||
|
setErrMsg("Something went wrong.");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setIsSubmitLoading(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(() => ({ type: "danger", msg: "" }));
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="h-screen flex justify-center">
|
||||||
|
<Title title={"Add Admin"} />
|
||||||
|
{isAlert.msg && (
|
||||||
|
<Alert type={isAlert.type}>
|
||||||
|
<div className="ml-3">{isAlert.msg}</div>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
{loader ? (
|
||||||
|
<div className="text-[grey] flex justify-center items-center text-lg md:text-2xl">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{errMsg ? (
|
||||||
|
<div className="text-[grey] flex justify-center items-center text-lg md:text-2xl">
|
||||||
|
{errMsg}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="w-[95%] md:w-[500px]">
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div className="w-full my-4 op-card bg-base-100 shadow-md outline outline-1 outline-slate-300/50 overflow-hidden">
|
||||||
|
{isSubmitLoading && (
|
||||||
|
<div className="absolute z-40 w-full h-full flex justify-center bg-black/30">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<h2 className="text-[30px] text-center mt-3 font-medium">
|
||||||
|
Opensign Setup
|
||||||
|
</h2>
|
||||||
|
<NavLink
|
||||||
|
to="https://discord.com/invite/xe9TDuyAyj"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-center text-sm mt-1 text-[blue] cursor-pointer"
|
||||||
|
>
|
||||||
|
Join our discord server
|
||||||
|
<i
|
||||||
|
aria-hidden="true"
|
||||||
|
className="fa-brands fa-discord ml-1"
|
||||||
|
></i>
|
||||||
|
{/* <span className="fa-sr-only">OpenSign's Discord</span> */}
|
||||||
|
</NavLink>
|
||||||
|
<div className="px-6 py-3 text-xs">
|
||||||
|
<label>
|
||||||
|
Email <span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="email"
|
||||||
|
type="email"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={formdata.email}
|
||||||
|
onChange={(e) =>
|
||||||
|
setFormdata((prev) => ({
|
||||||
|
...prev,
|
||||||
|
email: e.target.value?.toLowerCase()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<hr className="my-2 border-none" />
|
||||||
|
<label>
|
||||||
|
Master key{" "}
|
||||||
|
<span className="text-[red] text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={formdata.masterkey}
|
||||||
|
onChange={(e) =>
|
||||||
|
setFormdata((prev) => ({
|
||||||
|
...prev,
|
||||||
|
masterkey: e.target.value
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/*
|
||||||
|
<div className="mt-2.5 ml-1 flex flex-row items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="op-checkbox op-checkbox-sm"
|
||||||
|
id="termsandcondition"
|
||||||
|
checked={isSubscribeNews}
|
||||||
|
onChange={(e) => setIsSubscribeNews(e.target.checked)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="text-xs cursor-pointer ml-1 mb-0"
|
||||||
|
htmlFor="termsandcondition"
|
||||||
|
>
|
||||||
|
Subscribe to OpenSign newsletter
|
||||||
|
</label>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
<div className="mx-4 text-center text-xs font-bold mb-3">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="op-btn op-btn-primary w-full"
|
||||||
|
disabled={loader}
|
||||||
|
>
|
||||||
|
{loader ? "Loading..." : "Next"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UpdateExistUserAdmin;
|
||||||
@@ -0,0 +1,426 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import pad from "../assets/images/pad.svg";
|
||||||
|
import Tooltip from "../primitives/Tooltip";
|
||||||
|
import AddUser from "../components/AddUser";
|
||||||
|
import SubscribeCard from "../primitives/SubscribeCard";
|
||||||
|
import { isEnableSubscription } from "../constant/const";
|
||||||
|
import { checkIsSubscribedTeam } from "../constant/Utils";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
const heading = ["Sr.No", "Name", "Email", "Phone", "Role", "Team", "Active"];
|
||||||
|
// const actions = [];
|
||||||
|
const UserList = () => {
|
||||||
|
const [userList, setUserList] = useState([]);
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [isModal, setIsModal] = useState(false);
|
||||||
|
const location = useLocation();
|
||||||
|
const isDashboard =
|
||||||
|
location?.pathname === "/dashboard/35KBoSgoAK" ? true : false;
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [isAlert, setIsAlert] = useState({ type: "success", msg: "" });
|
||||||
|
const [isActiveModal, setIsActiveModal] = useState({});
|
||||||
|
const [isActLoader, setIsActLoader] = useState({});
|
||||||
|
const [isSubscribe, setIsSubscribe] = useState(false);
|
||||||
|
const [isAdmin, setIsAdmin] = useState(false);
|
||||||
|
const recordperPage = 10;
|
||||||
|
const startIndex = (currentPage - 1) * recordperPage; // user per page
|
||||||
|
|
||||||
|
const getPaginationRange = () => {
|
||||||
|
const totalPageNumbers = 7; // Adjust this value to show more/less page numbers
|
||||||
|
const pages = [];
|
||||||
|
const totalPages = Math.ceil(userList.length / recordperPage);
|
||||||
|
if (totalPages <= totalPageNumbers) {
|
||||||
|
for (let i = 1; i <= totalPages; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const leftSiblingIndex = Math.max(currentPage - 1, 1);
|
||||||
|
const rightSiblingIndex = Math.min(currentPage + 1, totalPages);
|
||||||
|
|
||||||
|
const showLeftDots = leftSiblingIndex > 2;
|
||||||
|
const showRightDots = rightSiblingIndex < totalPages - 2;
|
||||||
|
|
||||||
|
const firstPageIndex = 1;
|
||||||
|
const lastPageIndex = totalPages;
|
||||||
|
|
||||||
|
if (!showLeftDots && showRightDots) {
|
||||||
|
let leftItemCount = 3;
|
||||||
|
let leftRange = Array.from({ length: leftItemCount }, (_, i) => i + 1);
|
||||||
|
|
||||||
|
pages.push(...leftRange);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(totalPages);
|
||||||
|
} else if (showLeftDots && !showRightDots) {
|
||||||
|
let rightItemCount = 3;
|
||||||
|
let rightRange = Array.from(
|
||||||
|
{ length: rightItemCount },
|
||||||
|
(_, i) => totalPages - rightItemCount + i + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
pages.push(firstPageIndex);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(...rightRange);
|
||||||
|
} else if (showLeftDots && showRightDots) {
|
||||||
|
let middleRange = Array.from(
|
||||||
|
{ length: 3 },
|
||||||
|
(_, i) => leftSiblingIndex + i
|
||||||
|
);
|
||||||
|
|
||||||
|
pages.push(firstPageIndex);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(...middleRange);
|
||||||
|
pages.push("...");
|
||||||
|
pages.push(lastPageIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages;
|
||||||
|
};
|
||||||
|
const pageNumbers = getPaginationRange();
|
||||||
|
useEffect(() => {
|
||||||
|
fetchUserList();
|
||||||
|
}, []);
|
||||||
|
async function fetchUserList() {
|
||||||
|
try {
|
||||||
|
setIsLoader(true);
|
||||||
|
if (isEnableSubscription) {
|
||||||
|
const getIsSubscribe = await checkIsSubscribedTeam();
|
||||||
|
setIsSubscribe(getIsSubscribe);
|
||||||
|
} else {
|
||||||
|
setIsSubscribe(true);
|
||||||
|
}
|
||||||
|
const extUser = JSON.parse(localStorage.getItem("Extand_Class"))?.[0];
|
||||||
|
if (extUser) {
|
||||||
|
const admin =
|
||||||
|
extUser?.UserRole &&
|
||||||
|
(extUser?.UserRole === "contracts_Admin" ||
|
||||||
|
extUser?.UserRole === "contracts_OrgAdmin")
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
setIsAdmin(admin);
|
||||||
|
}
|
||||||
|
const res = await Parse.Cloud.run("getuserlistbyorg", {
|
||||||
|
organizationId: extUser.OrganizationId.objectId
|
||||||
|
});
|
||||||
|
const _userRes = JSON.parse(JSON.stringify(res));
|
||||||
|
setUserList(_userRes);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in fetch userlist", err);
|
||||||
|
setIsAlert({ type: "danger", msg: "Something went wrong." });
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert({ type: "success", msg: "" });
|
||||||
|
}, 1500);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const handleFormModal = () => {
|
||||||
|
setIsModal(!isModal);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Change page
|
||||||
|
const paginateFront = () => setCurrentPage(currentPage + 1);
|
||||||
|
const paginateBack = () => setCurrentPage(currentPage - 1);
|
||||||
|
// const handleActionBtn = (act, item) => {
|
||||||
|
// if (act.action === "delete") {
|
||||||
|
// setIsDeleteModal({ [item.objectId]: true });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
const handleUserData = (userData) => {
|
||||||
|
setUserList((prev) => [userData, ...prev]);
|
||||||
|
};
|
||||||
|
// `formatRow` is used to show data in poper manner like
|
||||||
|
// if data is of array type then it will join array items with ","
|
||||||
|
// if data is of object type then it Name values will be show in row
|
||||||
|
// if no data available it will show hyphen "-"
|
||||||
|
const formatRow = (row) => {
|
||||||
|
if (Array.isArray(row)) {
|
||||||
|
let updateArr = row.map((x) => x.Name);
|
||||||
|
return updateArr.join(", ");
|
||||||
|
} else if (typeof row === "object" && row !== null) {
|
||||||
|
return row?.Name || "-";
|
||||||
|
} else {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleClose = () => {
|
||||||
|
setIsActiveModal({});
|
||||||
|
};
|
||||||
|
const handleToggleSubmit = async (user) => {
|
||||||
|
const index = userList.findIndex((obj) => obj.objectId === user.objectId);
|
||||||
|
if (index !== -1) {
|
||||||
|
setIsActiveModal({});
|
||||||
|
setIsActLoader({ [user.objectId]: true });
|
||||||
|
const newArray = [...userList];
|
||||||
|
const IsDisabled = newArray[index]?.IsDisabled;
|
||||||
|
newArray[index] = { ...newArray[index], IsDisabled: !IsDisabled };
|
||||||
|
setUserList(newArray);
|
||||||
|
try {
|
||||||
|
const extUser = new Parse.Object("contracts_Users");
|
||||||
|
extUser.id = user.objectId;
|
||||||
|
extUser.set("IsDisabled", !IsDisabled);
|
||||||
|
await extUser.save();
|
||||||
|
setIsAlert({
|
||||||
|
type: !IsDisabled === true ? "danger" : "success",
|
||||||
|
msg: !IsDisabled === true ? "User deactivated." : "User activated."
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
setIsAlert({ type: "danger", msg: "something went wrong." });
|
||||||
|
console.log("err in disable team", err);
|
||||||
|
} finally {
|
||||||
|
setIsActLoader({});
|
||||||
|
setTimeout(() => setIsAlert({ type: "success", msg: "" }), 1500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleToggleBtn = (user) => {
|
||||||
|
setIsActiveModal({ [user.objectId]: true });
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<Title title={isAdmin ? "Users" : "Page not found"} />
|
||||||
|
{isLoader && (
|
||||||
|
<div className="absolute w-full h-[300px] md:h-[400px] flex justify-center items-center z-30 rounded-box">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{Object.keys(isActLoader)?.length > 0 && (
|
||||||
|
<div className="absolute w-full h-full flex justify-center items-center bg-black bg-opacity-30 z-30 rounded-box">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isSubscribe && !isLoader && (
|
||||||
|
<>
|
||||||
|
{isAdmin ? (
|
||||||
|
<div className="p-2 w-full bg-base-100 text-base-content op-card shadow-lg">
|
||||||
|
{isAlert.msg && (
|
||||||
|
<Alert type={isAlert.type}>
|
||||||
|
<div className="ml-3">{isAlert.msg}</div>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
||||||
|
<div className="font-light">
|
||||||
|
Users{" "}
|
||||||
|
<span className="text-xs md:text-[13px] font-normal">
|
||||||
|
<Tooltip message={"users from Teams"} />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="cursor-pointer"
|
||||||
|
onClick={() => handleFormModal()}
|
||||||
|
>
|
||||||
|
<i className="fa-light fa-square-plus text-accent text-[40px]"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={` overflow-x-auto w-full`}>
|
||||||
|
<table className="op-table border-collapse w-full">
|
||||||
|
<thead className="text-[14px]">
|
||||||
|
<tr className="border-y-[1px]">
|
||||||
|
{heading?.map((item, index) => (
|
||||||
|
<React.Fragment key={index}>
|
||||||
|
<th className="px-4 py-2">{item}</th>
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="text-[12px]">
|
||||||
|
{userList?.length > 0 && (
|
||||||
|
<>
|
||||||
|
{userList.map((item, index) => (
|
||||||
|
<tr className="border-y-[1px]" key={index}>
|
||||||
|
{heading.includes("Sr.No") && (
|
||||||
|
<th className="px-4 py-2">
|
||||||
|
{startIndex + index + 1}
|
||||||
|
</th>
|
||||||
|
)}
|
||||||
|
<td className="px-4 py-2 font-semibold">
|
||||||
|
{item?.Name}{" "}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-2 ">{item?.Email || "-"}</td>
|
||||||
|
<td className="px-4 py-2">{item?.Phone || "-"}</td>
|
||||||
|
<td className="px-4 py-2">
|
||||||
|
{item?.UserRole?.split("_").pop() || "-"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-2">
|
||||||
|
{formatRow(item.TeamIds)}
|
||||||
|
</td>
|
||||||
|
{item.UserRole !== "contracts_Admin" && (
|
||||||
|
<td className="px-4 py-2 font-semibold">
|
||||||
|
<label className="cursor-pointer relative block items-center mb-0">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="op-toggle transition-all op-toggle-secondary"
|
||||||
|
checked={item?.IsDisabled !== true}
|
||||||
|
onChange={() => handleToggleBtn(item)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
{isActiveModal[item.objectId] && (
|
||||||
|
<ModalUi
|
||||||
|
isOpen
|
||||||
|
title={"User status"}
|
||||||
|
handleClose={handleClose}
|
||||||
|
>
|
||||||
|
<div className="m-[20px]">
|
||||||
|
<div className="text-lg font-normal text-black">
|
||||||
|
Are you sure you want to{" "}
|
||||||
|
{item?.IsDisabled
|
||||||
|
? "activate"
|
||||||
|
: "deactivate"}{" "}
|
||||||
|
this user?
|
||||||
|
</div>
|
||||||
|
<hr className="bg-[#ccc] mt-4 " />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleToggleSubmit(item)
|
||||||
|
}
|
||||||
|
className="op-btn op-btn-primary"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleClose}
|
||||||
|
className="op-btn op-btn-secondary"
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
{/* <td className="px-3 py-2 text-white grid grid-cols-2">
|
||||||
|
{actions?.length > 0 &&
|
||||||
|
actions.map((act, index) => (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={() => handleActionBtn(act, item)}
|
||||||
|
title={act.hoverLabel}
|
||||||
|
className={`${
|
||||||
|
act?.btnColor ? act.btnColor : ""
|
||||||
|
} op-btn op-btn-sm`}
|
||||||
|
>
|
||||||
|
<i className={act.btnIcon}></i>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
{isDeleteModal[item.objectId] && (
|
||||||
|
<ModalUi
|
||||||
|
isOpen
|
||||||
|
title={"Delete User"}
|
||||||
|
handleClose={handleClose}
|
||||||
|
>
|
||||||
|
<div className="m-[20px]">
|
||||||
|
<div className="text-lg font-normal text-black">
|
||||||
|
Are you sure you want to delete this user?
|
||||||
|
</div>
|
||||||
|
<hr className="bg-[#ccc] mt-4 " />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
onClick={() => handleDelete(item)}
|
||||||
|
className="op-btn op-btn-primary"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleClose}
|
||||||
|
className="op-btn op-btn-secondary"
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
|
</td> */}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="op-join flex flex-wrap items-center p-2">
|
||||||
|
{userList.length > recordperPage && (
|
||||||
|
<button
|
||||||
|
onClick={() => paginateBack()}
|
||||||
|
className="op-join-item op-btn op-btn-sm"
|
||||||
|
>
|
||||||
|
Prev
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{pageNumbers.map((x, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={() => setCurrentPage(x)}
|
||||||
|
disabled={x === "..."}
|
||||||
|
className={`${
|
||||||
|
x === currentPage ? "op-btn-active" : ""
|
||||||
|
} op-join-item op-btn op-btn-sm`}
|
||||||
|
>
|
||||||
|
{x}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
{userList.length > recordperPage && (
|
||||||
|
<button
|
||||||
|
onClick={() => paginateFront()}
|
||||||
|
className="op-join-item op-btn op-btn-sm"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{userList?.length <= 0 && (
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
isDashboard ? "h-[317px]" : ""
|
||||||
|
} flex flex-col items-center justify-center w-ful bg-base-100 text-base-content rounded-xl py-4`}
|
||||||
|
>
|
||||||
|
<div className="w-[60px] h-[60px] overflow-hidden">
|
||||||
|
<img
|
||||||
|
className="w-full h-full object-contain"
|
||||||
|
src={pad}
|
||||||
|
alt="img"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm font-semibold">No Data Available</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ModalUi
|
||||||
|
title={"Add User"}
|
||||||
|
isOpen={isModal}
|
||||||
|
handleClose={handleFormModal}
|
||||||
|
>
|
||||||
|
<AddUser
|
||||||
|
setIsAlert={setIsAlert}
|
||||||
|
handleUserData={handleUserData}
|
||||||
|
closePopup={handleFormModal}
|
||||||
|
/>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center justify-center h-screen w-full bg-base-100 text-base-content rounded-box">
|
||||||
|
<div className="text-center">
|
||||||
|
<h1 className="text-[60px] lg:text-[120px] font-semibold">
|
||||||
|
404
|
||||||
|
</h1>
|
||||||
|
<p className="text-[30px] lg:text-[50px]">Page Not Found</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!isSubscribe && isEnableSubscription && !isLoader && (
|
||||||
|
<div data-tut="apisubscribe">
|
||||||
|
<SubscribeCard plan={"TEAMS"} price={"20"} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UserList;
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import React, {
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
useState,
|
|
||||||
useEffect
|
|
||||||
// useRef
|
|
||||||
} from "react";
|
|
||||||
import { Navigate, useNavigate } from "react-router-dom";
|
import { Navigate, useNavigate } from "react-router-dom";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { SaveFileSize } from "../constant/saveFileSize";
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
@@ -10,10 +6,13 @@ import dp from "../assets/images/dp.png";
|
|||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import sanitizeFileName from "../primitives/sanitizeFileName";
|
import sanitizeFileName from "../primitives/sanitizeFileName";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
|
||||||
import Tooltip from "../primitives/Tooltip";
|
import Tooltip from "../primitives/Tooltip";
|
||||||
import { isEnableSubscription } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { checkIsSubscribed, handleSendOTP } from "../constant/Utils";
|
import {
|
||||||
|
checkIsSubscribed,
|
||||||
|
checkIsSubscribedTeam,
|
||||||
|
handleSendOTP
|
||||||
|
} from "../constant/Utils";
|
||||||
import Upgrade from "../primitives/Upgrade";
|
import Upgrade from "../primitives/Upgrade";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
@@ -32,10 +31,11 @@ function UserProfile() {
|
|||||||
const [percentage, setpercentage] = useState(0);
|
const [percentage, setpercentage] = useState(0);
|
||||||
const [isDisableDocId, setIsDisableDocId] = useState(false);
|
const [isDisableDocId, setIsDisableDocId] = useState(false);
|
||||||
const [isSubscribe, setIsSubscribe] = useState(false);
|
const [isSubscribe, setIsSubscribe] = useState(false);
|
||||||
// const [publicUserName, setPublicUserName] = useState(
|
const [isUpgrade, setIsUpgrade] = useState(false);
|
||||||
// extendUser && extendUser?.[0]?.UserName
|
const [publicUserName, setPublicUserName] = useState(
|
||||||
// );
|
extendUser && extendUser?.[0]?.UserName
|
||||||
// const previousPublicUserName = useRef(publicUserName);
|
);
|
||||||
|
const previousPublicUserName = useRef(publicUserName);
|
||||||
const [company, setCompany] = useState(
|
const [company, setCompany] = useState(
|
||||||
extendUser && extendUser?.[0]?.Company
|
extendUser && extendUser?.[0]?.Company
|
||||||
);
|
);
|
||||||
@@ -46,7 +46,11 @@ function UserProfile() {
|
|||||||
const [otp, setOtp] = useState("");
|
const [otp, setOtp] = useState("");
|
||||||
const [otpLoader, setOtpLoader] = useState(false);
|
const [otpLoader, setOtpLoader] = useState(false);
|
||||||
const [isEmailVerified, setIsEmailVerified] = useState(false);
|
const [isEmailVerified, setIsEmailVerified] = useState(false);
|
||||||
// const [userNameError, setUserNameError] = useState("");
|
const [userNameError, setUserNameError] = useState("");
|
||||||
|
const [tagLine, setTagLine] = useState(
|
||||||
|
extendUser && extendUser?.[0]?.Tagline
|
||||||
|
);
|
||||||
|
const [isTeam, setIsTeam] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUserDetail();
|
getUserDetail();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -58,7 +62,9 @@ function UserProfile() {
|
|||||||
const HeaderDocId = jsonSender[0]?.HeaderDocId;
|
const HeaderDocId = jsonSender[0]?.HeaderDocId;
|
||||||
if (isEnableSubscription) {
|
if (isEnableSubscription) {
|
||||||
const getIsSubscribe = await checkIsSubscribed();
|
const getIsSubscribe = await checkIsSubscribed();
|
||||||
|
const getIsTeam = await checkIsSubscribedTeam();
|
||||||
setIsSubscribe(getIsSubscribe);
|
setIsSubscribe(getIsSubscribe);
|
||||||
|
setIsTeam(getIsTeam);
|
||||||
}
|
}
|
||||||
if (HeaderDocId) {
|
if (HeaderDocId) {
|
||||||
setIsDisableDocId(HeaderDocId);
|
setIsDisableDocId(HeaderDocId);
|
||||||
@@ -85,31 +91,31 @@ function UserProfile() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
//function to check public username already exist
|
//function to check public username already exist
|
||||||
// const handleCheckPublicUserName = async () => {
|
const handleCheckPublicUserName = async () => {
|
||||||
// try {
|
try {
|
||||||
// const res = await Parse.Cloud.run("getpublicusername", {
|
const res = await Parse.Cloud.run("getpublicusername", {
|
||||||
// username: publicUserName
|
username: publicUserName
|
||||||
// });
|
});
|
||||||
// if (res) {
|
if (res) {
|
||||||
// setIsLoader(false);
|
setIsLoader(false);
|
||||||
// setUserNameError("user name already exist");
|
setUserNameError("user name already exist");
|
||||||
// setTimeout(() => {
|
setTimeout(() => {
|
||||||
// setUserNameError("");
|
setUserNameError("");
|
||||||
// }, 3000);
|
}, 3000);
|
||||||
// return res;
|
return res;
|
||||||
// }
|
}
|
||||||
// } catch (e) {
|
} catch (e) {
|
||||||
// console.log("error in getpublicusername cloud function");
|
console.log("error in getpublicusername cloud function");
|
||||||
// }
|
}
|
||||||
// };
|
};
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let phn = Phone,
|
let phn = Phone,
|
||||||
res = "";
|
res = "";
|
||||||
//condition to call cloud function when user change publicUserName
|
//condition to call cloud function when user change publicUserName
|
||||||
// if (previousPublicUserName.current !== publicUserName) {
|
if (publicUserName && previousPublicUserName.current !== publicUserName) {
|
||||||
// res = await handleCheckPublicUserName();
|
res = await handleCheckPublicUserName();
|
||||||
// }
|
}
|
||||||
if (!res) {
|
if (!res) {
|
||||||
setIsLoader(true);
|
setIsLoader(true);
|
||||||
try {
|
try {
|
||||||
@@ -155,7 +161,6 @@ function UserProfile() {
|
|||||||
|
|
||||||
// `updateExtUser` is used to update user details in extended class
|
// `updateExtUser` is used to update user details in extended class
|
||||||
const updateExtUser = async (obj) => {
|
const updateExtUser = async (obj) => {
|
||||||
const extClass = localStorage.getItem("extended_class");
|
|
||||||
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
|
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||||
const ExtUserId = extData[0].objectId;
|
const ExtUserId = extData[0].objectId;
|
||||||
const body = {
|
const body = {
|
||||||
@@ -163,12 +168,13 @@ function UserProfile() {
|
|||||||
Name: obj.Name,
|
Name: obj.Name,
|
||||||
HeaderDocId: isDisableDocId,
|
HeaderDocId: isDisableDocId,
|
||||||
JobTitle: jobTitle,
|
JobTitle: jobTitle,
|
||||||
Company: company
|
Company: company,
|
||||||
// UserName: publicUserName || ""
|
UserName: publicUserName || "",
|
||||||
|
Tagline: tagLine || ""
|
||||||
};
|
};
|
||||||
|
|
||||||
await axios.put(
|
await axios.put(
|
||||||
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
|
parseBaseUrl + "classes/contracts_Users/" + ExtUserId,
|
||||||
body,
|
body,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@@ -185,6 +191,7 @@ function UserProfile() {
|
|||||||
const json = JSON.parse(JSON.stringify([res]));
|
const json = JSON.parse(JSON.stringify([res]));
|
||||||
const extRes = JSON.stringify(json);
|
const extRes = JSON.stringify(json);
|
||||||
localStorage.setItem("Extand_Class", extRes);
|
localStorage.setItem("Extand_Class", extRes);
|
||||||
|
previousPublicUserName.current = publicUserName;
|
||||||
// console.log("updateRes ", updateRes);
|
// console.log("updateRes ", updateRes);
|
||||||
};
|
};
|
||||||
// file upload function
|
// file upload function
|
||||||
@@ -278,23 +285,20 @@ function UserProfile() {
|
|||||||
alert("OTP sent on you email");
|
alert("OTP sent on you email");
|
||||||
};
|
};
|
||||||
//function to handle onchange username and restrict 6-characters username for free users
|
//function to handle onchange username and restrict 6-characters username for free users
|
||||||
// const handleOnchangeUserName = (e) => {
|
const handleOnchangeUserName = (e) => {
|
||||||
// const value = e.target.value;
|
const newValue = e.target.value.replace(/\s+/g, "");
|
||||||
// if (value.length > 6 && !isSubscribe) {
|
setPublicUserName(newValue);
|
||||||
// setUserNameError("Please upgrade to allow more than 6 characters.");
|
};
|
||||||
// setTimeout(() => {
|
|
||||||
// setUserNameError("");
|
const handleOnchangeTagLine = (e) => {
|
||||||
// }, 2000);
|
setTagLine(e.target.value);
|
||||||
// } else {
|
};
|
||||||
// setPublicUserName(e.target.value);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setEditMode(false);
|
setEditMode(false);
|
||||||
SetName(localStorage.getItem("username"));
|
SetName(localStorage.getItem("username"));
|
||||||
SetPhone(UserProfile && UserProfile.phone);
|
SetPhone(UserProfile && UserProfile.phone);
|
||||||
setImage(localStorage.getItem("profileImg"));
|
setImage(localStorage.getItem("profileImg"));
|
||||||
// setPublicUserName(extendUser && extendUser?.[0]?.UserName);
|
setPublicUserName(extendUser && extendUser?.[0]?.UserName);
|
||||||
setCompany(extendUser && extendUser?.[0]?.Company);
|
setCompany(extendUser && extendUser?.[0]?.Company);
|
||||||
setJobTitle(extendUser?.[0]?.JobTitle);
|
setJobTitle(extendUser?.[0]?.JobTitle);
|
||||||
setIsDisableDocId(extendUser?.[0]?.HeaderDocId);
|
setIsDisableDocId(extendUser?.[0]?.HeaderDocId);
|
||||||
@@ -308,13 +312,13 @@ function UserProfile() {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex justify-center items-center w-full relative">
|
<div className="flex justify-center items-center w-full relative">
|
||||||
{/* {userNameError && (
|
{userNameError && (
|
||||||
<div
|
<div
|
||||||
className={`z-[1000] fixed top-[50%] transform border-[1px] text-sm border-[#f0a8a8] bg-[#f4bebe] text-[#c42121] rounded py-[.75rem] px-[1.25rem]`}
|
className={`z-[1000] fixed top-[50%] transform border-[1px] text-sm border-[#f0a8a8] bg-[#f4bebe] text-[#c42121] rounded py-[.75rem] px-[1.25rem]`}
|
||||||
>
|
>
|
||||||
{userNameError}
|
{userNameError}
|
||||||
</div>
|
</div>
|
||||||
)} */}
|
)}
|
||||||
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow-md rounded-box w-[450px]">
|
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow-md rounded-box w-[450px]">
|
||||||
<div className="flex flex-col justify-center items-center my-4">
|
<div className="flex flex-col justify-center items-center my-4">
|
||||||
<div className="w-[200px] h-[200px] overflow-hidden rounded-full">
|
<div className="w-[200px] h-[200px] overflow-hidden rounded-full">
|
||||||
@@ -442,85 +446,126 @@ function UserProfile() {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
{/* {isEnableSubscription && (
|
{isEnableSubscription && (
|
||||||
<li className="flex justify-between items-center border-t-[1px] border-gray-300 py-2 break-all">
|
<>
|
||||||
<span className="font-semibold">
|
<li className="flex md:flex-row flex-col md:justify-between md:items-center border-t-[1px] border-gray-300 py-2 break-all">
|
||||||
Public profile :{" "}
|
<span className="font-semibold flex gap-1">
|
||||||
<Tooltip
|
Public profile :{" "}
|
||||||
message={`this is your public URL. Copy or share it
|
<Tooltip
|
||||||
with the signer, and you will be able to see
|
maxWidth="max-w-[250px]"
|
||||||
all your publicly set templates.`}
|
message={`This is your public URL. Copy or share it with the signer, and you will be able to see all your publicly set templates.`}
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<div className="flex text-xs items-center">
|
|
||||||
<span>opensign-me.vercel.app/</span>
|
|
||||||
{editmode ? (
|
|
||||||
<input
|
|
||||||
onChange={handleOnchangeUserName}
|
|
||||||
value={publicUserName}
|
|
||||||
disabled={!editmode}
|
|
||||||
placeholder="enter user name"
|
|
||||||
className="op-input op-input-bordered focus:outline-none hover:border-base-content op-input-xs"
|
|
||||||
/>
|
/>
|
||||||
) : (
|
</span>
|
||||||
<input
|
<div className="flex md:flex-row flex-col md:items-center">
|
||||||
value={extendUser?.[0]?.UserName}
|
<span className="mb-1 md:mb-1">opensign.me/</span>
|
||||||
disabled
|
{editmode ? (
|
||||||
placeholder="enter user name"
|
<input
|
||||||
className="op-input op-input-bordered op-input-xs"
|
maxLength={40}
|
||||||
|
style={{
|
||||||
|
border:
|
||||||
|
!isSubscribe &&
|
||||||
|
publicUserName?.length > 0 &&
|
||||||
|
publicUserName?.length < 9 &&
|
||||||
|
"solid red"
|
||||||
|
}}
|
||||||
|
onChange={handleOnchangeUserName}
|
||||||
|
value={publicUserName}
|
||||||
|
disabled={!editmode}
|
||||||
|
placeholder="enter user name"
|
||||||
|
className="op-input op-input-bordered focus:outline-none hover:border-base-content op-input-xs"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<input
|
||||||
|
value={extendUser?.[0]?.UserName}
|
||||||
|
disabled
|
||||||
|
placeholder="enter user name"
|
||||||
|
className="op-input op-input-bordered op-input-xs"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li className="flex md:flex-row flex-col md:justify-between md:items-center border-t-[1px] border-gray-300 py-2 break-all">
|
||||||
|
<span className="font-semibold flex gap-1">
|
||||||
|
Tagline :{" "}
|
||||||
|
<Tooltip
|
||||||
|
maxWidth="max-w-[250px]"
|
||||||
|
message={`This Tagline will appear on your OpenSign public profile for ex. https://opensign.me/alex`}
|
||||||
/>
|
/>
|
||||||
)}
|
</span>
|
||||||
|
<div className="flex md:flex-row flex-col md:items-center">
|
||||||
|
{editmode ? (
|
||||||
|
<input
|
||||||
|
onChange={handleOnchangeTagLine}
|
||||||
|
value={tagLine}
|
||||||
|
disabled={!editmode}
|
||||||
|
placeholder="enter tagline"
|
||||||
|
className="op-input op-input-bordered focus:outline-none hover:border-base-content op-input-xs"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<input
|
||||||
|
value={extendUser?.[0]?.Tagline}
|
||||||
|
disabled
|
||||||
|
placeholder="enter tagline"
|
||||||
|
className="op-input op-input-bordered op-input-xs"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{isEnableSubscription && (
|
||||||
|
<li className="border-y-[1px] border-gray-300 break-all">
|
||||||
|
<div className="flex justify-between items-center py-2">
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
isTeam ? "font-semibold" : "font-semibold text-gray-300"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Disable DocumentId :{" "}
|
||||||
|
<Tooltip
|
||||||
|
url={
|
||||||
|
"https://docs.opensignlabs.com/docs/help/Settings/disabledocumentid"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{!isTeam && isEnableSubscription && <Upgrade />}
|
||||||
|
</span>
|
||||||
|
<label
|
||||||
|
className={`${
|
||||||
|
isTeam
|
||||||
|
? `${editmode ? "cursor-pointer" : ""}`
|
||||||
|
: "pointer-events-none opacity-50"
|
||||||
|
} relative block items-center mb-0`}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
disabled={isTeam ? false : true}
|
||||||
|
type="checkbox"
|
||||||
|
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white"
|
||||||
|
checked={isDisableDocId}
|
||||||
|
onChange={handleDisableDocId}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
)} */}
|
)}
|
||||||
<li className="border-y-[1px] border-gray-300 break-all">
|
|
||||||
<div className="flex justify-between items-center py-2">
|
|
||||||
<span
|
|
||||||
className={
|
|
||||||
isSubscribe || !isEnableSubscription
|
|
||||||
? "font-semibold"
|
|
||||||
: "font-semibold text-gray-300"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Disable DocumentId :{" "}
|
|
||||||
<Tooltip
|
|
||||||
url={
|
|
||||||
"https://docs.opensignlabs.com/docs/help/Settings/disabledocumentid"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
|
||||||
</span>
|
|
||||||
<label
|
|
||||||
className={`${
|
|
||||||
isSubscribe || !isEnableSubscription
|
|
||||||
? `${editmode ? "cursor-pointer" : ""}`
|
|
||||||
: "pointer-events-none opacity-50"
|
|
||||||
} relative block items-center mb-0`}
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
disabled={editmode ? false : true}
|
|
||||||
type="checkbox"
|
|
||||||
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white"
|
|
||||||
checked={isDisableDocId}
|
|
||||||
onChange={handleDisableDocId}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{!isEnableSubscription && (
|
|
||||||
<PremiumAlertHeader
|
|
||||||
message={
|
|
||||||
"Disable documentId is free in beta, this feature will incur a fee later."
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<div className="flex justify-center gap-2 pt-2 pb-3 md:pt-3 md:pb-4">
|
<div
|
||||||
|
className={`${
|
||||||
|
!isEnableSubscription ? "border-t-[1px] border-gray-300" : ""
|
||||||
|
} flex justify-center gap-2 pt-2 pb-3 md:pt-3 md:pb-4`}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) =>
|
onClick={(e) => {
|
||||||
editmode ? handleSubmit(e) : setEditMode(true)
|
if (
|
||||||
}
|
!isSubscribe &&
|
||||||
|
publicUserName?.length > 0 &&
|
||||||
|
publicUserName?.length < 9
|
||||||
|
) {
|
||||||
|
setIsUpgrade(true);
|
||||||
|
} else {
|
||||||
|
editmode ? handleSubmit(e) : setEditMode(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
className="op-btn op-btn-primary"
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
{editmode ? "Save" : "Edit"}
|
{editmode ? "Save" : "Edit"}
|
||||||
@@ -577,6 +622,38 @@ function UserProfile() {
|
|||||||
)}
|
)}
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
)}
|
)}
|
||||||
|
{isUpgrade && (
|
||||||
|
<div className="op-modal op-modal-open">
|
||||||
|
<div className="max-h-90 bg-base-100 w-[95%] md:max-w-[500px] rounded-box relative">
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="op-btn op-btn-sm op-btn-circle op-btn-ghost text-primary-content absolute right-2 top-2 z-40"
|
||||||
|
onClick={() => setIsUpgrade(false)}
|
||||||
|
>
|
||||||
|
✕
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="op-card op-bg-primary text-primary-content w-full shadow-lg">
|
||||||
|
<div className="op-card-body">
|
||||||
|
<h2 className="op-card-title">Upgrade to Plan</h2>
|
||||||
|
<p>
|
||||||
|
To have a username less than 8 character please
|
||||||
|
subscribe
|
||||||
|
</p>
|
||||||
|
<div className="op-card-actions justify-end">
|
||||||
|
<button
|
||||||
|
onClick={() => navigate("/subscription")}
|
||||||
|
className="op-btn op-btn-accent"
|
||||||
|
>
|
||||||
|
Upgrade Now
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import ModalUi from "../primitives/ModalUi";
|
|||||||
import { isEnableSubscription } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { checkIsSubscribed, openInNewTab } from "../constant/Utils";
|
import { checkIsSubscribed, openInNewTab } from "../constant/Utils";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
|
||||||
import Tooltip from "../primitives/Tooltip";
|
import Tooltip from "../primitives/Tooltip";
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
import SubscribeCard from "../primitives/SubscribeCard";
|
import SubscribeCard from "../primitives/SubscribeCard";
|
||||||
@@ -107,7 +106,6 @@ function Webhook() {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow-md rounded-box mb-3">
|
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow-md rounded-box mb-3">
|
||||||
{!isEnableSubscription && <PremiumAlertHeader />}
|
|
||||||
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
||||||
OpenSign™ Webhook{" "}
|
OpenSign™ Webhook{" "}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
|
||||||
import Loader from "./Loader";
|
import Loader from "./Loader";
|
||||||
const AddContact = (props) => {
|
const AddContact = (props) => {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
@@ -9,8 +8,6 @@ const AddContact = (props) => {
|
|||||||
const [addYourself, setAddYourself] = useState(false);
|
const [addYourself, setAddYourself] = useState(false);
|
||||||
const [isLoader, setIsLoader] = useState(false);
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
const [isUserExist, setIsUserExist] = useState(false);
|
const [isUserExist, setIsUserExist] = useState(false);
|
||||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
|
||||||
const parseAppId = localStorage.getItem("parseAppId");
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkUserExist();
|
checkUserExist();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -77,18 +74,6 @@ const AddContact = (props) => {
|
|||||||
|
|
||||||
const user = await _user.save();
|
const user = await _user.save();
|
||||||
if (user) {
|
if (user) {
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_Guest",
|
|
||||||
userId: user.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
const currentUser = Parse.User.current();
|
||||||
contactQuery.set(
|
contactQuery.set(
|
||||||
"CreatedBy",
|
"CreatedBy",
|
||||||
@@ -124,18 +109,6 @@ const AddContact = (props) => {
|
|||||||
if (err.code === 202) {
|
if (err.code === 202) {
|
||||||
const params = { email: email };
|
const params = { email: email };
|
||||||
const userRes = await Parse.Cloud.run("getUserId", params);
|
const userRes = await Parse.Cloud.run("getUserId", params);
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_Guest",
|
|
||||||
userId: userRes.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
const currentUser = Parse.User.current();
|
||||||
contactQuery.set(
|
contactQuery.set(
|
||||||
"CreatedBy",
|
"CreatedBy",
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ const LottieWithLoader = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{!isLoaded && !hasError && (
|
{!isLoaded && !hasError && (
|
||||||
<div className="loader">
|
<div className="w-[120px] h-[120px] mx-auto">
|
||||||
{" "}
|
|
||||||
<Loader />
|
<Loader />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -39,9 +38,8 @@ const LottieWithLoader = () => {
|
|||||||
{isLoaded && animationSrc && (
|
{isLoaded && animationSrc && (
|
||||||
<DotLottieReact
|
<DotLottieReact
|
||||||
src={animationSrc}
|
src={animationSrc}
|
||||||
loop
|
|
||||||
autoplay
|
autoplay
|
||||||
style={{ display: "block" }}
|
className="w-[120px] h-[120px] md:w-[200px] md:h-[200px] mx-auto"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { isEnableSubscription } from "../constant/const";
|
|
||||||
import PremiumAlertHeader from "./PremiumAlertHeader";
|
|
||||||
|
|
||||||
const ModalUi = ({
|
const ModalUi = ({
|
||||||
children,
|
children,
|
||||||
@@ -9,8 +7,7 @@ const ModalUi = ({
|
|||||||
handleClose,
|
handleClose,
|
||||||
showHeader = true,
|
showHeader = true,
|
||||||
showClose = true,
|
showClose = true,
|
||||||
reduceWidth,
|
reduceWidth
|
||||||
showHeaderMessage
|
|
||||||
}) => {
|
}) => {
|
||||||
const width = reduceWidth;
|
const width = reduceWidth;
|
||||||
return (
|
return (
|
||||||
@@ -37,13 +34,6 @@ const ModalUi = ({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!isEnableSubscription && showHeaderMessage && (
|
|
||||||
<PremiumAlertHeader
|
|
||||||
message={
|
|
||||||
"Cutomize Email is free in beta, this feature will incur a fee later."
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div>{children}</div>
|
<div>{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
|
|
||||||
function CustomModal({
|
function CustomModal({
|
||||||
@@ -9,11 +9,12 @@ function CustomModal({
|
|||||||
declineDoc,
|
declineDoc,
|
||||||
setIsDecline
|
setIsDecline
|
||||||
}) {
|
}) {
|
||||||
|
const [reason, setReason] = useState("");
|
||||||
return (
|
return (
|
||||||
show && (
|
show && (
|
||||||
<dialog className="op-modal op-modal-open absolute z-[998]">
|
<dialog className="op-modal op-modal-open absolute z-[448]">
|
||||||
<div className="w-[80%] md:w-[40%] op-modal-box p-0 overflow-y-auto hide-scrollbar text-sm">
|
<div className="w-[95%] md:w-[60%] lg:w-[40%] op-modal-box p-0 overflow-y-auto hide-scrollbar text-sm">
|
||||||
<h3 className="text-[#de4337] font-bold text-lg pt-[15px] px-[20px]">
|
<h3 className="text-base-content font-bold text-lg pt-[15px] px-[20px]">
|
||||||
{headMsg && headMsg}
|
{headMsg && headMsg}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="p-[10px] px-[20px]">
|
<div className="p-[10px] px-[20px]">
|
||||||
@@ -21,19 +22,34 @@ function CustomModal({
|
|||||||
</div>
|
</div>
|
||||||
{footerMessage && (
|
{footerMessage && (
|
||||||
<>
|
<>
|
||||||
<div className="h-[1px] bg-[#9f9f9f] w-full"></div>
|
<div className="mx-3">
|
||||||
<div className="m-[15px] ">
|
<textarea
|
||||||
|
rows={3}
|
||||||
|
placeholder="Reason (optional)"
|
||||||
|
className="px-4 op-textarea op-textarea-bordered focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
value={reason}
|
||||||
|
onChange={(e) => setReason(e.target.value)}
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
{/* <div className="h-[1px] bg-[#9f9f9f] w-full"></div> */}
|
||||||
|
<div className="m-[15px]">
|
||||||
<button
|
<button
|
||||||
className="op-btn op-btn-primary mr-2"
|
className="op-btn op-btn-primary mr-2 px-6"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => declineDoc()}
|
onClick={() => {
|
||||||
|
setReason("");
|
||||||
|
declineDoc(reason);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-secondary"
|
className="op-btn op-btn-secondary"
|
||||||
onClick={() => setIsDecline({ isDeclined: false })}
|
onClick={() => {
|
||||||
|
setReason("");
|
||||||
|
setIsDecline({ isDeclined: false });
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
const PremiumAlertHeader = ({ message }) => (
|
|
||||||
<marquee className="bg-yellow-300 text-black px-2">
|
|
||||||
{message
|
|
||||||
? message
|
|
||||||
: "Currently free in Beta, this feature will incur a fee later."}
|
|
||||||
</marquee>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default PremiumAlertHeader;
|
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const SubscribeCard = () => {
|
const SubscribeCard = ({ plan, price }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
return (
|
return (
|
||||||
<div className="op-card op-bg-primary text-primary-content w-full shadow-lg">
|
<div className="op-card op-bg-primary text-primary-content w-full shadow-lg">
|
||||||
<div className="op-card-body">
|
<div className="op-card-body">
|
||||||
<h2 className="op-card-title">Upgrade to PRO Plan</h2>
|
<h2 className="op-card-title">Upgrade to {plan ? plan : "PRO"} Plan</h2>
|
||||||
<p>$29.99/month: Sign 100 docs using API. Only $0.15/doc after that.</p>
|
<p>
|
||||||
|
${price ? price : "29.99"}/month: Sign 100 docs using API. Only
|
||||||
|
$0.15/doc after that.
|
||||||
|
</p>
|
||||||
<div className="op-card-actions justify-end">
|
<div className="op-card-actions justify-end">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate("/subscription")}
|
onClick={() => navigate("/subscription")}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Tooltip as ReactTooltip } from "react-tooltip";
|
import { Tooltip as ReactTooltip } from "react-tooltip";
|
||||||
import { openInNewTab } from "../constant/Utils";
|
import { openInNewTab } from "../constant/Utils";
|
||||||
const Tooltip = ({ id, message, url, iconColor }) =>
|
const Tooltip = ({ id, message, url, iconColor, maxWidth }) =>
|
||||||
url ? (
|
url ? (
|
||||||
<button onClick={() => openInNewTab(url)} className={"text-center"}>
|
<button onClick={() => openInNewTab(url)} className={"text-center"}>
|
||||||
<sup>
|
<sup>
|
||||||
@@ -33,7 +33,7 @@ const Tooltip = ({ id, message, url, iconColor }) =>
|
|||||||
</a>
|
</a>
|
||||||
<ReactTooltip
|
<ReactTooltip
|
||||||
id={id ? id : "my-tooltip"}
|
id={id ? id : "my-tooltip"}
|
||||||
className="max-w-[200px] z-[200]"
|
className={`${maxWidth ? maxWidth : "max-w-[200px]"} z-[200]`}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,26 +7,34 @@ const ValidateRoute = () => {
|
|||||||
try {
|
try {
|
||||||
// Use the session token to validate the user
|
// Use the session token to validate the user
|
||||||
const userQuery = new Parse.Query(Parse.User);
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
const user = await userQuery.get(Parse.User.current().id, {
|
const user = await userQuery.get(Parse?.User?.current()?.id, {
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
});
|
});
|
||||||
if (!user) {
|
if (!user) {
|
||||||
handlelogout();
|
handlelogout();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log("err in validate route", error);
|
||||||
handlelogout();
|
handlelogout();
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
const handlelogout = async () => {
|
const handlelogout = async () => {
|
||||||
try {
|
let appdata = localStorage.getItem("userSettings");
|
||||||
Parse.User.logOut();
|
let applogo = localStorage.getItem("appLogo");
|
||||||
localStorage.removeItem("accesstoken");
|
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
} catch (err) {
|
let PageLanding = localStorage.getItem("PageLanding");
|
||||||
console.log("err ", err);
|
let baseUrl = localStorage.getItem("baseUrl");
|
||||||
} finally {
|
let appid = localStorage.getItem("parseAppId");
|
||||||
localStorage.removeItem("accesstoken");
|
|
||||||
}
|
localStorage.clear();
|
||||||
|
|
||||||
|
localStorage.setItem("appLogo", applogo);
|
||||||
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
|
localStorage.setItem("userSettings", appdata);
|
||||||
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
|
localStorage.setItem("parseAppId", appid);
|
||||||
};
|
};
|
||||||
return <div>{<Outlet />}</div>;
|
return <div>{<Outlet />}</div>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,15 +6,11 @@ const infoSlice = createSlice({
|
|||||||
initialState: {},
|
initialState: {},
|
||||||
reducers: {
|
reducers: {
|
||||||
fetchAppInfo: () => {
|
fetchAppInfo: () => {
|
||||||
localStorage.setItem("_appName", appInfo.appname);
|
|
||||||
localStorage.setItem("_app_objectId", appInfo.objectId);
|
|
||||||
localStorage.setItem("baseUrl", `${appInfo.baseUrl}/`);
|
localStorage.setItem("baseUrl", `${appInfo.baseUrl}/`);
|
||||||
localStorage.setItem("parseAppId", appInfo.appId);
|
localStorage.setItem("parseAppId", appInfo.appId);
|
||||||
localStorage.setItem("appLogo", appInfo.applogo);
|
localStorage.setItem("appLogo", appInfo.applogo);
|
||||||
localStorage.setItem("appVersion", appInfo.version);
|
|
||||||
localStorage.removeItem("userSettings");
|
localStorage.removeItem("userSettings");
|
||||||
localStorage.setItem("userSettings", JSON.stringify(appInfo.settings));
|
localStorage.setItem("userSettings", JSON.stringify(appInfo.settings));
|
||||||
localStorage.setItem("appTitle", appInfo.appTitle);
|
|
||||||
localStorage.setItem("fev_Icon", appInfo.fev_Icon);
|
localStorage.setItem("fev_Icon", appInfo.fev_Icon);
|
||||||
return appInfo;
|
return appInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import ReactDOM from "react-dom/client";
|
||||||
|
import PdfRequestFiles from "../pages/PdfRequestFiles";
|
||||||
|
import { pdfjs } from "react-pdf";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import { store } from "../redux/store";
|
||||||
|
import "../index.css";
|
||||||
|
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.mjs`;
|
||||||
|
|
||||||
|
// Wrapper component to manage props
|
||||||
|
const PublicScriptFileWrapper = ({ initialProps }) => {
|
||||||
|
const [props, setProps] = useState(initialProps);
|
||||||
|
|
||||||
|
// Make the setProps function globally accessible
|
||||||
|
window.updatePublicTemplateProps = setProps;
|
||||||
|
|
||||||
|
return <PdfRequestFiles {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const appId = "legadranaxn";
|
||||||
|
// "opensign";
|
||||||
|
const serverUrl = "https://app.opensignlabs.com/api/app";
|
||||||
|
// "https://staging-app.opensignlabs.com/api/app";
|
||||||
|
localStorage.setItem("baseUrl", `${serverUrl}/`);
|
||||||
|
localStorage.setItem("parseAppId", appId);
|
||||||
|
Parse.initialize(appId);
|
||||||
|
Parse.serverURL = serverUrl;
|
||||||
|
// Create a new div element and append it to the body
|
||||||
|
const scriptComponent = document.createElement("div");
|
||||||
|
scriptComponent.id = "script-component";
|
||||||
|
document.body.appendChild(scriptComponent);
|
||||||
|
const link = document.createElement("link");
|
||||||
|
link.href = "https://cdn.opensignlabs.com/fonts.css";
|
||||||
|
link.rel = "stylesheet";
|
||||||
|
document.head.appendChild(link);
|
||||||
|
|
||||||
|
//add the Tailwind CSS file
|
||||||
|
const tailwindCssLink = document.createElement("link");
|
||||||
|
tailwindCssLink.href =
|
||||||
|
"https://app.opensignlabs.com/static/js/public-template.bundle.css"; // css bundle file
|
||||||
|
// "https://staging-app.opensignlabs.com/static/js/public-template.bundle.css"; // css bundle file
|
||||||
|
tailwindCssLink.rel = "stylesheet";
|
||||||
|
document.head.appendChild(tailwindCssLink);
|
||||||
|
// Create a root and render the wrapper component with initial props
|
||||||
|
const root = ReactDOM.createRoot(document.getElementById("script-component"));
|
||||||
|
root.render(
|
||||||
|
<div>
|
||||||
|
<Provider store={store}>
|
||||||
|
<PublicScriptFileWrapper initialProps={{ text: "templateId" }} />
|
||||||
|
</Provider>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ["./src/**/*.{js,jsx,ts,tsx}"],
|
content: ["./src/**/*.{js,jsx,ts,tsx}", "./src/script/PublicTemplate.js"],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {}
|
extend: {}
|
||||||
},
|
},
|
||||||
@@ -8,38 +8,7 @@ module.exports = {
|
|||||||
daisyui: {
|
daisyui: {
|
||||||
// themes: true,
|
// themes: true,
|
||||||
themes: [
|
themes: [
|
||||||
"light",
|
|
||||||
"dark",
|
"dark",
|
||||||
"cupcake",
|
|
||||||
"bumblebee",
|
|
||||||
"emerald",
|
|
||||||
"corporate",
|
|
||||||
"synthwave",
|
|
||||||
"retro",
|
|
||||||
"cyberpunk",
|
|
||||||
"valentine",
|
|
||||||
"halloween",
|
|
||||||
"garden",
|
|
||||||
"forest",
|
|
||||||
"aqua",
|
|
||||||
"lofi",
|
|
||||||
"pastel",
|
|
||||||
"fantasy",
|
|
||||||
"wireframe",
|
|
||||||
"black",
|
|
||||||
"luxury",
|
|
||||||
"dracula",
|
|
||||||
"cmyk",
|
|
||||||
"autumn",
|
|
||||||
"business",
|
|
||||||
"acid",
|
|
||||||
"lemonade",
|
|
||||||
"night",
|
|
||||||
"coffee",
|
|
||||||
"winter",
|
|
||||||
"dim",
|
|
||||||
"nord",
|
|
||||||
"sunset",
|
|
||||||
{
|
{
|
||||||
opensigncss: {
|
opensigncss: {
|
||||||
primary: "#002864",
|
primary: "#002864",
|
||||||
@@ -60,8 +29,8 @@ module.exports = {
|
|||||||
"success-content": "#f5f5f4",
|
"success-content": "#f5f5f4",
|
||||||
warning: "#ffbe00",
|
warning: "#ffbe00",
|
||||||
"warning-content": "#ccd9e8",
|
"warning-content": "#ccd9e8",
|
||||||
error: "#ff0000",
|
error: "#ffa1a7",
|
||||||
"error-content": "#f3f4f6",
|
"error-content": "#16090a",
|
||||||
"--rounded-btn": "1.9rem",
|
"--rounded-btn": "1.9rem",
|
||||||
"--tab-border": "2px",
|
"--tab-border": "2px",
|
||||||
"--tab-radius": "0.7rem"
|
"--tab-radius": "0.7rem"
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const Dotenv = require("dotenv-webpack");
|
||||||
|
const { CleanWebpackPlugin } = require("clean-webpack-plugin"); //used to clean directory
|
||||||
|
const TerserPlugin = require("terser-webpack-plugin"); //used to minify and optimize JavaScript files
|
||||||
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //used to extract css file into separate files
|
||||||
|
|
||||||
|
const isProduction = process.env.NODE_ENV;
|
||||||
|
module.exports = {
|
||||||
|
mode: isProduction ? "production" : "development",
|
||||||
|
entry: "./src/script/PublicTemplate.js",
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, "public", "static", "js"),
|
||||||
|
filename: "public-template.bundle.js",
|
||||||
|
libraryTarget: "umd",
|
||||||
|
umdNamedDefine: true,
|
||||||
|
library: "PublicTemplate",
|
||||||
|
globalObject: "this"
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(js|jsx)$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: "babel-loader",
|
||||||
|
options: {
|
||||||
|
presets: ["@babel/preset-react"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [
|
||||||
|
isProduction ? MiniCssExtractPlugin.loader : "style-loader",
|
||||||
|
"css-loader",
|
||||||
|
"postcss-loader"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g|gif|svg)$/i,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: "file-loader",
|
||||||
|
options: {
|
||||||
|
name: "assets/images/[name].[hash].[ext]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: [".js", ".jsx"]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new Dotenv(),
|
||||||
|
new CleanWebpackPlugin(),
|
||||||
|
...(isProduction
|
||||||
|
? [
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: "public-template.bundle.css"
|
||||||
|
})
|
||||||
|
]
|
||||||
|
: [])
|
||||||
|
],
|
||||||
|
optimization: {
|
||||||
|
minimize: isProduction ? true : false,
|
||||||
|
minimizer: [new TerserPlugin()]
|
||||||
|
},
|
||||||
|
devtool: isProduction ? "source-map" : "inline-source-map"
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Use an official Node runtime as the base image
|
# Use an official Node runtime as the base image
|
||||||
FROM node:18
|
FROM node:20
|
||||||
|
|
||||||
# Set the working directory inside the container
|
# Set the working directory inside the container
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Use an official Node runtime as the base image
|
# Use an official Node runtime as the base image
|
||||||
FROM node:18
|
FROM node:20
|
||||||
|
|
||||||
# Set the working directory inside the container
|
# Set the working directory inside the container
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ dotenv.config();
|
|||||||
|
|
||||||
const appId = process.env.APP_ID;
|
const appId = process.env.APP_ID;
|
||||||
const serverUrl = process.env.SERVER_URL;
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
export const cloudServerUrl = 'http://localhost:8080/app';
|
||||||
export function customAPIurl() {
|
export function customAPIurl() {
|
||||||
const url = new URL(process.env.SERVER_URL);
|
const url = new URL(cloudServerUrl);
|
||||||
return url.pathname === '/api/app' ? url.origin + '/api' : url.origin;
|
return url.pathname === '/api/app' ? url.origin + '/api' : url.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,13 +144,13 @@ export const updateMailCount = async extUserId => {
|
|||||||
await contractUser.save(null, { useMasterKey: true });
|
await contractUser.save(null, { useMasterKey: true });
|
||||||
} else {
|
} else {
|
||||||
// Create new entry if not found
|
// Create new entry if not found
|
||||||
const ContractsUsers = Parse.Object.extend('contracts_users');
|
const ContractsUsers = Parse.Object.extend('contracts_Users');
|
||||||
const newContractUser = new ContractsUsers();
|
const newContractUser = new ContractsUsers();
|
||||||
newContractUser.set('EmailCount', 1);
|
newContractUser.set('EmailCount', 1);
|
||||||
await newContractUser.save(null, { useMasterKey: true });
|
await newContractUser.save(null, { useMasterKey: true });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('Error updating EmailCount in contracts_users: ' + error.message);
|
console.log('Error updating EmailCount in contracts_Users: ' + error.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { cloudServerUrl } from '../../Utils.js';
|
||||||
|
|
||||||
// `replaceMailVaribles` is used to replace variables from mail with there actual values
|
// `replaceMailVaribles` is used to replace variables from mail with there actual values
|
||||||
function replaceMailVaribles(subject, body, variables) {
|
function replaceMailVaribles(subject, body, variables) {
|
||||||
@@ -26,7 +27,7 @@ function replaceMailVaribles(subject, body, variables) {
|
|||||||
async function sendMail(doc, signer) {
|
async function sendMail(doc, signer) {
|
||||||
const subject = `{{sender_name}} has requested you to sign "{{document_title}}"`;
|
const subject = `{{sender_name}} has requested you to sign "{{document_title}}"`;
|
||||||
const body = `<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body><p>Hi {{receiver_name}},</p><br><p>We hope this email finds you well. {{sender_name}} has requested you to review and sign <b>"{{document_title}}"</b>.</p><p>Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.</p><br><p>{{signing_url}}</p><br><p>If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.</p><br><p>Thanks</p><p> Team OpenSign™</p><br></body> </html>`;
|
const body = `<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body><p>Hi {{receiver_name}},</p><br><p>We hope this email finds you well. {{sender_name}} has requested you to review and sign <b>"{{document_title}}"</b>.</p><p>Your signature is crucial to proceed with the next steps as it signifies your agreement and authorization.</p><br><p>{{signing_url}}</p><br><p>If you have any questions or need further clarification regarding the document or the signing process, please contact the sender.</p><br><p>Thanks</p><p> Team OpenSign™</p><br></body> </html>`;
|
||||||
const url = `${process.env.SERVER_URL}/functions/sendmailv3`;
|
const url = `${cloudServerUrl}/functions/sendmailv3`;
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-Parse-Application-Id': process.env.APP_ID,
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { cloudServerUrl } from '../../Utils.js';
|
||||||
const appId = process.env.APP_ID;
|
const appId = process.env.APP_ID;
|
||||||
const serverUrl = process.env.SERVER_URL;
|
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
|
||||||
export default async function gooogleauth(request, response) {
|
export default async function gooogleauth(request, response) {
|
||||||
const code = request.body.code;
|
const code = request.body.code;
|
||||||
const baseUrl = new URL(process.env.SERVER_URL);
|
const baseUrl = new URL(process.env.SERVER_URL);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import multer from 'multer';
|
|||||||
import multerS3 from 'multer-s3';
|
import multerS3 from 'multer-s3';
|
||||||
import aws from 'aws-sdk';
|
import aws from 'aws-sdk';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import { useLocal } from '../../Utils.js';
|
import { cloudServerUrl, useLocal } from '../../Utils.js';
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
function sanitizeFileName(fileName) {
|
function sanitizeFileName(fileName) {
|
||||||
@@ -49,7 +49,7 @@ async function uploadFile(req, res) {
|
|||||||
const DO_SECRET_ACCESS_KEY = process.env.DO_SECRET_ACCESS_KEY;
|
const DO_SECRET_ACCESS_KEY = process.env.DO_SECRET_ACCESS_KEY;
|
||||||
const DO_SPACE = process.env.DO_SPACE;
|
const DO_SPACE = process.env.DO_SPACE;
|
||||||
|
|
||||||
const parseBaseUrl = process.env.SERVER_URL;
|
const parseBaseUrl = cloudServerUrl; //process.env.SERVER_URL;
|
||||||
const parseAppId = process.env.APP_ID;
|
const parseAppId = process.env.APP_ID;
|
||||||
let fileStorage;
|
let fileStorage;
|
||||||
if (useLocal === 'true') {
|
if (useLocal === 'true') {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { customAPIurl, replaceMailVaribles } from '../../../../Utils.js';
|
import { cloudServerUrl, customAPIurl, replaceMailVaribles } from '../../../../Utils.js';
|
||||||
|
|
||||||
// `sendDoctoWebhook` is used to send res data of document on webhook
|
// `sendDoctoWebhook` is used to send res data of document on webhook
|
||||||
async function sendDoctoWebhook(doc, WebhookUrl, userId) {
|
async function sendDoctoWebhook(doc, WebhookUrl, userId) {
|
||||||
@@ -220,7 +220,7 @@ export default async function createDocumentWithTemplate(request, response) {
|
|||||||
for (let i = 0; i < contactMail.length; i++) {
|
for (let i = 0; i < contactMail.length; i++) {
|
||||||
try {
|
try {
|
||||||
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
|
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
|
||||||
let url = `${process.env.SERVER_URL}/functions/sendmailv3/`;
|
let url = `${cloudServerUrl}/functions/sendmailv3/`;
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-Parse-Application-Id': process.env.APP_ID,
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import axios from 'axios';
|
|
||||||
export default async function createContact(request, response) {
|
export default async function createContact(request, response) {
|
||||||
const serverUrl = process.env.SERVER_URL;
|
|
||||||
const appId = process.env.APP_ID;
|
|
||||||
const name = request.body.name;
|
const name = request.body.name;
|
||||||
const phone = request.body?.phone;
|
const phone = request.body?.phone;
|
||||||
const email = request.body.email;
|
const email = request.body.email;
|
||||||
@@ -74,18 +71,6 @@ export default async function createContact(request, response) {
|
|||||||
|
|
||||||
const user = await _user.save();
|
const user = await _user.save();
|
||||||
if (user) {
|
if (user) {
|
||||||
const roleurl = `${serverUrl}/functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-Parse-Application-Id': appId,
|
|
||||||
// sessionToken: localStorage.getItem('accesstoken'),
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: 'contracts',
|
|
||||||
roleName: 'contracts_Guest',
|
|
||||||
userId: user.id,
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = userPtr;
|
const currentUser = userPtr;
|
||||||
contactQuery.set('CreatedBy', currentUser);
|
contactQuery.set('CreatedBy', currentUser);
|
||||||
contactQuery.set('UserId', user);
|
contactQuery.set('UserId', user);
|
||||||
@@ -120,18 +105,6 @@ export default async function createContact(request, response) {
|
|||||||
if (err.code === 202) {
|
if (err.code === 202) {
|
||||||
const params = { email: email };
|
const params = { email: email };
|
||||||
const userRes = await Parse.Cloud.run('getUserId', params);
|
const userRes = await Parse.Cloud.run('getUserId', params);
|
||||||
const roleurl = `${serverUrl}/functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-Parse-Application-Id': appId,
|
|
||||||
// sessionToken: localStorage.getItem('accesstoken'),
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: 'contracts',
|
|
||||||
roleName: 'contracts_Guest',
|
|
||||||
userId: userRes.objectId,
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
contactQuery.set('CreatedBy', userPtr);
|
contactQuery.set('CreatedBy', userPtr);
|
||||||
contactQuery.set('UserId', {
|
contactQuery.set('UserId', {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
saveFileUsage,
|
saveFileUsage,
|
||||||
formatWidgetOptions,
|
formatWidgetOptions,
|
||||||
sanitizeFileName,
|
sanitizeFileName,
|
||||||
|
cloudServerUrl,
|
||||||
} from '../../../../Utils.js';
|
} from '../../../../Utils.js';
|
||||||
|
|
||||||
// `sendDoctoWebhook` is used to send res data of document on webhook
|
// `sendDoctoWebhook` is used to send res data of document on webhook
|
||||||
@@ -281,7 +282,7 @@ export default async function createDocumentwithCoordinate(request, response) {
|
|||||||
for (let i = 0; i < contactMail.length; i++) {
|
for (let i = 0; i < contactMail.length; i++) {
|
||||||
try {
|
try {
|
||||||
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
|
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
|
||||||
let url = `${process.env.SERVER_URL}/functions/sendmailv3/`;
|
let url = `${cloudServerUrl}/functions/sendmailv3/`;
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-Parse-Application-Id': process.env.APP_ID,
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user