Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e643d96797 | ||
|
|
1ff4160ca4 | ||
|
|
62f66bf524 | ||
|
|
de3bc37fa5 | ||
|
|
ea660384c3 | ||
|
|
210cb5e754 | ||
|
|
ed45bfef84 | ||
|
|
a8e77e93f7 | ||
|
|
969071bb28 | ||
|
|
76491a77f1 | ||
|
|
9a51eed2bc | ||
|
|
a675a3c8fd | ||
|
|
fea30930eb | ||
|
|
7373b086e4 | ||
|
|
2fc1eda761 | ||
|
|
2c100ad399 | ||
|
|
1cefe01aee | ||
|
|
f1cf395761 | ||
|
|
4af3d8f78b | ||
|
|
cf21ac7405 | ||
|
|
5f11e92c0c | ||
|
|
c3ffda4dd2 | ||
|
|
c929b6b7a9 | ||
|
|
eb2abd3e6d | ||
|
|
1c4c2e87b4 | ||
|
|
4fda5b4531 | ||
|
|
df61e143af | ||
|
|
3a55c35445 | ||
|
|
08476ba3d6 | ||
|
|
db9ae71d67 | ||
|
|
39806e3ad6 | ||
|
|
7882c61b81 | ||
|
|
b8f886902f | ||
|
|
17660dae21 | ||
|
|
7584667643 | ||
|
|
b47d1cff07 | ||
|
|
b99d8e6d6e | ||
|
|
8b15bceac8 | ||
|
|
86b0e90948 | ||
|
|
3bc57a999c | ||
|
|
27730c89e8 | ||
|
|
82eeffa6e4 | ||
|
|
53147caebc | ||
|
|
6004522d5c | ||
|
|
266c2463c9 | ||
|
|
1b215f53e7 | ||
|
|
73b2ba6abd | ||
|
|
c04fd80a38 | ||
|
|
61b123cb61 | ||
|
|
08e805569f | ||
|
|
375aa0b7e7 | ||
|
|
b94e0fa052 | ||
|
|
b6752549ed | ||
|
|
51505af6d8 | ||
|
|
0e5cffa1fa | ||
|
|
885b5287b4 | ||
|
|
5348c6620a | ||
|
|
73c219fa4d | ||
|
|
f4090c0c61 | ||
|
|
cd2be94d29 | ||
|
|
878dca3cd6 | ||
|
|
90cba26904 | ||
|
|
c5c001f030 | ||
|
|
a3ba4e26c3 | ||
|
|
dd95862d5a | ||
|
|
5d3de41e63 | ||
|
|
5cad0a96cd | ||
|
|
e74fd79efc | ||
|
|
6f49fc9126 | ||
|
|
bbf3cc2f44 | ||
|
|
7bf196ef75 | ||
|
|
4b5b3aff49 | ||
|
|
15b0cb132c | ||
|
|
e67f91ea90 | ||
|
|
59350f02fb | ||
|
|
32cde66d64 | ||
|
|
7ba111a275 | ||
|
|
8d3fa6cef8 | ||
|
|
ef7aede146 | ||
|
|
11ae58aad3 | ||
|
|
05e30a5d19 | ||
|
|
64773cafec | ||
|
|
c6be39ffc3 | ||
|
|
376d4293c2 | ||
|
|
67b3752297 | ||
|
|
f463ffc8ed | ||
|
|
6e2aac51b4 | ||
|
|
a9a3c25dfd | ||
|
|
645898ab14 | ||
|
|
3ad1c46455 | ||
|
|
d3d33c85d9 | ||
|
|
c2796f66fb | ||
|
|
f57fcd25c9 | ||
|
|
9bda7dee7f | ||
|
|
7e1f21b02b | ||
|
|
a83acabf1a | ||
|
|
fb99c76b0c | ||
|
|
cc0ff1f5e7 | ||
|
|
afbfd9ed43 | ||
|
|
fcad04461f | ||
|
|
ca98b5a210 | ||
|
|
bd72ef84ed | ||
|
|
cb3c62fb6c | ||
|
|
2976220e4d | ||
|
|
192371c07b | ||
|
|
708a3f4ad9 | ||
|
|
fbcdfa97cf | ||
|
|
4e39762b46 | ||
|
|
4239e8d5fb | ||
|
|
c8ee455865 | ||
|
|
d5be7b8c57 | ||
|
|
bc2f4f1ef3 | ||
|
|
e72baf3c1f | ||
|
|
b2b52b6af7 | ||
|
|
4f417ccf0f | ||
|
|
780c3f5f6d | ||
|
|
f9eff12f94 | ||
|
|
e912a8d4e0 | ||
|
|
224af292d6 | ||
|
|
e07a4457ec | ||
|
|
58cd0495e6 | ||
|
|
6b9b2afbef | ||
|
|
c55a8d09a2 | ||
|
|
71b06f92ec | ||
|
|
692ec8ecbf | ||
|
|
523ea7f314 | ||
|
|
f48444f21d | ||
|
|
b4c5b3cbe6 | ||
|
|
ed88ae013d | ||
|
|
0fe7937808 | ||
|
|
564f57b879 | ||
|
|
a47dc8e767 | ||
|
|
41e192acb0 | ||
|
|
ff4fb191b8 | ||
|
|
2feee80168 | ||
|
|
59fed8a9cc | ||
|
|
7cfca0a650 | ||
|
|
6f1a5fd3a9 | ||
|
|
cd6869778a | ||
|
|
2e8d84430e | ||
|
|
b8f32a6d8d | ||
|
|
11ab37baf1 | ||
|
|
9dbde43a44 | ||
|
|
2a24d71ee3 | ||
|
|
134444c20a | ||
|
|
44b87f178e | ||
|
|
666636d554 | ||
|
|
5ec9d59382 | ||
|
|
addc7622ab | ||
|
|
1c7c3a4777 | ||
|
|
2a46b02487 | ||
|
|
5974515362 | ||
|
|
3fab1d9c6f | ||
|
|
a283f2ee5d | ||
|
|
934823fad4 | ||
|
|
351ed795ca | ||
|
|
a335d02156 | ||
|
|
3e0747164a | ||
|
|
8ad396d3ba | ||
|
|
26b54f0c00 | ||
|
|
de5b58fff6 | ||
|
|
b9b329dde4 | ||
|
|
2581500307 | ||
|
|
ef5c20a9f2 | ||
|
|
01aee7c028 | ||
|
|
569c7f4b48 | ||
|
|
bb849f175c | ||
|
|
ede0eea944 | ||
|
|
47150cca41 | ||
|
|
86df98a6a4 | ||
|
|
8dd5e90f8b | ||
|
|
f31023e2ed | ||
|
|
740d2e5a6c | ||
|
|
20d37e1ac9 | ||
|
|
f3f79ed499 | ||
|
|
c581222022 | ||
|
|
a3fd738b46 | ||
|
|
3f16e973eb | ||
|
|
cb1013762f | ||
|
|
74e275c5d0 | ||
|
|
dbeb513f65 | ||
|
|
6f4561a38f | ||
|
|
12507190d8 | ||
|
|
85dac65030 | ||
|
|
4f1708619e | ||
|
|
84b545c37d | ||
|
|
b24086e679 | ||
|
|
8308376f53 | ||
|
|
137f371528 | ||
|
|
5707039002 | ||
|
|
d4fabf0fe9 | ||
|
|
a4a0630102 | ||
|
|
439ac7eac6 | ||
|
|
ef1b82f426 | ||
|
|
e7b9f3f121 | ||
|
|
14b4d10be3 | ||
|
|
987a4bd04c | ||
|
|
ce86510d8e | ||
|
|
156a05f6ed | ||
|
|
b35d8406a3 | ||
|
|
3910486b17 | ||
|
|
60ba77a06f | ||
|
|
f86ea04a02 | ||
|
|
db4b5f0452 | ||
|
|
c0ae0c7ffa | ||
|
|
6a0788c2a1 | ||
|
|
4a52d327ce | ||
|
|
ef68fe1c85 | ||
|
|
83fa9c9ebd | ||
|
|
5736306f8c | ||
|
|
67cb508944 | ||
|
|
87fe5cdd6f | ||
|
|
ca17f1cfc9 | ||
|
|
048629dd32 | ||
|
|
fe03da1d97 | ||
|
|
0a3d89d0e2 | ||
|
|
882b97da5e | ||
|
|
07a57969ac | ||
|
|
bc90da4cf2 | ||
|
|
ad5776cfba | ||
|
|
1f16123865 | ||
|
|
e85bbb7bd9 | ||
|
|
f4e907de36 | ||
|
|
72f7e1fb27 | ||
|
|
bb732d7606 | ||
|
|
221a49bb4a | ||
|
|
babe17838b | ||
|
|
f5d11f9ba6 | ||
|
|
939d917b7b | ||
|
|
288365b74b | ||
|
|
b57e17c01c | ||
|
|
92527e5847 |
@@ -1,6 +1,5 @@
|
||||
# Frontend config ************************************************************************************************************************************************************************************************
|
||||
# Set CI to false while running the app locally
|
||||
CI=false
|
||||
|
||||
# Set it to the URL form where the app home page will be accessed
|
||||
PUBLIC_URL=https://app.opensignlabs.com/
|
||||
# Set it to true if you want to generate the Sourcemap for debugging
|
||||
@@ -8,13 +7,13 @@ GENERATE_SOURCEMAP=false
|
||||
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
REACT_APP_SERVERURL=https://app.opensignlabs.com/api/app
|
||||
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
|
||||
REACT_APP_APPID=aDsADsqweqwe
|
||||
REACT_APP_APPID=opensign
|
||||
# Google tag manager container id for configuring GTM on all pages of the app
|
||||
REACT_APP_GTM=GTM-123N7LD
|
||||
|
||||
# Backend ExpressJS config ****************************************************************************************************************************************************************************************
|
||||
# A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App.
|
||||
APP_ID=aDsADsqweqwe
|
||||
APP_ID=opensign
|
||||
# Name of the app. It will be visible in the verification emails sent out.
|
||||
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.
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# When used as it is, this env config will connect to our hosted UAT backend
|
||||
# Note that any data in staging will get cleared from time to time and you may have to sign up again and again
|
||||
|
||||
# Set CI to false while running the app locally
|
||||
CI=false
|
||||
# Set it to the URL form where the app home page will be accessed
|
||||
PUBLIC_URL=http://localhost:3000
|
||||
# Set it to true if you want to generate the Sourcemap for debugging
|
||||
@@ -11,4 +9,4 @@ GENERATE_SOURCEMAP=false
|
||||
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
REACT_APP_SERVERURL=https://staging-app.opensignlabs.com/api/app
|
||||
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
|
||||
REACT_APP_APPID=opensignstgn
|
||||
REACT_APP_APPID=opensign
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# When used as it is, this env config will connect to our hosted UAT backend
|
||||
# Note that any data in staging will get cleared from time to time and you may have to sign up again and again
|
||||
|
||||
# Set CI to false while running the app locally
|
||||
CI=false
|
||||
# Set it to the URL form where the app home page will be accessed
|
||||
PUBLIC_URL=http://localhost:3000
|
||||
# Set it to true if you want to generate the Sourcemap for debugging
|
||||
@@ -11,18 +9,18 @@ GENERATE_SOURCEMAP=false
|
||||
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
REACT_APP_SERVERURL=http://localhost:8080/app
|
||||
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
|
||||
REACT_APP_APPID=opensignstgn
|
||||
REACT_APP_APPID=opensign
|
||||
|
||||
|
||||
# Backend ExpressJS config ****************************************************************************************************************************************************************************************
|
||||
# A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App.
|
||||
APP_ID=opensignstgn
|
||||
APP_ID=opensign
|
||||
# Name of the app. It will be visible in the verification emails sent out.
|
||||
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.
|
||||
MASTER_KEY=XnAadwKxxByMr
|
||||
# Mongodb URI to connect to
|
||||
MONGODB_URI=mongodb://host.docker.internal:27017/OpenSignDB
|
||||
MONGODB_URI=mongodb://localhost: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.
|
||||
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)
|
||||
@@ -52,7 +50,7 @@ SMTP_ENABLE=
|
||||
SMTP_HOST=smtp.yourhost.com
|
||||
SMTP_PORT=443
|
||||
SMTP_USER_EMAIL=mailer@yourdomain.com
|
||||
SMTP_PASS=password
|
||||
SMTP_PASS=password # if your password includes spaces then write password in single quotes ('asdf pasd asdf bgds').
|
||||
|
||||
|
||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||
|
||||
@@ -2,7 +2,7 @@ name: ci
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'staging'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
@@ -11,9 +11,9 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- image: amolshejole/OpenSign
|
||||
dockerfile: apps/OpenSign/Dockerfile
|
||||
dockerfile: apps/OpenSign/Dockerhubfile
|
||||
- image: amolshejole/OpenSignServer
|
||||
dockerfile: apps/OpenSignServer/Dockerfile
|
||||
dockerfile: apps/OpenSignServer/Dockerhubfile
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
@@ -31,8 +31,11 @@ jobs:
|
||||
with:
|
||||
images: ${{ matrix.image }}
|
||||
-
|
||||
name: Debug - List files
|
||||
name: Debug - List files opensign
|
||||
run: ls -R apps/OpenSign/ # Adjust the path as needed
|
||||
-
|
||||
name: Debug - List files opensignserver
|
||||
run: ls -R apps/OpenSignServer/ # Adjust the path as needed
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
|
||||
@@ -1,149 +1,29 @@
|
||||
|
||||
# INSTALLATON INSTRUCTIONS
|
||||
# INSTALLATON INSTRUCTIONS HAS A NEW HOME
|
||||
|
||||
You can use our app as a cloud version from [OpenSignLabs](https://www.opensignlabs.com)
|
||||
We've updated our installation instructions and moved them to our dedicated documentation portal to provide you with a better experience and updated guidance. Whether you're looking to self-host OpenSign™ or contribute to its development, you can find detailed instructions tailored to your needs at [docs.opensignlabs.com](https://docs.opensignlabs.com).
|
||||
|
||||
or follow below instructions to install it on your own infrastructure.
|
||||
## Self Hosting
|
||||
|
||||
- Localhost(Frontend only)
|
||||
- Digital Ocean
|
||||
- Localhost(Docker)
|
||||
If you're interested in self-hosting OpenSign™, our new documentation portal provides comprehensive, step-by-step instructions to help you set up OpenSign™ in your own environment. This section is designed for system administrators and those looking to deploy OpenSign™ within their organization or for personal use.
|
||||
|
||||
## Localhost(Frontend only)
|
||||
- **Access Self Hosting Instructions:** [Self Hosting Guide](https://docs.opensignlabs.com/docs/category/docker)
|
||||
|
||||
This is the easiest way to run the frontend application for development or testing purpose without the hassle of installing backend & DB. All the features including document upload, signing, email notifications will work seamlessly from staging backend.
|
||||
## Contributors
|
||||
|
||||
**Warning:** All data, including user accounts and documents, is stored in the staging backend. This data will be erased every time there is a merge to the main branch. As a result, you may need to recreate user accounts repeatedly. If you find that login attempts are failing, it is likely because the data has been cleared due to a recent merge.
|
||||
For developers and contributors who are looking to build upon or contribute to OpenSign™, we've prepared a separate section that covers the setup, development environment configuration, and guidelines for contributing to the OpenSign™ project.
|
||||
|
||||
Below are the steps to follow -
|
||||
- [Clone the repository](https://help.github.com/articles/cloning-a-repository/) to your local machine using below command -
|
||||
```
|
||||
git clone https://github.com/OpenSignLabs/OpenSign.git
|
||||
```
|
||||
- Copy the .env.frontend_dev file to apps/OpenSign/.env using below command(on mac & linux). For windows use COPY command instead.
|
||||
```
|
||||
cp .env.frontend_dev apps/OpenSign/.env
|
||||
```
|
||||
- CD to /apps/OpenSign directory
|
||||
- Install NPM packages using
|
||||
```
|
||||
npm install
|
||||
```
|
||||
- Run the project locally using
|
||||
```
|
||||
npm run start
|
||||
```
|
||||
You should be able to access the application from http://localhost:3000 after this.
|
||||
Create an account by signing-up and start contributing.
|
||||
- **Access Contributor Instructions:** [Contributors Guide](https://docs.opensignlabs.com/docs/contribute/INSTALLATION)
|
||||
|
||||
## Additional Resources
|
||||
|
||||
## Digital Ocean
|
||||
Should you need further assistance or have any questions, please feel free to reach out to us through our support channels:
|
||||
|
||||
OpenSign application consistes of 3 components -
|
||||
- ReactJS frontend
|
||||
- NodeJS API
|
||||
- MongoDB database
|
||||
- **Twitter:** [OpenSignHQ on Twitter](https://twitter.com/OpenSignHQ)
|
||||
- **Facebook:** [OpenSign on Facebook](https://www.facebook.com/profile.php?id=61551030403669)
|
||||
- **LinkedIn:** [OpenSign™ on LinkedIn](https://www.linkedin.com/company/opensign%E2%84%A2/)
|
||||
- **Discord:** [Join our Discord Community](https://discord.com/invite/opensign)
|
||||
- **YouTube:** [OpenSignHQ on YouTube](https://www.youtube.com/@opensignhq)
|
||||
|
||||
You can install all 3 components on digital ocean using the button below -
|
||||
We are committed to providing you with the support you need to successfully install and use OpenSign™. Visit our website at [www.opensignlabs.com](https://www.opensignlabs.com) for more information about our project and its features.
|
||||
|
||||
[](https://cloud.digitalocean.com/apps/new?repo=https://github.com/OpenSignLabs/Deploy-OpenSign-to-Digital-Ocean/tree/main&refcode=30db1c901ab0)
|
||||
|
||||
## You will need to create an AWS S3 bucket or digital ocean space in order to store your uploaded documents
|
||||
|
||||
### AWS S3 -
|
||||
- Step 1 : Create a S3 bucket
|
||||
- Login to AWS console
|
||||
- Navigate to S3 under services
|
||||
- Hit "Create Bucket" button on upper right corner
|
||||
- Remove the check from "block all public access" checkbox(we need this in order to provide access to not-logged in users after OTP verification)
|
||||
- Set bucket versioning and tags as per your requirements
|
||||
- Hit "Create bucket" button
|
||||
- Step 2 : Create IAM user and provide access to AWS bucket
|
||||
- Search for "IAM" on the search bar in AWS console
|
||||
- On IAM dashboard, click the number of users(count) under IAM resources table
|
||||
- Hit "create user" button on the upper right corner of the page
|
||||
- Enter the user name & click next
|
||||
- Click create policy, search for S3 and provide the Read, Write & list permissions
|
||||
- Click next and click "Create user"
|
||||
- Step 3 : Generate Credentials
|
||||
- Go to IAM/Users in AWS console
|
||||
- Hit the hyperlink for the user created in the previous step
|
||||
- Click the "Security credentials" tab
|
||||
- Scroll down to "Access keys" and hit "Create access key"
|
||||
- In the next step select "Application running outside AWS"
|
||||
- Add a description tag if needed & hit "Create access key"
|
||||
- In the next step you will see "Access key" and "Secret Access key". Copy both the values.
|
||||
- Set the value of "Access key" to "DO_ACCESS_KEY_ID" environment variable
|
||||
- Set the value of "Secret Access key" to "DO_SECRET_ACCESS_KEY" environment variable
|
||||
- Step 3 : Copy bucket credentials
|
||||
- Visit "Amazon S3 -> Buckets" in aws console
|
||||
- Click the bucket created in previous steps & visit the properties tab
|
||||
- Under "Bucket overview" you will find the value of AWS region(for ex. ap-south-1). Set that value to env variable "DO_REGION"
|
||||
- You can create the value for "DO_ENDPOINT" env variable by appending the region value to amazonaws.com (for ex. s3.ap-south-1.amazonaws.com)
|
||||
- You can create the value for "DO_BASEURL" by adding the bucketname in front of the endpoint value(for ex. https://bucketname.s3.ap-south-1.amazonaws.com)
|
||||
|
||||
Visit below link if you face any issues while following the above instructions -
|
||||
- https://repost.aws/knowledge-center/create-access-key
|
||||
|
||||
|
||||
## Localhost(Docker)
|
||||
|
||||
For local Setup we need to need following prerequisite:
|
||||
|
||||
Environment Varaibles:
|
||||
|
||||
| Environment Varibale | Value | Description |
|
||||
| ------------- | ------------- | ------------- |
|
||||
| CI | false | Set CI to false while running the app locally |
|
||||
| PUBLIC_URL | http://localhost:3000 | Set it to the URL form where the app home page will be accessed |
|
||||
| GENERATE_SOURCEMAP | false | Set it to true if you want to generate the Sourcemap for debugging |
|
||||
| REACT_APP_SERVERURL | http://localhost:8080/app | Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead) |
|
||||
| REACT_APP_APPID | opensignstgn | A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API. |
|
||||
| APP_ID | opensignstgn | A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App. |
|
||||
| appName | open_sign_server | Name of the app. It will be visible in the verification emails sent out. |
|
||||
| MASTER_KEY | XnAadwKxxByMr | A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database. |
|
||||
| MONGODB_URI | mongodb://host.docker.internal:27017/OpenSignDB | Mongodb URI to connect to |
|
||||
| PARSE_MOUNT |/app | 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. |
|
||||
| SERVER_URL | http://127.0.0.1:8080/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) |
|
||||
| DO_SPACE | DOSPACENAME | Digital ocean space name or AWS S3 bucket name for uploading documents |
|
||||
| DO_ENDPOINT | ams3.digitaloceanspaces.com | Digital ocean spaces endpoint or AWS S3 endpoint for uploading documents |
|
||||
| DO_BASEURL |https://DOSPACENAME.ams3.digitaloceanspaces.com | Digital ocean baseurl or AWS S3 base URL |
|
||||
| DO_ACCESS_KEY_ID | YOUR_S3_ACCESS_ID | Digital ocean spaces access key ID or AWS s3 Access key ID for uploading the docs |
|
||||
| DO_SECRET_ACCESS_KEY | YOUR_S3_ACCESS_KEY | Digital ocean spaces secret access key or AWS s3 secret access key for uploading the docs |
|
||||
| DO_REGION | YOUR_S3_REGION | Digital ocean spaces region or AWS s3 region |
|
||||
| USE_LOCAL | FALSE | To use local file storage to save file |
|
||||
| MAILGUN_API_KEY | YOUR_MAILGUNAPI_KEY | Mailgun API Key |
|
||||
| MAILGUN_DOMAIN | YOUR_MAILGUNAPI_DOMAIN | Mailgun API Domain |
|
||||
| MAILGUN_SENDER | - | Mailgun Sender Mail ID |
|
||||
| PFX_BASE64 | - | Base64 encoded PFX or p12 document signing certificate file. You can generate base64 encoded self sign certificate using the passphrase `emudhra` |
|
||||
|
||||
# Steps to Generate Self Sign Certificate
|
||||
```
|
||||
# execute below command and use passphrase emudhra
|
||||
openssl genrsa -des3 -out ./cert/local_dev.key 2048
|
||||
openssl req -key ./cert/local_dev.key -new -x509 -days 365 -out ./cert/local_dev.crt
|
||||
openssl pkcs12 -inkey ./cert/local_dev.key -in ./cert/local_dev.crt -export -out ./cert/local_dev.pfx
|
||||
openssl base64 -in ./cert/local_dev.pfx -out ./cert/base64_pfx
|
||||
```
|
||||
|
||||
# CORS Configuration
|
||||
|
||||
As document storage is delegated to S3-compatible services that reside in a different host than the OpenSign one, document operations (loading, storing, deleting) are subject to [Cross-Origin Resource Sharing](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) restriction policies; as a consequence, OpenSign app may fail with (browser console) errors like the following:
|
||||
```
|
||||
Access to fetch at 'https://foo.nyc3.digitaloceanspaces.com/exported_file_4627_0000-00-00T00%3A45%3A43.344Z.pdf'
|
||||
from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header
|
||||
is present on the requested resource. If an opaque response serves your needs, set the request's mode to
|
||||
'no-cors' to fetch the resource with CORS disabled.
|
||||
```
|
||||
|
||||
In order to address this, your document storage system must be instructed to accept requests from other hosts; below the relevant documentation links:
|
||||
- [How to Configure CORS on DigitalOcean Spaces](https://docs.digitalocean.com/products/spaces/how-to/configure-cors/)
|
||||
- [Configuring cross-origin resource sharing on AWS S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html)
|
||||
|
||||
# Build Local Environment
|
||||
|
||||
Command to build project -
|
||||
- Execute `make build`
|
||||
|
||||
Command to run project -
|
||||
- Execute `make run`
|
||||
@@ -1,7 +1,6 @@
|
||||
build:
|
||||
cp .env.local_dev .env
|
||||
rm -rf apps/OpenSign/public/mfbuild
|
||||
cd microfrontends/SignDocuments && npm install && npm run build
|
||||
cd apps/OpenSign && npm install && npm run build
|
||||
docker compose up --build --force-recreate
|
||||
|
||||
run:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Use an official Node runtime as the base image
|
||||
FROM node:16
|
||||
FROM node:18
|
||||
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Use an official Node runtime as the base image
|
||||
FROM node:18
|
||||
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy package.json and package-lock.json first to leverage Docker cache
|
||||
COPY apps/OpenSign/package*.json ./
|
||||
|
||||
# Install application dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the current directory contents into the container
|
||||
COPY apps/OpenSign/ .
|
||||
COPY apps/OpenSign/.husky .
|
||||
|
||||
# build
|
||||
RUN npm run build
|
||||
|
||||
# Make port 3000 available to the world outside this container
|
||||
EXPOSE 3000
|
||||
|
||||
# Define environment variables if needed
|
||||
# ENV NODE_ENV production
|
||||
|
||||
# Run the application
|
||||
CMD ["npm", "start"]
|
||||
@@ -1,25 +0,0 @@
|
||||
const { dependencies } = require("./package.json");
|
||||
|
||||
module.exports = {
|
||||
name: "shell_app", // change me
|
||||
filename: "remoteEntry.js",
|
||||
exposes: {},
|
||||
remotes: {},
|
||||
shared: {
|
||||
...dependencies,
|
||||
react: {
|
||||
singleton: true,
|
||||
import: "react", // fallback is also react
|
||||
shareScope: "default",
|
||||
requiredVersion: dependencies.react
|
||||
},
|
||||
"react-dom": {
|
||||
singleton: true,
|
||||
requiredVersion: dependencies["react-dom"]
|
||||
},
|
||||
"react-router-dom": {
|
||||
singleton: true,
|
||||
requiredVersion: dependencies["react-router-dom"]
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -3,44 +3,57 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@reduxjs/toolkit": "^1.9.7",
|
||||
"axios": "^1.5.1",
|
||||
"@radix-ui/themes": "^2.0.3",
|
||||
"@react-pdf/renderer": "^3.3.8",
|
||||
"@reduxjs/toolkit": "^2.2.1",
|
||||
"axios": "^1.6.0",
|
||||
"daisyui": "^3.9.2",
|
||||
"file-saver": "^2.0.5",
|
||||
"html-react-parser": "^4.2.2",
|
||||
"json-rules-engine-simplified": "^0.1.17",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"mf-cra": "^0.0.5",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"moment": "^2.29.4",
|
||||
"parse": "^4.2.0",
|
||||
"parse": "^4.3.1",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"print-js": "^1.6.0",
|
||||
"radix-ui": "^1.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.9.0",
|
||||
"react-bootstrap": "^2.10.1",
|
||||
"react-datepicker": "^6.2.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dnd-multi-backend": "^8.0.3",
|
||||
"react-dnd-touch-backend": "^16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-drag-listview": "^2.0.0",
|
||||
"react-draggable": "^4.4.6",
|
||||
"react-gtm-module": "^2.0.11",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-konva": "^18.2.10",
|
||||
"react-modal": "^3.16.1",
|
||||
"react-pdf": "^7.7.1",
|
||||
"react-redux": "^8.1.3",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"react-rnd": "^10.4.1",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-select": "^5.7.7",
|
||||
"react-scrollbars-custom": "^4.1.1",
|
||||
"react-select": "^5.8.0",
|
||||
"react-signature-canvas": "^1.0.6",
|
||||
"react-tooltip": "^5.26.3",
|
||||
"reactour": "^1.19.2",
|
||||
"redux": "^4.2.1",
|
||||
"redux-thunk": "^2.4.2",
|
||||
"regex-parser": "^2.3.0",
|
||||
"serve": "^14.2.1",
|
||||
"styled-components": "^4.4.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "serve -s build",
|
||||
"start-dev": "mf-cra start",
|
||||
"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",
|
||||
"build": "npm run version && rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
||||
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
|
||||
"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 && react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"release": "standard-version",
|
||||
@@ -70,14 +83,14 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/runtime-corejs2": "^7.23.2",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"@babel/runtime-corejs2": "^7.23.9",
|
||||
"autoprefixer": "^10.4.18",
|
||||
"commitizen": "^4.3.0",
|
||||
"eslint": "^8.51.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"lint-staged": "^15.0.1",
|
||||
"postcss": "^8.4.31",
|
||||
"lint-staged": "^15.2.2",
|
||||
"postcss": "^8.4.35",
|
||||
"prettier": "^2.8.0",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"tailwindcss": "^3.3.3"
|
||||
|
||||
@@ -1,25 +1,53 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, Suspense, lazy } from "react";
|
||||
import { Routes, Route, BrowserRouter } from "react-router-dom";
|
||||
import Pgsignup from "./routes/Pgsignup";
|
||||
import Login from "./routes/Login";
|
||||
import Microapp from "./routes/RemoteApp";
|
||||
import Signup from "./routes/Signup";
|
||||
import Form from "./routes/Form";
|
||||
import Report from "./routes/Report";
|
||||
import Dashboard from "./routes/Dashboard";
|
||||
import Subscriptions from "./routes/PlanSubscriptions";
|
||||
import { pdfjs } from "react-pdf";
|
||||
import Login from "./pages/Login";
|
||||
import Form from "./pages/Form";
|
||||
import Report from "./pages/Report";
|
||||
import Dashboard from "./pages/Dashboard";
|
||||
import HomeLayout from "./layout/HomeLayout";
|
||||
import UserProfile from "./routes/UserProfile";
|
||||
import PageNotFound from "./routes/PageNotFound";
|
||||
import ForgetPassword from "./routes/ForgetPassword";
|
||||
import ChangePassword from "./routes/ChangePassword";
|
||||
import ReportMicroapp from "./components/ReportMicroapp";
|
||||
import LoadMf from "./routes/LoadMf";
|
||||
import GenerateToken from "./routes/GenerateToken";
|
||||
import PageNotFound from "./pages/PageNotFound";
|
||||
import ValidateRoute from "./primitives/ValidateRoute";
|
||||
import Webhook from "./routes/Webhook";
|
||||
import Validate from "./primitives/Validate";
|
||||
import ManageSign from "./pages/Managesign";
|
||||
import TemplatePlaceholder from "./pages/TemplatePlaceholder";
|
||||
import SignYourSelf from "./pages/SignyourselfPdf";
|
||||
import DraftDocument from "./components/pdf/DraftDocument";
|
||||
import PlaceHolderSign from "./pages/PlaceHolderSign";
|
||||
import PdfRequestFiles from "./pages/PdfRequestFiles";
|
||||
const DebugPdf = lazy(() => import("./pages/DebugPdf"));
|
||||
const ForgetPassword = lazy(() => import("./pages/ForgetPassword"));
|
||||
const GuestLogin = lazy(() => import("./pages/GuestLogin"));
|
||||
const Pgsignup = lazy(() => import("./pages/Pgsignup"));
|
||||
const Subscriptions = lazy(() => import("./pages/PlanSubscriptions"));
|
||||
const ChangePassword = lazy(() => import("./pages/ChangePassword"));
|
||||
const UserProfile = lazy(() => import("./pages/UserProfile"));
|
||||
const Signup = lazy(() => import("./pages/Signup"));
|
||||
const GenerateToken = lazy(() => import("./pages/GenerateToken"));
|
||||
const Webhook = lazy(() => import("./pages/Webhook"));
|
||||
const Opensigndrive = lazy(() => import("./pages/Opensigndrive"));
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
|
||||
|
||||
const Loader = () => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
function App() {
|
||||
const [isloading, setIsLoading] = useState(true);
|
||||
useEffect(() => {
|
||||
@@ -27,12 +55,16 @@ function App() {
|
||||
}, []);
|
||||
|
||||
const handleCredentials = () => {
|
||||
const appId = process.env.REACT_APP_APPID;
|
||||
const baseurl = process.env.REACT_APP_SERVERURL;
|
||||
const appId = process.env.REACT_APP_APPID
|
||||
? process.env.REACT_APP_APPID
|
||||
: "opensign";
|
||||
const baseurl = process.env.REACT_APP_SERVERURL
|
||||
? process.env.REACT_APP_SERVERURL
|
||||
: window.location.origin + "/api/app";
|
||||
const appName = "contracts";
|
||||
try {
|
||||
localStorage.setItem("BaseUrl12", `${baseurl}/`);
|
||||
localStorage.setItem("AppID12", appId);
|
||||
localStorage.setItem("baseUrl", `${baseurl}/`);
|
||||
localStorage.setItem("parseAppId", appId);
|
||||
localStorage.setItem("domain", appName);
|
||||
setIsLoading(false);
|
||||
} catch (error) {
|
||||
@@ -43,54 +75,86 @@ function App() {
|
||||
return (
|
||||
<div className="bg-[#eef1f5]">
|
||||
{isloading ? (
|
||||
<div
|
||||
style={{
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
<Loader />
|
||||
) : (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route element={<ValidateRoute />}>
|
||||
<Route exact path="/" element={<Login />} />
|
||||
<Route exact path="/signup" element={<Signup />} />
|
||||
</Route>
|
||||
<Route element={<Validate />}>
|
||||
<Route exact path="/load/:remoteApp/*" element={<LoadMf />} />
|
||||
</Route>
|
||||
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
||||
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
||||
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
||||
<>
|
||||
<Route exact path="/pgsignup" element={<Pgsignup />} />
|
||||
<Route exact path="/subscription" element={<Subscriptions />} />
|
||||
</>
|
||||
)}
|
||||
<Route element={<HomeLayout />}>
|
||||
<Route path="/changepassword" element={<ChangePassword />} />
|
||||
<Route path="/mf/:remoteApp/*" element={<Microapp />} />
|
||||
<Route path="/asmf/:remoteApp/*" element={<Microapp />} />
|
||||
<Route path="/rpmf/:remoteApp/*" element={<ReportMicroapp />} />
|
||||
<Route path="/form/:id" element={<Form />} />
|
||||
<Route path="/report/:id" element={<Report />} />
|
||||
<Route path="/dashboard/:id" element={<Dashboard />} />
|
||||
<Route path="/profile" element={<UserProfile />} />
|
||||
<Route path="/generatetoken" element={<GenerateToken />} />
|
||||
<Route path="/webhook" element={<Webhook />} />
|
||||
</Route>
|
||||
<Route path="*" element={<PageNotFound />} />
|
||||
</Routes>
|
||||
<Suspense fallback={<Loader />}>
|
||||
<Routes>
|
||||
<Route element={<ValidateRoute />}>
|
||||
<Route exact path="/" element={<Login />} />
|
||||
<Route exact path="/signup" element={<Signup />} />
|
||||
</Route>
|
||||
<Route element={<Validate />}>
|
||||
<Route
|
||||
path="/load/template/:templateId"
|
||||
element={<TemplatePlaceholder />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/load/placeholdersign/:docId"
|
||||
element={<PlaceHolderSign />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/load/recipientSignPdf/:docId/:contactBookId"
|
||||
element={<PdfRequestFiles />}
|
||||
/>
|
||||
</Route>
|
||||
<Route
|
||||
path="/loadmf/signmicroapp/login/:id/:userMail/:contactBookId/:serverUrl"
|
||||
element={<GuestLogin />}
|
||||
/>
|
||||
<Route
|
||||
path="/login/:id/:userMail/:contactBookId/:serverUrl"
|
||||
element={<GuestLogin />}
|
||||
/>
|
||||
<Route path="/debugpdf" element={<DebugPdf />} />
|
||||
<Route path="/forgetpassword" element={<ForgetPassword />} />
|
||||
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
||||
<>
|
||||
<Route exact path="/pgsignup" element={<Pgsignup />} />
|
||||
<Route path="/subscription" element={<Subscriptions />} />
|
||||
</>
|
||||
)}
|
||||
<Route element={<HomeLayout />}>
|
||||
<Route path="/changepassword" element={<ChangePassword />} />
|
||||
<Route path="/form/:id" element={<Form />} />
|
||||
<Route path="/report/:id" element={<Report />} />
|
||||
<Route path="/dashboard/:id" element={<Dashboard />} />
|
||||
<Route path="/profile" element={<UserProfile />} />
|
||||
<Route path="/generatetoken" element={<GenerateToken />} />
|
||||
<Route path="/webhook" element={<Webhook />} />
|
||||
<Route path="/managesign" element={<ManageSign />} />
|
||||
<Route path="/opensigndrive" element={<Opensigndrive />} />
|
||||
<Route
|
||||
path="/template/:templateId"
|
||||
element={<TemplatePlaceholder />}
|
||||
/>
|
||||
{/* signyouself route with no rowlevel data using docId from url */}
|
||||
<Route path="/signaturePdf/:docId" element={<SignYourSelf />} />
|
||||
{/* draft document route to handle and navigate route page accordiing to document status */}
|
||||
<Route path="/draftDocument" element={<DraftDocument />} />
|
||||
{/* recipient placeholder set route with no rowlevel data using docId from url*/}
|
||||
<Route
|
||||
path="/placeHolderSign/:docId"
|
||||
element={<PlaceHolderSign />}
|
||||
/>
|
||||
{/* for user signature (need your sign route) with row level data */}
|
||||
<Route path="/pdfRequestFiles" element={<PdfRequestFiles />} />
|
||||
{/* for user signature (need your sign route) with no row level data */}
|
||||
<Route
|
||||
path="/pdfRequestFiles/:docId"
|
||||
element={<PdfRequestFiles />}
|
||||
/>
|
||||
{/* recipient signature route with no rowlevel data using docId from url */}
|
||||
<Route
|
||||
path="/recipientSignPdf/:docId/:contactBookId"
|
||||
element={<PdfRequestFiles />}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="*" element={<PageNotFound />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</BrowserRouter>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import { Provider } from "react-redux";
|
||||
import { store } from "./redux/store";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { TouchBackend } from "react-dnd-touch-backend";
|
||||
import {
|
||||
DndProvider,
|
||||
TouchTransition,
|
||||
MouseTransition,
|
||||
Preview
|
||||
} from "react-dnd-multi-backend";
|
||||
import DragElement from "./microappComponent/DragElement";
|
||||
import TagManager from "react-gtm-module";
|
||||
|
||||
const HTML5toTouch = {
|
||||
backends: [
|
||||
{
|
||||
id: "html5",
|
||||
backend: HTML5Backend,
|
||||
transition: MouseTransition
|
||||
},
|
||||
{
|
||||
id: "touch",
|
||||
backend: TouchBackend,
|
||||
options: { enableMouseEvents: true },
|
||||
preview: true,
|
||||
transition: TouchTransition
|
||||
}
|
||||
]
|
||||
};
|
||||
const generatePreview = (props) => {
|
||||
const { item, style } = props;
|
||||
const newStyle = {
|
||||
...style
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={newStyle}>
|
||||
<DragElement {...item} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
if (process.env.REACT_APP_GTM) {
|
||||
const tagManagerArgs = {
|
||||
gtmId: process.env.REACT_APP_GTM
|
||||
};
|
||||
TagManager.initialize(tagManagerArgs);
|
||||
}
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<DndProvider options={HTML5toTouch}>
|
||||
<Preview>{generatePreview}</Preview>
|
||||
<App />
|
||||
</DndProvider>
|
||||
</Provider>
|
||||
);
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 234 KiB After Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -3,7 +3,7 @@ import Parse from "parse";
|
||||
import axios from "axios";
|
||||
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
||||
|
||||
const AppendFormInForm = (props) => {
|
||||
const AddSigner = (props) => {
|
||||
const [name, setName] = useState("");
|
||||
const [phone, setPhone] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
@@ -49,8 +49,6 @@ const AppendFormInForm = (props) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsLoader(true);
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
try {
|
||||
const contactQuery = new Parse.Object("contracts_Contactbook");
|
||||
contactQuery.set("Name", name);
|
||||
@@ -314,4 +312,4 @@ const AppendFormInForm = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default AppendFormInForm;
|
||||
export default AddSigner;
|
||||
@@ -12,8 +12,6 @@ const AddUser = (props) => {
|
||||
const [isUserExist, setIsUserExist] = useState(false);
|
||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
|
||||
const checkUserExist = async () => {
|
||||
try {
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
export class ErrorBoundary extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { hasError: false };
|
||||
}
|
||||
|
||||
static getDerivedStateFromError() {
|
||||
return {
|
||||
hasError: true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidCatch(error, info) {
|
||||
console.log(error);
|
||||
console.log(info);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div className="p-2">
|
||||
<div
|
||||
style={{
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
|
||||
flexFlow: "column"
|
||||
}}
|
||||
>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: "2em",
|
||||
fontFamily: "sans-serif",
|
||||
textShadow: "0 0 20px black"
|
||||
}}
|
||||
>
|
||||
Something went wrong.
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
export default ErrorBoundary;
|
||||
@@ -11,8 +11,6 @@ const Header = ({ showSidebar }) => {
|
||||
let applogo = localStorage.getItem("appLogo") || "";
|
||||
let username = localStorage.getItem("username");
|
||||
const image = localStorage.getItem("profileImg") || dp;
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
@@ -22,8 +20,6 @@ const Header = ({ showSidebar }) => {
|
||||
|
||||
const closeDropdown = () => {
|
||||
setIsOpen(false);
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
Parse.User.logOut();
|
||||
let appdata = localStorage.getItem("userSettings");
|
||||
let applogo = localStorage.getItem("appLogo");
|
||||
@@ -32,8 +28,8 @@ const Header = ({ showSidebar }) => {
|
||||
let PageLanding = localStorage.getItem("PageLanding");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let _appName = localStorage.getItem("_appName");
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
let baseUrl = localStorage.getItem("baseUrl");
|
||||
let appid = localStorage.getItem("parseAppId");
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
@@ -44,8 +40,8 @@ const Header = ({ showSidebar }) => {
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("userSettings", appdata);
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
localStorage.setItem("baseUrl", baseUrl);
|
||||
localStorage.setItem("parseAppId", appid);
|
||||
|
||||
navigation("/");
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useRef } from "react";
|
||||
import Parse from "parse";
|
||||
import jwtDecode from "jwt-decode";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import { useScript } from "../hook/useScript";
|
||||
import ModalUi from "../primitives/ModalUi";
|
||||
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
||||
@@ -48,8 +48,8 @@ const GoogleSignInBtn = ({
|
||||
if (Parse.User.current()) {
|
||||
await Parse.User.logOut();
|
||||
}
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
let baseUrl = localStorage.getItem("baseUrl");
|
||||
let appid = localStorage.getItem("parseAppId");
|
||||
let applogo = localStorage.getItem("appLogo");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let appversion = localStorage.getItem("appVersion");
|
||||
@@ -63,8 +63,8 @@ const GoogleSignInBtn = ({
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
localStorage.setItem("baseUrl", baseUrl);
|
||||
localStorage.setItem("parseAppId", appid);
|
||||
localStorage.setItem("appLogo", applogo);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("appversion", appversion);
|
||||
@@ -191,8 +191,8 @@ const GoogleSignInBtn = ({
|
||||
let PageLanding = localStorage.getItem("PageLanding");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let _appName = localStorage.getItem("_appName");
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
let baseUrl = localStorage.getItem("baseUrl");
|
||||
let appid = localStorage.getItem("parseAppId");
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
@@ -203,8 +203,8 @@ const GoogleSignInBtn = ({
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("userSettings", appdata);
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
localStorage.setItem("baseUrl", baseUrl);
|
||||
localStorage.setItem("parseAppId", appid);
|
||||
};
|
||||
return (
|
||||
<div style={{ position: "relative" }}>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import React from "react";
|
||||
import { Document, Page, pdfjs } from "react-pdf";
|
||||
import { Document, Page } from "react-pdf";
|
||||
import { Stage, Layer, Rect } from "react-konva";
|
||||
const RenderDebugPdf = (props) => {
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
@@ -29,7 +27,7 @@ const RenderDebugPdf = (props) => {
|
||||
onMouseMove={props.handleMouseMoveDiv}
|
||||
>
|
||||
<Document
|
||||
onLoadError={(e) => {
|
||||
onLoadError={() => {
|
||||
const load = {
|
||||
status: false,
|
||||
type: "failed"
|
||||
@@ -66,6 +64,7 @@ const RenderDebugPdf = (props) => {
|
||||
.map((value) => {
|
||||
return (
|
||||
<Rect
|
||||
key={value.key}
|
||||
x={value.x}
|
||||
y={value.y}
|
||||
width={value.width}
|
||||
@@ -1,66 +0,0 @@
|
||||
import useFederatedComponent from "mf-cra";
|
||||
import React, { Suspense, useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
const MicroappModal = () => {
|
||||
const { remoteApp } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
return () => localStorage.removeItem("rowlevel");
|
||||
}, []);
|
||||
let paramString = remoteApp;
|
||||
let queryString = new URLSearchParams(paramString);
|
||||
let obj = {};
|
||||
for (const [key, value] of queryString.entries()) {
|
||||
// console.log("value ", key + ":" + value);
|
||||
|
||||
if (key === "remoteUrl") {
|
||||
const url = window.location.origin + "/mfbuild/remoteEntry.js";
|
||||
// console.log("atob(value) ", atob(value))
|
||||
obj = { ...obj, [key]: url };
|
||||
} else {
|
||||
if (key === "moduleToLoad") {
|
||||
obj = { ...obj, [key]: "./" + value };
|
||||
} else {
|
||||
obj = { ...obj, [key]: value };
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log("app ", remoteApp);
|
||||
const { Component: RemoteComponent } = useFederatedComponent(obj);
|
||||
// console.log("RemoteComponent ", RemoteComponent);
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center ">
|
||||
<div className="w-full">
|
||||
<Suspense
|
||||
fallback={
|
||||
<div style={{ height: "300px" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: "#ffffff",
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
minHeight: "50vh"
|
||||
}}
|
||||
>
|
||||
{RemoteComponent && <RemoteComponent />}
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MicroappModal;
|
||||
@@ -1,21 +1,11 @@
|
||||
import React from "react";
|
||||
import { Helmet } from "react-helmet";
|
||||
|
||||
function Title(props) {
|
||||
function Title({ title, drive }) {
|
||||
return (
|
||||
<Helmet>
|
||||
<title>{`${props.title} - OpenSign™`}</title>
|
||||
{/* <title>
|
||||
{`${localStorage.getItem("appTitle") ? localStorage.getItem("appTitle") : ""} - ${props.title}`}
|
||||
</title> */}
|
||||
<meta
|
||||
name="description"
|
||||
content={`${props.title} - OpenSign™`}
|
||||
/>
|
||||
{/* <meta
|
||||
name="description"
|
||||
content={`${localStorage.getItem("appTitle")} - ${props.title}`}
|
||||
/> */}
|
||||
<title>{drive ? title : `${title} - OpenSign™`}</title>
|
||||
<meta name="description" content={`${title} - OpenSign™`} />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import React from "react";
|
||||
import "../../styles/loader.css";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { openInNewTab } from "../../constant/Utils";
|
||||
|
||||
const DashboardButton = (props) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
function openReport() {
|
||||
if (props.Data && props.Data.Redirect_type) {
|
||||
const Redirect_type = props.Data.Redirect_type;
|
||||
const id = props.Data.Redirect_id;
|
||||
if (Redirect_type === "Form") {
|
||||
navigate(`/form/${id}`);
|
||||
} else if (Redirect_type === "Report") {
|
||||
navigate(`/report/${id}`);
|
||||
} else if (Redirect_type === "Url") {
|
||||
openInNewTab(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div
|
||||
onClick={() => openReport()}
|
||||
className={`${
|
||||
props.Data && props.Data.Redirect_type
|
||||
? "cursor-pointer"
|
||||
: "cursor-default"
|
||||
} w-full px-3 py-2 flex text-white rounded-md shadow overflow-hidden`}
|
||||
>
|
||||
<div className="flex items-center justify-start gap-5">
|
||||
<span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
|
||||
<i
|
||||
className={`${
|
||||
props.Icon ? props.Icon : "fa fa-solid fa-info"
|
||||
} text-[25px] lg:text-[30px]`}
|
||||
></i>
|
||||
</span>
|
||||
<div className="">
|
||||
<div className="text-base lg:text-lg text-black"> {props.Label}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardButton;
|
||||
@@ -24,9 +24,6 @@ const DashboardCard = (props) => {
|
||||
};
|
||||
let body = {};
|
||||
let currentUser;
|
||||
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
let currentUser1 = Parse.User.current();
|
||||
currentUser = currentUser1.id;
|
||||
let res;
|
||||
@@ -82,8 +79,6 @@ const DashboardCard = (props) => {
|
||||
} else {
|
||||
setLoading(true);
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const currentUser = Parse.User.current();
|
||||
let reg1 = /(\#.*?\#)/gi; // eslint-disable-line
|
||||
let _query = props.Data.query;
|
||||
@@ -223,8 +218,6 @@ const DashboardCard = (props) => {
|
||||
|
||||
if (restr.includes("#")) {
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const currentUser = Parse.User.current();
|
||||
let res;
|
||||
if (localStorage.getItem("Extand_Class")) {
|
||||
|
||||
@@ -45,18 +45,16 @@ function DashboardReport(props) {
|
||||
setActions(json.actions);
|
||||
setReportName(json.reportName);
|
||||
setHeading(json.heading);
|
||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||
Parse.initialize(localStorage.getItem("AppID12"));
|
||||
const currentUser = Parse.User.current().id;
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessiontoken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
try {
|
||||
const params = { reportId: id, skip: skipUserRecord, limit: limit };
|
||||
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
|
||||
const url = `${localStorage.getItem("baseUrl")}/functions/getReport`;
|
||||
const res = await axios.post(url, params, {
|
||||
headers: headers,
|
||||
signal: abortController.signal // is used to cancel fetch query
|
||||
|
||||
@@ -1,21 +1,69 @@
|
||||
import React, { Suspense, lazy } from "react";
|
||||
import ErrorBoundary from "../ErrorBoundary";
|
||||
|
||||
const DashboardButton = lazy(() => import("./DashboardButton"));
|
||||
const DashboardCard = lazy(() => import("./DashboardCard"));
|
||||
|
||||
const DashboardReport = lazy(() => import("./DashboardReport"));
|
||||
|
||||
const buttonList = [
|
||||
{
|
||||
label: "Sign yourself",
|
||||
redirectId: "sHAnZphf69",
|
||||
redirectType: "Form"
|
||||
},
|
||||
{
|
||||
label: "Request signature",
|
||||
redirectId: "8mZzFxbG1z",
|
||||
redirectType: "Form"
|
||||
}
|
||||
];
|
||||
const GetDashboard = (props) => {
|
||||
const Button = ({ label, redirectId, redirectType }) => (
|
||||
<div className={"bg-white rounded-md shadow w-full"}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div style={{ height: "300px" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<DashboardButton
|
||||
Icon={"fa-solid fa-plus"}
|
||||
Label={label}
|
||||
Data={{ Redirect_type: redirectType, Redirect_id: redirectId }}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
const renderSwitchWithTour = (col) => {
|
||||
switch (col.widget.type) {
|
||||
case "Card":
|
||||
return (
|
||||
<div
|
||||
className={"bg-[#2ed8b6] rounded-md shadow mb-4 md:mb-0"}
|
||||
className={"bg-[#2ed8b6] rounded-md shadow mb-3 md:mb-0"}
|
||||
data-tut={col.widget.data.tourSection}
|
||||
style={{ background: col.widget.bgColor }}
|
||||
>
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div style={{ height: "300px" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<DashboardCard
|
||||
Icon={col.widget.icon}
|
||||
Label={col.widget.label}
|
||||
@@ -31,7 +79,7 @@ const GetDashboard = (props) => {
|
||||
return (
|
||||
<div data-tut={col.widget.data.tourSection}>
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<div className="mb-4 md:mb-0">
|
||||
<div className="mb-3 md:mb-0">
|
||||
<DashboardReport Record={col.widget} />
|
||||
</div>
|
||||
</Suspense>
|
||||
@@ -47,7 +95,7 @@ const GetDashboard = (props) => {
|
||||
case "Card":
|
||||
return (
|
||||
<div
|
||||
className={"bg-[#2ed8b6] rounded-md shadow mb-4 md:mb-0"}
|
||||
className={"bg-[#2ed8b6] rounded-md shadow mb-3 md:mb-0"}
|
||||
style={{ background: col.widget.bgColor }}
|
||||
>
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
@@ -65,7 +113,7 @@ const GetDashboard = (props) => {
|
||||
case "report": {
|
||||
return (
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<div className="mb-4 md:mb-0">
|
||||
<div className="mb-3 md:mb-0">
|
||||
<DashboardReport Record={col.widget} />
|
||||
</div>
|
||||
</Suspense>
|
||||
@@ -76,25 +124,38 @@ const GetDashboard = (props) => {
|
||||
}
|
||||
};
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<div>
|
||||
{props.dashboard.map((val, key) => (
|
||||
<div key={"a" + key} className="row">
|
||||
{val.columns.map((col, i) =>
|
||||
col.widget.data && col.widget.data.tourSection ? (
|
||||
<div key={i} className={props.classnameArray[key][i]}>
|
||||
{renderSwitchWithTour(col)}
|
||||
</div>
|
||||
) : (
|
||||
<div key={i} className={props.classnameArray[key][i]}>
|
||||
{renderSwitch(col)}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
<div>
|
||||
<div className="mb-3">
|
||||
<div
|
||||
data-tut={"tourbutton"}
|
||||
className="flex flex-col md:flex-row gap-6 md:gap-8"
|
||||
>
|
||||
{buttonList.map((btn) => (
|
||||
<Button
|
||||
key={btn.label}
|
||||
label={btn.label}
|
||||
redirectType={btn.redirectType}
|
||||
redirectId={btn.redirectId}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
{props.dashboard.map((val, key) => (
|
||||
<div key={"a" + key} className="row">
|
||||
{val.columns.map((col, i) =>
|
||||
col.widget.data && col.widget.data.tourSection ? (
|
||||
<div key={i} className={props.classnameArray[key][i]}>
|
||||
{renderSwitchWithTour(col)}
|
||||
</div>
|
||||
) : (
|
||||
<div key={i} className={props.classnameArray[key][i]}>
|
||||
{renderSwitch(col)}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import folder from "../../../assests/folder.png";
|
||||
import "../LegaDrive.css";
|
||||
import draftDoc from "../../../assests/draftDoc1.png";
|
||||
import pdfLogo from "../../../assests/pdf3.png";
|
||||
import folder from "../../assets/images/folder.png";
|
||||
import "../../styles/opensigndrive.css";
|
||||
import pdfLogo from "../../assets/images/pdf3.png";
|
||||
import axios from "axios";
|
||||
import * as ContextMenu from "@radix-ui/react-context-menu";
|
||||
import { saveAs } from "file-saver";
|
||||
import { getHostUrl } from "../../../utils/Utils";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Table from "react-bootstrap/Table";
|
||||
import * as HoverCard from "@radix-ui/react-hover-card";
|
||||
import SelectFolder from "../../../premitives/SelectFolder";
|
||||
import ModalUi from "../../../premitives/ModalUi";
|
||||
import { themeColor } from "../../../utils/ThemeColor/backColor";
|
||||
import SelectFolder from "../shared/fields/SelectFolder"; //check this one
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
import { themeColor } from "../../constant/const";
|
||||
|
||||
function PdfFileComponent({
|
||||
function DriveBody({
|
||||
pdfData,
|
||||
setFolderName,
|
||||
setDocId,
|
||||
@@ -40,7 +38,6 @@ function PdfFileComponent({
|
||||
//to focus input box on press rename to change doc name
|
||||
useEffect(() => {
|
||||
if (rename && inputRef.current) {
|
||||
// console.log("ref", inputRef.current)
|
||||
setTimeout(() => {
|
||||
inputRef.current.focus();
|
||||
}, 10);
|
||||
@@ -99,11 +96,12 @@ function PdfFileComponent({
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((result) => {
|
||||
.then(() => {
|
||||
// const res = result.data;
|
||||
// console.log("res", res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Err ", err);
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "something went wrong"
|
||||
@@ -114,57 +112,66 @@ function PdfFileComponent({
|
||||
|
||||
//function for navigate user to microapp-signature component
|
||||
const checkPdfStatus = async (data) => {
|
||||
const hostUrl = getHostUrl();
|
||||
|
||||
const signerExist = data.Signers && data.Signers;
|
||||
const isDecline = data.IsDeclined && data.IsDeclined;
|
||||
const isPlaceholder = data.Placeholders && data.Placeholders;
|
||||
|
||||
const signedUrl = data.SignedUrl;
|
||||
//checking if document has completed and request signature flow
|
||||
if (data?.IsCompleted && signerExist?.length > 0) {
|
||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
||||
}
|
||||
//checking if document has completed and signyour-self flow
|
||||
else if (!signerExist && !isPlaceholder) {
|
||||
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
|
||||
navigate(`/signaturePdf/${data.objectId}`);
|
||||
}
|
||||
//checking if document has declined by someone
|
||||
else if (isDecline) {
|
||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
||||
//checking draft type document
|
||||
} else if (
|
||||
signerExist?.length > 0 &&
|
||||
isPlaceholder?.length > 0 &&
|
||||
!signedUrl
|
||||
) {
|
||||
navigate(`/placeHolderSign/${data.objectId}`);
|
||||
}
|
||||
//Inprogress document
|
||||
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
|
||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
||||
} //placeholder draft document
|
||||
else if (
|
||||
(signerExist?.length > 0 &&
|
||||
(!isPlaceholder || isPlaceholder?.length === 0)) ||
|
||||
((!signerExist || signerExist?.length === 0) && isPlaceholder?.length > 0)
|
||||
) {
|
||||
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
|
||||
navigate(`/placeHolderSign/${data.objectId}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMenuItemClick = (selectType, data) => {
|
||||
switch (selectType) {
|
||||
case "Download":
|
||||
case "Download": {
|
||||
const pdfName = data && data.Name;
|
||||
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
|
||||
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||
break;
|
||||
case "Rename":
|
||||
}
|
||||
case "Rename": {
|
||||
setRenameValue(data.Name);
|
||||
setRename(data.objectId);
|
||||
break;
|
||||
case "Delete":
|
||||
}
|
||||
case "Delete": {
|
||||
setIsDeleteDoc(true);
|
||||
setSelectDoc(data);
|
||||
break;
|
||||
|
||||
case "Move":
|
||||
}
|
||||
case "Move": {
|
||||
handleMoveDocument(data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
null;
|
||||
}
|
||||
};
|
||||
//function for delete document
|
||||
@@ -197,6 +204,7 @@ function PdfFileComponent({
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Err ", err);
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "something went wrong"
|
||||
@@ -282,10 +290,6 @@ function PdfFileComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const handleDraftDoc = (data) => {
|
||||
window.location.hash = `/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9MZWdhR2VuaWUtTWljcm9hcHBWMi9yZW1vdGVFbnRyeS5qcw==&moduleToLoad=AppRoutes&remoteName=legageniemicroapp/legagenie?${data.objectId}`;
|
||||
};
|
||||
|
||||
//component to handle type of document and render according to type
|
||||
const handleFolderData = (data, ind, listType) => {
|
||||
let createddate, status, isDecline, signerExist, isComplete, isPlaceholder;
|
||||
@@ -297,6 +301,7 @@ function PdfFileComponent({
|
||||
isDecline = data.IsDeclined && data.IsDeclined;
|
||||
isPlaceholder = data.Placeholders && data.Placeholders;
|
||||
signerExist = data.Signers && data.Signers;
|
||||
const signedUrl = data.SignedUrl;
|
||||
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
const currDate = new Date().getTime();
|
||||
@@ -316,6 +321,12 @@ function PdfFileComponent({
|
||||
(!isPlaceholder || isPlaceholder?.length === 0)
|
||||
) {
|
||||
status = "Draft";
|
||||
} else if (
|
||||
signerExist?.length > 0 &&
|
||||
isPlaceholder?.length > 0 &&
|
||||
!signedUrl
|
||||
) {
|
||||
status = "Draft";
|
||||
} else if (isExpire) {
|
||||
status = "Expired";
|
||||
} else {
|
||||
@@ -357,25 +368,6 @@ function PdfFileComponent({
|
||||
<td>_</td>
|
||||
<td>_</td>
|
||||
</tr>
|
||||
) : data.Type === "AIDoc" ? (
|
||||
<tr onClick={() => handleDraftDoc(data)}>
|
||||
<td
|
||||
style={{ cursor: "pointer", display: "flex", alignItems: "center" }}
|
||||
>
|
||||
<i
|
||||
className="fa fa-file-text"
|
||||
style={{ color: "#0ea3ed", marginRight: "8px", fontSize: "26px" }}
|
||||
></i>
|
||||
|
||||
<span style={{ fontSize: "12px", fontWeight: "500" }}>
|
||||
{data.Name}
|
||||
</span>
|
||||
</td>
|
||||
<td>{createddate}</td>
|
||||
<td>LegaGenie Draft</td>
|
||||
<td>_</td>
|
||||
<td>_</td>
|
||||
</tr>
|
||||
) : (
|
||||
<tr onClick={() => checkPdfStatus(data)}>
|
||||
<td
|
||||
@@ -464,72 +456,7 @@ function PdfFileComponent({
|
||||
onClick={() => handleMenuItemClick("Rename", data)}
|
||||
className="ContextMenuItem"
|
||||
>
|
||||
<i class="fa-solid fa-font"></i>
|
||||
<span style={{ marginLeft: "8px" }}>Rename</span>
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.Content>
|
||||
</ContextMenu.Portal>
|
||||
</ContextMenu.Root>
|
||||
</div>
|
||||
) : data.Type === "AIDoc" ? (
|
||||
<div key={ind} className="folderBox">
|
||||
<ContextMenu.Root>
|
||||
<ContextMenu.Trigger className="ContextMenuTrigger">
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
cursor: "pointer"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="no img"
|
||||
onClick={() => handleDraftDoc(data)}
|
||||
src={draftDoc}
|
||||
width={100}
|
||||
height={103}
|
||||
/>
|
||||
{rename === data.objectId ? (
|
||||
<input
|
||||
onFocus={() => {
|
||||
inputRef.current.setSelectionRange(0, 0);
|
||||
const input = inputRef.current;
|
||||
if (input) {
|
||||
input.select();
|
||||
}
|
||||
}}
|
||||
autoFocus={true}
|
||||
type="text"
|
||||
onBlur={() => handledRenameDoc(data)}
|
||||
onKeyDown={(e) => handleEnterPress(e, data)}
|
||||
ref={inputRef}
|
||||
defaultValue={renameValue}
|
||||
// value={renameValue}
|
||||
onChange={(e) => setRenameValue(e.target.value)}
|
||||
style={{
|
||||
width: "100px",
|
||||
border: "1.5px solid black",
|
||||
borderRadius: "2px",
|
||||
fontSize: "10px"
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<span className="foldName">{data.Name}</span>
|
||||
)}
|
||||
</div>
|
||||
</ContextMenu.Trigger>
|
||||
|
||||
<ContextMenu.Portal>
|
||||
<ContextMenu.Content
|
||||
className="ContextMenuContent"
|
||||
sideOffset={5}
|
||||
align="end"
|
||||
>
|
||||
<ContextMenu.Item
|
||||
onClick={() => handleMenuItemClick("Rename", data)}
|
||||
className="ContextMenuItem"
|
||||
>
|
||||
<i class="fa-solid fa-font"></i>
|
||||
<i className="fa-solid fa-font"></i>
|
||||
<span style={{ marginLeft: "8px" }}>Rename</span>
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.Content>
|
||||
@@ -615,7 +542,7 @@ function PdfFileComponent({
|
||||
onClick={() => handleMenuItemClick(menu.type, data)}
|
||||
className="ContextMenuItem"
|
||||
>
|
||||
<i class={menu.icon}></i>
|
||||
<i className={menu.icon}></i>
|
||||
<span style={{ marginLeft: "8px" }}>{menu.type}</span>
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
@@ -702,7 +629,7 @@ function PdfFileComponent({
|
||||
)}
|
||||
<ModalUi
|
||||
isOpen={isDeleteDoc}
|
||||
headerColor={themeColor()}
|
||||
headerColor={themeColor}
|
||||
title={"Delete Document"}
|
||||
handleClose={() => {
|
||||
setIsDeleteDoc(false);
|
||||
@@ -726,7 +653,7 @@ function PdfFileComponent({
|
||||
handleDeleteDocument(selectDoc);
|
||||
}}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
type="button"
|
||||
@@ -749,4 +676,4 @@ function PdfFileComponent({
|
||||
);
|
||||
}
|
||||
|
||||
export default PdfFileComponent;
|
||||
export default DriveBody;
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import ModalUi from "../../premitives/ModalUi";
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
|
||||
const AddRoleModal = (props) => {
|
||||
return (
|
||||
@@ -1,7 +1,5 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "./certificate.css";
|
||||
import opensignLogo from "../../assests/open-sign-logo.png";
|
||||
|
||||
import opensignLogo from "../../assets/images/logo.png";
|
||||
import {
|
||||
Page,
|
||||
Text,
|
||||
@@ -18,6 +16,7 @@ function Certificate({ pdfData }) {
|
||||
|
||||
useEffect(() => {
|
||||
handleSignerData();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const handleSignerData = () => {
|
||||
@@ -1,11 +1,6 @@
|
||||
import React from "react";
|
||||
|
||||
function DefaultSignature({
|
||||
themeColor,
|
||||
defaultSignImg,
|
||||
xyPostion,
|
||||
setDefaultSignAlert
|
||||
}) {
|
||||
import { themeColor } from "../../constant/const";
|
||||
function DefaultSignature({ defaultSignImg, xyPostion, setDefaultSignAlert }) {
|
||||
const confirmToaddDefaultSign = () => {
|
||||
if (xyPostion.length > 0) {
|
||||
setDefaultSignAlert({
|
||||
@@ -25,7 +20,7 @@ function DefaultSignature({
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white",
|
||||
padding: "5px",
|
||||
fontFamily: "sans-serif",
|
||||
@@ -58,7 +53,7 @@ function DefaultSignature({
|
||||
</div>
|
||||
<button
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white",
|
||||
marginTop: "20px",
|
||||
cursor: "pointer",
|
||||
@@ -1,12 +1,12 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Loader from "./component/loader";
|
||||
import { contractDocument, getHostUrl } from "../utils/Utils";
|
||||
import Loader from "../../primitives/LoaderWithMsg";
|
||||
import { contractDocument } from "../../constant/Utils";
|
||||
import HandleError from "../../primitives/HandleError";
|
||||
function DraftDocument() {
|
||||
const navigate = useNavigate();
|
||||
const [pdfDetails, setPdfDetails] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState({
|
||||
isLoad: true,
|
||||
isLoader: true,
|
||||
message: "This might take some time"
|
||||
});
|
||||
|
||||
@@ -19,68 +19,77 @@ function DraftDocument() {
|
||||
: rowLevel?.objectId && rowLevel.objectId;
|
||||
|
||||
useEffect(() => {
|
||||
if (docId) {
|
||||
getDocumentDetails();
|
||||
}
|
||||
getDocumentDetails();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
//get document details
|
||||
const getDocumentDetails = async () => {
|
||||
//getting document details
|
||||
const documentData = await contractDocument(docId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
setPdfDetails(documentData);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
handleDraftDoc(documentData);
|
||||
} else if (
|
||||
documentData === "Error: Something went wrong!" ||
|
||||
(documentData.result && documentData.result.error)
|
||||
) {
|
||||
alert("Error: Something went wrong!");
|
||||
setIsLoading({
|
||||
isLoader: false,
|
||||
message: "Error: Something went wrong!"
|
||||
});
|
||||
} else {
|
||||
alert("No data found!");
|
||||
setIsLoading({
|
||||
isLoader: false,
|
||||
message: "No data found!"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//check document type and render on signyour self and placeholder route
|
||||
const handleDraftDoc = () => {
|
||||
const data = pdfDetails[0];
|
||||
const hostUrl = getHostUrl();
|
||||
const handleDraftDoc = (documentData) => {
|
||||
const data = documentData[0];
|
||||
const signerExist = data.Signers && data.Signers;
|
||||
const isDecline = data.IsDeclined && data.IsDeclined;
|
||||
const isPlaceholder = data.Placeholders && data.Placeholders;
|
||||
|
||||
const signedUrl = data.SignedUrl;
|
||||
//checking if document has completed and request signature flow
|
||||
if (data?.IsCompleted && signerExist?.length > 0) {
|
||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
||||
}
|
||||
//checking if document has completed and signyour-self flow
|
||||
else if (!signerExist && !isPlaceholder) {
|
||||
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
|
||||
navigate(`/signaturePdf/${data.objectId}`);
|
||||
}
|
||||
//checking if document has declined by someone
|
||||
else if (isDecline) {
|
||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
||||
//checking draft type document
|
||||
} else if (
|
||||
signerExist?.length > 0 &&
|
||||
isPlaceholder?.length > 0 &&
|
||||
!signedUrl
|
||||
) {
|
||||
navigate(`/placeHolderSign/${data.objectId}`);
|
||||
}
|
||||
//Inprogress document
|
||||
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
|
||||
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
|
||||
navigate(`/pdfRequestFiles/${data.objectId}`);
|
||||
} //placeholder draft document
|
||||
else if (
|
||||
(signerExist?.length > 0 &&
|
||||
(!isPlaceholder || isPlaceholder?.length === 0)) ||
|
||||
((!signerExist || signerExist?.length === 0) && isPlaceholder?.length > 0)
|
||||
) {
|
||||
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
|
||||
navigate(`/placeHolderSign/${data.objectId}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading.isLoad ? <Loader isLoading={isLoading} /> : handleDraftDoc()}
|
||||
{isLoading.isLoader ? (
|
||||
<Loader isLoading={isLoading} />
|
||||
) : (
|
||||
<HandleError handleError={isLoading.message} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from "react";
|
||||
import { getWidgetType, widgets } from "../../constant/Utils";
|
||||
|
||||
function DragElement(item) {
|
||||
const getWidgets = widgets;
|
||||
const filterWidgetPreview = getWidgets.filter(
|
||||
(data) => data.type === item?.text
|
||||
);
|
||||
|
||||
return <div>{getWidgetType(filterWidgetPreview[0])}</div>;
|
||||
}
|
||||
|
||||
export default DragElement;
|
||||
@@ -0,0 +1,425 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { themeColor } from "../../constant/const";
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
import { radioButtonWidget } from "../../constant/Utils";
|
||||
function DropdownWidgetOption(props) {
|
||||
const [dropdownOptionList, setDropdownOptionList] = useState([
|
||||
"option-1",
|
||||
"option-2"
|
||||
]);
|
||||
const [minCount, setMinCount] = useState(0);
|
||||
const [maxCount, setMaxCount] = useState(0);
|
||||
const [dropdownName, setDropdownName] = useState(props.type);
|
||||
const [isReadOnly, setIsReadOnly] = useState(false);
|
||||
const [isHideLabel, setIsHideLabel] = useState(false);
|
||||
const [status, setStatus] = useState("required");
|
||||
const [defaultValue, setDefaultValue] = useState("");
|
||||
const statusArr = ["required", "optional"];
|
||||
const [defaultCheckbox, setDefaultCheckbox] = useState([]);
|
||||
|
||||
const resetState = () => {
|
||||
setDropdownOptionList(["option-1", "option-2"]);
|
||||
setDropdownName(props.type);
|
||||
setIsReadOnly(false);
|
||||
setIsHideLabel(false);
|
||||
setMinCount(0);
|
||||
setMaxCount(0);
|
||||
setDefaultCheckbox([]);
|
||||
setDefaultValue("");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
props.currWidgetsDetails?.options?.name &&
|
||||
props.currWidgetsDetails?.options?.values
|
||||
) {
|
||||
setDropdownName(props.currWidgetsDetails?.options?.name);
|
||||
setDropdownOptionList(props.currWidgetsDetails?.options?.values);
|
||||
setMinCount(
|
||||
props.currWidgetsDetails?.options?.validation?.minRequiredCount
|
||||
);
|
||||
setMaxCount(
|
||||
props.currWidgetsDetails?.options?.validation?.maxRequiredCount
|
||||
);
|
||||
setIsReadOnly(props.currWidgetsDetails?.options?.isReadOnly);
|
||||
setIsHideLabel(props.currWidgetsDetails?.options?.isHideLabel);
|
||||
setStatus(props.currWidgetsDetails?.options?.status || "required");
|
||||
setDefaultValue(props.currWidgetsDetails?.options?.defaultValue || "");
|
||||
setDefaultCheckbox(props.currWidgetsDetails?.options?.defaultValue || []);
|
||||
} else {
|
||||
setStatus("required");
|
||||
resetState();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [props.currWidgetsDetails]);
|
||||
const handleInputChange = (index, value) => {
|
||||
setDropdownOptionList((prevInputs) => {
|
||||
const newInputs = [...prevInputs];
|
||||
newInputs[index] = value;
|
||||
return newInputs;
|
||||
});
|
||||
};
|
||||
|
||||
//function add add checkbox option and add width of checkbox
|
||||
const handleAddInput = () => {
|
||||
const deleteOption = false;
|
||||
const addOption = true;
|
||||
setDropdownOptionList((prevInputs) => [...prevInputs, ""]);
|
||||
props.handleSaveWidgetsOptions(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
addOption,
|
||||
deleteOption
|
||||
);
|
||||
};
|
||||
|
||||
//function add add checkbox option and delete width of checkbox
|
||||
const handleDeleteInput = (ind) => {
|
||||
const deleteOption = true;
|
||||
const addOption = false;
|
||||
const getUpdatedOptions = dropdownOptionList.filter(
|
||||
(data, index) => index !== ind
|
||||
);
|
||||
setDropdownOptionList(getUpdatedOptions);
|
||||
props.handleSaveWidgetsOptions(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
addOption,
|
||||
deleteOption
|
||||
);
|
||||
};
|
||||
|
||||
const handleSaveOption = () => {
|
||||
const defaultData =
|
||||
defaultCheckbox && defaultCheckbox.length > 0
|
||||
? defaultCheckbox
|
||||
: defaultValue;
|
||||
|
||||
props.handleSaveWidgetsOptions(
|
||||
dropdownName,
|
||||
dropdownOptionList,
|
||||
minCount,
|
||||
maxCount,
|
||||
isReadOnly,
|
||||
null,
|
||||
null,
|
||||
status,
|
||||
defaultData,
|
||||
isHideLabel
|
||||
);
|
||||
// props.setShowDropdown(false);
|
||||
setDropdownOptionList(["option-1", "option-2"]);
|
||||
setDropdownName(props.type);
|
||||
// props.setCurrWidgetsDetails({});
|
||||
setIsReadOnly(false);
|
||||
setIsHideLabel(false);
|
||||
setMinCount(0);
|
||||
setMaxCount(0);
|
||||
setDefaultCheckbox([]);
|
||||
setDefaultValue("");
|
||||
};
|
||||
|
||||
const handleSetMinMax = (e) => {
|
||||
const minValue = e.target.value;
|
||||
if (minValue > dropdownOptionList.length) {
|
||||
return "";
|
||||
} else {
|
||||
return minValue;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDefaultCheck = (index) => {
|
||||
const getDefaultCheck = defaultCheckbox.includes(index);
|
||||
if (getDefaultCheck) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
//props.showDropdown
|
||||
<ModalUi
|
||||
// styleClass={"dropdownModal"}
|
||||
isOpen={props.showDropdown}
|
||||
title={props.title}
|
||||
showClose={false}
|
||||
>
|
||||
<div style={{ height: "100%", padding: 20 }}>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
handleSaveOption();
|
||||
}}
|
||||
>
|
||||
<div className="dropdownContainer">
|
||||
<label style={{ fontSize: "13px", fontWeight: "600" }}>
|
||||
Name<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||
</label>
|
||||
<input
|
||||
required
|
||||
defaultValue={dropdownName}
|
||||
value={dropdownName}
|
||||
onChange={(e) => setDropdownName(e.target.value)}
|
||||
className="drodown-input"
|
||||
/>
|
||||
|
||||
<label
|
||||
style={{ fontSize: "13px", fontWeight: "600", marginTop: "5px" }}
|
||||
>
|
||||
Options
|
||||
</label>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column"
|
||||
}}
|
||||
>
|
||||
{dropdownOptionList.map((option, index) => (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
marginBottom: "5px",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
{props.type === "checkbox" && !props.isSignYourself && (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={handleDefaultCheck(index)}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
const getDefaultCheck =
|
||||
defaultCheckbox?.includes(index);
|
||||
if (!getDefaultCheck) {
|
||||
setDefaultCheckbox((prev) => [...prev, index]);
|
||||
}
|
||||
} else {
|
||||
const removeOption = defaultCheckbox.filter(
|
||||
(data) => data !== index
|
||||
);
|
||||
setDefaultCheckbox(removeOption);
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
width: "23px",
|
||||
height: "19px",
|
||||
marginRight: "5px"
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<input
|
||||
required
|
||||
className="drodown-input"
|
||||
type="text"
|
||||
value={option}
|
||||
onChange={(e) => handleInputChange(index, e.target.value)}
|
||||
/>
|
||||
|
||||
<i
|
||||
className="fa-solid fa-rectangle-xmark"
|
||||
onClick={() => handleDeleteInput(index)}
|
||||
style={{
|
||||
color: "red",
|
||||
fontSize: "25px",
|
||||
marginLeft: "10px"
|
||||
}}
|
||||
></i>
|
||||
</div>
|
||||
))}
|
||||
<i
|
||||
onClick={handleAddInput}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
color: themeColor,
|
||||
fontSize: "25px",
|
||||
marginLeft: "10px"
|
||||
}}
|
||||
className="fa-solid fa-square-plus"
|
||||
></i>
|
||||
{props.type === "checkbox" && !props.isSignYourself && (
|
||||
<>
|
||||
<label style={{ fontSize: "13px", fontWeight: "600" }}>
|
||||
Minimun check
|
||||
</label>
|
||||
<input
|
||||
required
|
||||
defaultValue={0}
|
||||
value={minCount}
|
||||
onChange={(e) => {
|
||||
const count = handleSetMinMax(e);
|
||||
setMinCount(count);
|
||||
}}
|
||||
className="drodown-input"
|
||||
/>
|
||||
<label style={{ fontSize: "13px", fontWeight: "600" }}>
|
||||
Maximum check
|
||||
</label>
|
||||
<input
|
||||
required
|
||||
defaultValue={0}
|
||||
value={maxCount}
|
||||
onChange={(e) => {
|
||||
const count = handleSetMinMax(e);
|
||||
setMaxCount(count);
|
||||
}}
|
||||
className="drodown-input"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{["dropdown", radioButtonWidget].includes(props.type) && (
|
||||
<>
|
||||
<label
|
||||
style={{
|
||||
fontSize: "13px",
|
||||
fontWeight: "600",
|
||||
marginTop: "5px"
|
||||
}}
|
||||
>
|
||||
Default value
|
||||
</label>
|
||||
<select
|
||||
onChange={(e) => setDefaultValue(e.target.value)}
|
||||
className="drodown-input"
|
||||
name="defaultvalue"
|
||||
value={defaultValue}
|
||||
placeholder="select default value"
|
||||
>
|
||||
<option value="" disabled hidden style={{ fontSize: "13px" }}>
|
||||
Select...
|
||||
</option>
|
||||
{dropdownOptionList.map((data, ind) => {
|
||||
return (
|
||||
<option
|
||||
style={{ fontSize: "13px" }}
|
||||
key={ind}
|
||||
value={data}
|
||||
>
|
||||
{data}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</>
|
||||
)}
|
||||
{props.type !== "checkbox" && props.type !== radioButtonWidget && (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
marginTop: "0.5rem"
|
||||
}}
|
||||
>
|
||||
{statusArr.map((data, ind) => {
|
||||
return (
|
||||
<div
|
||||
key={ind}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 5,
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<input
|
||||
style={{ accentColor: "red" }}
|
||||
type="radio"
|
||||
name="status"
|
||||
onChange={() => setStatus(data.toLowerCase())}
|
||||
checked={status.toLowerCase() === data.toLowerCase()}
|
||||
/>
|
||||
<div style={{ fontSize: "13px", fontWeight: "500" }}>
|
||||
{data}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{["checkbox", radioButtonWidget].includes(props.type) && (
|
||||
<div className="flex flex-row gap-5 mt-2 items-center text-center">
|
||||
{!props.isSignYourself && (
|
||||
<div>
|
||||
<input
|
||||
id="isreadonly"
|
||||
type="checkbox"
|
||||
checked={isReadOnly}
|
||||
onChange={(e) => {
|
||||
setIsReadOnly(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
<label className="ml-1" htmlFor="isreadonly">
|
||||
Is read only
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<input
|
||||
id="ishidelabel"
|
||||
type="checkbox"
|
||||
checked={isHideLabel}
|
||||
onChange={(e) => {
|
||||
setIsHideLabel(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
|
||||
<label className="ml-1" htmlFor="ishidelabel">
|
||||
Hide labels
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
height: "1px",
|
||||
backgroundColor: "#9f9f9f",
|
||||
width: "100%",
|
||||
marginTop: "15px",
|
||||
marginBottom: "15px"
|
||||
}}
|
||||
></div>
|
||||
<button
|
||||
// onClick={() => handleSaveOption()}
|
||||
disabled={dropdownOptionList.length === 0 && true}
|
||||
style={{
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
type="submit"
|
||||
className={"finishBtn"}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
{props.currWidgetsDetails?.options?.values?.length > 0 && (
|
||||
<button
|
||||
type="submit"
|
||||
className="finishBtn cancelBtn"
|
||||
onClick={() => {
|
||||
props.handleClose && props.handleClose();
|
||||
resetState();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
</ModalUi>
|
||||
);
|
||||
}
|
||||
|
||||
export default DropdownWidgetOption;
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import "../../css/AddUser.css";
|
||||
import "../../styles/AddUser.css";
|
||||
// import SelectFolder from "../../premitives/SelectFolder";
|
||||
|
||||
const EditTemplate = ({ template, onSuccess }) => {
|
||||
@@ -45,7 +45,7 @@ const EditTemplate = ({ template, onSuccess }) => {
|
||||
fontWeight: "700"
|
||||
}}
|
||||
>
|
||||
{template.URL?.split("/")[3]?.split("_")[1]}
|
||||
{template.URL?.split("/")?.pop()?.split("_")[1]}
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-section">
|
||||
@@ -1,11 +1,11 @@
|
||||
import React, { useState } from "react";
|
||||
import { saveAs } from "file-saver";
|
||||
import celebration from "../../assests/newCeleb.gif";
|
||||
import celebration from "../../assets/images/newCeleb.gif";
|
||||
import axios from "axios";
|
||||
import { getBase64FromUrl } from "../../utils/Utils";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import { getBase64FromUrl } from "../../constant/Utils";
|
||||
import { themeColor } from "../../constant/const";
|
||||
import printModule from "print-js";
|
||||
import loader from "../../assests/loader2.gif";
|
||||
import loader from "../../assets/images/loader2.gif";
|
||||
|
||||
function EmailComponent({
|
||||
isEmail,
|
||||
@@ -28,7 +28,6 @@ function EmailComponent({
|
||||
try {
|
||||
const imgPng =
|
||||
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
||||
// "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png";
|
||||
|
||||
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3/`;
|
||||
const headers = {
|
||||
@@ -37,7 +36,7 @@ function EmailComponent({
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
const openSignUrl = "https://www.opensignlabs.com/contact-us";
|
||||
const themeBGcolor = themeColor();
|
||||
const themeBGcolor = themeColor;
|
||||
let params = {
|
||||
pdfName: pdfName,
|
||||
url: pdfUrl,
|
||||
@@ -362,7 +361,7 @@ function EmailComponent({
|
||||
>
|
||||
<i
|
||||
style={{
|
||||
backgroundColor: themeColor(),
|
||||
backgroundColor: themeColor,
|
||||
padding: "5px 7px",
|
||||
marginTop: "10px",
|
||||
color: "white",
|
||||
@@ -399,7 +398,7 @@ function EmailComponent({
|
||||
<button
|
||||
disabled={emailList.length === 0 && true}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
type="button"
|
||||
@@ -1,14 +1,14 @@
|
||||
import React from "react";
|
||||
import PrevNext from "./prevNext";
|
||||
import PrevNext from "./PrevNext";
|
||||
import { PDFDownloadLink } from "@react-pdf/renderer";
|
||||
import Certificate from "../Certificate/Certificate";
|
||||
import Certificate from "./Certificate";
|
||||
import printModule from "print-js";
|
||||
import { getBase64FromUrl } from "../../utils/Utils";
|
||||
import { getBase64FromUrl } from "../../constant/Utils";
|
||||
import { saveAs } from "file-saver";
|
||||
import "../../css/signature.css";
|
||||
import "../../styles/signature.css";
|
||||
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import { themeColor } from "../../constant/const";
|
||||
|
||||
function Header({
|
||||
isPdfRequestFiles,
|
||||
@@ -21,7 +21,7 @@ function Header({
|
||||
changePage,
|
||||
pdfUrl,
|
||||
documentStatus,
|
||||
embedImages,
|
||||
embedWidgetsData,
|
||||
pdfDetails,
|
||||
signerPos,
|
||||
signersdata,
|
||||
@@ -38,6 +38,8 @@ function Header({
|
||||
completeBtnTitle,
|
||||
setIsEditTemplate
|
||||
}) {
|
||||
const filterPrefill =
|
||||
signerPos && signerPos?.filter((data) => data.Role !== "prefill");
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const navigate = useNavigate();
|
||||
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||
@@ -119,7 +121,7 @@ function Header({
|
||||
style={{ textDecoration: "none", zIndex: "35" }}
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
>
|
||||
{({ blob, url, loading, error }) => (
|
||||
{({ blob, loading }) => (
|
||||
<>
|
||||
{loading ? (
|
||||
<div
|
||||
@@ -129,20 +131,15 @@ function Header({
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
marginRight: "2px"
|
||||
}}
|
||||
className="fa-solid fa-award"
|
||||
style={{ marginRight: "2px" }}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
border: "none",
|
||||
backgroundColor: "#fff"
|
||||
}}
|
||||
style={{ border: "none", backgroundColor: "#fff" }}
|
||||
onClick={() =>
|
||||
handleDownload(
|
||||
blob,
|
||||
@@ -153,10 +150,8 @@ function Header({
|
||||
}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
marginRight: "2px"
|
||||
}}
|
||||
className="fa-solid fa-award"
|
||||
style={{ marginRight: "2px" }}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
@@ -176,51 +171,29 @@ function Header({
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
{({ loading }) => (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
disabled={loading}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa-solid fa-award"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)}
|
||||
</PDFDownloadLink>
|
||||
);
|
||||
};
|
||||
@@ -245,7 +218,7 @@ function Header({
|
||||
<i
|
||||
className="fa fa-arrow-left"
|
||||
aria-hidden="true"
|
||||
style={{ color: themeColor(), cursor: "pointer" }}
|
||||
style={{ color: themeColor, cursor: "pointer" }}
|
||||
></i>
|
||||
</div>
|
||||
<div>
|
||||
@@ -283,7 +256,7 @@ function Header({
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<div
|
||||
style={{
|
||||
color: themeColor(),
|
||||
color: themeColor,
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px",
|
||||
@@ -407,7 +380,7 @@ function Header({
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
color: isMailSend ? "gray" : themeColor(),
|
||||
color: isMailSend ? "gray" : themeColor,
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px"
|
||||
@@ -421,13 +394,13 @@ function Header({
|
||||
data-tut="reactourThird"
|
||||
onClick={() => {
|
||||
if (!pdfUrl) {
|
||||
embedImages();
|
||||
embedWidgetsData();
|
||||
} else if (isPdfRequestFiles) {
|
||||
embedImages();
|
||||
embedWidgetsData();
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
color: themeColor(),
|
||||
color: themeColor,
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px"
|
||||
@@ -453,7 +426,7 @@ function Header({
|
||||
{recipient ? (
|
||||
pdfUrl || isAlreadySign.mssg ? (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
{pdfDetails[0] && pdfDetails.length > 0 && (
|
||||
{pdfDetails && pdfDetails.length > 0 && (
|
||||
<CertificateComponent />
|
||||
)}
|
||||
<button
|
||||
@@ -521,7 +494,7 @@ function Header({
|
||||
className="finishBtn sendHover"
|
||||
onClick={() => {
|
||||
if (!pdfUrl) {
|
||||
embedImages();
|
||||
embedWidgetsData();
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -533,16 +506,16 @@ function Header({
|
||||
<>
|
||||
{!isMailSend &&
|
||||
signersdata.length > 0 &&
|
||||
signersdata.length !== signerPos.length && (
|
||||
signersdata.length !== filterPrefill.length && (
|
||||
<div>
|
||||
{signerPos.length === 0 ? (
|
||||
{filterPrefill.length === 0 ? (
|
||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
||||
Add {signersdata.length - signerPos.length} recipients
|
||||
signature
|
||||
Add {signersdata.length - filterPrefill.length}{" "}
|
||||
recipients signature
|
||||
</span>
|
||||
) : (
|
||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
||||
Add {signersdata.length - signerPos.length} more
|
||||
Add {signersdata.length - filterPrefill.length} more
|
||||
recipients signature
|
||||
</span>
|
||||
)}
|
||||
@@ -667,7 +640,7 @@ function Header({
|
||||
type="button"
|
||||
className="finishBtn sendHover"
|
||||
onClick={() => {
|
||||
embedImages();
|
||||
embedWidgetsData();
|
||||
}}
|
||||
>
|
||||
Finish
|
||||
@@ -765,7 +738,7 @@ function Header({
|
||||
className="finishBtn sendHover"
|
||||
onClick={() => {
|
||||
if (!pdfUrl) {
|
||||
embedImages();
|
||||
embedWidgetsData();
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -0,0 +1,728 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import BorderResize from "./BorderResize";
|
||||
import PlaceholderBorder from "./PlaceholderBorder";
|
||||
import { Rnd } from "react-rnd";
|
||||
import {
|
||||
defaultWidthHeight,
|
||||
isMobile,
|
||||
onChangeInput,
|
||||
radioButtonWidget,
|
||||
textInputWidget,
|
||||
textWidget
|
||||
} from "../../constant/Utils";
|
||||
import PlaceholderType from "./PlaceholderType";
|
||||
import moment from "moment";
|
||||
import "../../styles/opensigndrive.css";
|
||||
|
||||
const selectFormat = (data) => {
|
||||
switch (data) {
|
||||
case "L":
|
||||
return "MM/dd/yyyy";
|
||||
case "DD-MM-YYYY":
|
||||
return "dd-MM-yyyy";
|
||||
case "DD/MM/YYYY":
|
||||
return "dd/MM/yyyy";
|
||||
case "LL":
|
||||
return "MMMM dd, yyyy";
|
||||
case "DD MMM, YYYY":
|
||||
return "dd MMM, yyyy";
|
||||
case "YYYY-MM-DD":
|
||||
return "yyyy-MM-dd";
|
||||
case "MM-DD-YYYY":
|
||||
return "MM-dd-yyyy";
|
||||
case "MM.DD.YYYY":
|
||||
return "MM.dd.yyyy";
|
||||
case "MMM DD, YYYY":
|
||||
return "MMM dd, yyyy";
|
||||
case "DD MMMM, YYYY":
|
||||
return "dd MMMM, yyyy";
|
||||
default:
|
||||
return "MM/dd/yyyy";
|
||||
}
|
||||
};
|
||||
|
||||
const changeDateToMomentFormat = (format) => {
|
||||
switch (format) {
|
||||
case "MM/dd/yyyy":
|
||||
return "L";
|
||||
case "dd-MM-yyyy":
|
||||
return "DD-MM-YYYY";
|
||||
case "dd/MM/yyyy":
|
||||
return "DD/MM/YYYY";
|
||||
case "MMMM dd, yyyy":
|
||||
return "LL";
|
||||
case "dd MMM, yyyy":
|
||||
return "DD MMM, YYYY";
|
||||
case "yyyy-MM-dd":
|
||||
return "YYYY-MM-DD";
|
||||
case "MM-dd-yyyy":
|
||||
return "MM-DD-YYYY";
|
||||
case "MM.dd.yyyy":
|
||||
return "MM.DD.YYYY";
|
||||
case "MMM dd, yyyy":
|
||||
return "MMM DD, YYYY";
|
||||
case "dd MMMM, yyyy":
|
||||
return "DD MMMM, YYYY";
|
||||
default:
|
||||
return "L";
|
||||
}
|
||||
};
|
||||
|
||||
//function to get default date
|
||||
const getDefaultdate = (selectedDate, format = "dd-MM-yyyy") => {
|
||||
let date;
|
||||
if (format && format === "dd-MM-yyyy") {
|
||||
const newdate = selectedDate
|
||||
? selectedDate
|
||||
: moment(new Date()).format(changeDateToMomentFormat(format));
|
||||
const [day, month, year] = newdate.split("-");
|
||||
date = new Date(`${year}-${month}-${day}`);
|
||||
} else {
|
||||
date = new Date(selectedDate);
|
||||
}
|
||||
const value = date;
|
||||
return value;
|
||||
};
|
||||
//function to get default format
|
||||
const getDefaultFormat = (dateFormat) => dateFormat || "MM/dd/yyyy";
|
||||
|
||||
function Placeholder(props) {
|
||||
const [isDraggingEnabled, setDraggingEnabled] = useState(true);
|
||||
const [isShowDateFormat, setIsShowDateFormat] = useState(false);
|
||||
const [selectDate, setSelectDate] = useState({
|
||||
date:
|
||||
props.pos.type === "date"
|
||||
? moment(
|
||||
getDefaultdate(
|
||||
props?.pos?.options?.response,
|
||||
props.pos?.options?.validation?.format
|
||||
).getTime()
|
||||
).format(
|
||||
changeDateToMomentFormat(props.pos?.options?.validation?.format)
|
||||
)
|
||||
: "",
|
||||
format:
|
||||
props.pos.type === "date"
|
||||
? getDefaultFormat(props.pos?.options?.validation?.format)
|
||||
: ""
|
||||
});
|
||||
const [dateFormat, setDateFormat] = useState([]);
|
||||
const [startDate, setStartDate] = useState(
|
||||
props.pos.type === "date" &&
|
||||
getDefaultdate(
|
||||
props?.pos?.options?.response,
|
||||
props.pos?.options?.validation?.format
|
||||
)
|
||||
);
|
||||
const [getCheckboxRenderWidth, setGetCheckboxRenderWidth] = useState({
|
||||
width: null,
|
||||
height: null
|
||||
});
|
||||
const dateFormatArr = [
|
||||
"L",
|
||||
"DD-MM-YYYY",
|
||||
"YYYY-MM-DD",
|
||||
"MM.DD.YYYY",
|
||||
"MM-DD-YYYY",
|
||||
"MMM DD, YYYY",
|
||||
"LL",
|
||||
"DD MMM, YYYY",
|
||||
"DD MMMM, YYYY"
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
const updateWidth = () => {
|
||||
const rndElement = document.getElementById(props.pos.key);
|
||||
if (rndElement) {
|
||||
const { width, height } = rndElement.getBoundingClientRect();
|
||||
setGetCheckboxRenderWidth({ width: width, height: height });
|
||||
}
|
||||
};
|
||||
|
||||
// Delay to ensure rendering is complete
|
||||
const timer = setTimeout(updateWidth, 0);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [props.pos]);
|
||||
|
||||
useEffect(() => {
|
||||
const closeMenuOnOutsideClick = (e) => {
|
||||
if (!isDraggingEnabled && !e.target.closest("#changeIsDragging")) {
|
||||
setDraggingEnabled(true);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("click", closeMenuOnOutsideClick);
|
||||
|
||||
return () => {
|
||||
// Cleanup the event listener when the component unmounts
|
||||
document.removeEventListener("click", closeMenuOnOutsideClick);
|
||||
};
|
||||
}, [isDraggingEnabled]);
|
||||
//function change format array list with selected date and format
|
||||
const changeDateFormat = () => {
|
||||
const updateDate = [];
|
||||
dateFormatArr.map((data) => {
|
||||
let date;
|
||||
if (selectDate && selectDate.format === "dd-MM-yyyy") {
|
||||
const [day, month, year] = selectDate.date.split("-");
|
||||
date = new Date(`${year}-${month}-${day}`);
|
||||
} else {
|
||||
date = new Date(selectDate?.date);
|
||||
}
|
||||
const milliseconds = date.getTime();
|
||||
const newDate = moment(milliseconds).format(data);
|
||||
const dateObj = {
|
||||
date: newDate,
|
||||
format: selectFormat(data)
|
||||
};
|
||||
updateDate.push(dateObj);
|
||||
});
|
||||
setDateFormat(updateDate);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (props.isPlaceholder || props.isSignYourself) {
|
||||
selectDate && changeDateFormat();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectDate]);
|
||||
|
||||
//it detect outside click of date dropdown menu
|
||||
useEffect(() => {
|
||||
const closeMenuOnOutsideClick = (e) => {
|
||||
if (isShowDateFormat && !e.target.closest("#menu-container")) {
|
||||
setIsShowDateFormat(!isShowDateFormat);
|
||||
}
|
||||
};
|
||||
document.addEventListener("click", closeMenuOnOutsideClick);
|
||||
return () => {
|
||||
// Cleanup the event listener when the component unmounts
|
||||
document.removeEventListener("click", closeMenuOnOutsideClick);
|
||||
};
|
||||
}, [isShowDateFormat]);
|
||||
|
||||
//`handleWidgetIdandPopup` is used to set current widget id and open relative popup
|
||||
const handleWidgetIdandPopup = () => {
|
||||
if (props.setSelectWidgetId) {
|
||||
props.setSelectWidgetId(props.pos.key);
|
||||
}
|
||||
|
||||
const widgetTypeExist = [
|
||||
textInputWidget,
|
||||
"checkbox",
|
||||
"name",
|
||||
"company",
|
||||
"job title",
|
||||
"date",
|
||||
"email",
|
||||
textWidget
|
||||
].includes(props.pos.type);
|
||||
|
||||
if (widgetTypeExist) {
|
||||
setDraggingEnabled(false);
|
||||
}
|
||||
if ((props.isNeedSign || props.isSignYourself) && !props.isDragging) {
|
||||
if (props.pos.type) {
|
||||
if (
|
||||
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 (
|
||||
props.isPlaceholder &&
|
||||
!props.isDragging &&
|
||||
props.pos.type !== textWidget
|
||||
) {
|
||||
if (props.pos.key === props.selectWidgetId) {
|
||||
props.handleLinkUser(props.data.Id);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}
|
||||
} else if (!props.pos.type) {
|
||||
if (
|
||||
!props.pos.type &&
|
||||
props.isNeedSign &&
|
||||
props.data.signerObjId === props.signerObjId
|
||||
) {
|
||||
props.setIsSignPad(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setIsStamp(props.pos.isStamp);
|
||||
} else if (
|
||||
(props.isNeedSign && props.pos.type === "signature") ||
|
||||
props.pos.type === "stamp"
|
||||
) {
|
||||
props.setIsSignPad(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setIsStamp(props.pos.isStamp);
|
||||
} else if (props.isNeedSign && props.pos.type === "dropdown") {
|
||||
props.setSignKey(props.pos.key);
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleOnClickPlaceholder = () => {
|
||||
if (!props.isNeedSign) {
|
||||
props.setWidgetType(props.pos.type);
|
||||
}
|
||||
if (props.isNeedSign && props.data?.signerObjId === props.signerObjId) {
|
||||
handleWidgetIdandPopup();
|
||||
} else if (props.isPlaceholder || props.isSignYourself) {
|
||||
handleWidgetIdandPopup();
|
||||
}
|
||||
};
|
||||
//`handleOnClickSettingIcon` is used set current widget details and open setting of it
|
||||
const handleOnClickSettingIcon = () => {
|
||||
if (props.pos.type === radioButtonWidget) {
|
||||
props.setIsRadio(true);
|
||||
} else if (props.pos.type === "dropdown") {
|
||||
props?.setShowDropdown(true);
|
||||
} else if (props.pos.type === "checkbox") {
|
||||
props?.setIsCheckbox(true);
|
||||
} else {
|
||||
props?.handleNameModal(true);
|
||||
}
|
||||
|
||||
if (props.isPlaceholder && props.type !== textWidget) {
|
||||
props.setUniqueId(props.data.Id);
|
||||
}
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setWidgetType(props.pos.type);
|
||||
props.setCurrWidgetsDetails(props.pos);
|
||||
};
|
||||
//function ro set state value of onclick on widget's copy icon
|
||||
const handleCopyPlaceholder = (e) => {
|
||||
if (props.data && props?.pos?.type !== textWidget) {
|
||||
props.setSignerObjId(props?.data?.signerObjId);
|
||||
props.setUniqueId(props?.data?.Id);
|
||||
} else if (props.data && props.pos.type === textWidget) {
|
||||
props.setTempSignerId(props.uniqueId);
|
||||
props.setSignerObjId(props?.data?.signerObjId);
|
||||
props.setUniqueId(props?.data?.Id);
|
||||
}
|
||||
e.stopPropagation();
|
||||
props.setIsPageCopy(true);
|
||||
props.setSignKey(props.pos.key);
|
||||
};
|
||||
|
||||
//function to save date and format on local array onchange date and onclick format
|
||||
const handleSaveDate = (data, isDateChange) => {
|
||||
let updateDate = data.date;
|
||||
//check if date change by user
|
||||
if (isDateChange) {
|
||||
//`changeDateToMomentFormat` is used to convert date as per required to moment package
|
||||
updateDate = moment(data.date).format(
|
||||
changeDateToMomentFormat(data.format)
|
||||
);
|
||||
}
|
||||
//using moment package is used to change date as per the format provided in selectDate obj e.g. - MM/dd/yyyy -> 03/12/2024
|
||||
//`getDefaultdate` is used to convert update date in new Date() format
|
||||
const date = moment(
|
||||
getDefaultdate(updateDate, data?.format).getTime()
|
||||
).format(changeDateToMomentFormat(data?.format));
|
||||
|
||||
//`onChangeInput` is used to save data related to date in a placeholder field
|
||||
onChangeInput(
|
||||
date,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data.Id,
|
||||
false,
|
||||
data?.format
|
||||
);
|
||||
setSelectDate({ date: date, format: data?.format });
|
||||
};
|
||||
const PlaceholderIcon = () => {
|
||||
return (
|
||||
props.isShowBorder && (
|
||||
<>
|
||||
{(props.isPlaceholder || props.isSignYourself) && (
|
||||
<>
|
||||
{props.pos.type === "checkbox" && props.isSignYourself ? (
|
||||
<i
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleOnClickSettingIcon();
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
handleOnClickSettingIcon();
|
||||
}}
|
||||
className="fa-solid fa-gear settingIcon"
|
||||
style={{
|
||||
color: "#188ae2",
|
||||
right: "29px",
|
||||
top: "-19px"
|
||||
}}
|
||||
></i>
|
||||
) : (
|
||||
((!props?.pos?.type && props.pos.isStamp) ||
|
||||
(props?.pos?.type &&
|
||||
!["date", textWidget, "signature"].includes(
|
||||
props.pos.type
|
||||
) &&
|
||||
!props.isSignYourself)) && (
|
||||
<i
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleOnClickSettingIcon();
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
handleOnClickSettingIcon();
|
||||
}}
|
||||
className="fa-solid fa-gear settingIcon"
|
||||
style={{ color: "#188ae2", right: "47px", top: "-19px" }}
|
||||
></i>
|
||||
)
|
||||
)}
|
||||
|
||||
{props.pos.type !== textWidget && !props.isSignYourself && (
|
||||
<i
|
||||
data-tut="reactourLinkUser"
|
||||
className="fa-regular fa-user signUserIcon"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
props.handleLinkUser(props.data.Id);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
props.handleLinkUser(props.data.Id);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
style={{ color: "#188ae2", right: "32px", top: "-18px" }}
|
||||
></i>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{props.pos.type === "date" && selectDate && (
|
||||
<div
|
||||
id="menu-container"
|
||||
style={{
|
||||
zIndex: "99",
|
||||
top: "-19px",
|
||||
right: props.isPlaceholder ? "60px" : "44px"
|
||||
}}
|
||||
className={
|
||||
isShowDateFormat
|
||||
? "dropdown signUserIcon show"
|
||||
: "dropdown signUserIcon"
|
||||
}
|
||||
onClick={(e) => {
|
||||
setIsShowDateFormat(!isShowDateFormat);
|
||||
e.stopPropagation();
|
||||
if (props.data) {
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsShowDateFormat(!isShowDateFormat);
|
||||
if (props.data) {
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa-solid fa-gear settingIcon"
|
||||
style={{
|
||||
color: "#188ae2",
|
||||
fontSize: "14px"
|
||||
}}
|
||||
></i>
|
||||
<div
|
||||
className={
|
||||
isShowDateFormat ? "dropdown-menu show" : "dropdown-menu"
|
||||
}
|
||||
aria-labelledby="dropdownMenuButton"
|
||||
aria-expanded={isShowDateFormat ? "true" : "false"}
|
||||
>
|
||||
{dateFormat.map((data, ind) => {
|
||||
return (
|
||||
<span
|
||||
key={ind}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsShowDateFormat(!isShowDateFormat);
|
||||
setSelectDate(data);
|
||||
handleSaveDate(data);
|
||||
}}
|
||||
onClick={() => {
|
||||
setIsShowDateFormat(!isShowDateFormat);
|
||||
setSelectDate(data);
|
||||
handleSaveDate(data);
|
||||
}}
|
||||
className="dropdown-item itemColor"
|
||||
style={{ fontSize: "12px" }}
|
||||
>
|
||||
{data?.date ? data?.date : "nodata"}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<i
|
||||
className="fa-regular fa-copy signCopy"
|
||||
onClick={(e) => handleCopyPlaceholder(e)}
|
||||
onTouchEnd={(e) => handleCopyPlaceholder(e)}
|
||||
style={{ color: "#188ae2", right: "12px", top: "-18px" }}
|
||||
></i>
|
||||
<i
|
||||
className="fa-regular fa-circle-xmark signCloseBtn"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (props.data) {
|
||||
props.handleDeleteSign(props.pos.key, props.data.Id);
|
||||
} else {
|
||||
props.handleDeleteSign(props.pos.key);
|
||||
props.setIsStamp(false);
|
||||
}
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
if (props.data) {
|
||||
props.handleDeleteSign(props.pos.key, props.data?.Id);
|
||||
} else {
|
||||
props.handleDeleteSign(props.pos.key);
|
||||
props.setIsStamp(false);
|
||||
}
|
||||
}}
|
||||
style={{ color: "#188ae2", right: "-8px", top: "-18px" }}
|
||||
></i>
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Rnd
|
||||
id={props.pos.key}
|
||||
data-tut={props.pos.key === props.unSignedWidgetId ? "IsSigned" : ""}
|
||||
key={props.pos.key}
|
||||
lockAspectRatio={
|
||||
props.pos.type !== textWidget &&
|
||||
(props.pos.Width
|
||||
? props.pos.Width / props.pos.Height
|
||||
: defaultWidthHeight(props.pos.type).width /
|
||||
defaultWidthHeight(props.pos.type).height)
|
||||
}
|
||||
enableResizing={{
|
||||
top: false,
|
||||
right: false,
|
||||
bottom: false,
|
||||
left: false,
|
||||
topRight: false,
|
||||
bottomRight:
|
||||
props.data && props.isNeedSign
|
||||
? props.data?.signerObjId === props.signerObjId &&
|
||||
props.pos.type !== "checkbox" &&
|
||||
props.pos.type !== radioButtonWidget
|
||||
? true
|
||||
: false
|
||||
: props.pos.type !== radioButtonWidget &&
|
||||
props.pos.type !== "checkbox" &&
|
||||
props.pos.key === props.selectWidgetId &&
|
||||
true,
|
||||
bottomLeft: false,
|
||||
topLeft: false
|
||||
}}
|
||||
bounds="parent"
|
||||
className="signYourselfBlock"
|
||||
style={{
|
||||
border: "1px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
textAlign:
|
||||
props.pos.type !== "name" &&
|
||||
props.pos.type !== "company" &&
|
||||
props.pos.type !== "job title" &&
|
||||
"center",
|
||||
cursor:
|
||||
props.data && props.isNeedSign
|
||||
? props.data?.signerObjId === props.signerObjId
|
||||
? "pointer"
|
||||
: "not-allowed"
|
||||
: "all-scroll",
|
||||
zIndex:
|
||||
props.pos.type === "date"
|
||||
? props.pos.key === props.selectWidgetId
|
||||
? 99 + 1
|
||||
: 99
|
||||
: props?.pos?.zIndex
|
||||
? props.pos.zIndex
|
||||
: "5",
|
||||
background: props.data ? props.data.blockColor : "rgb(203 233 237)"
|
||||
}}
|
||||
onDrag={() => {
|
||||
setDraggingEnabled(true);
|
||||
props.handleTabDrag && props.handleTabDrag(props.pos.key);
|
||||
}}
|
||||
size={{
|
||||
width:
|
||||
props.pos.type === radioButtonWidget || props.pos.type === "checkbox"
|
||||
? "auto"
|
||||
: props.posWidth(props.pos, props.isSignYourself),
|
||||
height:
|
||||
props.pos.type === radioButtonWidget || props.pos.type === "checkbox"
|
||||
? "auto"
|
||||
: props.posHeight(props.pos, props.isSignYourself)
|
||||
}}
|
||||
onResizeStart={() => {
|
||||
setDraggingEnabled(true);
|
||||
props.setIsResize && props.setIsResize(true);
|
||||
}}
|
||||
onResizeStop={() => {
|
||||
props.setIsResize && props.setIsResize(false);
|
||||
}}
|
||||
disableDragging={
|
||||
props.isNeedSign
|
||||
? true
|
||||
: props.isPlaceholder && ![textWidget].includes(props.pos.type)
|
||||
? false
|
||||
: !isDraggingEnabled
|
||||
}
|
||||
onDragStop={(event, dragElement) =>
|
||||
props.handleStop &&
|
||||
props.handleStop(event, dragElement, props.data?.Id, props.pos?.key)
|
||||
}
|
||||
default={{
|
||||
x: props.xPos(props.pos, props.isSignYourself),
|
||||
y: props.yPos(props.pos, props.isSignYourself)
|
||||
}}
|
||||
onResize={(e, direction, ref) => {
|
||||
props.handleSignYourselfImageResize &&
|
||||
props.handleSignYourselfImageResize(
|
||||
ref,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.setXyPostion,
|
||||
props.index,
|
||||
props.data && props.data.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
onClick={() => handleOnClickPlaceholder()}
|
||||
>
|
||||
{props.isShowBorder &&
|
||||
props.pos.type !== radioButtonWidget &&
|
||||
props.pos.type !== "checkbox" &&
|
||||
props.pos.key === props.selectWidgetId ? (
|
||||
<BorderResize right={-12} top={-11} />
|
||||
) : props.data && props.isNeedSign && props.pos.type !== "checkbox" ? (
|
||||
props.data?.signerObjId === props.signerObjId &&
|
||||
props.pos.type !== radioButtonWidget &&
|
||||
props.pos.type !== "checkbox" ? (
|
||||
<BorderResize />
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
) : (
|
||||
props.pos.type !== radioButtonWidget &&
|
||||
props.pos.type !== "checkbox" &&
|
||||
props.pos.key === props.selectWidgetId && <BorderResize />
|
||||
)}
|
||||
|
||||
{props.isShowBorder && props.pos.key === props.selectWidgetId && (
|
||||
<PlaceholderBorder
|
||||
setDraggingEnabled={setDraggingEnabled}
|
||||
pos={props.pos}
|
||||
isPlaceholder={props.isPlaceholder}
|
||||
getCheckboxRenderWidth={getCheckboxRenderWidth}
|
||||
/>
|
||||
)}
|
||||
{isMobile ? (
|
||||
<div
|
||||
style={{
|
||||
left: props.xPos(props.pos, props.isSignYourself),
|
||||
top: props.yPos(props.pos, props.isSignYourself),
|
||||
width:
|
||||
props.pos.type === radioButtonWidget ||
|
||||
props.pos.type === "checkbox"
|
||||
? "auto"
|
||||
: props.posWidth(props.pos, props.isSignYourself),
|
||||
// "auto", //props.posWidth(props.pos, props.isSignYourself),
|
||||
// height: props.posHeight(props.pos, props.isSignYourself),
|
||||
height:
|
||||
props.pos.type === radioButtonWidget ||
|
||||
props.pos.type === "checkbox"
|
||||
? "auto"
|
||||
: props.posHeight(props.pos, props.isSignYourself),
|
||||
zIndex: "10"
|
||||
}}
|
||||
onTouchEnd={() => handleOnClickPlaceholder()}
|
||||
>
|
||||
{props.pos.key === props.selectWidgetId && <PlaceholderIcon />}
|
||||
|
||||
<PlaceholderType
|
||||
pos={props.pos}
|
||||
xyPostion={props.xyPostion}
|
||||
index={props.index}
|
||||
setXyPostion={props.setXyPostion}
|
||||
data={props.data}
|
||||
setSignKey={props.setSignKey}
|
||||
isShowDropdown={props?.isShowDropdown}
|
||||
isPlaceholder={props.isPlaceholder}
|
||||
isSignYourself={props.isSignYourself}
|
||||
signerObjId={props.signerObjId}
|
||||
handleUserName={props.handleUserName}
|
||||
setDraggingEnabled={setDraggingEnabled}
|
||||
pdfDetails={props?.pdfDetails && props?.pdfDetails[0]}
|
||||
isNeedSign={props.isNeedSign}
|
||||
setSelectDate={setSelectDate}
|
||||
selectDate={selectDate}
|
||||
setValidateAlert={props.setValidateAlert}
|
||||
setStartDate={setStartDate}
|
||||
startDate={startDate}
|
||||
handleSaveDate={handleSaveDate}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{props.pos.key === props.selectWidgetId && <PlaceholderIcon />}
|
||||
<PlaceholderType
|
||||
pos={props.pos}
|
||||
xyPostion={props.xyPostion}
|
||||
index={props.index}
|
||||
setXyPostion={props.setXyPostion}
|
||||
data={props.data}
|
||||
setSignKey={props.setSignKey}
|
||||
isShowDropdown={props?.isShowDropdown}
|
||||
isPlaceholder={props.isPlaceholder}
|
||||
isSignYourself={props.isSignYourself}
|
||||
signerObjId={props.signerObjId}
|
||||
handleUserName={props.handleUserName}
|
||||
setDraggingEnabled={setDraggingEnabled}
|
||||
pdfDetails={props?.pdfDetails && props?.pdfDetails[0]}
|
||||
isNeedSign={props.isNeedSign}
|
||||
setSelectDate={setSelectDate}
|
||||
selectDate={selectDate}
|
||||
setValidateAlert={props.setValidateAlert}
|
||||
setStartDate={setStartDate}
|
||||
startDate={startDate}
|
||||
handleSaveDate={handleSaveDate}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Rnd>
|
||||
);
|
||||
}
|
||||
|
||||
export default Placeholder;
|
||||
@@ -0,0 +1,52 @@
|
||||
import React from "react";
|
||||
import { themeColor } from "../../constant/const";
|
||||
import {
|
||||
defaultWidthHeight,
|
||||
isMobile,
|
||||
radioButtonWidget,
|
||||
resizeBorderExtraWidth,
|
||||
textWidget
|
||||
} from "../../constant/Utils";
|
||||
function PlaceholderBorder(props) {
|
||||
const getResizeBorderExtraWidth = resizeBorderExtraWidth();
|
||||
const defaultWidth = defaultWidthHeight(props.pos.type).width;
|
||||
const defaultHeight = defaultWidthHeight(props.pos.type).height;
|
||||
|
||||
const handleMinWidth = () => {
|
||||
if (props.pos.type === "checkbox" || props.pos.type === radioButtonWidget) {
|
||||
return props.getCheckboxRenderWidth.width + getResizeBorderExtraWidth;
|
||||
} else {
|
||||
return props.pos.Width
|
||||
? props.pos.Width + getResizeBorderExtraWidth
|
||||
: defaultWidth + getResizeBorderExtraWidth;
|
||||
}
|
||||
};
|
||||
const handleMinHeight = () => {
|
||||
if (props.pos.type === "checkbox" || props.pos.type === radioButtonWidget) {
|
||||
return props.getCheckboxRenderWidth.height + getResizeBorderExtraWidth;
|
||||
} else {
|
||||
return props.pos.Height
|
||||
? props.pos.Height + getResizeBorderExtraWidth
|
||||
: defaultHeight + getResizeBorderExtraWidth;
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={() => !isMobile && props?.setDraggingEnabled(true)}
|
||||
onTouchEnd={() =>
|
||||
props.pos.type === textWidget && props?.setDraggingEnabled(true)
|
||||
}
|
||||
className="borderResize"
|
||||
style={{
|
||||
borderColor: themeColor,
|
||||
borderStyle: "dashed",
|
||||
minWidth: handleMinWidth(),
|
||||
minHeight: handleMinHeight(),
|
||||
borderWidth: "0.2px",
|
||||
overflow: "hidden"
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlaceholderBorder;
|
||||
@@ -1,62 +1,55 @@
|
||||
import React, { useState } from "react";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import ModalUi from "../../premitives/ModalUi";
|
||||
import { themeColor } from "../../constant/const";
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
import { randomId, textWidget } from "../../constant/Utils";
|
||||
|
||||
function PlaceholderCopy(props) {
|
||||
const copyType = ["All pages", "All pages but last", "All pages but first"];
|
||||
const [selectCopyType, setSelectCopyType] = useState("");
|
||||
|
||||
//get RandomKey Id
|
||||
const randomKey = () => {
|
||||
const randomId = Math.floor(1000 + Math.random() * 9000);
|
||||
return randomId;
|
||||
};
|
||||
|
||||
//function for get copy placeholder position
|
||||
const getCopyPlaceholderPosition = (
|
||||
type,
|
||||
rest,
|
||||
currentPlaceholder,
|
||||
newPageNumber,
|
||||
existPlaceholderPosition
|
||||
) => {
|
||||
let obj;
|
||||
|
||||
const filterPosition =
|
||||
existPlaceholderPosition &&
|
||||
existPlaceholderPosition.filter(
|
||||
(data) => data.xPosition !== rest.xPosition
|
||||
(data) => data.xPosition !== currentPlaceholder.xPosition
|
||||
);
|
||||
//copy all page placeholder at requested position except first page
|
||||
if (newPageNumber === 1 && type === "first") {
|
||||
if (filterPosition && filterPosition.length > 0) {
|
||||
return (obj = {
|
||||
return {
|
||||
pageNumber: newPageNumber,
|
||||
pos: [...filterPosition]
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
//copy all page placeholder at requested position except last page
|
||||
else if (newPageNumber === props.allPages && type === "last") {
|
||||
if (existPlaceholderPosition) {
|
||||
return (obj = {
|
||||
return {
|
||||
pageNumber: newPageNumber,
|
||||
pos: [...filterPosition]
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
//copy all page placeholder at requested position with existing placeholder position
|
||||
else if (existPlaceholderPosition) {
|
||||
return (obj = {
|
||||
return {
|
||||
pageNumber: newPageNumber,
|
||||
pos: [...filterPosition, rest]
|
||||
});
|
||||
pos: [...filterPosition, currentPlaceholder]
|
||||
};
|
||||
}
|
||||
//copy all page placeholder at requested position
|
||||
else {
|
||||
return (obj = {
|
||||
return {
|
||||
pageNumber: newPageNumber,
|
||||
pos: [rest]
|
||||
});
|
||||
pos: [currentPlaceholder]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,6 +59,7 @@ function PlaceholderCopy(props) {
|
||||
let newPageNumber = 1;
|
||||
const signerPosition = props.xyPostion;
|
||||
const signerId = props.signerObjId ? props.signerObjId : props.Id;
|
||||
|
||||
//handle placeholder array and copy for multiple signers placeholder at requested location
|
||||
if (signerId) {
|
||||
//get current signers data
|
||||
@@ -84,13 +78,13 @@ function PlaceholderCopy(props) {
|
||||
(data) => data.pageNumber === props.pageNumber
|
||||
);
|
||||
//get current placeholder position data which user want to copy
|
||||
const currentPlaceholder = placeholderPosition[0].pos.filter(
|
||||
const currentPlaceholder = placeholderPosition[0].pos.find(
|
||||
(position) => position.key === props.signKey
|
||||
);
|
||||
const { key, ...rest } = currentPlaceholder[0];
|
||||
|
||||
for (let i = 0; i < props.allPages; i++) {
|
||||
const newId = randomKey();
|
||||
rest.key = newId;
|
||||
const newId = randomId();
|
||||
currentPlaceholder.key = newId;
|
||||
//get exist placeholder position for particular page
|
||||
const existPlaceholder = filterSignerPosition[0].placeHolder.filter(
|
||||
(data) => data.pageNumber === newPageNumber
|
||||
@@ -101,7 +95,7 @@ function PlaceholderCopy(props) {
|
||||
//function for get copy to requested location of placeholder position
|
||||
const getPlaceholderObj = getCopyPlaceholderPosition(
|
||||
type,
|
||||
rest,
|
||||
currentPlaceholder,
|
||||
newPageNumber,
|
||||
existPlaceholderPosition
|
||||
);
|
||||
@@ -112,7 +106,7 @@ function PlaceholderCopy(props) {
|
||||
}
|
||||
let updatedSignerPlaceholder;
|
||||
if (props?.signerObjId) {
|
||||
updatedSignerPlaceholder = signerPosition.map((signersData, ind) => {
|
||||
updatedSignerPlaceholder = signerPosition.map((signersData) => {
|
||||
if (signersData.signerObjId === props.signerObjId) {
|
||||
return {
|
||||
...signersData,
|
||||
@@ -122,7 +116,7 @@ function PlaceholderCopy(props) {
|
||||
return signersData;
|
||||
});
|
||||
} else {
|
||||
updatedSignerPlaceholder = signerPosition.map((signersData, ind) => {
|
||||
updatedSignerPlaceholder = signerPosition.map((signersData) => {
|
||||
if (signersData.Id === props.Id) {
|
||||
return {
|
||||
...signersData,
|
||||
@@ -132,17 +126,6 @@ function PlaceholderCopy(props) {
|
||||
return signersData;
|
||||
});
|
||||
}
|
||||
// const updatedSignerPlaceholder = signerPosition.map(
|
||||
// (signersData, ind) => {
|
||||
// if (signersData.signerObjId === props.signerObjId) {
|
||||
// return {
|
||||
// ...signersData,
|
||||
// placeHolder: newPlaceholderPosition
|
||||
// };
|
||||
// }
|
||||
// return signersData;
|
||||
// }
|
||||
// );
|
||||
|
||||
const signersData = signerPosition;
|
||||
signersData.splice(0, signerPosition.length, ...updatedSignerPlaceholder);
|
||||
@@ -156,10 +139,10 @@ function PlaceholderCopy(props) {
|
||||
(data) => data.pageNumber === props.pageNumber
|
||||
);
|
||||
//get current placeholder position data which user want to copy
|
||||
const currentPlaceholder = placeholderPosition[0].pos.filter(
|
||||
const currentPlaceholder = placeholderPosition[0].pos.find(
|
||||
(pos) => pos.key === props.signKey
|
||||
);
|
||||
const { key, ...rest } = currentPlaceholder[0];
|
||||
|
||||
for (let i = 0; i < props.allPages; i++) {
|
||||
//get exist placeholder position for particular page
|
||||
const existPlaceholder = xyPostion.filter(
|
||||
@@ -168,12 +151,12 @@ function PlaceholderCopy(props) {
|
||||
const existPlaceholderPosition =
|
||||
existPlaceholder[0] && existPlaceholder[0].pos;
|
||||
|
||||
const newId = randomKey();
|
||||
rest.key = newId;
|
||||
const newId = randomId();
|
||||
currentPlaceholder.key = newId;
|
||||
//function for get copy to requested location of placeholder position
|
||||
const getPlaceholderObj = getCopyPlaceholderPosition(
|
||||
type,
|
||||
rest,
|
||||
currentPlaceholder,
|
||||
newPageNumber,
|
||||
existPlaceholderPosition
|
||||
);
|
||||
@@ -197,7 +180,13 @@ function PlaceholderCopy(props) {
|
||||
copyPlaceholder("first");
|
||||
}
|
||||
};
|
||||
|
||||
const handleUniqueId = () => {
|
||||
if (props.widgetType === textWidget) {
|
||||
props.setUniqueId(props?.tempSignerId);
|
||||
props.setTempSignerId("");
|
||||
}
|
||||
props.setIsPageCopy(false);
|
||||
};
|
||||
return (
|
||||
<ModalUi
|
||||
isOpen={props.isPageCopy}
|
||||
@@ -237,11 +226,9 @@ function PlaceholderCopy(props) {
|
||||
<button
|
||||
onClick={() => {
|
||||
handleApplyCopy();
|
||||
props.setIsPageCopy(false);
|
||||
}}
|
||||
style={{
|
||||
background: themeColor()
|
||||
handleUniqueId();
|
||||
}}
|
||||
style={{ background: themeColor }}
|
||||
type="button"
|
||||
disabled={!selectCopyType}
|
||||
className="finishBtn"
|
||||
@@ -251,7 +238,9 @@ function PlaceholderCopy(props) {
|
||||
<button
|
||||
type="button"
|
||||
className="finishBtn cancelBtn"
|
||||
onClick={() => props.setIsPageCopy(false)}
|
||||
onClick={() => {
|
||||
handleUniqueId();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
@@ -0,0 +1,796 @@
|
||||
import React, { useEffect, useState, forwardRef, useRef } from "react";
|
||||
import {
|
||||
getMonth,
|
||||
getYear,
|
||||
isMobile,
|
||||
onChangeInput,
|
||||
radioButtonWidget,
|
||||
range,
|
||||
textInputWidget,
|
||||
textWidget
|
||||
} from "../../constant/Utils";
|
||||
import DatePicker from "react-datepicker";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import "../../styles/signature.css";
|
||||
import RegexParser from "regex-parser";
|
||||
|
||||
function PlaceholderType(props) {
|
||||
const type = props?.pos?.type;
|
||||
const [selectOption, setSelectOption] = useState("");
|
||||
const [validatePlaceholder, setValidatePlaceholder] = useState("");
|
||||
const inputRef = useRef(null);
|
||||
const [textValue, setTextValue] = useState();
|
||||
const [selectedCheckbox, setSelectedCheckbox] = useState([]);
|
||||
const years = range(1990, getYear(new Date()) + 16, 1);
|
||||
const months = [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
];
|
||||
const validateExpression = (regexValidation) => {
|
||||
let regexObject = regexValidation;
|
||||
if (props.pos?.options.validation.type === "regex") {
|
||||
regexObject = RegexParser(regexValidation);
|
||||
}
|
||||
// new RegExp(regexValidation);
|
||||
let isValidate = regexObject.test(textValue);
|
||||
if (!isValidate) {
|
||||
props?.setValidateAlert(true);
|
||||
inputRef.current.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputBlur = () => {
|
||||
props.setDraggingEnabled(true);
|
||||
const validateType = props.pos?.options?.validation?.type;
|
||||
let regexValidation;
|
||||
if (validateType) {
|
||||
switch (validateType) {
|
||||
case "email":
|
||||
regexValidation = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
validateExpression(regexValidation);
|
||||
break;
|
||||
case "number":
|
||||
regexValidation = /^\d+$/;
|
||||
validateExpression(regexValidation);
|
||||
break;
|
||||
case "text":
|
||||
regexValidation = /^[a-zA-Z\s]+$/;
|
||||
validateExpression(regexValidation);
|
||||
break;
|
||||
default:
|
||||
regexValidation = props.pos?.options.validation.pattern;
|
||||
validateExpression(regexValidation);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleTextValid = (e) => {
|
||||
const textInput = e.target.value;
|
||||
setTextValue(textInput);
|
||||
};
|
||||
function checkRegularExpress(validateType) {
|
||||
switch (validateType) {
|
||||
case "email":
|
||||
setValidatePlaceholder("demo@gmail.com");
|
||||
break;
|
||||
case "number":
|
||||
setValidatePlaceholder("12345");
|
||||
break;
|
||||
case textInputWidget:
|
||||
setValidatePlaceholder("enter text");
|
||||
break;
|
||||
default:
|
||||
setValidatePlaceholder("enter text");
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (type && type === "checkbox" && props.isNeedSign) {
|
||||
const isDefaultValue = props.pos.options?.defaultValue;
|
||||
if (isDefaultValue) {
|
||||
setSelectedCheckbox(isDefaultValue);
|
||||
}
|
||||
} else if (props.pos?.options?.hint) {
|
||||
setValidatePlaceholder(props.pos?.options.hint);
|
||||
} else if (props.pos?.options?.validation?.type) {
|
||||
checkRegularExpress(props.pos?.options?.validation?.type);
|
||||
}
|
||||
setTextValue(
|
||||
props.pos?.options?.response
|
||||
? props.pos?.options?.response
|
||||
: props.pos?.options?.defaultValue
|
||||
? props.pos?.options?.defaultValue
|
||||
: ""
|
||||
);
|
||||
setSelectOption(
|
||||
props.pos?.options?.response
|
||||
? props.pos?.options?.response
|
||||
: props.pos?.options?.defaultValue
|
||||
? props.pos?.options?.defaultValue
|
||||
: ""
|
||||
);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
["name", "email", "job title", "company"].includes(props.pos?.type) &&
|
||||
props.isNeedSign &&
|
||||
props.data?.signerObjId === props?.signerObjId
|
||||
) {
|
||||
const defaultData = props.pos?.options?.defaultValue;
|
||||
if (defaultData) {
|
||||
setTextValue(defaultData);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [props.pos]);
|
||||
|
||||
const ExampleCustomInput = forwardRef(({ value, onClick }, ref) => (
|
||||
<div
|
||||
className="inputPlaceholder"
|
||||
style={{ overflow: "hidden", fontSize: calculateFontSize() }}
|
||||
onClick={onClick}
|
||||
ref={ref}
|
||||
>
|
||||
{value}
|
||||
<i className="fa-regular fa-calendar" style={{ marginLeft: "5px" }}></i>
|
||||
</div>
|
||||
));
|
||||
ExampleCustomInput.displayName = "ExampleCustomInput";
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
["name", "email", "job title", "company"].includes(type) &&
|
||||
props.isNeedSign &&
|
||||
props.data?.signerObjId === props.signerObjId
|
||||
) {
|
||||
const isDefault = true;
|
||||
const senderUser = localStorage.getItem(`Extand_Class`);
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
onChangeInput(
|
||||
jsonSender && jsonSender[0],
|
||||
null,
|
||||
props.xyPostion,
|
||||
null,
|
||||
props.setXyPostion,
|
||||
props.data.Id,
|
||||
isDefault
|
||||
);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [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
|
||||
const selectCheckbox = (ind) => {
|
||||
const res = props.pos.options?.response;
|
||||
const defaultCheck = props.pos.options?.defaultValue;
|
||||
if (res && res?.length > 0) {
|
||||
const isSelectIndex = res.indexOf(ind);
|
||||
if (isSelectIndex > -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// }
|
||||
} else if (defaultCheck) {
|
||||
const isSelectIndex = defaultCheck.indexOf(ind);
|
||||
if (isSelectIndex > -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRadioCheck = (data) => {
|
||||
const defaultData = props.pos.options?.defaultValue;
|
||||
if (textValue === data) {
|
||||
return true;
|
||||
} else if (defaultData === data) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//function for set checked and unchecked value of checkbox
|
||||
const handleCheckboxValue = (isChecked, ind) => {
|
||||
let updateSelectedCheckbox = [],
|
||||
checkedList;
|
||||
let isDefaultValue, isDefaultEmpty;
|
||||
if (type === "checkbox") {
|
||||
updateSelectedCheckbox = selectedCheckbox ? selectedCheckbox : [];
|
||||
|
||||
if (isChecked) {
|
||||
updateSelectedCheckbox.push(ind);
|
||||
setSelectedCheckbox(updateSelectedCheckbox);
|
||||
} else {
|
||||
checkedList = selectedCheckbox.filter((data) => data !== ind);
|
||||
setSelectedCheckbox(checkedList);
|
||||
}
|
||||
if (props.isNeedSign) {
|
||||
isDefaultValue = props.pos.options?.defaultValue;
|
||||
}
|
||||
if (isDefaultValue && isDefaultValue.length > 0) {
|
||||
isDefaultEmpty = true;
|
||||
}
|
||||
onChangeInput(
|
||||
checkedList ? checkedList : updateSelectedCheckbox,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data.Id,
|
||||
false,
|
||||
null,
|
||||
isDefaultEmpty
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
//function to handle select radio widget and set value seletced by user
|
||||
const handleCheckRadio = (isChecked, data) => {
|
||||
let isDefaultValue,
|
||||
isDefaultEmpty,
|
||||
isRadio = true;
|
||||
if (props.isNeedSign) {
|
||||
isDefaultValue = props.pos.options?.defaultValue;
|
||||
}
|
||||
if (isDefaultValue) {
|
||||
isDefaultEmpty = true;
|
||||
}
|
||||
if (isChecked) {
|
||||
setTextValue(data);
|
||||
} else {
|
||||
setTextValue("");
|
||||
}
|
||||
onChangeInput(
|
||||
data,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data.Id,
|
||||
false,
|
||||
null,
|
||||
isDefaultEmpty,
|
||||
isRadio
|
||||
);
|
||||
};
|
||||
//function to set onchange date
|
||||
const handleOnDateChange = (date) => {
|
||||
props.setStartDate(date);
|
||||
const isDateChange = true;
|
||||
const dateObj = {
|
||||
date: date,
|
||||
format: props.selectDate.format
|
||||
};
|
||||
props.handleSaveDate(dateObj, isDateChange);
|
||||
};
|
||||
switch (type) {
|
||||
case "signature":
|
||||
return props.pos.SignUrl ? (
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(
|
||||
props?.data?.Id,
|
||||
props?.data?.Role,
|
||||
props?.pos?.type
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
case "stamp":
|
||||
return props.pos.SignUrl ? (
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(
|
||||
props?.data?.Id,
|
||||
props?.data?.Role,
|
||||
props?.pos?.type
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
case "checkbox":
|
||||
return (
|
||||
<div style={{ zIndex: props.isSignYourself && "99" }}>
|
||||
{props.pos.options?.values?.map((data, ind) => {
|
||||
return (
|
||||
<div key={ind} className="flex items-center text-center gap-0.5">
|
||||
<input
|
||||
style={{
|
||||
width: props.pos.Width,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
marginTop: ind === 0 ? 0 : "5px"
|
||||
}}
|
||||
onBlur={handleInputBlur}
|
||||
disabled={
|
||||
props.isNeedSign &&
|
||||
(props.pos.options?.isReadOnly ||
|
||||
props.data?.signerObjId !== props.signerObjId)
|
||||
}
|
||||
type="checkbox"
|
||||
checked={selectCheckbox(ind)}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
if (!props.isPlaceholder) {
|
||||
const maxRequired =
|
||||
props.pos.options?.validation?.maxRequiredCount;
|
||||
const maxCountInt =
|
||||
maxRequired && parseInt(maxRequired);
|
||||
|
||||
if (maxCountInt > 0) {
|
||||
if (
|
||||
selectedCheckbox &&
|
||||
selectedCheckbox?.length <= maxCountInt - 1
|
||||
) {
|
||||
handleCheckboxValue(e.target.checked, ind);
|
||||
}
|
||||
} else {
|
||||
handleCheckboxValue(e.target.checked, ind);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleCheckboxValue(e.target.checked, ind);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{!props.pos.options?.isHideLabel && (
|
||||
<label className="text-xs mb-0 text-center">{data}</label>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
case textInputWidget:
|
||||
return props.isSignYourself ||
|
||||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
ref={inputRef}
|
||||
placeholder={validatePlaceholder}
|
||||
style={{ fontSize: calculateFontSize() }}
|
||||
value={textValue}
|
||||
type="text"
|
||||
tabIndex="0"
|
||||
disabled={
|
||||
props.isNeedSign && props.data?.signerObjId !== props.signerObjId
|
||||
? true
|
||||
: props.isPlaceholder
|
||||
}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) => {
|
||||
setTextValue(e.target.value);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data?.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
color: "black",
|
||||
fontSize: calculateFontSize()
|
||||
}}
|
||||
>
|
||||
<span>{type}</span>
|
||||
</div>
|
||||
);
|
||||
case "dropdown":
|
||||
return props.data?.signerObjId === props.signerObjId ? (
|
||||
<select
|
||||
className="inputPlaceholder"
|
||||
id="myDropdown"
|
||||
style={{ fontSize: "12px" }}
|
||||
value={selectOption}
|
||||
onChange={(e) => {
|
||||
setSelectOption(e.target.value);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data?.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
>
|
||||
{/* Default/Title option */}
|
||||
<option value="" disabled hidden>
|
||||
{props.pos.options.name}
|
||||
</option>
|
||||
|
||||
{props.pos?.options?.values.map((data, ind) => {
|
||||
return (
|
||||
<option key={ind} value={data}>
|
||||
{data}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
) : (
|
||||
<div
|
||||
className="inputPlaceholder"
|
||||
style={{ fontSize: calculateFontSize() }}
|
||||
>
|
||||
{props.pos?.options?.name ? props.pos.options.name : type}
|
||||
</div>
|
||||
);
|
||||
case "initials":
|
||||
return props.pos.SignUrl ? (
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(
|
||||
props?.data?.Id,
|
||||
props?.data?.Role,
|
||||
props?.pos?.type
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
case "name":
|
||||
return props.isSignYourself ||
|
||||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
|
||||
<input
|
||||
tabIndex="0"
|
||||
ref={inputRef}
|
||||
placeholder={"name"}
|
||||
style={{ fontSize: calculateFontSize() }}
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
value={textValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) => {
|
||||
const isDefault = false;
|
||||
handleTextValid(e);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data?.Id,
|
||||
isDefault
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
color: "black",
|
||||
fontSize: calculateFontSize()
|
||||
}}
|
||||
>
|
||||
<span>{type}</span>
|
||||
</div>
|
||||
);
|
||||
case "company":
|
||||
return props.isSignYourself ||
|
||||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
ref={inputRef}
|
||||
placeholder={"company"}
|
||||
style={{ fontSize: calculateFontSize() }}
|
||||
value={textValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) => {
|
||||
handleTextValid(e);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data?.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
color: "black",
|
||||
fontSize: calculateFontSize()
|
||||
}}
|
||||
>
|
||||
<span>{type}</span>
|
||||
</div>
|
||||
);
|
||||
case "job title":
|
||||
return props.isSignYourself ||
|
||||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
ref={inputRef}
|
||||
placeholder={"job title"}
|
||||
style={{ fontSize: calculateFontSize() }}
|
||||
value={textValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) => {
|
||||
handleTextValid(e);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data?.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
color: "black",
|
||||
fontSize: calculateFontSize()
|
||||
}}
|
||||
>
|
||||
<span>{type}</span>
|
||||
</div>
|
||||
);
|
||||
case "date":
|
||||
return (
|
||||
<div>
|
||||
<DatePicker
|
||||
renderCustomHeader={({ date, changeYear, changeMonth }) => (
|
||||
<div className="flex justify-start ml-2 ">
|
||||
<select
|
||||
className="bg-transparent outline-none"
|
||||
value={months[getMonth(date)]}
|
||||
onChange={({ target: { value } }) =>
|
||||
changeMonth(months.indexOf(value))
|
||||
}
|
||||
>
|
||||
{months.map((option) => (
|
||||
<option key={option} value={option}>
|
||||
{option}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
className="bg-transparent outline-none"
|
||||
value={getYear(date)}
|
||||
onChange={({ target: { value } }) => changeYear(value)}
|
||||
>
|
||||
{years.map((option) => (
|
||||
<option key={option} value={option}>
|
||||
{option}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
disabled={
|
||||
props.isPlaceholder ||
|
||||
(props.isNeedSign &&
|
||||
props.data?.signerObjId !== props.signerObjId)
|
||||
}
|
||||
onBlur={handleInputBlur}
|
||||
closeOnScroll={true}
|
||||
className="inputPlaceholder"
|
||||
style={{ outlineColor: "#007bff" }}
|
||||
selected={
|
||||
props?.startDate
|
||||
? props?.startDate
|
||||
: props.pos.options?.response &&
|
||||
new Date(props.pos.options.response)
|
||||
}
|
||||
onChange={(date) => handleOnDateChange(date)}
|
||||
popperPlacement="top-end"
|
||||
customInput={<ExampleCustomInput />}
|
||||
dateFormat={
|
||||
props.selectDate
|
||||
? props.selectDate?.format
|
||||
: props.pos?.options?.validation?.format
|
||||
? props.pos?.options?.validation?.format
|
||||
: "MM/dd/yyyy"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
case "image":
|
||||
return props.pos.SignUrl ? (
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(
|
||||
props?.data?.Id,
|
||||
props?.data?.Role,
|
||||
props?.pos?.type
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
case "email":
|
||||
return props.isSignYourself ||
|
||||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
ref={inputRef}
|
||||
placeholder={"email"}
|
||||
style={{ fontSize: calculateFontSize() }}
|
||||
value={textValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) => {
|
||||
handleTextValid(e);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data?.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
color: "black",
|
||||
fontSize: calculateFontSize()
|
||||
}}
|
||||
>
|
||||
<span>{type}</span>
|
||||
</div>
|
||||
);
|
||||
case radioButtonWidget:
|
||||
return (
|
||||
<div>
|
||||
{props.pos.options?.values.map((data, ind) => {
|
||||
return (
|
||||
<div key={ind} className="flex items-center text-center gap-0.5">
|
||||
<input
|
||||
style={{
|
||||
width: props.pos.Width,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
marginTop: ind === 0 ? 0 : "5px"
|
||||
}}
|
||||
type="radio"
|
||||
disabled={
|
||||
props.isNeedSign &&
|
||||
(props.pos.options?.isReadOnly ||
|
||||
props.data?.signerObjId !== props.signerObjId)
|
||||
}
|
||||
checked={handleRadioCheck(data)}
|
||||
onChange={(e) => {
|
||||
if (!props.isPlaceholder) {
|
||||
handleCheckRadio(e.target.checked, data);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{!props.pos.options?.isHideLabel && (
|
||||
<label className="text-xs mb-0">{data}</label>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
case textWidget:
|
||||
return (
|
||||
<textarea
|
||||
placeholder="Enter label"
|
||||
rows={1}
|
||||
value={textValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) => {
|
||||
setTextValue(e.target.value);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
props.xyPostion,
|
||||
props.index,
|
||||
props.setXyPostion,
|
||||
props.data && props.data?.Id,
|
||||
false
|
||||
);
|
||||
}}
|
||||
className={
|
||||
isMobile
|
||||
? "labelTextArea labelWidthMobile"
|
||||
: "labelTextArea labelWidthDesktop"
|
||||
}
|
||||
style={{ whiteSpace: "pre-wrap" }}
|
||||
cols="50"
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return props.pos.SignUrl ? (
|
||||
<div style={{ pointerEvents: "none" }}>
|
||||
<img
|
||||
alt="signimg"
|
||||
src={props.pos.SignUrl}
|
||||
style={{
|
||||
width: "99%",
|
||||
height: "100%",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
fontSize: "10px",
|
||||
color: "black",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
{props.pos.isStamp ? <div>stamp</div> : <div>signature</div>}
|
||||
{props?.handleUserName &&
|
||||
props?.handleUserName(props?.data?.Id, props?.data?.Role)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PlaceholderType;
|
||||
@@ -21,7 +21,7 @@ function PrevNext({ pageNumber, allPages, changePage }) {
|
||||
fontWeight: "600",
|
||||
|
||||
border: "0px",
|
||||
marginRight: "5px",
|
||||
marginRight: "5px"
|
||||
}}
|
||||
disabled={pageNumber <= 1}
|
||||
onClick={previousPage}
|
||||
@@ -31,7 +31,7 @@ function PrevNext({ pageNumber, allPages, changePage }) {
|
||||
<span
|
||||
style={{
|
||||
fontSize: "13px",
|
||||
fontWeight: "600",
|
||||
fontWeight: "600"
|
||||
}}
|
||||
>
|
||||
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
|
||||
@@ -43,7 +43,7 @@ function PrevNext({ pageNumber, allPages, changePage }) {
|
||||
background: "#d3edeb",
|
||||
fontWeight: "600",
|
||||
marginLeft: "5px",
|
||||
border: "0px",
|
||||
border: "0px"
|
||||
}}
|
||||
disabled={pageNumber >= allPages}
|
||||
onClick={nextPage}
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import "../css/signerListPlace.css";
|
||||
import { darkenColor, getFirstLetter } from "../utils/Utils";
|
||||
import { darkenColor, getFirstLetter } from "../../constant/Utils";
|
||||
|
||||
const RecipientList = (props) => {
|
||||
const color = [
|
||||
@@ -49,7 +48,7 @@ const RecipientList = (props) => {
|
||||
return style;
|
||||
};
|
||||
//function for onhover signer name remove background color
|
||||
const nonHoverStyle = (ind) => {
|
||||
const nonHoverStyle = () => {
|
||||
const style = {
|
||||
padding: "10px",
|
||||
marginTop: "2px",
|
||||
@@ -85,8 +84,8 @@ const RecipientList = (props) => {
|
||||
props.setContractName(obj?.className || "");
|
||||
props.setUniqueId(obj.Id);
|
||||
props.setRoleName(obj.Role);
|
||||
if(props.handleModal){
|
||||
props.handleModal()
|
||||
if (props.handleModal) {
|
||||
props.handleModal();
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import RSC from "react-scrollbars-custom";
|
||||
import { Document, Page, pdfjs } from "react-pdf";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import { Document, Page } from "react-pdf";
|
||||
import { themeColor } from "../../constant/const";
|
||||
|
||||
function RenderAllPdfPage({
|
||||
pdfUrl,
|
||||
@@ -12,8 +12,6 @@ function RenderAllPdfPage({
|
||||
setSignBtnPosition,
|
||||
pageNumber
|
||||
}) {
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
|
||||
|
||||
//set all number of pages after load pdf
|
||||
function onDocumentLoad({ numPages }) {
|
||||
setAllPages(numPages);
|
||||
@@ -33,7 +31,7 @@ function RenderAllPdfPage({
|
||||
<div style={{ width: "140px" }}>
|
||||
<div
|
||||
style={{
|
||||
background: themeColor()
|
||||
background: themeColor
|
||||
// color:"white"
|
||||
}}
|
||||
className="signedStyle"
|
||||
@@ -0,0 +1,693 @@
|
||||
import React from "react";
|
||||
import RSC from "react-scrollbars-custom";
|
||||
import { Document, Page } from "react-pdf";
|
||||
import {
|
||||
defaultWidthHeight,
|
||||
handleImageResize,
|
||||
handleSignYourselfImageResize
|
||||
} from "../../constant/Utils";
|
||||
import Placeholder from "./Placeholder";
|
||||
import Alert from "../../primitives/Alert";
|
||||
|
||||
function RenderPdf({
|
||||
pageNumber,
|
||||
pdfOriginalWidth,
|
||||
pdfNewWidth,
|
||||
drop,
|
||||
signerPos,
|
||||
successEmail,
|
||||
handleTabDrag,
|
||||
handleStop,
|
||||
isDragging,
|
||||
setIsSignPad,
|
||||
setIsStamp,
|
||||
handleDeleteSign,
|
||||
setSignKey,
|
||||
pdfDetails,
|
||||
xyPostion,
|
||||
pdfUrl,
|
||||
numPages,
|
||||
pageDetails,
|
||||
pdfRequest,
|
||||
setCurrentSigner,
|
||||
signerObjectId,
|
||||
signedSigners,
|
||||
setPdfLoadFail,
|
||||
placeholder,
|
||||
pdfLoadFail,
|
||||
setSignerPos,
|
||||
setXyPostion,
|
||||
index,
|
||||
containerWH,
|
||||
setIsResize,
|
||||
handleLinkUser,
|
||||
setUniqueId,
|
||||
signersdata,
|
||||
setIsPageCopy,
|
||||
setSignerObjId,
|
||||
setShowDropdown,
|
||||
setIsInitial,
|
||||
setIsValidate,
|
||||
setWidgetType,
|
||||
setValidateAlert,
|
||||
setIsRadio,
|
||||
setCurrWidgetsDetails,
|
||||
setSelectWidgetId,
|
||||
selectWidgetId,
|
||||
unSignedWidgetId,
|
||||
setIsCheckbox,
|
||||
handleNameModal,
|
||||
setTempSignerId,
|
||||
uniqueId
|
||||
}) {
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = containerWH.width;
|
||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
|
||||
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||
|
||||
// handle signature block width and height according to screen
|
||||
const posWidth = (pos, signYourself) => {
|
||||
const defaultWidth = defaultWidthHeight(pos.type).width;
|
||||
const posWidth = pos.Width ? pos.Width : defaultWidth;
|
||||
let width;
|
||||
if (signYourself) {
|
||||
width = posWidth;
|
||||
return width;
|
||||
} else {
|
||||
if (isMobile) {
|
||||
if (!pos.isMobile) {
|
||||
if (pos.IsResize) {
|
||||
width = posWidth ? posWidth : defaultWidth;
|
||||
return width;
|
||||
} else {
|
||||
width = (posWidth || defaultWidth) / scale;
|
||||
|
||||
return width;
|
||||
}
|
||||
} else {
|
||||
width = posWidth;
|
||||
return width;
|
||||
}
|
||||
} else {
|
||||
if (pos.isMobile) {
|
||||
if (pos.IsResize) {
|
||||
width = posWidth ? posWidth : defaultWidth;
|
||||
return width;
|
||||
} else {
|
||||
width = (posWidth || defaultWidth) * pos.scale;
|
||||
return width;
|
||||
}
|
||||
} else {
|
||||
width = posWidth ? posWidth : defaultWidth;
|
||||
return width;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const posHeight = (pos, signYourself) => {
|
||||
let height;
|
||||
const posHeight = pos.Height;
|
||||
const defaultHeight = defaultWidthHeight(pos.type).height;
|
||||
|
||||
if (signYourself) {
|
||||
height = posHeight ? posHeight : defaultHeight;
|
||||
|
||||
return height;
|
||||
} else {
|
||||
if (isMobile) {
|
||||
if (!pos.isMobile) {
|
||||
if (pos.IsResize) {
|
||||
height = posHeight ? posHeight : defaultHeight;
|
||||
return height;
|
||||
} else {
|
||||
height = (posHeight || defaultHeight) / scale;
|
||||
|
||||
return height;
|
||||
}
|
||||
} else {
|
||||
height = posHeight ? posHeight : defaultHeight;
|
||||
return height;
|
||||
}
|
||||
} else {
|
||||
if (pos.isMobile) {
|
||||
if (pos.IsResize) {
|
||||
height = posHeight ? posHeight : defaultHeight;
|
||||
return height;
|
||||
} else {
|
||||
height = (posHeight || defaultHeight) * pos.scale;
|
||||
return height;
|
||||
}
|
||||
} else {
|
||||
height = posHeight ? posHeight : defaultHeight;
|
||||
return height;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const xPos = (pos, signYourself) => {
|
||||
const resizePos = pos.xPosition;
|
||||
if (signYourself) {
|
||||
return resizePos;
|
||||
} else {
|
||||
//checking both condition mobile and desktop view
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (!pos.isMobile) {
|
||||
return resizePos / scale;
|
||||
}
|
||||
//pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale
|
||||
else {
|
||||
return resizePos * (pos.scale / scale);
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
|
||||
if (pos.isMobile) {
|
||||
return pos.scale && resizePos * pos.scale;
|
||||
}
|
||||
//else placeholder save from desktop(bigscreen) and show in desktop(bigscreen)
|
||||
else {
|
||||
return resizePos;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const yPos = (pos, signYourself) => {
|
||||
const resizePos = pos.yPosition;
|
||||
if (signYourself) {
|
||||
return resizePos;
|
||||
} else {
|
||||
//checking both condition mobile and desktop view
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (!pos.isMobile) {
|
||||
return resizePos / scale;
|
||||
}
|
||||
//pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale
|
||||
else {
|
||||
return resizePos * (pos.scale / scale);
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
|
||||
if (pos.isMobile) {
|
||||
return pos.scale && resizePos * pos.scale;
|
||||
}
|
||||
//else placeholder save from desktop(bigscreen) and show in desktop(bigscreen)
|
||||
else {
|
||||
return resizePos;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
//function for render placeholder block over pdf document
|
||||
const checkSignedSignes = (data) => {
|
||||
const checkSign = signedSigners.filter(
|
||||
(sign) => sign.objectId === data.signerObjId
|
||||
);
|
||||
if (data.signerObjId === signerObjectId) {
|
||||
setCurrentSigner(true);
|
||||
}
|
||||
const handleAllUserName = (Id, Role, type) => {
|
||||
return pdfDetails[0].Signers.map((signerData, key) => {
|
||||
return (
|
||||
signerData.objectId === data.signerObjId && (
|
||||
<React.Fragment key={key}>
|
||||
{signerData?.Name && (
|
||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
||||
{signerData.Name}
|
||||
</div>
|
||||
)}
|
||||
{type && (
|
||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
||||
)}
|
||||
{Role && (
|
||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
||||
{`(${Role})`}
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
checkSign.length === 0 &&
|
||||
data.placeHolder.map((placeData, key) => {
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
{placeData.pageNumber === pageNumber &&
|
||||
placeData.pos.map((pos) => {
|
||||
return (
|
||||
pos && (
|
||||
<React.Fragment key={pos.key}>
|
||||
<Placeholder
|
||||
pos={pos}
|
||||
setSignKey={setSignKey}
|
||||
setIsSignPad={setIsSignPad}
|
||||
setIsStamp={setIsStamp}
|
||||
handleSignYourselfImageResize={handleImageResize}
|
||||
index={pageNumber}
|
||||
xyPostion={signerPos}
|
||||
setXyPostion={setSignerPos}
|
||||
data={data}
|
||||
setIsResize={setIsResize}
|
||||
isShowBorder={false}
|
||||
signerObjId={signerObjectId}
|
||||
isShowDropdown={true}
|
||||
isNeedSign={true}
|
||||
isSignYourself={false}
|
||||
xPos={xPos}
|
||||
yPos={yPos}
|
||||
posWidth={posWidth}
|
||||
posHeight={posHeight}
|
||||
handleUserName={handleAllUserName}
|
||||
isDragging={false}
|
||||
pdfDetails={pdfDetails}
|
||||
setIsInitial={setIsInitial}
|
||||
setValidateAlert={setValidateAlert}
|
||||
unSignedWidgetId={unSignedWidgetId}
|
||||
setSelectWidgetId={setSelectWidgetId}
|
||||
selectWidgetId={selectWidgetId}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleUserName = (Id, Role, type) => {
|
||||
if (Id) {
|
||||
const checkSign = signersdata.find((sign) => sign.Id === Id);
|
||||
if (checkSign?.Name) {
|
||||
return (
|
||||
<>
|
||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
||||
{checkSign?.Name}
|
||||
</div>
|
||||
{type && (
|
||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
||||
)}
|
||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
||||
{`(${Role})`}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
{type && (
|
||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
||||
)}
|
||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
||||
{Role}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
{type && (
|
||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
||||
)}
|
||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
||||
{Role}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{successEmail && <Alert type={"success"}>Email sent successfully!</Alert>}
|
||||
{isMobile && scale ? (
|
||||
<div
|
||||
style={{
|
||||
border: "0.1px solid #ebe8e8",
|
||||
marginTop: isGuestSigner && "30px"
|
||||
}}
|
||||
ref={drop}
|
||||
id="container"
|
||||
>
|
||||
{pdfLoadFail.status &&
|
||||
(pdfRequest
|
||||
? signerPos.map((data, key) => {
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
{checkSignedSignes(data)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})
|
||||
: placeholder // placeholder mobile
|
||||
? signerPos.map((data, ind) => {
|
||||
return (
|
||||
<React.Fragment key={ind}>
|
||||
{data.placeHolder.map((placeData, index) => {
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
{placeData.pageNumber === pageNumber &&
|
||||
placeData.pos.map((pos) => {
|
||||
return (
|
||||
<React.Fragment key={pos.key}>
|
||||
<Placeholder
|
||||
pos={pos}
|
||||
setIsPageCopy={setIsPageCopy}
|
||||
setSignKey={setSignKey}
|
||||
handleDeleteSign={handleDeleteSign}
|
||||
setIsStamp={setIsStamp}
|
||||
handleTabDrag={handleTabDrag}
|
||||
handleStop={handleStop}
|
||||
handleSignYourselfImageResize={
|
||||
handleImageResize
|
||||
}
|
||||
index={pageNumber}
|
||||
xyPostion={signerPos}
|
||||
setXyPostion={setSignerPos}
|
||||
setSignerObjId={setSignerObjId}
|
||||
data={data}
|
||||
setIsResize={setIsResize}
|
||||
setShowDropdown={setShowDropdown}
|
||||
isShowBorder={true}
|
||||
isPlaceholder={true}
|
||||
setUniqueId={setUniqueId}
|
||||
handleLinkUser={handleLinkUser}
|
||||
handleUserName={handleUserName}
|
||||
isSignYourself={false}
|
||||
xPos={xPos}
|
||||
yPos={yPos}
|
||||
posWidth={posWidth}
|
||||
posHeight={posHeight}
|
||||
isDragging={isDragging}
|
||||
setIsValidate={setIsValidate}
|
||||
setWidgetType={setWidgetType}
|
||||
setIsRadio={setIsRadio}
|
||||
setIsCheckbox={setIsCheckbox}
|
||||
setCurrWidgetsDetails={
|
||||
setCurrWidgetsDetails
|
||||
}
|
||||
setSelectWidgetId={setSelectWidgetId}
|
||||
selectWidgetId={selectWidgetId}
|
||||
handleNameModal={handleNameModal}
|
||||
setTempSignerId={setTempSignerId}
|
||||
uniqueId={uniqueId}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
})
|
||||
: xyPostion.map((data, ind) => {
|
||||
return (
|
||||
<React.Fragment key={ind}>
|
||||
{data.pageNumber === pageNumber &&
|
||||
data.pos.map((pos) => {
|
||||
return (
|
||||
pos && (
|
||||
<Placeholder
|
||||
pos={pos}
|
||||
setIsPageCopy={setIsPageCopy}
|
||||
setSignKey={setSignKey}
|
||||
handleDeleteSign={handleDeleteSign}
|
||||
setIsStamp={setIsStamp}
|
||||
handleTabDrag={handleTabDrag}
|
||||
handleStop={handleStop}
|
||||
handleSignYourselfImageResize={
|
||||
handleSignYourselfImageResize
|
||||
}
|
||||
index={index}
|
||||
xyPostion={xyPostion}
|
||||
setXyPostion={setXyPostion}
|
||||
pdfOriginalWidth={pdfOriginalWidth}
|
||||
containerWH={containerWH}
|
||||
setIsSignPad={setIsSignPad}
|
||||
isShowBorder={true}
|
||||
isSignYourself={true}
|
||||
xPos={xPos}
|
||||
yPos={yPos}
|
||||
posWidth={posWidth}
|
||||
posHeight={posHeight}
|
||||
pdfDetails={pdfDetails[0]}
|
||||
isDragging={isDragging}
|
||||
setIsInitial={setIsInitial}
|
||||
setWidgetType={setWidgetType}
|
||||
setSelectWidgetId={setSelectWidgetId}
|
||||
selectWidgetId={selectWidgetId}
|
||||
handleUserName={handleUserName}
|
||||
setIsCheckbox={setIsCheckbox}
|
||||
setValidateAlert={setValidateAlert}
|
||||
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||
/>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
}))}
|
||||
|
||||
{/* this component for render pdf document is in middle of the component */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<Document
|
||||
onLoadError={() => {
|
||||
setPdfLoadFail(true);
|
||||
}}
|
||||
loading={"Loading Document.."}
|
||||
onLoadSuccess={pageDetails}
|
||||
// ref={pdfRef}'
|
||||
onClick={() => {
|
||||
if (setSelectWidgetId) {
|
||||
setSelectWidgetId("");
|
||||
}
|
||||
}}
|
||||
file={
|
||||
pdfUrl
|
||||
? pdfUrl
|
||||
: pdfDetails[0] && pdfDetails[0].SignedUrl
|
||||
? pdfDetails[0].SignedUrl
|
||||
: pdfDetails[0].URL
|
||||
}
|
||||
>
|
||||
{Array.from(new Array(numPages), (el, index) => (
|
||||
<Page
|
||||
key={index}
|
||||
pageNumber={pageNumber}
|
||||
width={containerWH.width}
|
||||
height={containerWH.height}
|
||||
renderAnnotationLayer={false}
|
||||
renderTextLayer={false}
|
||||
onGetAnnotationsError={(error) => {
|
||||
console.log("annotation error", error);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Document>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<RSC
|
||||
style={{
|
||||
position: "relative",
|
||||
boxShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px",
|
||||
width:
|
||||
pdfOriginalWidth > pdfNewWidth ? pdfNewWidth : pdfOriginalWidth,
|
||||
height: window.innerHeight - 110 + "px"
|
||||
}}
|
||||
noScrollY={false}
|
||||
noScrollX={pdfNewWidth < pdfOriginalWidth ? false : true}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
border: "0.1px solid #ebe8e8",
|
||||
width: pdfOriginalWidth
|
||||
}}
|
||||
ref={drop}
|
||||
id="container"
|
||||
>
|
||||
{pdfLoadFail.status &&
|
||||
(pdfRequest
|
||||
? signerPos.map((data, key) => {
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
{checkSignedSignes(data)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})
|
||||
: placeholder
|
||||
? signerPos.map((data, ind) => {
|
||||
return (
|
||||
<React.Fragment key={ind}>
|
||||
{data.placeHolder.map((placeData, index) => {
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
{placeData.pageNumber === pageNumber &&
|
||||
placeData.pos.map((pos) => {
|
||||
return (
|
||||
<React.Fragment key={pos.key}>
|
||||
<Placeholder
|
||||
pos={pos}
|
||||
setIsPageCopy={setIsPageCopy}
|
||||
setSignKey={setSignKey}
|
||||
handleDeleteSign={handleDeleteSign}
|
||||
setIsStamp={setIsStamp}
|
||||
handleTabDrag={handleTabDrag}
|
||||
handleStop={handleStop}
|
||||
handleSignYourselfImageResize={
|
||||
handleImageResize
|
||||
}
|
||||
index={pageNumber}
|
||||
xyPostion={signerPos}
|
||||
setXyPostion={setSignerPos}
|
||||
setSignerObjId={setSignerObjId}
|
||||
data={data}
|
||||
setIsResize={setIsResize}
|
||||
setShowDropdown={setShowDropdown}
|
||||
isShowBorder={true}
|
||||
isPlaceholder={true}
|
||||
setUniqueId={setUniqueId}
|
||||
handleLinkUser={handleLinkUser}
|
||||
handleUserName={handleUserName}
|
||||
isSignYourself={false}
|
||||
xPos={xPos}
|
||||
yPos={yPos}
|
||||
posWidth={posWidth}
|
||||
posHeight={posHeight}
|
||||
isDragging={isDragging}
|
||||
setIsValidate={setIsValidate}
|
||||
setWidgetType={setWidgetType}
|
||||
setIsRadio={setIsRadio}
|
||||
setIsCheckbox={setIsCheckbox}
|
||||
setCurrWidgetsDetails={
|
||||
setCurrWidgetsDetails
|
||||
}
|
||||
setSelectWidgetId={setSelectWidgetId}
|
||||
selectWidgetId={selectWidgetId}
|
||||
handleNameModal={handleNameModal}
|
||||
setTempSignerId={setTempSignerId}
|
||||
uniqueId={uniqueId}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
})
|
||||
: xyPostion.map((data, ind) => {
|
||||
return (
|
||||
<React.Fragment key={ind}>
|
||||
{data.pageNumber === pageNumber &&
|
||||
data.pos.map((pos) => {
|
||||
return (
|
||||
pos && (
|
||||
<React.Fragment key={pos.key}>
|
||||
<Placeholder
|
||||
pos={pos}
|
||||
setIsPageCopy={setIsPageCopy}
|
||||
setSignKey={setSignKey}
|
||||
handleDeleteSign={handleDeleteSign}
|
||||
setIsStamp={setIsStamp}
|
||||
handleTabDrag={handleTabDrag}
|
||||
handleStop={(event, dragElement) =>
|
||||
handleStop(event, dragElement, pos.type)
|
||||
}
|
||||
handleSignYourselfImageResize={
|
||||
handleSignYourselfImageResize
|
||||
}
|
||||
index={index}
|
||||
xyPostion={xyPostion}
|
||||
setXyPostion={setXyPostion}
|
||||
pdfOriginalWidth={pdfOriginalWidth}
|
||||
containerWH={containerWH}
|
||||
setIsSignPad={setIsSignPad}
|
||||
isShowBorder={true}
|
||||
isSignYourself={true}
|
||||
xPos={xPos}
|
||||
yPos={yPos}
|
||||
posWidth={posWidth}
|
||||
posHeight={posHeight}
|
||||
pdfDetails={pdfDetails[0]}
|
||||
isDragging={isDragging}
|
||||
setIsInitial={setIsInitial}
|
||||
setWidgetType={setWidgetType}
|
||||
setSelectWidgetId={setSelectWidgetId}
|
||||
selectWidgetId={selectWidgetId}
|
||||
handleUserName={handleUserName}
|
||||
setIsCheckbox={setIsCheckbox}
|
||||
setValidateAlert={setValidateAlert}
|
||||
setCurrWidgetsDetails={
|
||||
setCurrWidgetsDetails
|
||||
}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</React.Fragment>
|
||||
);
|
||||
}))}
|
||||
|
||||
{/* this component for render pdf document is in middle of the component */}
|
||||
<Document
|
||||
onLoadError={() => {
|
||||
const load = {
|
||||
status: false,
|
||||
type: "failed"
|
||||
};
|
||||
setPdfLoadFail(load);
|
||||
}}
|
||||
loading={"Loading Document.."}
|
||||
onLoadSuccess={pageDetails}
|
||||
onClick={() => {
|
||||
if (setSelectWidgetId) {
|
||||
setSelectWidgetId("");
|
||||
}
|
||||
}}
|
||||
// ref={pdfRef}
|
||||
file={
|
||||
pdfUrl
|
||||
? pdfUrl
|
||||
: pdfDetails[0] && pdfDetails[0].SignedUrl
|
||||
? pdfDetails[0].SignedUrl
|
||||
: pdfDetails[0].URL
|
||||
}
|
||||
>
|
||||
{Array.from(new Array(numPages), (el, index) => (
|
||||
<Page
|
||||
key={index}
|
||||
pageNumber={pageNumber}
|
||||
renderAnnotationLayer={false}
|
||||
renderTextLayer={false}
|
||||
onGetAnnotationsError={(error) => {
|
||||
console.log("annotation error", error);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Document>
|
||||
</div>
|
||||
</RSC>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default RenderPdf;
|
||||
@@ -1,11 +1,6 @@
|
||||
import React from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import SignatureCanvas from "react-signature-canvas";
|
||||
import redPen from "../../assests/redPen.png";
|
||||
import bluePen from "../../assests/bluePen.png";
|
||||
import blackPen from "../../assests/blackPen.png";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import { useEffect } from "react";
|
||||
import { themeColor } from "../../constant/const";
|
||||
|
||||
function SignPad({
|
||||
isSignPad,
|
||||
@@ -20,10 +15,15 @@ function SignPad({
|
||||
onSaveImage,
|
||||
image,
|
||||
defaultSign,
|
||||
setSignature
|
||||
setSignature,
|
||||
myInitial,
|
||||
isInitial,
|
||||
setIsInitial,
|
||||
setIsStamp,
|
||||
widgetType
|
||||
}) {
|
||||
const [penColor, setPenColor] = useState("blue");
|
||||
const allColor = [bluePen, redPen, blackPen];
|
||||
const allColor = ["blue", "red", "black"];
|
||||
const canvasRef = useRef(null);
|
||||
const [isDefaultSign, setIsDefaultSign] = useState(false);
|
||||
const [isTab, setIsTab] = useState("draw");
|
||||
@@ -40,20 +40,24 @@ function SignPad({
|
||||
];
|
||||
const [fontSelect, setFontSelect] = useState(fontOptions[0].value);
|
||||
|
||||
useEffect(() => {
|
||||
const senderUser =
|
||||
localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
) &&
|
||||
localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
);
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
const senderUser =
|
||||
localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
) &&
|
||||
localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
);
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
|
||||
const currentUserName = jsonSender && jsonSender.name;
|
||||
//function for clear signature
|
||||
setSignValue(currentUserName);
|
||||
const currentUserName = jsonSender && jsonSender.name;
|
||||
|
||||
useEffect(() => {
|
||||
const trimmedName = currentUserName.trim();
|
||||
const firstCharacter = trimmedName.charAt(0);
|
||||
const userName = isInitial ? firstCharacter : currentUserName;
|
||||
setSignValue(userName);
|
||||
setFontSelect("Fasthand");
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
//function for clear signature image
|
||||
const handleClear = () => {
|
||||
@@ -66,11 +70,12 @@ function SignPad({
|
||||
|
||||
setIsSignImg("");
|
||||
} else if (isTab === "uploadImage") {
|
||||
setImage("");
|
||||
setImage("");
|
||||
}
|
||||
setIsInitial(false);
|
||||
};
|
||||
//function for set signature url
|
||||
const handleSignatureChange = (dataURL) => {
|
||||
const handleSignatureChange = () => {
|
||||
// canvasRef.current.backgroundColor = 'rgb(165, 26, 26)'
|
||||
setSignature(canvasRef.current.toDataURL());
|
||||
setIsSignImg(canvasRef.current.toDataURL());
|
||||
@@ -97,9 +102,13 @@ function SignPad({
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!image) {
|
||||
if (isDefaultSign) {
|
||||
if (isTab === "mysignature") {
|
||||
setIsSignImg("");
|
||||
onSaveSign(isDefaultSign);
|
||||
if (isInitial) {
|
||||
onSaveSign("initials");
|
||||
} else {
|
||||
onSaveSign("default");
|
||||
}
|
||||
} else {
|
||||
if (isTab === "type") {
|
||||
setIsSignImg("");
|
||||
@@ -116,14 +125,16 @@ function SignPad({
|
||||
onSaveImage();
|
||||
}
|
||||
setIsSignPad(false);
|
||||
|
||||
setIsInitial(false);
|
||||
setIsImageSelect(false);
|
||||
setIsDefaultSign(false);
|
||||
setImage();
|
||||
setIsTab("draw");
|
||||
setSignValue("");
|
||||
setIsStamp(false);
|
||||
}}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
disabled={
|
||||
@@ -156,6 +167,7 @@ function SignPad({
|
||||
};
|
||||
|
||||
loadFont();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [fontSelect]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -164,9 +176,15 @@ function SignPad({
|
||||
canvasRef.current.fromDataURL(isSignImg);
|
||||
}
|
||||
if (isTab === "type") {
|
||||
convertToImg(fontSelect, signValue);
|
||||
const trimmedName = signValue ? signValue.trim() : currentUserName.trim();
|
||||
const firstCharacter = trimmedName.charAt(0);
|
||||
const userName = isInitial ? firstCharacter : signValue;
|
||||
setSignValue(userName);
|
||||
convertToImg(fontSelect, userName);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isTab]);
|
||||
|
||||
//function for convert input text value in image
|
||||
const convertToImg = async (fontStyle, text) => {
|
||||
//get text content to convert in image
|
||||
@@ -246,8 +264,10 @@ function SignPad({
|
||||
}}
|
||||
>
|
||||
{isStamp ? (
|
||||
<span style={{ color: themeColor() }} className="signTab">
|
||||
Upload stamp image
|
||||
<span style={{ color: themeColor }} className="signTab">
|
||||
{widgetType === "image"
|
||||
? "Upload image"
|
||||
: "Upload stamp image"}
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
@@ -260,9 +280,7 @@ function SignPad({
|
||||
setImage();
|
||||
}}
|
||||
style={{
|
||||
color:
|
||||
isTab === "draw" ? themeColor() : "#515252",
|
||||
|
||||
color: isTab === "draw" ? themeColor : "#515252",
|
||||
marginLeft: "2px"
|
||||
}}
|
||||
className="signTab"
|
||||
@@ -288,9 +306,7 @@ function SignPad({
|
||||
}}
|
||||
style={{
|
||||
color:
|
||||
isTab === "uploadImage"
|
||||
? themeColor()
|
||||
: "#515252"
|
||||
isTab === "uploadImage" ? themeColor : "#515252"
|
||||
}}
|
||||
className="signTab"
|
||||
>
|
||||
@@ -314,9 +330,7 @@ function SignPad({
|
||||
setImage();
|
||||
}}
|
||||
style={{
|
||||
color:
|
||||
isTab === "type" ? themeColor() : "#515252",
|
||||
|
||||
color: isTab === "type" ? themeColor : "#515252",
|
||||
marginLeft: "2px"
|
||||
}}
|
||||
className="signTab"
|
||||
@@ -333,7 +347,7 @@ function SignPad({
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
{defaultSign && (
|
||||
{!isInitial && defaultSign ? (
|
||||
<div>
|
||||
<span
|
||||
onClick={() => {
|
||||
@@ -345,7 +359,7 @@ function SignPad({
|
||||
style={{
|
||||
color:
|
||||
isTab === "mysignature"
|
||||
? themeColor()
|
||||
? themeColor
|
||||
: "#515252"
|
||||
}}
|
||||
className="signTab"
|
||||
@@ -361,6 +375,37 @@ function SignPad({
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
) : (
|
||||
isInitial &&
|
||||
myInitial && (
|
||||
<div>
|
||||
<span
|
||||
onClick={() => {
|
||||
setIsDefaultSign(true);
|
||||
setIsImageSelect(true);
|
||||
setIsTab("mysignature");
|
||||
setImage();
|
||||
}}
|
||||
style={{
|
||||
color:
|
||||
isTab === "mysignature"
|
||||
? themeColor
|
||||
: "#515252"
|
||||
}}
|
||||
className="signTab"
|
||||
>
|
||||
My Initials
|
||||
</span>
|
||||
<div
|
||||
style={{
|
||||
border:
|
||||
isTab === "mysignature"
|
||||
? "1.5px solid #108783"
|
||||
: "1.5px solid #ffffff"
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
@@ -373,11 +418,13 @@ function SignPad({
|
||||
onClick={() => {
|
||||
setPenColor("blue");
|
||||
setIsSignPad(false);
|
||||
|
||||
setIsInitial(false);
|
||||
setIsImageSelect(false);
|
||||
setIsDefaultSign(false);
|
||||
setImage();
|
||||
setIsTab("draw");
|
||||
setSignValue("");
|
||||
setIsStamp(false);
|
||||
}}
|
||||
>
|
||||
×
|
||||
@@ -386,28 +433,33 @@ function SignPad({
|
||||
<div style={{ height: "100%", padding: 20 }}>
|
||||
{isDefaultSign ? (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 6,
|
||||
cursor: "pointer"
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
>
|
||||
<img
|
||||
alt="stamp img"
|
||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
background: "rgb(255, 255, 255)",
|
||||
objectFit: "contain"
|
||||
border: "1.3px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 6,
|
||||
cursor: "pointer"
|
||||
}}
|
||||
src={defaultSign}
|
||||
/>
|
||||
className={
|
||||
isInitial ? "intialSignatureCanvas" : "signatureCanvas"
|
||||
}
|
||||
>
|
||||
<img
|
||||
alt="stamp img"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
background: "rgb(255, 255, 255)",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
src={isInitial ? myInitial : defaultSign}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
<SaveBtn />
|
||||
@@ -415,52 +467,63 @@ function SignPad({
|
||||
</>
|
||||
) : isImageSelect || isStamp ? (
|
||||
!image ? (
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||
<div
|
||||
style={{
|
||||
border: "1.3px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 6,
|
||||
cursor: "pointer"
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
onClick={() => imageRef.current.click()}
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
onChange={onImageChange}
|
||||
className="filetype"
|
||||
accept="image/*"
|
||||
ref={imageRef}
|
||||
hidden
|
||||
/>
|
||||
<i className="fas fa-cloud-upload-alt uploadImgLogo"></i>
|
||||
<div className="uploadImg">Upload</div>
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 6,
|
||||
cursor: "pointer"
|
||||
}}
|
||||
className={
|
||||
isInitial ? "intialSignatureCanvas" : "signatureCanvas"
|
||||
}
|
||||
onClick={() => imageRef.current.click()}
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
onChange={onImageChange}
|
||||
className="filetype"
|
||||
accept="image/*"
|
||||
ref={imageRef}
|
||||
hidden
|
||||
/>
|
||||
<i className="fas fa-cloud-upload-alt uploadImgLogo"></i>
|
||||
<div className="uploadImg">Upload</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid black",
|
||||
marginBottom: 6,
|
||||
|
||||
overflow: "hidden"
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
>
|
||||
<img
|
||||
alt="print img"
|
||||
ref={imageRef}
|
||||
src={image.src}
|
||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||
<div
|
||||
style={{
|
||||
objectFit: "contain",
|
||||
height: "100%",
|
||||
width: "100%"
|
||||
border: "1.3px solid #007bff",
|
||||
borderRadius: "2px",
|
||||
marginBottom: 6,
|
||||
overflow: "hidden"
|
||||
}}
|
||||
/>
|
||||
className={
|
||||
isInitial
|
||||
? "intialSignatureCanvas"
|
||||
: "signatureCanvas"
|
||||
}
|
||||
>
|
||||
<img
|
||||
alt="print img"
|
||||
ref={imageRef}
|
||||
src={image.src}
|
||||
style={{
|
||||
objectFit: "contain",
|
||||
height: "100%",
|
||||
width: "100%"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{ display: "flex", justifyContent: "flex-end" }}
|
||||
@@ -478,10 +541,12 @@ function SignPad({
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<span className="signatureText">Signature:</span>
|
||||
<span className="signatureText">
|
||||
{isInitial ? "Initials" : "Signature"}:
|
||||
</span>
|
||||
|
||||
<input
|
||||
maxLength={30}
|
||||
maxLength={isInitial ? 3 : 30}
|
||||
style={{ fontFamily: fontSelect }}
|
||||
type="text"
|
||||
className="signatureInput"
|
||||
@@ -529,19 +594,26 @@ function SignPad({
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<SignatureCanvas
|
||||
ref={canvasRef}
|
||||
penColor={penColor}
|
||||
canvasProps={{
|
||||
className: "signatureCanvas"
|
||||
}}
|
||||
backgroundColor="rgb(255, 255, 255)"
|
||||
onEnd={() =>
|
||||
handleSignatureChange(canvasRef.current.toDataURL())
|
||||
}
|
||||
dotSize={1}
|
||||
/>
|
||||
|
||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||
<SignatureCanvas
|
||||
ref={canvasRef}
|
||||
penColor={penColor}
|
||||
canvasProps={{
|
||||
className: isInitial
|
||||
? "intialSignatureCanvas"
|
||||
: "signatureCanvas",
|
||||
style: {
|
||||
border: "1.6px solid #007bff",
|
||||
borderRadius: "2px"
|
||||
}
|
||||
}}
|
||||
backgroundColor="rgb(255, 255, 255)"
|
||||
onEnd={() =>
|
||||
handleSignatureChange(canvasRef.current.toDataURL())
|
||||
}
|
||||
dotSize={1}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
@@ -553,12 +625,10 @@ function SignPad({
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
{allColor.map((data, key) => {
|
||||
return (
|
||||
<img
|
||||
key={key}
|
||||
alt="pen img"
|
||||
<i
|
||||
style={{
|
||||
border: "none",
|
||||
margin: "5px",
|
||||
color: data,
|
||||
borderBottom:
|
||||
key === 0 && penColor === "blue"
|
||||
? "2px solid blue"
|
||||
@@ -577,14 +647,14 @@ function SignPad({
|
||||
setPenColor("black");
|
||||
}
|
||||
}}
|
||||
src={data}
|
||||
key={key}
|
||||
className="fa solid fa-pen-nib"
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
></i>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<SaveBtn />
|
||||
</div>
|
||||
</>
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from "react";
|
||||
import { themeColor } from "../../constant/const";
|
||||
import "../../styles/signature.css";
|
||||
function Signedby({ pdfDetails }) {
|
||||
const getFirstLetter = (name) => {
|
||||
const firstLetter = name.charAt(0);
|
||||
return firstLetter;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="signerComponent">
|
||||
<div
|
||||
style={{
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
className="signedStyle"
|
||||
>
|
||||
Signed By
|
||||
</div>
|
||||
<div style={{ marginTop: "2px", background: "white" }}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
padding: "10px",
|
||||
background: "#93a3db"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="signerStyle"
|
||||
style={{
|
||||
background: "#abd1d0",
|
||||
width: 20,
|
||||
height: 20,
|
||||
display: "flex",
|
||||
borderRadius: 30 / 2,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginRight: "20px",
|
||||
marginTop: "5px"
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "8px",
|
||||
textAlign: "center",
|
||||
fontWeight: "bold"
|
||||
}}
|
||||
>
|
||||
{getFirstLetter(pdfDetails.ExtUserPtr.Name)}
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
<span className="userName">{pdfDetails.ExtUserPtr.Name}</span>
|
||||
<span className="useEmail">{pdfDetails.ExtUserPtr.Email}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Signedby;
|
||||
@@ -1,14 +1,13 @@
|
||||
import React from "react";
|
||||
import { themeColor } from "../../utils/ThemeColor/backColor";
|
||||
import "../../css/signerListPlace.css";
|
||||
import RecipientList from "../../premitives/RecipientList";
|
||||
import { themeColor } from "../../constant/const";
|
||||
import RecipientList from "./RecipientList";
|
||||
|
||||
function SignerListPlace(props) {
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
padding: "5px"
|
||||
}}
|
||||
>
|
||||
@@ -22,7 +21,7 @@ function SignerListPlace(props) {
|
||||
{props.handleAddSigner && (
|
||||
<div
|
||||
data-tut="reactourAddbtn"
|
||||
className="addSignerBtn"
|
||||
className="p-[10px] my-[2px] flex flex-row items-center justify-center border-[1px] border-[#47a3ad] hover:bg-[#47a3ad] text-[#47a3ad] hover:text-white cursor-pointer"
|
||||
onClick={() => props.handleAddSigner()}
|
||||
>
|
||||
<i className="fa-solid fa-plus"></i>
|
||||
@@ -0,0 +1,421 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
import RecipientList from "./RecipientList";
|
||||
import { useDrag } from "react-dnd";
|
||||
import WidgetList from "./WidgetList";
|
||||
import {
|
||||
radioButtonWidget,
|
||||
textInputWidget,
|
||||
textWidget,
|
||||
widgets
|
||||
} from "../../constant/Utils";
|
||||
import { themeColor } from "../../constant/const";
|
||||
function WidgetComponent({
|
||||
dragSignature,
|
||||
signRef,
|
||||
handleDivClick,
|
||||
handleMouseLeave,
|
||||
dragStamp,
|
||||
isSignYourself,
|
||||
addPositionOfSignature,
|
||||
signersdata,
|
||||
isSelectListId,
|
||||
setSignerObjId,
|
||||
setIsSelectId,
|
||||
setContractName,
|
||||
isSigners,
|
||||
dataTut,
|
||||
isMailSend,
|
||||
handleAddSigner,
|
||||
setUniqueId,
|
||||
setRoleName,
|
||||
handleDeleteUser,
|
||||
signerPos,
|
||||
handleRoleChange,
|
||||
handleOnBlur,
|
||||
title,
|
||||
|
||||
isTemplateFlow
|
||||
}) {
|
||||
const [isSignersModal, setIsSignersModal] = useState(false);
|
||||
|
||||
const [, dropdown] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 5,
|
||||
text: "dropdown"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragDropdown: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, checkbox] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 6,
|
||||
text: "checkbox"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragCheck: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, textInput] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 7,
|
||||
text: textInputWidget
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragTextInput: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, initials] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 8,
|
||||
text: "initials"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragInitial: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, name] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 9,
|
||||
text: "name"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragName: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, company] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 10,
|
||||
text: "company"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragCompany: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, jobTitle] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 11,
|
||||
text: "job title"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragJobtitle: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, date] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 12,
|
||||
text: "date"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragDate: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, image] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 13,
|
||||
text: "image"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragImage: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, email] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 14,
|
||||
text: "email"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragEmail: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, radioButton] = useDrag({
|
||||
type: "BOX",
|
||||
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 15,
|
||||
text: radioButtonWidget
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragRadiotton: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const [, text] = useDrag({
|
||||
type: "BOX",
|
||||
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 16,
|
||||
text: textWidget
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragText: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const scrollContainerRef = useRef(null);
|
||||
const [widget, setWidget] = useState([]);
|
||||
|
||||
const color = [
|
||||
"#93a3db",
|
||||
"#e6c3db",
|
||||
"#c0e3bc",
|
||||
"#bce3db",
|
||||
"#b8ccdb",
|
||||
"#ceb8db",
|
||||
"#ffccff",
|
||||
"#99ffcc",
|
||||
"#cc99ff",
|
||||
"#ffcc99",
|
||||
"#66ccff",
|
||||
"#ffffcc"
|
||||
];
|
||||
const handleModal = () => {
|
||||
setIsSignersModal(!isSignersModal);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const widgetRef = [
|
||||
dragSignature,
|
||||
dragStamp,
|
||||
initials,
|
||||
name,
|
||||
jobTitle,
|
||||
company,
|
||||
date,
|
||||
text,
|
||||
textInput,
|
||||
checkbox,
|
||||
dropdown,
|
||||
radioButton,
|
||||
image,
|
||||
email
|
||||
];
|
||||
const getWidgetArray = widgets;
|
||||
const newUpdateSigner = getWidgetArray.map((obj, ind) => {
|
||||
return { ...obj, ref: widgetRef[ind] };
|
||||
});
|
||||
|
||||
setWidget(newUpdateSigner);
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const filterWidgets = widget.filter(
|
||||
(data) =>
|
||||
data.type !== "dropdown" &&
|
||||
data.type !== radioButtonWidget &&
|
||||
data.type !== textWidget
|
||||
);
|
||||
const textWidgetData = widget.filter((data) => data.type !== textWidget);
|
||||
const updateWidgets = isSignYourself
|
||||
? filterWidgets
|
||||
: isTemplateFlow
|
||||
? textWidgetData
|
||||
: widget;
|
||||
|
||||
return (
|
||||
<>
|
||||
{isMobile ? (
|
||||
!isMailSend && (
|
||||
<div
|
||||
data-tut={dataTut}
|
||||
id="navbar"
|
||||
className="stickyfooter"
|
||||
style={{ width: window.innerWidth + "px" }}
|
||||
>
|
||||
{isSigners && (
|
||||
<div
|
||||
data-tut={dataTut}
|
||||
style={{
|
||||
background: isSelectListId
|
||||
? color[isSelectListId % color.length]
|
||||
: color[0],
|
||||
padding: "10px 20px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
onClick={() => handleModal()}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "13px",
|
||||
fontWeight: "700",
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
{title ? title : "Recipient"}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "13px",
|
||||
fontWeight: "700",
|
||||
display: "flex",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
{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 style={{ marginLeft: 6, fontSize: 16 }}>
|
||||
<i className="fa-solid fa-angle-down"></i>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{handleAddSigner && (
|
||||
<div
|
||||
data-tut="reactourAddbtn"
|
||||
style={{
|
||||
margin: "5px 0 5px 0",
|
||||
backgroundColor: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
className="p-[10px] my-[2px] flex flex-row items-center justify-center border-[1px] border-[#47a3ad] hover:bg-[#47a3ad] text-[#47a3ad] hover:text-white cursor-pointer"
|
||||
onClick={() => handleAddSigner()}
|
||||
>
|
||||
<i className="fa-solid fa-plus"></i>
|
||||
<span style={{ marginLeft: 2 }}>Add role</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
style={{
|
||||
background: "white",
|
||||
borderTop: `2px solid ${themeColor}`
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
overflowX: "scroll",
|
||||
whiteSpace: "nowrap",
|
||||
padding: "10px 5px 10px 1px"
|
||||
}}
|
||||
>
|
||||
<WidgetList
|
||||
updateWidgets={updateWidgets}
|
||||
handleDivClick={handleDivClick}
|
||||
handleMouseLeave={handleMouseLeave}
|
||||
signRef={signRef}
|
||||
marginLeft={5}
|
||||
addPositionOfSignature={addPositionOfSignature}
|
||||
isMobile={isMobile}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<div data-tut={dataTut} className="signerComponent">
|
||||
<div
|
||||
style={{
|
||||
background: themeColor,
|
||||
padding: "5px"
|
||||
}}
|
||||
>
|
||||
<span className="signedStyle">Fields</span>
|
||||
</div>
|
||||
|
||||
<div className="signLayoutContainer1">
|
||||
<WidgetList
|
||||
updateWidgets={updateWidgets}
|
||||
handleDivClick={handleDivClick}
|
||||
handleMouseLeave={handleMouseLeave}
|
||||
signRef={signRef}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isSignersModal && (
|
||||
<ModalUi
|
||||
title={"Roles"}
|
||||
isOpen={isSignersModal}
|
||||
handleClose={handleModal}
|
||||
>
|
||||
{signersdata.length > 0 ? (
|
||||
<RecipientList
|
||||
signerPos={signerPos}
|
||||
signersdata={signersdata}
|
||||
isSelectListId={isSelectListId}
|
||||
setSignerObjId={setSignerObjId}
|
||||
setIsSelectId={setIsSelectId}
|
||||
setContractName={setContractName}
|
||||
setUniqueId={setUniqueId}
|
||||
setRoleName={setRoleName}
|
||||
handleDeleteUser={handleDeleteUser}
|
||||
handleRoleChange={handleRoleChange}
|
||||
handleOnBlur={handleOnBlur}
|
||||
handleModal={handleModal}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
padding: 20,
|
||||
fontSize: 15,
|
||||
fontWeight: "500",
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
Please add a role
|
||||
</div>
|
||||
)}
|
||||
</ModalUi>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default WidgetComponent;
|
||||
@@ -0,0 +1,36 @@
|
||||
import React from "react";
|
||||
import { getWidgetType } from "../../constant/Utils";
|
||||
|
||||
function WidgetList(props) {
|
||||
return props.updateWidgets.map((item, ind) => {
|
||||
return (
|
||||
<div key={ind} style={{ marginBottom: "5px" }}>
|
||||
<div
|
||||
className="widgets"
|
||||
onClick={() => {
|
||||
props.addPositionOfSignature &&
|
||||
props.addPositionOfSignature("onclick", item);
|
||||
}}
|
||||
ref={(element) => {
|
||||
if (!props.isMobile) {
|
||||
item.ref(element);
|
||||
if (element) {
|
||||
if (props?.signRef) {
|
||||
props.signRef.current = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
onMouseMove={props?.handleDivClick}
|
||||
onMouseDown={() => {
|
||||
props?.handleMouseLeave();
|
||||
}}
|
||||
>
|
||||
{item.ref && getWidgetType(item, props?.marginLeft)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export default WidgetList;
|
||||
@@ -0,0 +1,273 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
import "../../styles/AddUser.css";
|
||||
import RegexParser from "regex-parser";
|
||||
import { textInputWidget } from "../../constant/Utils";
|
||||
|
||||
const WidgetNameModal = (props) => {
|
||||
const [formdata, setFormdata] = useState({
|
||||
name: "",
|
||||
defaultValue: "",
|
||||
status: "required",
|
||||
hint: "",
|
||||
textvalidate: "text"
|
||||
});
|
||||
const [isValid, setIsValid] = useState(true);
|
||||
const statusArr = ["Required", "Optional"];
|
||||
const inputOpt = ["email", "number"];
|
||||
|
||||
useEffect(() => {
|
||||
if (props.defaultdata) {
|
||||
setFormdata({
|
||||
name: props.defaultdata?.options?.name || props?.widgetName || "",
|
||||
defaultValue: props.defaultdata?.options?.defaultValue || "",
|
||||
status: props.defaultdata?.options?.status || "required",
|
||||
hint: props.defaultdata?.options?.hint || "",
|
||||
textvalidate:
|
||||
props.defaultdata?.options?.validation?.type === "regex"
|
||||
? props.defaultdata?.options?.validation?.pattern
|
||||
: props.defaultdata?.options?.validation?.type || ""
|
||||
});
|
||||
} else {
|
||||
setFormdata({
|
||||
...formdata,
|
||||
name: props.defaultdata?.options?.name || props?.widgetName || ""
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [props.defaultdata, props.widgetName]);
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (props.handleData) {
|
||||
props.handleData(formdata);
|
||||
setFormdata({
|
||||
name: "",
|
||||
defaultValue: "",
|
||||
status: "required",
|
||||
hint: "",
|
||||
textvalidate: "text"
|
||||
});
|
||||
}
|
||||
};
|
||||
const handleChange = (e) => {
|
||||
setFormdata({ ...formdata, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
const handledefaultChange = (e) => {
|
||||
if (formdata.textvalidate) {
|
||||
const regexObject = RegexParser(handleValidation(formdata.textvalidate));
|
||||
const isValidate = regexObject?.test(e.target.value);
|
||||
setIsValid(isValidate);
|
||||
} else {
|
||||
setIsValid(true);
|
||||
}
|
||||
setFormdata({ ...formdata, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
function handleValidation(type) {
|
||||
switch (type) {
|
||||
case "email":
|
||||
return "/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/";
|
||||
case "number":
|
||||
return "/^\\d+$/";
|
||||
case textInputWidget:
|
||||
return "/^[a-zA-Zs]+$/";
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
function handleBlurRegex() {
|
||||
if (!formdata.textvalidate) {
|
||||
setFormdata({ ...formdata, textvalidate: "text" });
|
||||
} else {
|
||||
if (formdata.defaultValue) {
|
||||
const regexObject = RegexParser(
|
||||
handleValidation(formdata.textvalidate)
|
||||
);
|
||||
const isValidate = regexObject?.test(formdata.defaultValue);
|
||||
if (isValidate === false) {
|
||||
setFormdata({ ...formdata, defaultValue: "" });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<ModalUi
|
||||
isOpen={props.isOpen}
|
||||
handleClose={props.handleClose && props.handleClose}
|
||||
title={"Widget info"}
|
||||
>
|
||||
<form onSubmit={handleSubmit} style={{ padding: 20 }}>
|
||||
<div className="form-section">
|
||||
<label htmlFor="name" style={{ fontSize: 13 }}>
|
||||
Name
|
||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||
</label>
|
||||
<input
|
||||
className="addUserInput"
|
||||
name="name"
|
||||
value={formdata.name}
|
||||
onChange={(e) => handleChange(e)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
{(props.defaultdata?.type === textInputWidget ||
|
||||
props.widgetName === textInputWidget) && (
|
||||
<>
|
||||
<div className="form-section">
|
||||
<label htmlFor="textvalidate" style={{ fontSize: 13 }}>
|
||||
Validation
|
||||
</label>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
marginBottom: "0.5rem"
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "100%", position: "relative" }}>
|
||||
<input
|
||||
className="relative z-20 w-[87%] md:w-[92%] p-2.5 border-[1px] border-[#d1d5db] rounded-l-md outline-none text-xs"
|
||||
name="textvalidate"
|
||||
placeholder="Enter custom expression"
|
||||
value={formdata.textvalidate}
|
||||
onChange={(e) => handleChange(e)}
|
||||
// onBlur={() => handleBlurRegex()}
|
||||
/>
|
||||
<select
|
||||
className="validationlist addUserInput"
|
||||
name="textvalidate"
|
||||
value={formdata.textvalidate}
|
||||
onChange={(e) => handleChange(e)}
|
||||
onBlur={() => handleBlurRegex()}
|
||||
>
|
||||
<option disabled style={{ fontSize: "13px" }}>
|
||||
Select...
|
||||
</option>
|
||||
{inputOpt.map((data, ind) => {
|
||||
return (
|
||||
<option
|
||||
style={{ fontSize: "13px" }}
|
||||
key={ind}
|
||||
value={data}
|
||||
>
|
||||
{data}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-section">
|
||||
<label htmlFor="name" style={{ fontSize: 13 }}>
|
||||
Default value
|
||||
</label>
|
||||
<input
|
||||
className="addUserInput"
|
||||
name="defaultValue"
|
||||
value={formdata.defaultValue}
|
||||
onChange={(e) => handledefaultChange(e)}
|
||||
onBlur={() =>
|
||||
isValid === false &&
|
||||
setFormdata({ ...formdata, defaultValue: "" })
|
||||
}
|
||||
/>
|
||||
{isValid === false ? (
|
||||
<p style={{ color: "Red", fontSize: 8 }}>
|
||||
invalid default value
|
||||
</p>
|
||||
) : (
|
||||
<p
|
||||
style={{
|
||||
color: "transparent",
|
||||
fontSize: 10,
|
||||
margin: "3px 8px"
|
||||
}}
|
||||
>
|
||||
.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="form-section">
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
marginBottom: "0.5rem"
|
||||
}}
|
||||
>
|
||||
{statusArr.map((data, ind) => {
|
||||
return (
|
||||
<div
|
||||
key={ind}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 5,
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<input
|
||||
style={{ accentColor: "red", marginRight: "10px" }}
|
||||
type="radio"
|
||||
name="status"
|
||||
onChange={() =>
|
||||
setFormdata({ ...formdata, status: data.toLowerCase() })
|
||||
}
|
||||
checked={
|
||||
formdata.status.toLowerCase() === data.toLowerCase()
|
||||
}
|
||||
/>
|
||||
<div style={{ fontSize: "13px", fontWeight: "500" }}>
|
||||
{data}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{(props.defaultdata?.type === textInputWidget ||
|
||||
props?.widgetName === textInputWidget) && (
|
||||
<div className="form-section">
|
||||
<label htmlFor="hint" style={{ fontSize: 13 }}>
|
||||
Hint
|
||||
</label>
|
||||
<input
|
||||
className="addUserInput"
|
||||
name="hint"
|
||||
value={formdata.hint}
|
||||
onChange={(e) => handleChange(e)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
height: 1,
|
||||
backgroundColor: "#b7b3b3",
|
||||
width: "100%",
|
||||
marginBottom: "16px"
|
||||
}}
|
||||
></div>
|
||||
<button
|
||||
style={{
|
||||
color: "white",
|
||||
padding: "5px 20px",
|
||||
backgroundColor: "#32a3ac"
|
||||
}}
|
||||
type="submit"
|
||||
className="finishBtn"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</form>
|
||||
</ModalUi>
|
||||
);
|
||||
};
|
||||
|
||||
export default WidgetNameModal;
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Parse from "parse";
|
||||
import Alert from "../../primitives/Alert";
|
||||
import Alert from "../../../primitives/Alert";
|
||||
|
||||
const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
const folderPtr = {
|
||||
@@ -11,6 +11,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
const [name, setName] = useState("");
|
||||
const [folderList, setFolderList] = useState([]);
|
||||
const [isAlert, setIsAlert] = useState(false);
|
||||
const [isLoader, setIsLoader] = useState(false);
|
||||
const [selectedParent, setSelectedParent] = useState();
|
||||
const [alert, setAlert] = useState({ type: "info", message: "" });
|
||||
useEffect(() => {
|
||||
@@ -42,6 +43,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
};
|
||||
const handleCreateFolder = async (event) => {
|
||||
event.preventDefault();
|
||||
handleLoader(true);
|
||||
if (name) {
|
||||
const currentUser = Parse.User.current();
|
||||
const exsitQuery = new Parse.Query(folderCls);
|
||||
@@ -52,7 +54,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
}
|
||||
const templExist = await exsitQuery.first();
|
||||
if (templExist) {
|
||||
setAlert({ type: "dange", message: "Folder already exist!" });
|
||||
setAlert({ type: "danger", message: "Folder already exist!" });
|
||||
setIsAlert(true);
|
||||
setTimeout(() => {
|
||||
setIsAlert(false);
|
||||
@@ -74,6 +76,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||
const res = await template.save();
|
||||
if (res) {
|
||||
handleLoader(false);
|
||||
setAlert({
|
||||
type: "success",
|
||||
message: "Folder created successfully!"
|
||||
@@ -88,6 +91,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleLoader(false);
|
||||
setAlert({ type: "info", message: "Please fill folder name" });
|
||||
setIsAlert(true);
|
||||
setTimeout(() => {
|
||||
@@ -98,10 +102,21 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
const handleOptions = (e) => {
|
||||
setSelectedParent(e.target.value);
|
||||
};
|
||||
const handleLoader = (status) => {
|
||||
setIsLoader(status);
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
{isAlert && <Alert type={alert.type}>{alert.message}</Alert>}
|
||||
<div id="createFolder">
|
||||
<div id="createFolder" className="relative">
|
||||
{isLoader && (
|
||||
<div className="absolute h-full w-full flex justify-center items-center ">
|
||||
<div
|
||||
style={{ fontSize: "45px", color: "#3dd3e0" }}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
)}
|
||||
<h1 className="text-base font-semibold">Create Folder</h1>
|
||||
<div className="text-xs mt-2">
|
||||
<label className="block">
|
||||
@@ -133,6 +148,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||
<div>
|
||||
<button
|
||||
onClick={handleCreateFolder}
|
||||
disabled={isLoader}
|
||||
className="flex items-center rounded p-2 bg-[#32a3ac] text-white mt-3"
|
||||
>
|
||||
<i className="fa-solid fa-plus mr-1"></i>
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import { useDropScript } from "../../hook/useScript";
|
||||
import { useDropScript } from "../../../hook/useScript";
|
||||
|
||||
const DROPBOX_APP_KEY = process.env.REACT_APP_DROPBOX_API_KEY; // App key
|
||||
const DROPBOX_SDK_URL = "https://www.dropbox.com/static/api/2/dropins.js";
|
||||
@@ -41,12 +41,15 @@ export default function DropboxChooser({ children, onSuccess, onCancel }) {
|
||||
[onSuccess, onCancel]
|
||||
);
|
||||
|
||||
const handleChoose = useCallback((e) => {
|
||||
e.preventDefault()
|
||||
if (window.Dropbox) {
|
||||
window.Dropbox.choose(options);
|
||||
}
|
||||
}, [options]);
|
||||
const handleChoose = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
if (window.Dropbox) {
|
||||
window.Dropbox.choose(options);
|
||||
}
|
||||
},
|
||||
[options]
|
||||
);
|
||||
|
||||
return (
|
||||
<div onClick={handleChoose}>
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Parse from "parse";
|
||||
import CreateFolder from "./CreateFolder";
|
||||
import ModalUi from "../../primitives/ModalUi";
|
||||
import ModalUi from "../../../primitives/ModalUi";
|
||||
import Tooltip from "../../../primitives/Tooltip";
|
||||
|
||||
const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
const SelectFolder = ({ required, onSuccess, folderCls, isReset }) => {
|
||||
const [isOpen, SetIsOpen] = useState(false);
|
||||
const [clickFolder, setClickFolder] = useState("");
|
||||
const [selectFolder, setSelectedFolder] = useState({});
|
||||
@@ -22,6 +23,21 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [isOpen]);
|
||||
// below useEffect is used to reset folder selection if user pass isReset = true from parent component
|
||||
useEffect(() => {
|
||||
if (isReset == true) {
|
||||
handleReset();
|
||||
}
|
||||
}, [isReset]);
|
||||
const handleReset = () => {
|
||||
setFolderPath({});
|
||||
setSelectedFolder("");
|
||||
setClickFolder("");
|
||||
setIsAdd(false);
|
||||
setFolderList([]);
|
||||
setTabList([]);
|
||||
};
|
||||
// `fetchFolder` is used to fetch of folder list created by user on basis of folderPtr or without folderPtr
|
||||
const fetchFolder = async (folderPtr) => {
|
||||
setIsLoader(true);
|
||||
try {
|
||||
@@ -47,6 +63,8 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
setIsLoader(false);
|
||||
}
|
||||
};
|
||||
|
||||
// `handleSelect` is used to save pointer of folder selected by user and it's path in state
|
||||
const handleSelect = (item) => {
|
||||
setFolderList([]);
|
||||
setClickFolder({ ObjectId: item.objectId, Name: item.Name });
|
||||
@@ -73,8 +91,9 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
}
|
||||
};
|
||||
|
||||
// `handleSubmit` is used to pass folderPtr to parent component
|
||||
const handleSubmit = () => {
|
||||
let url = "Root";
|
||||
let url = "OpenSign™ Drive";
|
||||
tabList.forEach((t) => {
|
||||
url = url + " / " + t.Name;
|
||||
});
|
||||
@@ -85,6 +104,8 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
}
|
||||
SetIsOpen(false);
|
||||
};
|
||||
|
||||
// `handleCancel` is used to clear list of folder, close popup and folderUrl
|
||||
const handleCancel = () => {
|
||||
SetIsOpen(false);
|
||||
setClickFolder({});
|
||||
@@ -92,6 +113,7 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
setTabList([]);
|
||||
};
|
||||
|
||||
// `handleCancel` is call when user click on folder name from path/tab in popup
|
||||
const removeTabListItem = async (e, i) => {
|
||||
e.preventDefault();
|
||||
// setEditable(false);
|
||||
@@ -121,9 +143,11 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
fetchFolder(folderPtr);
|
||||
}
|
||||
};
|
||||
// `handleCreate` is used to open folder creation form in popup
|
||||
const handleCreate = () => {
|
||||
setIsAdd(!isAdd);
|
||||
};
|
||||
// `handleAddFolder` is call when user folder created successfully and it fetch folder list on the basis of folderPtr or without folderPtr
|
||||
const handleAddFolder = () => {
|
||||
setFolderList([]);
|
||||
if (clickFolder && clickFolder.ObjectId) {
|
||||
@@ -145,7 +169,7 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
{required && <span className="text-red-500 text-[13px]">*</span>}
|
||||
</label>
|
||||
</div>
|
||||
<div className="rounded px-[20px] py-[20px] bg-white border border-gray-200 shadow flex max-w-sm gap-8 items-center">
|
||||
<div className="relative rounded px-[20px] py-[20px] bg-white border border-gray-200 shadow flex max-w-sm gap-8 items-center">
|
||||
<div>
|
||||
<i
|
||||
className="far fa-folder-open text-[40px] text-[#33bbff]"
|
||||
@@ -156,7 +180,9 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
<div className="font-semibold ">
|
||||
<div className="flex items-center gap-2">
|
||||
<p>
|
||||
{selectFolder && selectFolder.Name ? selectFolder.Name : "Root"}
|
||||
{selectFolder && selectFolder.Name
|
||||
? selectFolder.Name
|
||||
: "OpenSign™ Drive"}
|
||||
</p>
|
||||
<div className="text-black text-sm" onClick={() => SetIsOpen(true)}>
|
||||
<i
|
||||
@@ -170,20 +196,27 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
{selectFolder && selectFolder.Name ? `(${folderPath})` : ""}
|
||||
</p>
|
||||
</div>
|
||||
<div className="absolute top-1 right-1 cursor-pointer">
|
||||
<Tooltip
|
||||
message={
|
||||
"If you do not select a folder, your signed document will be saved in the Main OpenSign drive folder."
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ModalUi
|
||||
title={"Select Folder"}
|
||||
isOpen={isOpen}
|
||||
handleClose={handleCancel}
|
||||
>
|
||||
<div className="w-full min-w-[300px] md:min-w-[500px] px-3">
|
||||
<div className="w-full min-w-[300px] md:min-w-[500px] max-w-[500px] px-3">
|
||||
<div className="py-2 text-[#ac4848] text-[14px] font-[500]">
|
||||
<span
|
||||
className="cursor-pointer"
|
||||
title="Root"
|
||||
title="OpenSign™ Drive"
|
||||
onClick={(e) => removeTabListItem(e)}
|
||||
>
|
||||
Root /{" "}
|
||||
OpenSign™ Drive /{" "}
|
||||
</span>
|
||||
{tabList &&
|
||||
tabList.map((tab, i) => (
|
||||
@@ -201,23 +234,25 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||
<hr />
|
||||
</div>
|
||||
<div className="mt-2 mb-3">
|
||||
{!isAdd &&
|
||||
folderList.length > 0 &&
|
||||
folderList.map((folder) => (
|
||||
<div
|
||||
key={folder.Name}
|
||||
className="border-[1px] border-[#8a8a8a] px-2 py-2 mb-2 cursor-pointer"
|
||||
onClick={() => handleSelect(folder)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<i
|
||||
className="fa fa-folder text-[#33bbff] text-[1.4rem]"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span className="font-semibold">{folder.Name}</span>
|
||||
<div className="max-h-[210px] overflow-auto">
|
||||
{!isAdd &&
|
||||
folderList.length > 0 &&
|
||||
folderList.map((folder) => (
|
||||
<div
|
||||
key={folder.Name}
|
||||
className="border-[1px] border-[#8a8a8a] px-2 py-2 mb-2 cursor-pointer "
|
||||
onClick={() => handleSelect(folder)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<i
|
||||
className="fa fa-folder text-[#33bbff] text-[1.4rem]"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span className="font-semibold">{folder.Name}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
))}
|
||||
</div>
|
||||
{isAdd && (
|
||||
<CreateFolder
|
||||
parentFolderId={clickFolder && clickFolder.ObjectId}
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import Parse from "parse";
|
||||
import "../css/AddUser.css";
|
||||
import "../../../styles/AddUser.css";
|
||||
import AsyncSelect from "react-select/async";
|
||||
|
||||
const customStyles = {
|
||||
@@ -17,12 +17,7 @@ const SelectSigners = (props) => {
|
||||
const [userList, setUserList] = useState([]);
|
||||
const [selected, setSelected] = useState();
|
||||
const [userData, setUserData] = useState({});
|
||||
const [isError, setIsError]= useState(false)
|
||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
|
||||
const [isError, setIsError] = useState(false);
|
||||
// `handleOptions` is used to set just save from quick form to selected option in dropdown
|
||||
const handleOptions = (item) => {
|
||||
setSelected(item);
|
||||
@@ -32,14 +27,14 @@ const SelectSigners = (props) => {
|
||||
}
|
||||
};
|
||||
const handleAdd = () => {
|
||||
if(userData && userData.objectId){
|
||||
if (userData && userData.objectId) {
|
||||
props.details(userData);
|
||||
if (props.closePopup) {
|
||||
props.closePopup();
|
||||
}
|
||||
}else{
|
||||
setIsError(true)
|
||||
setTimeout(()=> setIsError(false), 1000)
|
||||
} else {
|
||||
setIsError(true);
|
||||
setTimeout(() => setIsError(false), 1000);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -73,8 +68,8 @@ const SelectSigners = (props) => {
|
||||
return (
|
||||
<div className="addusercontainer">
|
||||
<div className="form-wrapper">
|
||||
<div className="form-section" style={{marginBottom: 0}}>
|
||||
<label style={{ fontSize: 14 , fontWeight: "700"}}>Choose User</label>
|
||||
<div className="form-section" style={{ marginBottom: 0 }}>
|
||||
<label style={{ fontSize: 14, fontWeight: "700" }}>Choose User</label>
|
||||
<AsyncSelect
|
||||
cacheOptions
|
||||
defaultOptions
|
||||
@@ -86,7 +81,15 @@ const SelectSigners = (props) => {
|
||||
styles={customStyles}
|
||||
/>
|
||||
</div>
|
||||
{isError ? <p style={{color:'red', fontSize: "12px", margin:"5px"}}>Please select signer</p>: <p style={{color:'transparent', fontSize: "12px", margin:"5px"}}>.</p>}
|
||||
{isError ? (
|
||||
<p style={{ color: "red", fontSize: "12px", margin: "5px" }}>
|
||||
Please select signer
|
||||
</p>
|
||||
) : (
|
||||
<p style={{ color: "transparent", fontSize: "12px", margin: "5px" }}>
|
||||
.
|
||||
</p>
|
||||
)}
|
||||
<div>
|
||||
<button className="submitbutton" onClick={() => handleAdd()}>
|
||||
Submit
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Select from "react-select";
|
||||
import AppendFormInForm from "../AppendFormInForm";
|
||||
import AddSigner from "../../AddSigner";
|
||||
import Modal from "react-modal";
|
||||
import Parse from "parse";
|
||||
function arrayMove(array, from, to) {
|
||||
@@ -19,7 +19,7 @@ const SignersInput = (props) => {
|
||||
Modal.setAppElement("body");
|
||||
const [state, setState] = useState(undefined);
|
||||
// const [editFormData, setEditFormData] = useState([]);
|
||||
const [selected, setSelected] = React.useState([]);
|
||||
const [selected, setSelected] = useState([]);
|
||||
const [isModal, setIsModel] = useState(false);
|
||||
const onChange = (selectedOptions) => setSelected(selectedOptions);
|
||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
||||
@@ -63,6 +63,11 @@ const SignersInput = (props) => {
|
||||
useEffect(() => {
|
||||
GetSelectListData();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (props.isReset && props.isReset === true) {
|
||||
setSelected([]);
|
||||
}
|
||||
}, [props.isReset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selected && selected.length) {
|
||||
@@ -172,7 +177,7 @@ const SignersInput = (props) => {
|
||||
</div>
|
||||
|
||||
{isModal && (
|
||||
<AppendFormInForm
|
||||
<AddSigner
|
||||
valueKey={"objectId"}
|
||||
displayKey={"Name"}
|
||||
details={handleNewDetails}
|
||||
@@ -2,20 +2,24 @@ import React from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
|
||||
const Menu = ({ item, isOpen, closeSidebar }) => {
|
||||
return (
|
||||
<li key={item.title} role="none">
|
||||
<NavLink
|
||||
to={`/${item.pageType}/${item.objectId}`}
|
||||
className="mx-auto flex items-center hover:bg-[#eef1f5] p-3 lg:p-4"
|
||||
onClick={closeSidebar}
|
||||
tabIndex={isOpen ? 0 : -1}
|
||||
role="menuitem"
|
||||
>
|
||||
<i className={`${item.icon} text-[18px]`} aria-hidden="true"></i>
|
||||
<span className="ml-3 lg:ml-4">{item.title}</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<li key={item.title} role="none">
|
||||
<NavLink
|
||||
to={
|
||||
item.pageType
|
||||
? `/${item.pageType}/${item.objectId}`
|
||||
: `/${item.objectId}`
|
||||
}
|
||||
className="mx-auto flex items-center hover:bg-[#eef1f5] p-3 lg:p-4 cursor-pointer"
|
||||
onClick={closeSidebar}
|
||||
tabIndex={isOpen ? 0 : -1}
|
||||
role="menuitem"
|
||||
>
|
||||
<i className={`${item.icon} text-[18px]`} aria-hidden="true"></i>
|
||||
<span className="ml-3 lg:ml-4">{item.title}</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
export default Menu;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
import Menu from './Menu';
|
||||
import Menu from "./Menu";
|
||||
import Submenu from "./SubMenu";
|
||||
import SocialMedia from './SocialMedia';
|
||||
import SocialMedia from "./SocialMedia";
|
||||
|
||||
import Parse from "parse";
|
||||
import dp from "../../assets/images/dp.png";
|
||||
@@ -20,16 +20,10 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||
}, []);
|
||||
|
||||
const menuItem = async () => {
|
||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
var sideMenu = Parse.Object.extend("w_menu");
|
||||
var query = new Parse.Query(sideMenu);
|
||||
query.equalTo("objectId", localStorage.getItem("defaultmenuid"));
|
||||
|
||||
const results = await query.first();
|
||||
const resultjson = results.toJSON();
|
||||
let result = resultjson;
|
||||
@@ -37,7 +31,6 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -47,7 +40,11 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||
>
|
||||
<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">
|
||||
<img className="w-full h-full object-cover" src={image} alt="Profile" />
|
||||
<img
|
||||
className="w-full h-full object-cover"
|
||||
src={image}
|
||||
alt="Profile"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[14px] font-bold">{username}</p>
|
||||
@@ -57,14 +54,27 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||
</div>
|
||||
</div>
|
||||
<nav aria-label="OpenSign Sidebar Navigation">
|
||||
<ul className="text-sm" role="menubar" aria-label="OpenSign Sidebar Navigation">
|
||||
{menuList.map((item) => (
|
||||
<ul
|
||||
className="text-sm"
|
||||
role="menubar"
|
||||
aria-label="OpenSign Sidebar Navigation"
|
||||
>
|
||||
{menuList.map((item) =>
|
||||
!item.children ? (
|
||||
<Menu key={item.title} item={item} isOpen={isOpen} closeSidebar={closeSidebar} />
|
||||
<Menu
|
||||
key={item.title}
|
||||
item={item}
|
||||
isOpen={isOpen}
|
||||
closeSidebar={closeSidebar}
|
||||
/>
|
||||
) : (
|
||||
<Submenu key={item.title} item={item} closeSidebar={closeSidebar} />
|
||||
<Submenu
|
||||
key={item.title}
|
||||
item={item}
|
||||
closeSidebar={closeSidebar}
|
||||
/>
|
||||
)
|
||||
))}
|
||||
)}
|
||||
</ul>
|
||||
</nav>
|
||||
<footer className="mt-4 flex justify-center items-center text-[25px] text-black gap-3">
|
||||
|
||||
@@ -22,8 +22,9 @@ const Submenu = ({ item, closeSidebar }) => {
|
||||
<div className="flex justify-between items-center w-full">
|
||||
<span className="ml-3 lg:ml-4">{title}</span>
|
||||
<i
|
||||
className={`${submenuOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
|
||||
}`}
|
||||
className={`${
|
||||
submenuOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
|
||||
}`}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</div>
|
||||
@@ -33,13 +34,20 @@ const Submenu = ({ item, closeSidebar }) => {
|
||||
{children.map((childItem) => (
|
||||
<li key={childItem.title} role="none">
|
||||
<NavLink
|
||||
to={`/${childItem.pageType}/${childItem.objectId}`}
|
||||
className="block pl-6 md:pl-8 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white"
|
||||
to={
|
||||
childItem.pageType
|
||||
? `/${childItem.pageType}/${childItem.objectId}`
|
||||
: `/${childItem.objectId}`
|
||||
}
|
||||
className="block pl-6 md:pl-8 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white cursor-pointer"
|
||||
onClick={closeSidebar}
|
||||
role="menuitem"
|
||||
tabIndex={submenuOpen ? 0 : -1}
|
||||
>
|
||||
<i className={`${childItem.icon} text-[18px]`} aria-hidden="true"></i>
|
||||
<i
|
||||
className={`${childItem.icon} text-[18px]`}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span className="ml-3 lg:ml-4">{childItem.title}</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
@@ -3,7 +3,10 @@ export const appInfo = {
|
||||
appTitle: "contracts",
|
||||
applogo: logo,
|
||||
appname: "contracts",
|
||||
baseurl: process.env.REACT_APP_SERVERURL,
|
||||
appId: process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign",
|
||||
baseUrl: process.env.REACT_APP_SERVERURL
|
||||
? process.env.REACT_APP_SERVERURL
|
||||
: window.location.origin + "/api/app",
|
||||
defaultRole: "contracts_User",
|
||||
fbAppId: process.env.REACT_APP_FBAPPID
|
||||
? `${process.env.REACT_APP_FBAPPID}`
|
||||
|
||||
@@ -7,3 +7,5 @@ export const submitBtn =
|
||||
"bg-[#32a3ac] rounded-sm shadow-md text-[12px] font-semibold uppercase text-white py-1.5 px-4 focus:outline-none text-center";
|
||||
export const modalSubmitBtnColor = "#17a2b8";
|
||||
export const modalCancelBtnColor = "white";
|
||||
export const themeColor = "#47a3ad";
|
||||
export const iconColor = "#686968";
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import axios from "axios";
|
||||
import Parse from "parse";
|
||||
const parseAppId = localStorage.getItem("AppID12");
|
||||
const serverUrl = localStorage.getItem("BaseUrl12");
|
||||
Parse.serverURL = serverUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
const serverUrl = localStorage.getItem("baseUrl");
|
||||
|
||||
export const SaveFileSize = async (size, imageUrl) => {
|
||||
//checking server url and save file's size
|
||||
|
||||
@@ -1 +1,71 @@
|
||||
import("./Bootstrap");
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import { Provider } from "react-redux";
|
||||
import { store } from "./redux/store";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { TouchBackend } from "react-dnd-touch-backend";
|
||||
import {
|
||||
DndProvider,
|
||||
TouchTransition,
|
||||
MouseTransition,
|
||||
Preview
|
||||
} from "react-dnd-multi-backend";
|
||||
import DragElement from "./components/pdf/DragElement";
|
||||
import TagManager from "react-gtm-module";
|
||||
import Parse from "parse";
|
||||
const appId = process.env.REACT_APP_APPID
|
||||
? process.env.REACT_APP_APPID
|
||||
: "opensign";
|
||||
const serverUrl = process.env.REACT_APP_SERVERURL
|
||||
? process.env.REACT_APP_SERVERURL
|
||||
: window.location.origin + "/api/app";
|
||||
Parse.initialize(appId);
|
||||
Parse.serverURL = serverUrl;
|
||||
|
||||
const HTML5toTouch = {
|
||||
backends: [
|
||||
{
|
||||
id: "html5",
|
||||
backend: HTML5Backend,
|
||||
transition: MouseTransition
|
||||
},
|
||||
{
|
||||
id: "touch",
|
||||
backend: TouchBackend,
|
||||
options: { enableMouseEvents: true },
|
||||
preview: true,
|
||||
transition: TouchTransition
|
||||
}
|
||||
]
|
||||
};
|
||||
const generatePreview = (props) => {
|
||||
const { item, style } = props;
|
||||
const newStyle = {
|
||||
...style
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={newStyle}>
|
||||
<DragElement {...item} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
if (process.env.REACT_APP_GTM) {
|
||||
const tagManagerArgs = {
|
||||
gtmId: process.env.REACT_APP_GTM
|
||||
};
|
||||
TagManager.initialize(tagManagerArgs);
|
||||
}
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<DndProvider options={HTML5toTouch}>
|
||||
<Preview>{generatePreview}</Preview>
|
||||
<App />
|
||||
</DndProvider>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
@@ -16,8 +16,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
redirectUrl: "draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -32,8 +31,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#3ac9d6",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
redirectUrl: "pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -48,8 +46,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#3ac9d6",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
redirectUrl: "pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -64,8 +61,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
redirectUrl: "draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -80,8 +76,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
redirectUrl: "draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -96,8 +91,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
redirectUrl: "draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -112,8 +106,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
redirectUrl: "pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -128,8 +121,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
redirectUrl: "pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -144,8 +136,7 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
redirectUrl: "draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -175,16 +166,14 @@ export default function reportJson(id) {
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/placeHolderSign"
|
||||
redirectUrl: "placeHolderSign"
|
||||
},
|
||||
{
|
||||
btnLabel: "Edit",
|
||||
btnColor: "#00c9d5",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/template"
|
||||
redirectUrl: "template"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -94,10 +94,16 @@ const HomeLayout = () => {
|
||||
position: "top"
|
||||
// style: { backgroundColor: "#abd4d2" },
|
||||
},
|
||||
{
|
||||
selector: '[data-tut="tourbutton"]',
|
||||
content: `To upload documents for self-signing or to request others’ signatures, simply select the respective buttons.`,
|
||||
position: "top"
|
||||
// style: { backgroundColor: "#abd4d2" },
|
||||
},
|
||||
...resArr,
|
||||
{
|
||||
selector: '[data-tut="reactourLast"]',
|
||||
content: `You are good to go`,
|
||||
content: `You are ready to start using OpenSign! If you need support feel free to contact us.`,
|
||||
position: "top"
|
||||
// style: { backgroundColor: "#abd4d2" },
|
||||
}
|
||||
@@ -110,7 +116,7 @@ const HomeLayout = () => {
|
||||
// console.log("closeTour");
|
||||
setIsTour(false);
|
||||
const serverUrl = localStorage.getItem("baseUrl");
|
||||
const appId = localStorage.getItem("AppID12");
|
||||
const appId = localStorage.getItem("parseAppId");
|
||||
const extUserClass = localStorage.getItem("extended_class");
|
||||
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
const extUserId = json && json.length > 0 && json[0].objectId;
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import React from "react";
|
||||
import stamp from "./stamp2.png";
|
||||
import sign from "./sign3.png";
|
||||
import { themeColor } from "./IconColor.js";
|
||||
|
||||
function DragElement({ id }) {
|
||||
const selectedId = id;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{selectedId === 3 ? (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="sign img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "23px",
|
||||
background: themeColor()
|
||||
}}
|
||||
src={sign}
|
||||
/>
|
||||
<span style={{ color: themeColor(), fontSize: "12px" }}>
|
||||
Signature
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="stamp img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "23px",
|
||||
background: themeColor()
|
||||
}}
|
||||
src={stamp}
|
||||
/>
|
||||
<span style={{ color: themeColor(), fontSize: "12px" }}>Stamp</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DragElement;
|
||||
@@ -1,3 +0,0 @@
|
||||
export const themeColor = () => {
|
||||
return "#47a3ad";
|
||||
};
|
||||
|
Before Width: | Height: | Size: 804 B |
|
Before Width: | Height: | Size: 561 B |
@@ -11,8 +11,6 @@ function ChangePassword() {
|
||||
evt.preventDefault();
|
||||
try {
|
||||
if (newpassword === confirmpassword) {
|
||||
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||
Parse.User.logIn(localStorage.getItem("userEmail"), currentpassword)
|
||||
.then(async (user) => {
|
||||
if (user) {
|
||||
@@ -12,8 +12,6 @@ const Dashboard = (props) => {
|
||||
const [dashboard, setdashboard] = useState([]);
|
||||
const [classnameArray, setclassnameArray] = useState([]);
|
||||
const [loading, setloading] = useState(false);
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [defaultQuery, setDefaultQuery] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
@@ -32,8 +30,6 @@ const Dashboard = (props) => {
|
||||
const getDashboard = async (id) => {
|
||||
setloading(true);
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
var forms = Parse.Object.extend("w_dashboard");
|
||||
var query = new Parse.Query(forms);
|
||||
query.equalTo("objectId", id);
|
||||
@@ -1,13 +1,13 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||
import "../css/./signature.css";
|
||||
import "../css/AddUser.css";
|
||||
import Title from "./component/Title";
|
||||
import ModalUi from "../premitives/ModalUi";
|
||||
import RenderDebugPdf from "./component/RenderDebugPdf";
|
||||
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
||||
import "../styles/signature.css";
|
||||
import "../styles/AddUser.css";
|
||||
import Title from "../components/Title";
|
||||
import RenderDebugPdf from "../components/RenderDebugPdf";
|
||||
import { pdfjs } from "react-pdf";
|
||||
import Alert from "../premitives/Alert";
|
||||
import HandleError from "./component/HandleError";
|
||||
import ModalUi from "../primitives/ModalUi";
|
||||
import Alert from "../primitives/Alert";
|
||||
import HandleError from "../primitives/HandleError";
|
||||
import { useWindowSize } from "../hook/useWindowSize";
|
||||
|
||||
function processDimensions(x, y, width, height) {
|
||||
@@ -28,7 +28,7 @@ function processDimensions(x, y, width, height) {
|
||||
height: Math.floor(height)
|
||||
};
|
||||
}
|
||||
const DebugUi = () => {
|
||||
const DebugPdf = () => {
|
||||
const { width } = useWindowSize();
|
||||
const [pdf, setPdf] = useState("");
|
||||
const [isModal, setIsModal] = useState(true);
|
||||
@@ -426,4 +426,4 @@ const DebugUi = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default DebugUi;
|
||||
export default DebugPdf;
|
||||
@@ -4,13 +4,15 @@ import { fetchAppInfo, forgetPassword } from "../redux/actions";
|
||||
import Title from "../components/Title";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import login_img from "../assets/images/login_img.svg";
|
||||
|
||||
import Parse from "parse";
|
||||
import Alert from "../primitives/Alert";
|
||||
function ForgotPassword(props) {
|
||||
const [state, setState] = useState({
|
||||
email: "",
|
||||
password: "",
|
||||
hideNav: ""
|
||||
});
|
||||
const [sentStatus, setSentStatus] = useState("");
|
||||
const handleChange = (event) => {
|
||||
const { name, value } = event.target;
|
||||
setState({ ...state, [name]: value });
|
||||
@@ -23,7 +25,7 @@ function ForgotPassword(props) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
localStorage.setItem("appLogo", props.appInfo.applogo);
|
||||
localStorage.setItem("appName", props.appInfo.appname);
|
||||
@@ -33,14 +35,22 @@ function ForgotPassword(props) {
|
||||
"userSettings",
|
||||
JSON.stringify(props.appInfo.settings)
|
||||
);
|
||||
|
||||
if (state.email) {
|
||||
props.forgetPassword(state.email);
|
||||
const username = state.email;
|
||||
try {
|
||||
await Parse.User.requestPasswordReset(username);
|
||||
setSentStatus("success");
|
||||
} catch (err) {
|
||||
console.log("err ", err.code);
|
||||
setSentStatus("failed");
|
||||
} finally {
|
||||
setTimeout(() => setSentStatus(""), 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
props.fetchAppInfo(localStorage.getItem("domain"));
|
||||
props.fetchAppInfo();
|
||||
resize();
|
||||
window.addEventListener("resize", resize);
|
||||
return () => window.removeEventListener("resize", resize);
|
||||
@@ -51,6 +61,14 @@ function ForgotPassword(props) {
|
||||
return (
|
||||
<div className="bg-white">
|
||||
<Title title="Forgot password page" />
|
||||
{sentStatus === "success" && (
|
||||
<Alert type="success">
|
||||
Reset password link has been sent to your email id
|
||||
</Alert>
|
||||
)}
|
||||
{sentStatus === "failed" && (
|
||||
<Alert type={"danger"}>Please setup email adapter </Alert>
|
||||
)}
|
||||
<div>
|
||||
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
||||
<div className="w-[250px] h-[66px] inline-block">
|
||||
@@ -1,16 +1,17 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { formJson } from "../json/FormJson";
|
||||
import AddUser from "../components/AddUser";
|
||||
import sanitizeFileName from "../primitives/sanitizeFileName";
|
||||
import Parse from "parse";
|
||||
import DropboxChooser from "../components/fields/DropboxChoose";
|
||||
import DropboxChooser from "../components/shared/fields/DropboxChoose";
|
||||
import Alert from "../primitives/Alert";
|
||||
import SelectFolder from "../components/fields/SelectFolder";
|
||||
import SignersInput from "../components/fields/SignersInput";
|
||||
import SelectFolder from "../components/shared/fields/SelectFolder";
|
||||
import SignersInput from "../components/shared/fields/SignersInput";
|
||||
import Title from "../components/Title";
|
||||
import PageNotFound from "./PageNotFound";
|
||||
|
||||
// `Form` render all type of Form on this basis of their provided in path
|
||||
function Form() {
|
||||
const { id } = useParams();
|
||||
|
||||
@@ -27,6 +28,7 @@ function Form() {
|
||||
}
|
||||
|
||||
const Forms = (props) => {
|
||||
const maxFileSize = 20;
|
||||
const navigate = useNavigate();
|
||||
const [signers, setSigners] = useState([]);
|
||||
const [folder, setFolder] = useState({ ObjectId: "", Name: "" });
|
||||
@@ -40,29 +42,32 @@ const Forms = (props) => {
|
||||
const [fileupload, setFileUpload] = useState([]);
|
||||
const [fileload, setfileload] = useState(false);
|
||||
const [percentage, setpercentage] = useState(0);
|
||||
const [isReset, setIsReset] = useState(false);
|
||||
const [isAlert, setIsAlert] = useState(false);
|
||||
const [isSubmit, setIsSubmit] = useState(false);
|
||||
const [isErr, setIsErr] = useState("");
|
||||
const handleStrInput = (e) => {
|
||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
handleReset();
|
||||
}, [props.title]);
|
||||
const handleFileInput = (e) => {
|
||||
setpercentage(0);
|
||||
try {
|
||||
let files = e.target.files;
|
||||
if (typeof files[0] !== "undefined") {
|
||||
const mb = Math.round(files[0].bytes / Math.pow(1024, 2));
|
||||
if (mb > 10) {
|
||||
const mb = Math.round(files[0].size / Math.pow(1024, 2));
|
||||
if (mb > maxFileSize) {
|
||||
alert(
|
||||
`The selected file size is too large. Please select a file less than ${Math.round(
|
||||
10
|
||||
)} MB`
|
||||
`The selected file size is too large. Please select a file less than ${maxFileSize} MB`
|
||||
);
|
||||
setFileUpload([]);
|
||||
e.target.value = "";
|
||||
return;
|
||||
} else {
|
||||
handleFileUpload(files[0]);
|
||||
}
|
||||
|
||||
handleFileUpload(files[0]);
|
||||
} else {
|
||||
alert("Please select file.");
|
||||
return false;
|
||||
@@ -74,8 +79,6 @@ const Forms = (props) => {
|
||||
};
|
||||
|
||||
const handleFileUpload = async (file) => {
|
||||
Parse.serverURL = process.env.REACT_APP_SERVERURL;
|
||||
Parse.initialize(process.env.REACT_APP_APPID);
|
||||
setfileload(true);
|
||||
const fileName = file.name;
|
||||
const name = sanitizeFileName(fileName);
|
||||
@@ -112,10 +115,10 @@ const Forms = (props) => {
|
||||
const url = file.link;
|
||||
const mb = Math.round(file.bytes / Math.pow(1024, 2));
|
||||
|
||||
if (mb > 10) {
|
||||
if (mb > maxFileSize) {
|
||||
setTimeout(() => {
|
||||
alert(
|
||||
`The selected file size is too large. Please select a file less than 10 MB`
|
||||
`The selected file size is too large. Please select a file less than ${maxFileSize} MB`
|
||||
);
|
||||
}, 500);
|
||||
return;
|
||||
@@ -195,9 +198,7 @@ const Forms = (props) => {
|
||||
});
|
||||
setFileUpload([]);
|
||||
setpercentage(0);
|
||||
navigate(
|
||||
`/asmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/${props?.redirectRoute}/${res.id}`
|
||||
);
|
||||
navigate(`/${props?.redirectRoute}/${res.id}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("err ", err);
|
||||
@@ -226,15 +227,19 @@ const Forms = (props) => {
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setIsReset(true);
|
||||
setSigners([]);
|
||||
setFolder({ ObjectId: "", Name: "" });
|
||||
setFormData({
|
||||
Name: "",
|
||||
Description: "",
|
||||
Note: ""
|
||||
Note: "Please review and sign this document",
|
||||
TimeToCompleteDays: 15,
|
||||
SendinOrder: "false"
|
||||
});
|
||||
setFileUpload([]);
|
||||
setpercentage(0);
|
||||
setTimeout(() => setIsReset(false), 50);
|
||||
};
|
||||
return (
|
||||
<div className="shadow-md rounded my-2 p-3 bg-[#ffffff] md:border-[1px] md:border-gray-600/50">
|
||||
@@ -280,7 +285,8 @@ const Forms = (props) => {
|
||||
<div className="flex gap-2 justify-center items-center">
|
||||
<div className="flex justify-between items-center px-2 py-2 w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]">
|
||||
<div className="break-all">
|
||||
file selected : {fileupload?.split("/")[3]?.split("_")[1]}
|
||||
file selected :{" "}
|
||||
{fileupload?.split("/")?.pop()?.split("_")[1]}
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
@@ -337,7 +343,9 @@ const Forms = (props) => {
|
||||
onChange={(e) => handleStrInput(e)}
|
||||
/>
|
||||
</div>
|
||||
{props.signers && <SignersInput onChange={handleSigners} required />}
|
||||
{props.signers && (
|
||||
<SignersInput onChange={handleSigners} isReset={isReset} required />
|
||||
)}
|
||||
<div className="text-xs mt-2">
|
||||
<label className="block">
|
||||
Note<span className="text-red-500 text-[13px]">*</span>
|
||||
@@ -350,7 +358,11 @@ const Forms = (props) => {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<SelectFolder onSuccess={handleFolder} folderCls={props.Cls} />
|
||||
<SelectFolder
|
||||
onSuccess={handleFolder}
|
||||
folderCls={props.Cls}
|
||||
isReset={isReset}
|
||||
/>
|
||||
|
||||
{props.title === "Request Signatures" && (
|
||||
<div className="text-xs mt-2">
|
||||
@@ -402,10 +414,10 @@ const Forms = (props) => {
|
||||
type="submit"
|
||||
disabled={isSubmit}
|
||||
>
|
||||
Submit
|
||||
Next
|
||||
</button>
|
||||
<div
|
||||
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="cursor-pointer 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"
|
||||
onClick={() => handleReset()}
|
||||
>
|
||||
Reset
|
||||
@@ -1,13 +1,12 @@
|
||||
import React, { useState } from "react";
|
||||
import "../css/LoginPage.css";
|
||||
import loader from "../assests/loader2.gif";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import "../styles/loginPage.css";
|
||||
import loader from "../assets/images/loader2.gif";
|
||||
import axios from "axios";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||
import { useEffect } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { themeColor } from "../constant/const";
|
||||
import { contractUsers } from "../constant/Utils";
|
||||
|
||||
function Login() {
|
||||
function GuestLogin() {
|
||||
const { id, userMail, contactBookId, serverUrl } = useParams();
|
||||
let navigate = useNavigate();
|
||||
const [email, setEmail] = useState(userMail);
|
||||
@@ -18,6 +17,7 @@ function Login() {
|
||||
|
||||
useEffect(() => {
|
||||
handleServerUrl();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
//function generate serverUrl and parseAppId from url and save it in local storage
|
||||
@@ -104,28 +104,36 @@ function Login() {
|
||||
} else {
|
||||
let _user = user.data.result;
|
||||
const parseId = localStorage.getItem("parseAppId");
|
||||
const contractUserDetails = await contractUsers(_user.email);
|
||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||
localStorage.setItem(
|
||||
`Parse/${parseId}/currentUser`,
|
||||
JSON.stringify(_user)
|
||||
);
|
||||
if (contractUserDetails) {
|
||||
localStorage.setItem(
|
||||
"Extand_Class",
|
||||
JSON.stringify(contractUserDetails)
|
||||
);
|
||||
}
|
||||
|
||||
localStorage.setItem("username", _user.name);
|
||||
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||
//save isGuestSigner true in local to handle login flow header in mobile view
|
||||
localStorage.setItem("isGuestSigner", true);
|
||||
setLoading(false);
|
||||
navigate(
|
||||
`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`
|
||||
);
|
||||
navigate(`/load/recipientSignPdf/${id}/${contactBookId}`);
|
||||
}
|
||||
} catch (error) {}
|
||||
} catch (error) {
|
||||
console.log("err ", error);
|
||||
}
|
||||
} else {
|
||||
alert("Please Enter OTP!");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: "2rem" }}>
|
||||
<div style={{ padding: "2rem", background: "white" }}>
|
||||
{isLoading ? (
|
||||
<div
|
||||
style={{
|
||||
@@ -189,7 +197,7 @@ function Login() {
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
className="verifyBtn"
|
||||
@@ -206,7 +214,7 @@ function Login() {
|
||||
<button
|
||||
className="verifyBtn"
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white",
|
||||
marginLeft: "0px !important"
|
||||
}}
|
||||
@@ -242,7 +250,7 @@ function Login() {
|
||||
{loading ? (
|
||||
<button
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
className="verifyBtn"
|
||||
@@ -261,7 +269,7 @@ function Login() {
|
||||
type="button"
|
||||
onClick={(e) => VerifyOTP(e)}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
className="verifyBtn"
|
||||
@@ -279,4 +287,4 @@ function Login() {
|
||||
);
|
||||
}
|
||||
|
||||
export default Login;
|
||||
export default GuestLogin;
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Parse from "parse";
|
||||
import "../styles/toast.css";
|
||||
import "../styles/loader.css";
|
||||
import { connect } from "react-redux";
|
||||
import { fetchAppInfo, showTenantName } from "../redux/actions";
|
||||
@@ -13,6 +12,7 @@ import login_img from "../assets/images/login_img.svg";
|
||||
import { useWindowSize } from "../hook/useWindowSize";
|
||||
import ModalUi from "../primitives/ModalUi";
|
||||
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
||||
import Alert from "../primitives/Alert";
|
||||
|
||||
function Login(props) {
|
||||
const navigate = useNavigate();
|
||||
@@ -20,8 +20,8 @@ function Login(props) {
|
||||
const { width } = useWindowSize();
|
||||
const [state, setState] = useState({
|
||||
email: "",
|
||||
toastColor: "#5cb85c",
|
||||
toastDescription: "",
|
||||
alertType: "success",
|
||||
alertMsg: "",
|
||||
password: "",
|
||||
passwordVisible: false,
|
||||
mobile: "",
|
||||
@@ -44,11 +44,7 @@ function Login(props) {
|
||||
setState({ ...state, loading: true });
|
||||
GetLoginData();
|
||||
}
|
||||
props.fetchAppInfo(
|
||||
localStorage.getItem("domain"),
|
||||
localStorage.getItem("BaseUrl12"),
|
||||
localStorage.getItem("AppID12")
|
||||
);
|
||||
props.fetchAppInfo();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
const handleChange = (event) => {
|
||||
@@ -67,8 +63,6 @@ function Login(props) {
|
||||
let parseAppId = localStorage.getItem("parseAppId");
|
||||
localStorage.setItem("appLogo", props.appInfo.applogo);
|
||||
localStorage.setItem("appName", props.appInfo.appname);
|
||||
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||
// Pass the username and password to logIn function
|
||||
await Parse.User.logIn(email, password)
|
||||
.then(async (user) => {
|
||||
@@ -149,11 +143,6 @@ function Login(props) {
|
||||
"extended_class",
|
||||
element.extended_class
|
||||
);
|
||||
localStorage.setItem(
|
||||
"userpointer",
|
||||
element.userpointer
|
||||
);
|
||||
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
@@ -354,13 +343,16 @@ function Login(props) {
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: `${error.message}`
|
||||
alertType: "danger",
|
||||
alertMsg: `${error.message}`
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
console.log(error);
|
||||
}
|
||||
@@ -370,13 +362,16 @@ function Login(props) {
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: "Login failed: Invalid username or password."
|
||||
alertType: "danger",
|
||||
alertMsg: "Invalid username or password!"
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
console.error("Error while logging in user", error);
|
||||
});
|
||||
@@ -391,8 +386,8 @@ function Login(props) {
|
||||
setState({ ...state, thirdpartyLoader: value });
|
||||
};
|
||||
const thirdpartyLoginfn = async (sessionToken, billingDate) => {
|
||||
const baseUrl = localStorage.getItem("BaseUrl12");
|
||||
const parseAppId = localStorage.getItem("AppID12");
|
||||
const baseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
const res = await axios.get(baseUrl + "users/me", {
|
||||
headers: {
|
||||
"X-Parse-Session-Token": sessionToken,
|
||||
@@ -480,7 +475,6 @@ function Login(props) {
|
||||
"extended_class",
|
||||
element.extended_class
|
||||
);
|
||||
localStorage.setItem("userpointer", element.userpointer);
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
@@ -647,13 +641,16 @@ function Login(props) {
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: `${error.message}`
|
||||
alertType: "danger",
|
||||
alertMsg: `${error.message}`
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
console.log(error);
|
||||
}
|
||||
@@ -663,8 +660,6 @@ function Login(props) {
|
||||
const GetLoginData = async () => {
|
||||
setState({ ...state, loading: true });
|
||||
try {
|
||||
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||
const user = await Parse.User.become(localStorage.getItem("accesstoken"));
|
||||
let _usss = user.toJSON();
|
||||
localStorage.setItem("UserInformation", JSON.stringify(_usss));
|
||||
@@ -717,13 +712,17 @@ function Login(props) {
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: `Does not have permissions to access this application.`
|
||||
alertType: "danger",
|
||||
alertMsg:
|
||||
"Does not have permissions to access this application!"
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
// _currentRole = userRoles[0];
|
||||
@@ -802,14 +801,16 @@ function Login(props) {
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription:
|
||||
"You don`t have access to this application."
|
||||
alertType: "danger",
|
||||
alertMsg: "You don`t have access to this application!"
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
...state,
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
localStorage.setItem("accesstoken", null);
|
||||
console.error("Error while fetching Follow", error);
|
||||
@@ -895,8 +896,8 @@ function Login(props) {
|
||||
let PageLanding = localStorage.getItem("PageLanding");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let _appName = localStorage.getItem("_appName");
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
let baseUrl = localStorage.getItem("baseUrl");
|
||||
let appid = localStorage.getItem("parseAppId");
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
@@ -907,8 +908,8 @@ function Login(props) {
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("userSettings", appdata);
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
localStorage.setItem("baseUrl", baseUrl);
|
||||
localStorage.setItem("parseAppId", appid);
|
||||
};
|
||||
return (
|
||||
<div className="bg-white">
|
||||
@@ -1124,14 +1125,7 @@ function Login(props) {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="snackbar"
|
||||
role="alert"
|
||||
style={{ backgroundColor: state.toastColor }}
|
||||
>
|
||||
{state.toastDescription}
|
||||
</div>
|
||||
<Alert type={state.alertType}>{state.alertMsg}</Alert>
|
||||
</div>
|
||||
<ModalUi isOpen={isModal} title="Additional Info" showClose={false}>
|
||||
<form className="px-4 py-3">
|
||||
@@ -1,16 +1,12 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import SignatureCanvas from "react-signature-canvas";
|
||||
import redPen from "../assests/redPen.png";
|
||||
import bluePen from "../assests/bluePen.png";
|
||||
import blackPen from "../assests/blackPen.png";
|
||||
import "../css/custom.css";
|
||||
import "../css/signature.css";
|
||||
import axios from "axios";
|
||||
import { toDataUrl } from "../utils/toDataUrl";
|
||||
|
||||
|
||||
import "../styles/managesign.css";
|
||||
import "../styles/signature.css";
|
||||
import { toDataUrl } from "../constant/Utils";
|
||||
import Parse from "parse";
|
||||
import { appInfo } from "../constant/appinfo";
|
||||
const ManageSign = () => {
|
||||
let appName;
|
||||
const appName = appInfo.appname;
|
||||
const [penColor, setPenColor] = useState("blue");
|
||||
const [initialPen, setInitialPen] = useState("blue");
|
||||
const [image, setImage] = useState();
|
||||
@@ -19,7 +15,7 @@ const ManageSign = () => {
|
||||
const [warning, setWarning] = useState(false);
|
||||
const [nameWarning, setNameWarning] = useState(false);
|
||||
const [isvalue, setIsValue] = useState(false);
|
||||
const allColor = [bluePen, redPen, blackPen];
|
||||
const allColor = ["blue", "red", "black"];
|
||||
const [isLoader, setIsLoader] = useState(true);
|
||||
const [isSuccess, setIsSuccess] = useState(false);
|
||||
const [Initials, setInitials] = useState("");
|
||||
@@ -29,59 +25,40 @@ const ManageSign = () => {
|
||||
const imageRef = useRef(null);
|
||||
const initailsRef = useRef(null);
|
||||
useEffect(() => {
|
||||
getLocalStorageValue();
|
||||
fetchUserSign();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
//function for get localstorage value first and than call another function.
|
||||
const getLocalStorageValue = () => {
|
||||
let User = JSON.parse(
|
||||
localStorage.getItem(
|
||||
"Parse/" + localStorage.getItem("parseAppId") + "/currentUser"
|
||||
)
|
||||
);
|
||||
appName =
|
||||
localStorage.getItem("_appName") && localStorage.getItem("_appName");
|
||||
const fetchUserSign = async () => {
|
||||
const User = Parse.User.current();
|
||||
if (User) {
|
||||
fetchUserSign(User);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchUserSign = async (User) => {
|
||||
const userId = {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: User.objectId,
|
||||
};
|
||||
const strObj = JSON.stringify(userId);
|
||||
const url =
|
||||
localStorage.getItem("baseUrl") +
|
||||
`classes/${appName}_Signature?where={"UserId":${strObj}}&limit=1`;
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
// "X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
||||
};
|
||||
const res = await axios
|
||||
.get(url, { headers: headers })
|
||||
.then((res) => {
|
||||
if (res.data.results.length > 0) {
|
||||
setId(res.data.results[0].objectId);
|
||||
setSignName(res.data.results[0].SignatureName);
|
||||
setImage(res.data.results[0].ImageURL);
|
||||
if (res.data.results[0] && res.data.results[0].Initials) {
|
||||
setInitials(res.data.results[0].Initials);
|
||||
const userId = {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: User.id
|
||||
};
|
||||
try {
|
||||
const signCls = `${appName}_Signature`;
|
||||
const signQuery = new Parse.Query(signCls);
|
||||
signQuery.equalTo("UserId", userId);
|
||||
const signRes = await signQuery.first();
|
||||
if (signRes) {
|
||||
const res = signRes.toJSON();
|
||||
setId(res.objectId);
|
||||
setSignName(res?.SignatureName);
|
||||
setImage(res.ImageURL);
|
||||
if (res && res.Initials) {
|
||||
setInitials(res.Initials);
|
||||
setIsInitials(true);
|
||||
}
|
||||
} else {
|
||||
setSignName(User?.get("name") || "");
|
||||
}
|
||||
setIsLoader(false);
|
||||
return res;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
alert(`${error.message}`);
|
||||
});
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.log("Err", err);
|
||||
alert(`${err.message}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleSignatureChange = () => {
|
||||
if (imageRef.current) {
|
||||
@@ -112,18 +89,6 @@ const ManageSign = () => {
|
||||
setIsInitials(false);
|
||||
};
|
||||
|
||||
// const handleReset = () => {
|
||||
// if (canvasRef.current) {
|
||||
// canvasRef.current.clear();
|
||||
// }
|
||||
// if (imageRef.current) {
|
||||
// imageRef.current.value = "";
|
||||
// }
|
||||
// setImage("");
|
||||
// setSignature("");
|
||||
// setIsValue(false);
|
||||
// setSignName("");
|
||||
// };
|
||||
const onImageChange = async (event) => {
|
||||
if (canvasRef.current) {
|
||||
canvasRef.current.clear();
|
||||
@@ -142,7 +107,6 @@ const ManageSign = () => {
|
||||
|
||||
if (!signName) {
|
||||
setNameWarning(true);
|
||||
|
||||
} else if (!isvalue) {
|
||||
setWarning(true);
|
||||
setTimeout(() => setWarning(false), 1000);
|
||||
@@ -151,29 +115,32 @@ const ManageSign = () => {
|
||||
const replaceSpace = signName.replace(/ /g, "_");
|
||||
let file;
|
||||
if (signature) {
|
||||
file = base64StringtoFile(signature, `${replaceSpace}.png`);
|
||||
file = base64StringtoFile(signature, `${replaceSpace}_sign.png`);
|
||||
} else {
|
||||
if (!isUrl) {
|
||||
file = base64StringtoFile(image, `${replaceSpace}.png`);
|
||||
file = base64StringtoFile(image, `${replaceSpace}__sign.png`);
|
||||
}
|
||||
}
|
||||
// console.log("isUrl ", isUrl);
|
||||
let imgUrl;
|
||||
if (!isUrl) {
|
||||
imgUrl = await uploadFile(file);
|
||||
} else {
|
||||
imgUrl = { data: { imageUrl: image } };
|
||||
imgUrl = image;
|
||||
}
|
||||
let initialsUrl = "";
|
||||
if (Initials) {
|
||||
const initialsImg = base64StringtoFile(Initials, `${replaceSpace}.png`);
|
||||
const isInitialsUrl = Initials.includes("https");
|
||||
if (!isInitialsUrl && Initials) {
|
||||
const initialsImg = base64StringtoFile(
|
||||
Initials,
|
||||
`${replaceSpace}_initials.png`
|
||||
);
|
||||
initialsUrl = await uploadFile(initialsImg);
|
||||
}
|
||||
if (imgUrl.data && imgUrl.data.imageUrl) {
|
||||
if (imgUrl) {
|
||||
await saveEntry({
|
||||
name: signName,
|
||||
url: imgUrl.data.imageUrl,
|
||||
initialsUrl: initialsUrl,
|
||||
url: imgUrl,
|
||||
initialsUrl: initialsUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -191,116 +158,54 @@ const ManageSign = () => {
|
||||
}
|
||||
|
||||
const uploadFile = async (file) => {
|
||||
let parseBaseUrl = localStorage.getItem("baseUrl");
|
||||
parseBaseUrl = parseBaseUrl.slice(0, -4);
|
||||
const url = parseBaseUrl + `file_upload`;
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
const config = {
|
||||
headers: {
|
||||
"content-type": "multipart/form-data",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
},
|
||||
onUploadProgress: function (progressEvent) {
|
||||
let percentCompleted = Math.round(
|
||||
(progressEvent.loaded * 100) / progressEvent.total
|
||||
);
|
||||
// setpercentage(percentCompleted);
|
||||
},
|
||||
};
|
||||
const response = await axios
|
||||
.post(url, formData, config)
|
||||
.then((res) => {
|
||||
if (res.data.status === "Error") {
|
||||
alert(res.data.message);
|
||||
}
|
||||
return res;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setIsLoader(false);
|
||||
alert(`${error.message}`);
|
||||
});
|
||||
return response;
|
||||
try {
|
||||
const parseFile = new Parse.File(file.name, file);
|
||||
const response = await parseFile.save();
|
||||
return response?.url();
|
||||
} catch (err) {
|
||||
console.log("sign upload err", err);
|
||||
setIsLoader(false);
|
||||
alert(`${err.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
const saveEntry = async (obj) => {
|
||||
const signCls = `${appName}_Signature`;
|
||||
const User = Parse.User.current().id;
|
||||
const userId = { __type: "Pointer", className: "_User", objectId: User };
|
||||
if (id) {
|
||||
const User = JSON.parse(
|
||||
localStorage.getItem(
|
||||
"Parse/" + localStorage.getItem("parseAppId") + "/currentUser"
|
||||
)
|
||||
);
|
||||
const url =
|
||||
localStorage.getItem("baseUrl") +
|
||||
`classes/${localStorage.getItem("_appName")}_Signature/${id}`;
|
||||
const body = {
|
||||
Initials: obj.initialsUrl ? obj.initialsUrl.data.imageUrl : "",
|
||||
ImageURL: obj.url,
|
||||
SignatureName: obj.name,
|
||||
UserId: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: User.objectId,
|
||||
},
|
||||
};
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
// "X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
||||
};
|
||||
const res = await axios
|
||||
.put(url, body, { headers: headers })
|
||||
.then((res) => {
|
||||
// handleReset();
|
||||
setIsLoader(false);
|
||||
setIsSuccess(true);
|
||||
return res;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setIsLoader(false);
|
||||
alert(`${error.message}`);
|
||||
});
|
||||
return res;
|
||||
try {
|
||||
const updateSign = new Parse.Object(signCls);
|
||||
updateSign.id = id;
|
||||
updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : "");
|
||||
updateSign.set("ImageURL", obj.url);
|
||||
updateSign.set("SignatureName", obj.name);
|
||||
updateSign.set("UserId", userId);
|
||||
const res = await updateSign.save();
|
||||
setIsLoader(false);
|
||||
setIsSuccess(true);
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
setIsLoader(false);
|
||||
alert(`${err.message}`);
|
||||
}
|
||||
} else {
|
||||
const User = JSON.parse(
|
||||
localStorage.getItem(
|
||||
"Parse/" + localStorage.getItem("parseAppId") + "/currentUser"
|
||||
)
|
||||
);
|
||||
const url =
|
||||
localStorage.getItem("baseUrl") +
|
||||
`classes/${localStorage.getItem("_appName")}_Signature`;
|
||||
const body = {
|
||||
Initials: obj.initialsUrl ? obj.initialsUrl.data.imageUrl : "",
|
||||
ImageURL: obj.url,
|
||||
SignatureName: obj.name,
|
||||
UserId: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: User.objectId,
|
||||
},
|
||||
};
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
// "X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
||||
};
|
||||
const res = await axios
|
||||
.post(url, body, { headers: headers })
|
||||
.then((res) => {
|
||||
// handleReset();
|
||||
setIsLoader(false);
|
||||
setIsSuccess(true);
|
||||
return res;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setIsLoader(false);
|
||||
alert(`${error.message}`);
|
||||
});
|
||||
return res;
|
||||
try {
|
||||
const updateSign = new Parse.Object(signCls);
|
||||
updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : "");
|
||||
updateSign.set("ImageURL", obj.url);
|
||||
updateSign.set("SignatureName", obj.name);
|
||||
updateSign.set("UserId", userId);
|
||||
const res = await updateSign.save();
|
||||
setIsLoader(false);
|
||||
setIsSuccess(true);
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
setIsLoader(false);
|
||||
alert(`${err.message}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleSignatureBtn = () => {
|
||||
@@ -319,10 +224,26 @@ const ManageSign = () => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
maxHeight: "500px",
|
||||
overflow: "auto",
|
||||
overflow: "auto"
|
||||
}}
|
||||
>
|
||||
{isLoader && (
|
||||
<div className="absolute bg-black bg-opacity-75 inset-0 z-50 flex justify-center items-center">
|
||||
<div style={{ height: "300px" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isSuccess && (
|
||||
<div
|
||||
className="alert alert-success successBox"
|
||||
@@ -332,12 +253,11 @@ const ManageSign = () => {
|
||||
Signature saved successfully!
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className="mainDiv"
|
||||
style={{
|
||||
width: "100%",
|
||||
paddingRight: "10px",
|
||||
paddingRight: "10px"
|
||||
}}
|
||||
>
|
||||
<div style={{ margin: 20 }}>
|
||||
@@ -346,7 +266,7 @@ const ManageSign = () => {
|
||||
fontWeight: "700",
|
||||
fontSize: 15,
|
||||
color: "#000",
|
||||
paddingBottom: 8,
|
||||
paddingBottom: 8
|
||||
}}
|
||||
>
|
||||
Manage Signature
|
||||
@@ -357,10 +277,10 @@ const ManageSign = () => {
|
||||
style={{
|
||||
fontSize: 12,
|
||||
position: "relative",
|
||||
paddingBottom: 5,
|
||||
paddingBottom: 5
|
||||
}}
|
||||
>
|
||||
Signer's Name
|
||||
Signer's Name
|
||||
{nameWarning && (
|
||||
<div
|
||||
className="warning nameWarning"
|
||||
@@ -386,7 +306,7 @@ const ManageSign = () => {
|
||||
height: 35,
|
||||
padding: "6px 12px",
|
||||
marginBottom: 10,
|
||||
fontSize: 12,
|
||||
fontSize: 12
|
||||
}}
|
||||
required
|
||||
onFocus={() => setNameWarning(false)}
|
||||
@@ -397,7 +317,7 @@ const ManageSign = () => {
|
||||
htmlFor="imgoverview"
|
||||
style={{
|
||||
fontSize: 12,
|
||||
paddingBottom: 5,
|
||||
paddingBottom: 5
|
||||
}}
|
||||
>
|
||||
Signature/Image
|
||||
@@ -412,7 +332,7 @@ const ManageSign = () => {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
width: "50%",
|
||||
paddingLeft: 10,
|
||||
paddingLeft: 10
|
||||
}}
|
||||
>
|
||||
<div
|
||||
@@ -422,7 +342,7 @@ const ManageSign = () => {
|
||||
justifyContent: "space-around",
|
||||
alignItems: "center",
|
||||
gap: 10,
|
||||
marginBottom: 10,
|
||||
marginBottom: 10
|
||||
}}
|
||||
>
|
||||
<>
|
||||
@@ -456,9 +376,7 @@ const ManageSign = () => {
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
|
||||
border: "2px solid #888",
|
||||
marginBottom: 6,
|
||||
border: "2px solid #888"
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
>
|
||||
@@ -468,7 +386,7 @@ const ManageSign = () => {
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -479,7 +397,7 @@ const ManageSign = () => {
|
||||
canvasProps={{
|
||||
width: "456px",
|
||||
height: "180px",
|
||||
className: "signatureCanvas",
|
||||
className: "signatureCanvas"
|
||||
}}
|
||||
backgroundColor="rgb(255, 255, 255)"
|
||||
onEnd={() =>
|
||||
@@ -492,10 +410,9 @@ const ManageSign = () => {
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
// width: 460,
|
||||
justifyContent: "space-between"
|
||||
}}
|
||||
className="penContainer"
|
||||
className="penContainerDefault"
|
||||
>
|
||||
<div>
|
||||
{!image && (
|
||||
@@ -504,19 +421,18 @@ const ManageSign = () => {
|
||||
>
|
||||
{allColor.map((data, key) => {
|
||||
return (
|
||||
<img
|
||||
alt="black img"
|
||||
<i
|
||||
style={{
|
||||
border: "none",
|
||||
margin: "5px",
|
||||
color: data,
|
||||
borderBottom:
|
||||
key === 0 && penColor === "blue"
|
||||
? "2px solid blue"
|
||||
: key === 1 && penColor === "red"
|
||||
? "2px solid red"
|
||||
: key === 2 && penColor === "black"
|
||||
? "2px solid black"
|
||||
: "2px solid white",
|
||||
? "2px solid red"
|
||||
: key === 2 && penColor === "black"
|
||||
? "2px solid black"
|
||||
: "2px solid white"
|
||||
}}
|
||||
onClick={() => {
|
||||
if (key === 0) {
|
||||
@@ -528,10 +444,10 @@ const ManageSign = () => {
|
||||
}
|
||||
}}
|
||||
key={key}
|
||||
src={data}
|
||||
className="fa solid fa-pen-nib"
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
></i>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
@@ -540,7 +456,7 @@ const ManageSign = () => {
|
||||
<div>
|
||||
<div
|
||||
type="button"
|
||||
className="clearbtn"
|
||||
className="clearbtn cursor-pointer"
|
||||
onClick={() => handleClear()}
|
||||
>
|
||||
Clear
|
||||
@@ -565,23 +481,16 @@ const ManageSign = () => {
|
||||
</div>
|
||||
<div style={{ position: "relative" }}>
|
||||
<div style={{ margin: "6px 5px 18px" }}>
|
||||
<span
|
||||
// onClick={() => handleSignatureBtn()}
|
||||
className="signature"
|
||||
>
|
||||
Initials
|
||||
</span>
|
||||
<span className="signature">Initials</span>
|
||||
</div>
|
||||
<div>
|
||||
{isInitials ? (
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
|
||||
border: "2px solid #888",
|
||||
marginBottom: 6,
|
||||
border: "2px solid #888"
|
||||
}}
|
||||
className="signatureCanvas"
|
||||
className="intialSignature"
|
||||
>
|
||||
<img
|
||||
alt="preview image"
|
||||
@@ -589,7 +498,7 @@ const ManageSign = () => {
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
objectFit: "contain"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -598,9 +507,7 @@ const ManageSign = () => {
|
||||
ref={initailsRef}
|
||||
penColor={initialPen}
|
||||
canvasProps={{
|
||||
width: "456px",
|
||||
height: "180px",
|
||||
className: "signatureCanvas",
|
||||
className: "intialSignature"
|
||||
}}
|
||||
backgroundColor="rgb(255, 255, 255)"
|
||||
onEnd={() =>
|
||||
@@ -613,29 +520,27 @@ const ManageSign = () => {
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
// width: 460,
|
||||
justifyContent: "space-between"
|
||||
}}
|
||||
className="penContainer"
|
||||
className="penContainerInitial"
|
||||
>
|
||||
<div>
|
||||
{!isInitials && (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
{allColor.map((data, key) => {
|
||||
return (
|
||||
<img
|
||||
alt="pen"
|
||||
<i
|
||||
style={{
|
||||
border: "none",
|
||||
margin: "5px",
|
||||
color: data,
|
||||
borderBottom:
|
||||
key === 0 && initialPen === "blue"
|
||||
? "2px solid blue"
|
||||
: key === 1 && initialPen === "red"
|
||||
? "2px solid red"
|
||||
: key === 2 && initialPen === "black"
|
||||
? "2px solid black"
|
||||
: "2px solid white",
|
||||
? "2px solid red"
|
||||
: key === 2 && initialPen === "black"
|
||||
? "2px solid black"
|
||||
: "2px solid white"
|
||||
}}
|
||||
onClick={() => {
|
||||
if (key === 0) {
|
||||
@@ -647,10 +552,10 @@ const ManageSign = () => {
|
||||
}
|
||||
}}
|
||||
key={key}
|
||||
src={data}
|
||||
className="fa solid fa-pen-nib"
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
></i>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
@@ -659,7 +564,7 @@ const ManageSign = () => {
|
||||
<div>
|
||||
<div
|
||||
type="button"
|
||||
className="clearbtn"
|
||||
className="clearbtn cursor-pointer"
|
||||
onClick={() => handleClearInitials()}
|
||||
>
|
||||
Clear
|
||||
@@ -687,11 +592,6 @@ const ManageSign = () => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{isLoader && (
|
||||
<div className="loaderContainer">
|
||||
<div className="loader"></div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -1,15 +1,15 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import "./LegaDrive.css";
|
||||
import loader from "../../assests/loader2.gif";
|
||||
import PdfFileComponent from "./FolderDrive/legaDriveComponent";
|
||||
import { themeColor, iconColor } from "../../utils/ThemeColor/backColor";
|
||||
import { getDrive } from "../../utils/Utils";
|
||||
import "../styles/opensigndrive.css";
|
||||
import loader from "../assets/images/loader2.gif";
|
||||
import DriveBody from "../components/opensigndrive/DriveBody";
|
||||
import { themeColor, iconColor } from "../constant/const";
|
||||
import { getDrive } from "../constant/Utils";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Title from "../component/Title";
|
||||
import Title from "../components/Title";
|
||||
import Parse from "parse";
|
||||
import ModalUi from "../../premitives/ModalUi";
|
||||
import ModalUi from "../primitives/ModalUi";
|
||||
|
||||
function PdfFile() {
|
||||
function Opensigndrive() {
|
||||
const navigate = useNavigate();
|
||||
const scrollRef = useRef(null);
|
||||
const [isList, setIsList] = useState(false);
|
||||
@@ -45,6 +45,7 @@ function PdfFile() {
|
||||
} else {
|
||||
getPdfDocumentList();
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [docId]);
|
||||
|
||||
//function for get all pdf document list
|
||||
@@ -300,9 +301,9 @@ function PdfFile() {
|
||||
// Cleanup the event listener when the component unmounts
|
||||
document.removeEventListener("click", closeMenuOnOutsideClick);
|
||||
};
|
||||
}, [isShowSort || isNewFol]);
|
||||
}, [isShowSort, isNewFol]);
|
||||
|
||||
const handleFolderTab = (folderData, isMove) => {
|
||||
const handleFolderTab = (folderData) => {
|
||||
return folderData.map((data, id) => {
|
||||
return (
|
||||
<React.Fragment key={id}>
|
||||
@@ -336,7 +337,7 @@ function PdfFile() {
|
||||
setError("");
|
||||
};
|
||||
return (
|
||||
<div className="folderComponent ">
|
||||
<div style={{ backgroundColor: "white" }} className="folderComponent">
|
||||
<Title title={"OpenSign™ Drive"} drive={true} />
|
||||
<div>
|
||||
<ModalUi
|
||||
@@ -444,9 +445,7 @@ function PdfFile() {
|
||||
></div>
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
<button
|
||||
style={{
|
||||
background: themeColor()
|
||||
}}
|
||||
style={{ background: themeColor }}
|
||||
type="submit"
|
||||
className="finishBtn"
|
||||
>
|
||||
@@ -524,7 +523,7 @@ function PdfFile() {
|
||||
<i
|
||||
className="fa fa-plus-square"
|
||||
aria-hidden="true"
|
||||
style={{ fontSize: "25px", color: `${iconColor()}` }}
|
||||
style={{ fontSize: "25px", color: `${iconColor}` }}
|
||||
></i>
|
||||
</div>
|
||||
<div
|
||||
@@ -588,13 +587,13 @@ function PdfFile() {
|
||||
style={{
|
||||
marginRight: "5px",
|
||||
fontSize: "14px",
|
||||
color: `${iconColor()}`
|
||||
color: `${iconColor}`
|
||||
}}
|
||||
></i>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "15px",
|
||||
color: `${iconColor()}`
|
||||
color: `${iconColor}`
|
||||
}}
|
||||
>
|
||||
{selectedSort}
|
||||
@@ -705,7 +704,7 @@ function PdfFile() {
|
||||
<i
|
||||
onClick={() => setIsList(!isList)}
|
||||
className="fa fa-th-large"
|
||||
style={{ fontSize: "24px", color: `${iconColor()}` }}
|
||||
style={{ fontSize: "24px", color: `${iconColor}` }}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</div>
|
||||
@@ -714,7 +713,7 @@ function PdfFile() {
|
||||
<i
|
||||
className="fa fa-list"
|
||||
aria-hidden="true"
|
||||
style={{ fontSize: "23px", color: `${iconColor()}` }}
|
||||
style={{ fontSize: "23px", color: `${iconColor}` }}
|
||||
></i>
|
||||
</div>
|
||||
)}
|
||||
@@ -735,7 +734,7 @@ function PdfFile() {
|
||||
<span style={{ fontWeight: "bold" }}>No Data Found!</span>
|
||||
</div>
|
||||
) : (
|
||||
<PdfFileComponent
|
||||
<DriveBody
|
||||
pdfData={pdfData}
|
||||
setFolderName={setFolderName}
|
||||
setIsLoading={setIsLoading}
|
||||
@@ -755,4 +754,4 @@ function PdfFile() {
|
||||
);
|
||||
}
|
||||
|
||||
export default PdfFile;
|
||||
export default Opensigndrive;
|
||||
@@ -1,14 +1,15 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||
import { themeColor } from "../constant/const";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import "../css/signature.css";
|
||||
import "../styles/signature.css";
|
||||
import axios from "axios";
|
||||
import loader from "../assests/loader2.gif";
|
||||
import loader from "../assets/images/loader2.gif";
|
||||
import { DndProvider } from "react-dnd";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { useParams } from "react-router-dom";
|
||||
import SignPad from "./component/signPad";
|
||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||
import SignPad from "../components/pdf/SignPad";
|
||||
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
||||
import Tour from "reactour";
|
||||
import {
|
||||
contractDocument,
|
||||
multiSignEmbed,
|
||||
@@ -18,17 +19,17 @@ import {
|
||||
onImageSelect,
|
||||
onSaveSign,
|
||||
onSaveImage,
|
||||
addDefaultSignatureImg
|
||||
} from "../utils/Utils";
|
||||
import Loader from "./component/loader";
|
||||
import HandleError from "./component/HandleError";
|
||||
import Nodata from "./component/Nodata";
|
||||
import Header from "./component/header";
|
||||
import RenderPdf from "./component/renderPdf";
|
||||
import CustomModal from "./component/CustomModal";
|
||||
import Title from "./component/Title";
|
||||
import DefaultSignature from "./component/defaultSignature";
|
||||
import ModalUi from "../premitives/ModalUi";
|
||||
addDefaultSignatureImg,
|
||||
radioButtonWidget
|
||||
} from "../constant/Utils";
|
||||
import Loader from "../primitives/LoaderWithMsg";
|
||||
import HandleError from "../primitives/HandleError";
|
||||
import Header from "../components/pdf/PdfHeader";
|
||||
import RenderPdf from "../components/pdf/RenderPdf";
|
||||
import PdfDeclineModal from "../primitives/PdfDeclineModal";
|
||||
import Title from "../components/Title";
|
||||
import DefaultSignature from "../components/pdf/DefaultSignature";
|
||||
import ModalUi from "../primitives/ModalUi";
|
||||
|
||||
function PdfRequestFiles() {
|
||||
const { docId } = useParams();
|
||||
@@ -48,6 +49,7 @@ function PdfRequestFiles() {
|
||||
const [imgWH, setImgWH] = useState({});
|
||||
const imageRef = useRef(null);
|
||||
const [handleError, setHandleError] = useState();
|
||||
const [selectWidgetId, setSelectWidgetId] = useState("");
|
||||
const [isLoading, setIsLoading] = useState({
|
||||
isLoad: true,
|
||||
message: "This might take some time"
|
||||
@@ -57,12 +59,12 @@ function PdfRequestFiles() {
|
||||
const [pdfNewWidth, setPdfNewWidth] = useState();
|
||||
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
||||
const [signerPos, setSignerPos] = useState([]);
|
||||
const [noData, setNoData] = useState(false);
|
||||
const [signerObjectId, setSignerObjectId] = useState();
|
||||
const [isUiLoading, setIsUiLoading] = useState(false);
|
||||
const [isDecline, setIsDecline] = useState({ isDeclined: false });
|
||||
const [currentSigner, setCurrentSigner] = useState(false);
|
||||
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
||||
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
|
||||
const [defaultSignAlert, setDefaultSignAlert] = useState({
|
||||
isShow: false,
|
||||
alertMessage: ""
|
||||
@@ -71,6 +73,8 @@ function PdfRequestFiles() {
|
||||
isCertificate: false,
|
||||
isModal: false
|
||||
});
|
||||
const [myInitial, setMyInitial] = useState("");
|
||||
const [isInitial, setIsInitial] = useState(false);
|
||||
const [pdfLoadFail, setPdfLoadFail] = useState({
|
||||
status: false,
|
||||
type: "load"
|
||||
@@ -79,6 +83,9 @@ function PdfRequestFiles() {
|
||||
const [isExpired, setIsExpired] = useState(false);
|
||||
const [alreadySign, setAlreadySign] = useState(false);
|
||||
const [containerWH, setContainerWH] = useState({});
|
||||
const [validateAlert, setValidateAlert] = useState(false);
|
||||
const [widgetsTour, setWidgetsTour] = useState(false);
|
||||
const [minRequiredCount, setminRequiredCount] = useState();
|
||||
const [sendInOrder, setSendInOrder] = useState(false);
|
||||
const divRef = useRef(null);
|
||||
const isMobile = window.innerWidth < 767;
|
||||
@@ -105,6 +112,7 @@ function PdfRequestFiles() {
|
||||
if (documentId) {
|
||||
getDocumentDetails();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (divRef.current) {
|
||||
@@ -115,10 +123,12 @@ function PdfRequestFiles() {
|
||||
height: divRef.current.offsetHeight
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [divRef.current]);
|
||||
|
||||
//function for get document details for perticular signer with signer'object id
|
||||
const getDocumentDetails = async () => {
|
||||
let currUserId;
|
||||
//getting document details
|
||||
const documentData = await contractDocument(documentId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
@@ -135,9 +145,7 @@ function PdfRequestFiles() {
|
||||
(data) => data.UserId.objectId === jsonSender.objectId
|
||||
);
|
||||
|
||||
const currUserId = getCurrentSigner[0]
|
||||
? getCurrentSigner[0].objectId
|
||||
: "";
|
||||
currUserId = getCurrentSigner[0] ? getCurrentSigner[0].objectId : "";
|
||||
setSignerObjectId(currUserId);
|
||||
if (documentData[0].SignedUrl) {
|
||||
setPdfUrl(documentData[0].SignedUrl);
|
||||
@@ -287,7 +295,7 @@ function PdfRequestFiles() {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
setNoData(true);
|
||||
setHandleError("No Data Found!");
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
@@ -315,7 +323,9 @@ function PdfRequestFiles() {
|
||||
|
||||
if (res[0] && res.length > 0) {
|
||||
setDefaultSignImg(res[0].ImageURL);
|
||||
setMyInitial(res[0]?.Initials);
|
||||
}
|
||||
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
@@ -325,6 +335,7 @@ function PdfRequestFiles() {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
console.log("Err ", err);
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
});
|
||||
@@ -356,30 +367,137 @@ function PdfRequestFiles() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//function for embed signature or image url in pdf
|
||||
async function embedImages() {
|
||||
async function embedWidgetsData() {
|
||||
const validateSigning = checkSendInOrder();
|
||||
if (validateSigning) {
|
||||
const checkUser = signerPos.filter(
|
||||
(data) => data.signerObjId === signerObjectId
|
||||
);
|
||||
if (checkUser && checkUser.length > 0) {
|
||||
let checkSignUrl = [];
|
||||
const checkSign = checkUser[0].placeHolder.filter(
|
||||
(data, ind) => data.pos
|
||||
);
|
||||
for (let i = 0; i < checkSign.length; i++) {
|
||||
const posData = checkSign[i].pos.filter((pos) => !pos.SignUrl);
|
||||
if (posData && posData.length > 0) {
|
||||
checkSignUrl.push(posData);
|
||||
let checkboxExist,
|
||||
requiredRadio,
|
||||
showAlert = false,
|
||||
widgetKey,
|
||||
radioExist,
|
||||
requiredCheckbox;
|
||||
|
||||
for (let i = 0; i < checkUser[0].placeHolder.length; i++) {
|
||||
for (let j = 0; j < checkUser[0].placeHolder[i].pos.length; j++) {
|
||||
checkboxExist =
|
||||
checkUser[0].placeHolder[i].pos[j].type === "checkbox";
|
||||
radioExist =
|
||||
checkUser[0].placeHolder[i].pos[j].type === radioButtonWidget;
|
||||
if (checkboxExist) {
|
||||
requiredCheckbox = checkUser[0].placeHolder[i].pos.filter(
|
||||
(position) =>
|
||||
!position.options?.isReadOnly && position.type === "checkbox"
|
||||
);
|
||||
|
||||
if (requiredCheckbox && requiredCheckbox.length > 0) {
|
||||
for (let i = 0; i < requiredCheckbox.length; i++) {
|
||||
const minCount =
|
||||
requiredCheckbox[i].options?.validation?.minRequiredCount;
|
||||
const parseMin = minCount && parseInt(minCount);
|
||||
const maxCount =
|
||||
requiredCheckbox[i].options?.validation?.maxRequiredCount;
|
||||
const parseMax = maxCount && parseInt(maxCount);
|
||||
const response =
|
||||
requiredCheckbox[i].options?.response?.length;
|
||||
const defaultValue =
|
||||
requiredCheckbox[i].options?.defaultValue?.length;
|
||||
if (parseMin === 0 && parseMax === 0) {
|
||||
if (!showAlert) {
|
||||
showAlert = false;
|
||||
setminRequiredCount(null);
|
||||
}
|
||||
} else if (parseMin === 0 && parseMax > 0) {
|
||||
if (!showAlert) {
|
||||
showAlert = false;
|
||||
setminRequiredCount(null);
|
||||
}
|
||||
} else if (!response) {
|
||||
if (!defaultValue) {
|
||||
if (!showAlert) {
|
||||
showAlert = true;
|
||||
widgetKey = requiredCheckbox[i].key;
|
||||
setminRequiredCount(parseMin);
|
||||
}
|
||||
}
|
||||
} else if (parseMin > 0 && parseMin > response) {
|
||||
if (!showAlert) {
|
||||
showAlert = true;
|
||||
widgetKey = requiredCheckbox[i].key;
|
||||
setminRequiredCount(parseMin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (radioExist) {
|
||||
requiredRadio = checkUser[0].placeHolder[i].pos.filter(
|
||||
(position) =>
|
||||
!position.options?.isReadOnly &&
|
||||
position.type === radioButtonWidget
|
||||
);
|
||||
if (requiredRadio && requiredRadio?.length > 0) {
|
||||
let checkSigned;
|
||||
for (let i = 0; i < requiredRadio?.length; i++) {
|
||||
checkSigned = requiredRadio[i]?.options.response;
|
||||
if (!checkSigned) {
|
||||
let checkDefaultSigned =
|
||||
requiredRadio[i]?.options.defaultValue;
|
||||
if (!checkDefaultSigned) {
|
||||
if (!showAlert) {
|
||||
showAlert = true;
|
||||
widgetKey = requiredRadio[i].key;
|
||||
setminRequiredCount(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const requiredWidgets = checkUser[0].placeHolder[i].pos.filter(
|
||||
(position) =>
|
||||
position.options?.status === "required" &&
|
||||
position.type !== radioButtonWidget &&
|
||||
position.type !== "checkbox"
|
||||
);
|
||||
if (requiredWidgets && requiredWidgets?.length > 0) {
|
||||
let checkSigned;
|
||||
for (let i = 0; i < requiredWidgets?.length; i++) {
|
||||
checkSigned = requiredWidgets[i]?.options?.response;
|
||||
if (!checkSigned) {
|
||||
const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl;
|
||||
|
||||
let checkDefaultSigned =
|
||||
requiredWidgets[i]?.options?.defaultValue;
|
||||
if (!checkSignUrl) {
|
||||
if (!checkDefaultSigned) {
|
||||
if (!showAlert) {
|
||||
showAlert = true;
|
||||
widgetKey = requiredWidgets[i].key;
|
||||
setminRequiredCount(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkSignUrl && checkSignUrl.length > 0) {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: "Please complete your signature!"
|
||||
});
|
||||
if (checkboxExist && requiredCheckbox && showAlert) {
|
||||
setUnSignedWidgetId(widgetKey);
|
||||
setWidgetsTour(true);
|
||||
} else if (radioExist && showAlert) {
|
||||
setUnSignedWidgetId(widgetKey);
|
||||
setWidgetsTour(true);
|
||||
} else if (showAlert) {
|
||||
setUnSignedWidgetId(widgetKey);
|
||||
setWidgetsTour(true);
|
||||
} else {
|
||||
setIsUiLoading(true);
|
||||
const pngUrl = checkUser[0].placeHolder;
|
||||
@@ -390,97 +508,14 @@ function PdfRequestFiles() {
|
||||
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
||||
ignoreEncryption: true
|
||||
});
|
||||
// let pdfBase64;
|
||||
|
||||
//checking if signature is only one then send image url in jpeg formate to server
|
||||
// if (pngUrl.length === 1 && pngUrl[0].pos.length === 1) {
|
||||
// if (isDocId) {
|
||||
// try {
|
||||
// pdfBase64 = await getBase64FromUrl(pdfUrl);
|
||||
// } catch (err) {
|
||||
// console.log(err);
|
||||
// }
|
||||
// } else {
|
||||
// //embed document's object id to all pages in pdf document
|
||||
// try {
|
||||
// await embedDocId(pdfDoc, documentId, allPages);
|
||||
// } catch (err) {
|
||||
// console.log(err);
|
||||
// }
|
||||
// try {
|
||||
// pdfBase64 = await pdfDoc.saveAsBase64({
|
||||
// useObjectStreams: false
|
||||
// });
|
||||
// } catch (err) {
|
||||
// console.log(err);
|
||||
// }
|
||||
// }
|
||||
// for (let pngData of pngUrl) {
|
||||
// const imgUrlList = pngData.pos;
|
||||
// const pageNo = pngData.pageNumber;
|
||||
// imgUrlList.map(async (data) => {
|
||||
// //cheking signUrl is defau;t signature url of custom url
|
||||
// let ImgUrl = data.SignUrl;
|
||||
// const checkUrl = urlValidator(ImgUrl);
|
||||
// //if default signature url then convert it in base 64
|
||||
// if (checkUrl) {
|
||||
// ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
||||
// }
|
||||
// //function for called convert png signatre to jpeg in base 64
|
||||
// convertPNGtoJPEG(ImgUrl)
|
||||
// .then((jpegBase64Data) => {
|
||||
// const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
||||
// const newImgUrl = jpegBase64Data.replace(
|
||||
// removeBase64Fromjpeg,
|
||||
// ""
|
||||
// );
|
||||
|
||||
// //function for call to embed signature in pdf and get digital signature pdf
|
||||
// signPdfFun(
|
||||
// newImgUrl,
|
||||
// documentId,
|
||||
// signerObjectId,
|
||||
// pdfOriginalWidth,
|
||||
// pngUrl,
|
||||
// containerWH,
|
||||
// setIsAlert,
|
||||
// data,
|
||||
// pdfBase64,
|
||||
// pageNo
|
||||
// )
|
||||
// .then((res) => {
|
||||
// if (res && res.status === "success") {
|
||||
// setPdfUrl(res.data);
|
||||
// setIsSigned(true);
|
||||
// setSignedSigners([]);
|
||||
// setUnSignedSigners([]);
|
||||
// getDocumentDetails();
|
||||
// } else {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "something went wrong"
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// setIsAlert({
|
||||
// isShow: true,
|
||||
// alertMessage: "something went wrong"
|
||||
// });
|
||||
// });
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// console.error("Error:", error);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// //else if signature is more than one then embed all sign with the use of pdf-lib
|
||||
// else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) {
|
||||
const flag = false;
|
||||
const extUserPtr = pdfDetails[0].ExtUserPtr;
|
||||
const HeaderDocId = extUserPtr?.HeaderDocId;
|
||||
//embed document's object id to all pages in pdf document
|
||||
if (!isDocId) {
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
if (!HeaderDocId) {
|
||||
if (!isDocId) {
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
}
|
||||
}
|
||||
//embed multi signature in pdf
|
||||
const pdfBytes = await multiSignEmbed(
|
||||
@@ -490,15 +525,13 @@ function PdfRequestFiles() {
|
||||
flag,
|
||||
containerWH
|
||||
);
|
||||
|
||||
//function for call to embed signature in pdf and get digital signature pdf
|
||||
try {
|
||||
const res = await signPdfFun(
|
||||
pdfBytes,
|
||||
documentId,
|
||||
signerObjectId,
|
||||
pdfOriginalWidth,
|
||||
pngUrl,
|
||||
containerWH,
|
||||
setIsAlert
|
||||
);
|
||||
if (res && res.status === "success") {
|
||||
@@ -514,7 +547,6 @@ function PdfRequestFiles() {
|
||||
const newIndex = index + 1;
|
||||
const user = pdfDetails?.[0].Signers[newIndex];
|
||||
if (user) {
|
||||
let sendMail;
|
||||
// console.log("pdfDetails", pdfDetails);
|
||||
const expireDate = pdfDetails?.[0].ExpiryDate.iso;
|
||||
const newDate = new Date(expireDate);
|
||||
@@ -543,16 +575,14 @@ function PdfRequestFiles() {
|
||||
const serverParams = `${newServer}&${localStorage.getItem(
|
||||
"parseAppId"
|
||||
)}&${localStorage.getItem("_appName")}`;
|
||||
|
||||
const hostUrl =
|
||||
window.location.origin + "/loadmf/signmicroapp";
|
||||
const hostUrl = window.location.origin;
|
||||
let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${user.Email}/${objectId}/${serverParams}`;
|
||||
const openSignUrl =
|
||||
"https://www.opensignlabs.com/contact-us";
|
||||
const orgName = pdfDetails[0]?.ExtUserPtr.Company
|
||||
? pdfDetails[0].ExtUserPtr.Company
|
||||
: "";
|
||||
const themeBGcolor = themeColor();
|
||||
const themeBGcolor = themeColor;
|
||||
let params = {
|
||||
recipient: user.Email,
|
||||
subject: `${pdfDetails?.[0].ExtUserPtr.Name} has requested you to sign ${pdfDetails?.[0].Name}`,
|
||||
@@ -581,7 +611,7 @@ function PdfRequestFiles() {
|
||||
openSignUrl +
|
||||
" target=_blank>here</a>.</p> </div></div></body> </html>"
|
||||
};
|
||||
sendMail = await axios.post(url, params, {
|
||||
await axios.post(url, params, {
|
||||
headers: headers
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -602,9 +632,7 @@ function PdfRequestFiles() {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setIsSignPad(false);
|
||||
// }
|
||||
} else {
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
@@ -619,6 +647,21 @@ function PdfRequestFiles() {
|
||||
});
|
||||
}
|
||||
}
|
||||
//function for update TourStatus
|
||||
const closeTour = async () => {
|
||||
setWidgetsTour(false);
|
||||
};
|
||||
|
||||
const tourConfig = [
|
||||
{
|
||||
selector: '[data-tut="IsSigned"]',
|
||||
content: minRequiredCount
|
||||
? `Please confirm that you have selected at least ${minRequiredCount} checkboxes.`
|
||||
: "Ensure this field is accurately filled and meets all requirements.",
|
||||
position: "top",
|
||||
style: { fontSize: "13px" }
|
||||
}
|
||||
];
|
||||
|
||||
//function for get pdf page details
|
||||
const pageDetails = async (pdf) => {
|
||||
@@ -690,7 +733,11 @@ function PdfRequestFiles() {
|
||||
//function for save button to save signature or image url
|
||||
const saveSign = (isDefaultSign, width, height) => {
|
||||
const isTypeText = width && height ? true : false;
|
||||
const signatureImg = isDefaultSign ? defaultSignImg : signature;
|
||||
const signatureImg = isDefaultSign
|
||||
? isDefaultSign === "initials"
|
||||
? myInitial
|
||||
: defaultSignImg
|
||||
: signature;
|
||||
let imgWH = { width: width ? width : "", height: height ? height : "" };
|
||||
setIsSignPad(false);
|
||||
setIsImageSelect(false);
|
||||
@@ -729,7 +776,7 @@ function PdfRequestFiles() {
|
||||
isTypeText
|
||||
);
|
||||
|
||||
const updateSignerData = currentSigner.map((obj, ind) => {
|
||||
const updateSignerData = currentSigner.map((obj) => {
|
||||
if (obj.signerObjId === signerObjectId) {
|
||||
return { ...obj, placeHolder: getUpdatePosition };
|
||||
}
|
||||
@@ -851,8 +898,6 @@ function PdfRequestFiles() {
|
||||
<Loader isLoading={isLoading} />
|
||||
) : handleError ? (
|
||||
<HandleError handleError={handleError} />
|
||||
) : noData ? (
|
||||
<Nodata />
|
||||
) : (
|
||||
<div>
|
||||
{isUiLoading && (
|
||||
@@ -865,7 +910,7 @@ function PdfRequestFiles() {
|
||||
justifyContent: "center",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
zIndex: "20",
|
||||
zIndex: "999",
|
||||
backgroundColor: "#e6f2f2",
|
||||
opacity: 0.8
|
||||
}}
|
||||
@@ -920,40 +965,45 @@ function PdfRequestFiles() {
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
|
||||
<Tour
|
||||
showNumber={false}
|
||||
showNavigation={false}
|
||||
showNavigationNumber={false}
|
||||
onRequestClose={closeTour}
|
||||
steps={tourConfig}
|
||||
isOpen={widgetsTour}
|
||||
rounded={5}
|
||||
closeWithMask={false}
|
||||
/>
|
||||
|
||||
{/* this modal is used to show decline alert */}
|
||||
<CustomModal
|
||||
<PdfDeclineModal
|
||||
containerWH={containerWH}
|
||||
show={isDecline.isDeclined}
|
||||
headMsg="Document Declined"
|
||||
bodyMssg={
|
||||
isDecline.currnt === "Sure" ? (
|
||||
<p className="pTagBody">
|
||||
Are you sure want to decline this document ?
|
||||
</p>
|
||||
) : isDecline.currnt === "YouDeclined" ? (
|
||||
<p className="pTagBody">You have declined this document!</p>
|
||||
) : (
|
||||
isDecline.currnt === "another" && (
|
||||
<p className="pTagBody">
|
||||
You cannot sign this document as it has been declined by
|
||||
one or more person(s).
|
||||
</p>
|
||||
)
|
||||
)
|
||||
isDecline.currnt === "Sure"
|
||||
? "Are you sure want to decline this document ?"
|
||||
: isDecline.currnt === "YouDeclined"
|
||||
? "You have declined this document!"
|
||||
: isDecline.currnt === "another" &&
|
||||
"You cannot sign this document as it has been declined by one or more recipient(s)."
|
||||
}
|
||||
footerMessage={isDecline.currnt === "Sure"}
|
||||
declineDoc={declineDoc}
|
||||
setIsDecline={setIsDecline}
|
||||
/>
|
||||
{/* this modal is used for show expired alert */}
|
||||
<CustomModal
|
||||
<PdfDeclineModal
|
||||
containerWH={containerWH}
|
||||
show={isExpired}
|
||||
headMsg="Document Expired!"
|
||||
bodyMssg="This Document is no longer available."
|
||||
/>
|
||||
|
||||
<ModalUi
|
||||
headerColor={defaultSignImg ? themeColor() : "#dc3545"}
|
||||
headerColor={defaultSignImg ? themeColor : "#dc3545"}
|
||||
isOpen={defaultSignAlert.isShow}
|
||||
title={"Auto sign"}
|
||||
handleClose={() => {
|
||||
@@ -980,7 +1030,7 @@ function PdfRequestFiles() {
|
||||
<button
|
||||
onClick={() => addDefaultSignature()}
|
||||
style={{
|
||||
background: themeColor()
|
||||
background: themeColor
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn"
|
||||
@@ -1079,6 +1129,10 @@ function PdfRequestFiles() {
|
||||
onSaveImage={saveImage}
|
||||
onSaveSign={saveSign}
|
||||
defaultSign={defaultSignImg}
|
||||
myInitial={myInitial}
|
||||
isInitial={isInitial}
|
||||
setIsInitial={setIsInitial}
|
||||
setIsStamp={setIsStamp}
|
||||
/>
|
||||
{/* pdf header which contain funish back button */}
|
||||
<Header
|
||||
@@ -1090,7 +1144,7 @@ function PdfRequestFiles() {
|
||||
signerPos={signerPos}
|
||||
isSigned={isSigned}
|
||||
isCompleted={isCompleted}
|
||||
embedImages={embedImages}
|
||||
embedWidgetsData={embedWidgetsData}
|
||||
isShowHeader={true}
|
||||
setIsDecline={setIsDecline}
|
||||
decline={true}
|
||||
@@ -1120,6 +1174,11 @@ function PdfRequestFiles() {
|
||||
pdfLoadFail={pdfLoadFail}
|
||||
setSignerPos={setSignerPos}
|
||||
containerWH={containerWH}
|
||||
setIsInitial={setIsInitial}
|
||||
setValidateAlert={setValidateAlert}
|
||||
unSignedWidgetId={unSignedWidgetId}
|
||||
setSelectWidgetId={setSelectWidgetId}
|
||||
selectWidgetId={selectWidgetId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -1132,9 +1191,7 @@ function PdfRequestFiles() {
|
||||
{signedSigners.length > 0 && (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
background: themeColor()
|
||||
}}
|
||||
style={{ background: themeColor }}
|
||||
className="signedStyle"
|
||||
>
|
||||
Signed by
|
||||
@@ -1197,7 +1254,7 @@ function PdfRequestFiles() {
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white",
|
||||
padding: "5px",
|
||||
fontFamily: "sans-serif",
|
||||
@@ -1262,7 +1319,6 @@ function PdfRequestFiles() {
|
||||
)}
|
||||
{defaultSignImg && !alreadySign && (
|
||||
<DefaultSignature
|
||||
themeColor={themeColor}
|
||||
defaultSignImg={defaultSignImg}
|
||||
setDefaultSignImg={setDefaultSignImg}
|
||||
userObjectId={signerObjectId}
|
||||
@@ -1277,6 +1333,38 @@ function PdfRequestFiles() {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ModalUi
|
||||
headerColor={"#dc3545"}
|
||||
isOpen={validateAlert}
|
||||
title={"Validation alert"}
|
||||
handleClose={() => {
|
||||
setValidateAlert(false);
|
||||
}}
|
||||
>
|
||||
<div style={{ height: "100%", padding: 20 }}>
|
||||
<p>
|
||||
The input does not meet the criteria set by the regular expression.
|
||||
</p>
|
||||
|
||||
<div
|
||||
style={{
|
||||
height: "1px",
|
||||
backgroundColor: "#9f9f9f",
|
||||
width: "100%",
|
||||
marginTop: "15px",
|
||||
marginBottom: "15px"
|
||||
}}
|
||||
></div>
|
||||
<button
|
||||
onClick={() => setValidateAlert(false)}
|
||||
type="button"
|
||||
className="finishBtn cancelBtn"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
</DndProvider>
|
||||
);
|
||||
}
|
||||
@@ -7,15 +7,11 @@ import { connect } from "react-redux";
|
||||
import Title from "../components/Title";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
|
||||
const appId = localStorage.getItem("AppID12");
|
||||
const server = localStorage.getItem("BaseUrl12");
|
||||
Parse.serverURL = server;
|
||||
Parse.initialize(appId);
|
||||
const PgSignUp = (props) => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("BaseUrl12"));
|
||||
const [parseAppId] = useState(localStorage.getItem("AppID12"));
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [formData, setFormData] = useState({
|
||||
password: "",
|
||||
confirmPassword: ""
|
||||
@@ -29,11 +25,7 @@ const PgSignUp = (props) => {
|
||||
// below useEffect is used to fetch App data and save to redux state
|
||||
useEffect(() => {
|
||||
// Parse.User.logOut()
|
||||
props.fetchAppInfo(
|
||||
localStorage.getItem("domain"),
|
||||
localStorage.getItem("BaseUrl12"),
|
||||
localStorage.getItem("AppID12")
|
||||
);
|
||||
props.fetchAppInfo();
|
||||
handleSignedUpUser();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
@@ -224,8 +216,8 @@ const PgSignUp = (props) => {
|
||||
};
|
||||
|
||||
const handleNavigation = async (sessionToken) => {
|
||||
const baseUrl = localStorage.getItem("BaseUrl12");
|
||||
const parseAppId = localStorage.getItem("AppID12");
|
||||
const baseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
const res = await axios.get(baseUrl + "users/me", {
|
||||
headers: {
|
||||
"X-Parse-Session-Token": sessionToken,
|
||||
@@ -299,8 +291,6 @@ const PgSignUp = (props) => {
|
||||
"extended_class",
|
||||
element.extended_class
|
||||
);
|
||||
localStorage.setItem("userpointer", element.userpointer);
|
||||
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
@@ -407,11 +397,11 @@ const PgSignUp = (props) => {
|
||||
localStorage.setItem("pageType", element.pageType);
|
||||
setIsLoader(false);
|
||||
const redirectUrl =
|
||||
location?.state?.from ||
|
||||
`/${element.pageType}/${element.pageId}`;
|
||||
location?.state?.from ||
|
||||
`/${element.pageType}/${element.pageId}`;
|
||||
|
||||
// Redirect to the appropriate URL after successful login
|
||||
navigate(redirectUrl);
|
||||
// Redirect to the appropriate URL after successful login
|
||||
navigate(redirectUrl);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
@@ -53,18 +53,16 @@ const Report = () => {
|
||||
setHeading(json.heading);
|
||||
setReportName(json.reportName);
|
||||
setForm(json.form);
|
||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||
Parse.initialize(localStorage.getItem("AppID12"));
|
||||
const currentUser = Parse.User.current().id;
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessiontoken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
try {
|
||||
const params = { reportId: id, skip: skipUserRecord, limit: limit };
|
||||
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
|
||||
const url = `${localStorage.getItem("baseUrl")}/functions/getReport`;
|
||||
const res = await axios.post(url, params, {
|
||||
headers: headers,
|
||||
signal: abortController.signal // is used to cancel fetch query
|
||||
@@ -7,6 +7,7 @@ import { fetchAppInfo, showTenantName } from "../redux/actions";
|
||||
import { useNavigate, NavLink } from "react-router-dom";
|
||||
import login_img from "../assets/images/login_img.svg";
|
||||
import { useWindowSize } from "../hook/useWindowSize";
|
||||
import Alert from "../primitives/Alert";
|
||||
|
||||
const Signup = (props) => {
|
||||
const { width } = useWindowSize();
|
||||
@@ -15,14 +16,12 @@ const Signup = (props) => {
|
||||
const [phone, setPhone] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [company, setCompany] = useState("");
|
||||
const [jobTitle, setJobTitle] = useState("");
|
||||
const [state, setState] = useState({
|
||||
loading: false,
|
||||
toastColor: "#5cb85c",
|
||||
toastDescription: ""
|
||||
alertType: "success",
|
||||
alertMsg: ""
|
||||
});
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [lengthValid, setLengthValid] = useState(false);
|
||||
@@ -36,8 +35,8 @@ const Signup = (props) => {
|
||||
if (Parse.User.current()) {
|
||||
await Parse.User.logOut();
|
||||
}
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
let baseUrl = localStorage.getItem("baseUrl");
|
||||
let appid = localStorage.getItem("parseAppId");
|
||||
let applogo = localStorage.getItem("appLogo");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let appversion = localStorage.getItem("appVersion");
|
||||
@@ -51,8 +50,8 @@ const Signup = (props) => {
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
localStorage.setItem("baseUrl", baseUrl);
|
||||
localStorage.setItem("parseAppId", appid);
|
||||
localStorage.setItem("appLogo", applogo);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("appversion", appversion);
|
||||
@@ -80,8 +79,6 @@ const Signup = (props) => {
|
||||
};
|
||||
localStorage.setItem("userDetails", JSON.stringify(userDetails));
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
event.preventDefault();
|
||||
var user = new Parse.User();
|
||||
user.set("name", name);
|
||||
@@ -129,12 +126,8 @@ const Signup = (props) => {
|
||||
alert("User already exists with this username!");
|
||||
setState({ loading: false });
|
||||
} else {
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let parseAppId = localStorage.getItem("AppID12");
|
||||
// console.log("state.email ", email);
|
||||
try {
|
||||
Parse.serverURL = baseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
await Parse.User.requestPasswordReset(email).then(
|
||||
async function (res1) {
|
||||
if (res1.data === undefined) {
|
||||
@@ -161,8 +154,8 @@ const Signup = (props) => {
|
||||
};
|
||||
|
||||
const handleNavigation = async (sessionToken) => {
|
||||
const baseUrl = localStorage.getItem("BaseUrl12");
|
||||
const parseAppId = localStorage.getItem("AppID12");
|
||||
const baseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
const res = await axios.get(baseUrl + "users/me", {
|
||||
headers: {
|
||||
"X-Parse-Session-Token": sessionToken,
|
||||
@@ -236,8 +229,6 @@ const Signup = (props) => {
|
||||
"extended_class",
|
||||
element.extended_class
|
||||
);
|
||||
localStorage.setItem("userpointer", element.userpointer);
|
||||
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: email
|
||||
}).then(
|
||||
@@ -358,19 +349,18 @@ const Signup = (props) => {
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
/* alert(
|
||||
"You dont have access to this application."
|
||||
); */
|
||||
setState({
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription:
|
||||
"You dont have access to this application."
|
||||
alertType: "danger",
|
||||
alertMsg:
|
||||
"You dont have access to this application!"
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
localStorage.setItem("accesstoken", null);
|
||||
console.error("Error while fetching Follow", error);
|
||||
@@ -381,25 +371,29 @@ const Signup = (props) => {
|
||||
} else {
|
||||
setState({
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: "User Role Not Found."
|
||||
alertType: "danger",
|
||||
alertMsg: "User Role Not Found!"
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
} else {
|
||||
setState({
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: "User Role Not Found."
|
||||
alertType: "danger",
|
||||
alertMsg: "User Role Not Found!"
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
})
|
||||
@@ -407,13 +401,16 @@ const Signup = (props) => {
|
||||
console.log("err", err);
|
||||
setState({
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: `Does not have permissions to access this application.`
|
||||
alertType: "danger",
|
||||
alertMsg:
|
||||
"Does not have permissions to access this application!"
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
@@ -421,24 +418,22 @@ const Signup = (props) => {
|
||||
// alert(`${error.message}`);
|
||||
setState({
|
||||
loading: false,
|
||||
toastColor: "#d9534f",
|
||||
toastDescription: `${error.message}`
|
||||
alertType: "danger",
|
||||
alertMsg: `${error.message}`
|
||||
});
|
||||
const x = document.getElementById("snackbar");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
setState({
|
||||
loading: false,
|
||||
alertType: "danger",
|
||||
alertMsg: ""
|
||||
});
|
||||
}, 2000);
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
props.fetchAppInfo(
|
||||
localStorage.getItem("domain"),
|
||||
localStorage.getItem("BaseUrl12"),
|
||||
localStorage.getItem("AppID12")
|
||||
);
|
||||
props.fetchAppInfo();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
@@ -644,10 +639,7 @@ const Signup = (props) => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="snackbar" style={{ backgroundColor: state.toastColor }}>
|
||||
{state.toastDescription}
|
||||
</div>
|
||||
<Alert type={state.alertType}>{state.alertMsg}</Alert>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
@@ -1,39 +1,40 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
||||
import { useParams, useNavigate } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import "../css/./signature.css";
|
||||
import sign from "../assests/sign3.png";
|
||||
import stamp from "../assests/stamp2.png";
|
||||
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||
import "../styles/signature.css";
|
||||
import { themeColor } from "../constant/const";
|
||||
import { DndProvider } from "react-dnd";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { useDrag, useDrop } from "react-dnd";
|
||||
import FieldsComponent from "./component/fieldsComponent";
|
||||
import WidgetComponent from "../components/pdf/WidgetComponent";
|
||||
import Tour from "reactour";
|
||||
import Loader from "./component/loader";
|
||||
import HandleError from "./component/HandleError";
|
||||
import Nodata from "./component/Nodata";
|
||||
import SignerListPlace from "./component/signerListPlace";
|
||||
import Header from "./component/header";
|
||||
import Loader from "../primitives/LoaderWithMsg";
|
||||
import HandleError from "../primitives/HandleError";
|
||||
import SignerListPlace from "../components/pdf/SignerListPlace";
|
||||
import Header from "../components/pdf/PdfHeader";
|
||||
import WidgetNameModal from "../components/pdf/WidgetNameModal";
|
||||
import {
|
||||
pdfNewWidthFun,
|
||||
contractUsers,
|
||||
getHostUrl,
|
||||
randomId,
|
||||
addZIndex,
|
||||
createDocument
|
||||
} from "../utils/Utils";
|
||||
import RenderPdf from "./component/renderPdf";
|
||||
import "../css/AddUser.css";
|
||||
import Title from "./component/Title";
|
||||
import LinkUserModal from "./component/LinkUserModal";
|
||||
import EditTemplate from "./component/EditTemplate";
|
||||
import ModalUi from "../premitives/ModalUi";
|
||||
import AddRoleModal from "./component/AddRoleModal";
|
||||
import PlaceholderCopy from "./component/PlaceholderCopy";
|
||||
import ModalComponent from "./component/modalComponent";
|
||||
import TourContentWithBtn from "../premitives/TourContentWithBtn";
|
||||
createDocument,
|
||||
defaultWidthHeight,
|
||||
addWidgetOptions,
|
||||
textInputWidget,
|
||||
radioButtonWidget
|
||||
} from "../constant/Utils";
|
||||
import RenderPdf from "../components/pdf/RenderPdf";
|
||||
import "../styles/AddUser.css";
|
||||
import Title from "../components/Title";
|
||||
import LinkUserModal from "../primitives/LinkUserModal";
|
||||
import EditTemplate from "../components/pdf/EditTemplate";
|
||||
import ModalUi from "../primitives/ModalUi";
|
||||
import AddRoleModal from "../components/pdf/AddRoleModal";
|
||||
import PlaceholderCopy from "../components/pdf/PlaceholderCopy";
|
||||
import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
||||
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
|
||||
const TemplatePlaceholder = () => {
|
||||
const navigate = useNavigate();
|
||||
const { templateId } = useParams();
|
||||
@@ -62,7 +63,6 @@ const TemplatePlaceholder = () => {
|
||||
const [checkTourStatus, setCheckTourStatus] = useState(false);
|
||||
const [tourStatus, setTourStatus] = useState([]);
|
||||
const [signerUserId, setSignerUserId] = useState();
|
||||
const [noData, setNoData] = useState(false);
|
||||
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
||||
const [contractName, setContractName] = useState("");
|
||||
const [containerWH, setContainerWH] = useState();
|
||||
@@ -74,6 +74,11 @@ const TemplatePlaceholder = () => {
|
||||
const [isResize, setIsResize] = useState(false);
|
||||
const [isSigners, setIsSigners] = useState(false);
|
||||
const [zIndex, setZIndex] = useState(1);
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
const [widgetType, setWidgetType] = useState("");
|
||||
const [isRadio, setIsRadio] = useState(false);
|
||||
const [selectWidgetId, setSelectWidgetId] = useState("");
|
||||
const [isNameModal, setIsNameModal] = useState(false);
|
||||
const [pdfLoadFail, setPdfLoadFail] = useState({
|
||||
status: false,
|
||||
type: "load"
|
||||
@@ -93,7 +98,7 @@ const TemplatePlaceholder = () => {
|
||||
"#ffffcc"
|
||||
];
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const [{ isOver }, drop] = useDrop({
|
||||
const [, drop] = useDrop({
|
||||
accept: "BOX",
|
||||
drop: (item, monitor) => addPositionOfSignature(item, monitor),
|
||||
collect: (monitor) => ({
|
||||
@@ -105,7 +110,7 @@ const TemplatePlaceholder = () => {
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 1,
|
||||
text: "drag me"
|
||||
text: "signature"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragSign: !!monitor.isDragging()
|
||||
@@ -117,37 +122,12 @@ const TemplatePlaceholder = () => {
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 2,
|
||||
text: "drag me"
|
||||
text: "stamp"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragStamp: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
|
||||
const [{ isDragSignatureSS }, dragSignatureSS] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 3,
|
||||
text: "drag me"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragSignatureSS: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
|
||||
const [{ isDragStampSS }, dragStampSS] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
type: "BOX",
|
||||
id: 4,
|
||||
text: "drag me"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragStampSS: !!monitor.isDragging()
|
||||
})
|
||||
});
|
||||
|
||||
const [uniqueId, setUniqueId] = useState("");
|
||||
const [isModalRole, setIsModalRole] = useState(false);
|
||||
const [roleName, setRoleName] = useState("");
|
||||
@@ -159,6 +139,9 @@ const TemplatePlaceholder = () => {
|
||||
const [IsReceipent, setIsReceipent] = useState(true);
|
||||
const [isDontShow, setIsDontShow] = useState(false);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [currWidgetsDetails, setCurrWidgetsDetails] = useState([]);
|
||||
const [isCheckbox, setIsCheckbox] = useState(false);
|
||||
const [widgetName, setWidgetName] = useState(false);
|
||||
const senderUser =
|
||||
localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
@@ -170,7 +153,7 @@ const TemplatePlaceholder = () => {
|
||||
|
||||
useEffect(() => {
|
||||
fetchTemplate();
|
||||
// eslint-disable-next-line
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -182,6 +165,7 @@ const TemplatePlaceholder = () => {
|
||||
height: divRef.current.offsetHeight
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [divRef.current]);
|
||||
|
||||
// `fetchTemplate` function in used to get Template from server and setPlaceholder ,setSigner if present
|
||||
@@ -277,8 +261,7 @@ const TemplatePlaceholder = () => {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
setNoData(true);
|
||||
|
||||
setHandleError("No Data Found!");
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
@@ -317,8 +300,7 @@ const TemplatePlaceholder = () => {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else if (res.length === 0) {
|
||||
setNoData(true);
|
||||
|
||||
setHandleError("No Data Found!");
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
@@ -328,6 +310,9 @@ const TemplatePlaceholder = () => {
|
||||
|
||||
//function for setting position after drop signature button over pdf
|
||||
const addPositionOfSignature = (item, monitor) => {
|
||||
if (item && item.text) {
|
||||
setWidgetName(item.text);
|
||||
}
|
||||
getSignerPos(item, monitor);
|
||||
};
|
||||
|
||||
@@ -345,26 +330,29 @@ const TemplatePlaceholder = () => {
|
||||
// (data) => data.signerObjId === signerObjId
|
||||
// );
|
||||
let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
||||
const dragTypeValue = item?.text ? item.text : monitor.type;
|
||||
let dropData = [];
|
||||
let placeHolder;
|
||||
if (item === "onclick") {
|
||||
const dropObj = {
|
||||
xPosition: window.innerWidth / 2 - 100,
|
||||
//onclick put placeholder center on pdf
|
||||
xPosition: window.innerWidth / 2 - 150,
|
||||
yPosition: window.innerHeight / 2 - 60,
|
||||
isStamp: monitor,
|
||||
isStamp:
|
||||
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
|
||||
key: key,
|
||||
isDrag: false,
|
||||
scale: scale,
|
||||
isMobile: isMobile,
|
||||
yBottom: window.innerHeight / 2 - 60,
|
||||
zIndex: posZIndex
|
||||
zIndex: posZIndex,
|
||||
type: dragTypeValue,
|
||||
options: addWidgetOptions(dragTypeValue)
|
||||
};
|
||||
dropData.push(dropObj);
|
||||
placeHolder = {
|
||||
pageNumber: pageNumber,
|
||||
pos: dropData
|
||||
};
|
||||
} else if (item.type === "BOX") {
|
||||
} else {
|
||||
const offset = monitor.getClientOffset();
|
||||
//adding and updating drop position in array when user drop signature button in div
|
||||
const containerRect = document
|
||||
@@ -372,20 +360,17 @@ const TemplatePlaceholder = () => {
|
||||
.getBoundingClientRect();
|
||||
const x = offset.x - containerRect.left;
|
||||
const y = offset.y - containerRect.top;
|
||||
const ybottom = containerRect.bottom - offset.y;
|
||||
|
||||
const dropObj = {
|
||||
xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x,
|
||||
yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y,
|
||||
isStamp: isDragStamp || isDragStampSS ? true : false,
|
||||
isStamp:
|
||||
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
|
||||
key: key,
|
||||
isDrag: false,
|
||||
firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos,
|
||||
firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos,
|
||||
yBottom: ybottom,
|
||||
scale: scale,
|
||||
isMobile: isMobile,
|
||||
zIndex: posZIndex
|
||||
zIndex: posZIndex,
|
||||
type: item.text,
|
||||
options: addWidgetOptions(dragTypeValue)
|
||||
};
|
||||
|
||||
dropData.push(dropObj);
|
||||
@@ -454,12 +439,26 @@ const TemplatePlaceholder = () => {
|
||||
}
|
||||
setSignerPos((prev) => [...prev, placeHolderPos]);
|
||||
}
|
||||
|
||||
if (dragTypeValue === "dropdown") {
|
||||
setShowDropdown(true);
|
||||
} else if (dragTypeValue === "checkbox") {
|
||||
setIsCheckbox(true);
|
||||
} else if (dragTypeValue === radioButtonWidget) {
|
||||
setIsRadio(true);
|
||||
}
|
||||
setCurrWidgetsDetails({});
|
||||
setWidgetType(dragTypeValue);
|
||||
setSignKey(key);
|
||||
setSelectWidgetId(key);
|
||||
|
||||
setIsMailSend(false);
|
||||
} else {
|
||||
setIsReceipent(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//function for get pdf page details
|
||||
const pageDetails = async (pdf) => {
|
||||
const load = {
|
||||
@@ -507,7 +506,7 @@ const TemplatePlaceholder = () => {
|
||||
const getXYdata = getPageNumer[0].pos;
|
||||
|
||||
const getPosData = getXYdata;
|
||||
const addSignPos = getPosData.map((url, ind) => {
|
||||
const addSignPos = getPosData.map((url) => {
|
||||
if (url.key === keyValue) {
|
||||
return {
|
||||
...url,
|
||||
@@ -520,13 +519,13 @@ const TemplatePlaceholder = () => {
|
||||
return url;
|
||||
});
|
||||
|
||||
const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
|
||||
const newUpdateSignPos = getPlaceHolder.map((obj) => {
|
||||
if (obj.pageNumber === pageNumber) {
|
||||
return { ...obj, pos: addSignPos };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
const newUpdateSigner = updateSignPos.map((obj, ind) => {
|
||||
const newUpdateSigner = updateSignPos.map((obj) => {
|
||||
if (obj.Id === signId) {
|
||||
return { ...obj, placeHolder: newUpdateSignPos };
|
||||
}
|
||||
@@ -562,19 +561,19 @@ const TemplatePlaceholder = () => {
|
||||
|
||||
if (getPageNumer.length > 0) {
|
||||
const getXYdata = getPageNumer[0].pos.filter(
|
||||
(data, ind) => data.key !== key
|
||||
(data) => data.key !== key
|
||||
);
|
||||
|
||||
if (getXYdata.length > 0) {
|
||||
updateData.push(getXYdata);
|
||||
const newUpdatePos = getPlaceHolder.map((obj, ind) => {
|
||||
const newUpdatePos = getPlaceHolder.map((obj) => {
|
||||
if (obj.pageNumber === pageNumber) {
|
||||
return { ...obj, pos: updateData[0] };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
const newUpdateSigner = signerPos.map((obj, ind) => {
|
||||
const newUpdateSigner = signerPos.map((obj) => {
|
||||
if (obj.Id === Id) {
|
||||
return { ...obj, placeHolder: newUpdatePos };
|
||||
}
|
||||
@@ -589,7 +588,7 @@ const TemplatePlaceholder = () => {
|
||||
);
|
||||
|
||||
if (getRemainPage && getRemainPage.length > 0) {
|
||||
const newUpdatePos = filterSignerPos.map((obj, ind) => {
|
||||
const newUpdatePos = filterSignerPos.map((obj) => {
|
||||
if (obj.Id === Id) {
|
||||
return { ...obj, placeHolder: getRemainPage };
|
||||
}
|
||||
@@ -629,7 +628,7 @@ const TemplatePlaceholder = () => {
|
||||
};
|
||||
|
||||
//function for capture position of x and y on hover signature button last position
|
||||
const handleMouseLeave = (e) => {
|
||||
const handleMouseLeave = () => {
|
||||
setSignBtnPosition([xySignature]);
|
||||
};
|
||||
|
||||
@@ -664,7 +663,6 @@ const TemplatePlaceholder = () => {
|
||||
try {
|
||||
const data = {
|
||||
Placeholders: signerPos,
|
||||
SignedUrl: pdfDetails[0].URL,
|
||||
Signers: signers,
|
||||
Name: pdfDetails[0]?.Name || "",
|
||||
Note: pdfDetails[0]?.Note || "",
|
||||
@@ -686,7 +684,7 @@ const TemplatePlaceholder = () => {
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((result) => {
|
||||
.then(() => {
|
||||
setIsCreateDocModal(true);
|
||||
setIsMailSend(true);
|
||||
const loadObj = {
|
||||
@@ -727,7 +725,7 @@ const TemplatePlaceholder = () => {
|
||||
selector: '[data-tut="reactourFirst"]',
|
||||
content: () => (
|
||||
<TourContentWithBtn
|
||||
message={`Select a role from this list to add a place-holder where he is supposed to sign.The placeholder will appear in the same colour as the recipient name once you drop it on the document.`}
|
||||
message={`Once roles are added, select a role from list to add a place-holder where he is supposed to sign. The placeholder will appear in the same colour as the role name once you drop it on the document.`}
|
||||
isChecked={handleDontShow}
|
||||
/>
|
||||
),
|
||||
@@ -739,7 +737,7 @@ const TemplatePlaceholder = () => {
|
||||
selector: '[data-tut="reactourSecond"]',
|
||||
content: () => (
|
||||
<TourContentWithBtn
|
||||
message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`}
|
||||
message={`Drag a widget placeholder onto the PDF to choose your desired signing location.`}
|
||||
isChecked={handleDontShow}
|
||||
/>
|
||||
),
|
||||
@@ -761,7 +759,7 @@ const TemplatePlaceholder = () => {
|
||||
selector: '[data-tut="reactourFour"]',
|
||||
content: () => (
|
||||
<TourContentWithBtn
|
||||
message={`Clicking "Save" button will save the template and will ask you for creating new document.`}
|
||||
message={`Clicking "Save" button will save the template and will ask you if you want to create a new document using this template.`}
|
||||
isChecked={handleDontShow}
|
||||
/>
|
||||
),
|
||||
@@ -805,7 +803,7 @@ const TemplatePlaceholder = () => {
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
.then(() => {
|
||||
// const json = Listdata.data;
|
||||
// const res = json.results;
|
||||
})
|
||||
@@ -819,11 +817,10 @@ const TemplatePlaceholder = () => {
|
||||
const handleCreateDocModal = async () => {
|
||||
setIsCreateDocModal(false);
|
||||
setIsCreateDoc(true);
|
||||
const hostUrl = getHostUrl();
|
||||
// handle create document
|
||||
const res = await createDocument(pdfDetails, signerPos, signersdata);
|
||||
if (res.status === "success") {
|
||||
navigate(`${hostUrl}placeHolderSign/${res.id}`, {
|
||||
navigate(`/placeHolderSign/${res.id}`, {
|
||||
state: { title: "Use Template" }
|
||||
});
|
||||
setIsCreateDoc(false);
|
||||
@@ -964,6 +961,211 @@ const TemplatePlaceholder = () => {
|
||||
setIsModalRole(false);
|
||||
};
|
||||
|
||||
const handleSaveWidgetsOptions = (
|
||||
dropdownName,
|
||||
dropdownOptions,
|
||||
minCount,
|
||||
maxCount,
|
||||
isReadOnly,
|
||||
addOption,
|
||||
deleteOption,
|
||||
status,
|
||||
defaultValue,
|
||||
isHideLabel
|
||||
) => {
|
||||
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) {
|
||||
if (widgetType === radioButtonWidget) {
|
||||
if (addOption) {
|
||||
return {
|
||||
...position,
|
||||
Height: position.Height
|
||||
? position.Height + 15
|
||||
: defaultWidthHeight(widgetType).height + 15
|
||||
};
|
||||
} else if (deleteOption) {
|
||||
return {
|
||||
...position,
|
||||
Height: position.Height
|
||||
? position.Height - 15
|
||||
: defaultWidthHeight(widgetType).height - 15
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
options: {
|
||||
...position.options,
|
||||
name: dropdownName,
|
||||
values: dropdownOptions,
|
||||
status: status,
|
||||
defaultValue: defaultValue,
|
||||
isReadOnly: isReadOnly || false,
|
||||
isHideLabel: isHideLabel || false
|
||||
}
|
||||
};
|
||||
}
|
||||
} else if (widgetType === "checkbox") {
|
||||
if (addOption) {
|
||||
return {
|
||||
...position,
|
||||
Height: position.Height
|
||||
? position.Height + 15
|
||||
: defaultWidthHeight(widgetType).height + 15
|
||||
};
|
||||
} else if (deleteOption) {
|
||||
return {
|
||||
...position,
|
||||
Height: position.Height
|
||||
? position.Height - 15
|
||||
: defaultWidthHeight(widgetType).height - 15
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
options: {
|
||||
...position.options,
|
||||
name: dropdownName,
|
||||
values: dropdownOptions,
|
||||
validation: {
|
||||
minRequiredCount: minCount,
|
||||
maxRequiredCount: maxCount
|
||||
},
|
||||
isReadOnly: isReadOnly || false,
|
||||
defaultValue: defaultValue,
|
||||
isHideLabel: isHideLabel || false
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
options: {
|
||||
...position.options,
|
||||
name: dropdownName,
|
||||
status: status,
|
||||
values: dropdownOptions,
|
||||
defaultValue: defaultValue
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (!addOption && !deleteOption) {
|
||||
handleNameModal();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleWidgetdefaultdata = (defaultdata) => {
|
||||
const options = ["email", "number", "text"];
|
||||
let inputype;
|
||||
if (defaultdata.textvalidate) {
|
||||
inputype = options.includes(defaultdata.textvalidate)
|
||||
? defaultdata.textvalidate
|
||||
: "regex";
|
||||
} else {
|
||||
inputype = "text";
|
||||
}
|
||||
|
||||
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) {
|
||||
if (position.type === textInputWidget) {
|
||||
return {
|
||||
...position,
|
||||
options: {
|
||||
...position.options,
|
||||
name: defaultdata?.name || "text",
|
||||
status: defaultdata?.status || "required",
|
||||
hint: defaultdata?.hint || "",
|
||||
defaultValue: defaultdata?.defaultValue || "",
|
||||
validation: {
|
||||
type: inputype,
|
||||
pattern:
|
||||
inputype === "regex" ? defaultdata.textvalidate : ""
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
options: {
|
||||
...position.options,
|
||||
name: defaultdata.name,
|
||||
status: defaultdata.status,
|
||||
defaultValue: defaultdata.defaultValue
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
setCurrWidgetsDetails({});
|
||||
handleNameModal();
|
||||
};
|
||||
const handleNameModal = () => {
|
||||
setIsNameModal(false);
|
||||
setCurrWidgetsDetails({});
|
||||
setShowDropdown(false);
|
||||
setIsRadio(false);
|
||||
setIsCheckbox(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Title title={"Template"} />
|
||||
@@ -972,8 +1174,6 @@ const TemplatePlaceholder = () => {
|
||||
<Loader isLoading={isLoading} />
|
||||
) : handleError ? (
|
||||
<HandleError handleError={handleError} />
|
||||
) : noData ? (
|
||||
<Nodata />
|
||||
) : (
|
||||
<div className="signatureContainer" ref={divRef}>
|
||||
{/* this component used for UI interaction and show their functionality */}
|
||||
@@ -1055,7 +1255,7 @@ const TemplatePlaceholder = () => {
|
||||
handleCreateDocModal();
|
||||
}}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor,
|
||||
color: "white"
|
||||
}}
|
||||
type="button"
|
||||
@@ -1077,10 +1277,65 @@ const TemplatePlaceholder = () => {
|
||||
</div>
|
||||
</ModalUi>
|
||||
{isCreateDoc && <Loader isLoading={isLoading} />}
|
||||
<ModalComponent
|
||||
isShow={isShowEmail}
|
||||
type={"signersAlert"}
|
||||
setIsShowEmail={setIsShowEmail}
|
||||
<ModalUi
|
||||
headerColor={"#dc3545"}
|
||||
isOpen={isShowEmail}
|
||||
title={"signers alert"}
|
||||
handleClose={() => {
|
||||
setIsShowEmail(false);
|
||||
}}
|
||||
>
|
||||
<div style={{ height: "100%", padding: 20 }}>
|
||||
<p>Please select signer for add placeholder!</p>
|
||||
<div
|
||||
style={{
|
||||
height: "1px",
|
||||
backgroundColor: "#9f9f9f",
|
||||
width: "100%",
|
||||
marginTop: "15px",
|
||||
marginBottom: "15px"
|
||||
}}
|
||||
></div>
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsShowEmail(false);
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn cancelBtn"
|
||||
>
|
||||
Ok
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
<DropdownWidgetOption
|
||||
type={radioButtonWidget}
|
||||
title="Radio group"
|
||||
showDropdown={isRadio}
|
||||
setShowDropdown={setIsRadio}
|
||||
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
|
||||
currWidgetsDetails={currWidgetsDetails}
|
||||
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||
handleClose={handleNameModal}
|
||||
/>
|
||||
<DropdownWidgetOption
|
||||
type="checkbox"
|
||||
title="Checkbox"
|
||||
showDropdown={isCheckbox}
|
||||
setShowDropdown={setIsCheckbox}
|
||||
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
|
||||
currWidgetsDetails={currWidgetsDetails}
|
||||
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||
handleClose={handleNameModal}
|
||||
/>
|
||||
<DropdownWidgetOption
|
||||
type="dropdown"
|
||||
title="Dropdown options"
|
||||
showDropdown={showDropdown}
|
||||
setShowDropdown={setShowDropdown}
|
||||
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
|
||||
currWidgetsDetails={currWidgetsDetails}
|
||||
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||
handleClose={handleNameModal}
|
||||
/>
|
||||
<PlaceholderCopy
|
||||
isPageCopy={isPageCopy}
|
||||
@@ -1139,6 +1394,14 @@ const TemplatePlaceholder = () => {
|
||||
setSignKey={setSignKey}
|
||||
setSignerObjId={setSignerObjId}
|
||||
isDragging={isDragging}
|
||||
setShowDropdown={setShowDropdown}
|
||||
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||
setWidgetType={setWidgetType}
|
||||
setIsRadio={setIsRadio}
|
||||
setSelectWidgetId={setSelectWidgetId}
|
||||
selectWidgetId={selectWidgetId}
|
||||
setIsCheckbox={setIsCheckbox}
|
||||
handleNameModal={setIsNameModal}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -1146,25 +1409,19 @@ const TemplatePlaceholder = () => {
|
||||
{/* signature button */}
|
||||
{isMobile ? (
|
||||
<div>
|
||||
<FieldsComponent
|
||||
<WidgetComponent
|
||||
dataTut="reactourFirst"
|
||||
dataTut2="reactourSecond"
|
||||
pdfUrl={isMailSend}
|
||||
sign={sign}
|
||||
stamp={stamp}
|
||||
dragSignature={dragSignature}
|
||||
signRef={signRef}
|
||||
handleDivClick={handleDivClick}
|
||||
handleMouseLeave={handleMouseLeave}
|
||||
isDragSign={isDragSign}
|
||||
themeColor={themeColor}
|
||||
dragStamp={dragStamp}
|
||||
dragRef={dragRef}
|
||||
isDragStamp={isDragStamp}
|
||||
isSignYourself={true}
|
||||
isDragSignatureSS={isDragSignatureSS}
|
||||
dragSignatureSS={dragSignatureSS}
|
||||
dragStampSS={dragStampSS}
|
||||
isSignYourself={false}
|
||||
addPositionOfSignature={addPositionOfSignature}
|
||||
signerPos={signerPos}
|
||||
signersdata={signersdata}
|
||||
@@ -1184,44 +1441,50 @@ const TemplatePlaceholder = () => {
|
||||
handleRoleChange={handleRoleChange}
|
||||
handleOnBlur={handleOnBlur}
|
||||
title={"Roles"}
|
||||
initial={true}
|
||||
isTemplateFlow={true}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<div className="signerComponent">
|
||||
<SignerListPlace
|
||||
signerPos={signerPos}
|
||||
signersdata={signersdata}
|
||||
isSelectListId={isSelectListId}
|
||||
setSignerObjId={setSignerObjId}
|
||||
setRoleName={setRoleName}
|
||||
setIsSelectId={setIsSelectId}
|
||||
setContractName={setContractName}
|
||||
handleAddSigner={handleAddSigner}
|
||||
setUniqueId={setUniqueId}
|
||||
handleDeleteUser={handleDeleteUser}
|
||||
handleRoleChange={handleRoleChange}
|
||||
handleOnBlur={handleOnBlur}
|
||||
title={"Roles"}
|
||||
/>
|
||||
<div data-tut="reactourSecond">
|
||||
<FieldsComponent
|
||||
pdfUrl={isMailSend}
|
||||
sign={sign}
|
||||
stamp={stamp}
|
||||
dragSignature={dragSignature}
|
||||
signRef={signRef}
|
||||
handleDivClick={handleDivClick}
|
||||
handleMouseLeave={handleMouseLeave}
|
||||
isDragSign={isDragSign}
|
||||
themeColor={themeColor}
|
||||
dragStamp={dragStamp}
|
||||
dragRef={dragRef}
|
||||
isDragStamp={isDragStamp}
|
||||
isSignYourself={false}
|
||||
addPositionOfSignature={addPositionOfSignature}
|
||||
<div
|
||||
style={{ maxHeight: window.innerHeight - 70 + "px" }}
|
||||
className="autoSignScroll"
|
||||
>
|
||||
<SignerListPlace
|
||||
signerPos={signerPos}
|
||||
signersdata={signersdata}
|
||||
isSelectListId={isSelectListId}
|
||||
setSignerObjId={setSignerObjId}
|
||||
setRoleName={setRoleName}
|
||||
setIsSelectId={setIsSelectId}
|
||||
setContractName={setContractName}
|
||||
handleAddSigner={handleAddSigner}
|
||||
setUniqueId={setUniqueId}
|
||||
handleDeleteUser={handleDeleteUser}
|
||||
handleRoleChange={handleRoleChange}
|
||||
handleOnBlur={handleOnBlur}
|
||||
title={"Roles"}
|
||||
/>
|
||||
<div data-tut="reactourSecond">
|
||||
<WidgetComponent
|
||||
pdfUrl={isMailSend}
|
||||
dragSignature={dragSignature}
|
||||
signRef={signRef}
|
||||
handleDivClick={handleDivClick}
|
||||
handleMouseLeave={handleMouseLeave}
|
||||
isDragSign={isDragSign}
|
||||
dragStamp={dragStamp}
|
||||
dragRef={dragRef}
|
||||
isDragStamp={isDragStamp}
|
||||
isSignYourself={false}
|
||||
addPositionOfSignature={addPositionOfSignature}
|
||||
title={"Roles"}
|
||||
initial={true}
|
||||
isTemplateFlow={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1257,6 +1520,13 @@ const TemplatePlaceholder = () => {
|
||||
onSuccess={handleEditTemplateForm}
|
||||
/>
|
||||
</ModalUi>
|
||||
<WidgetNameModal
|
||||
widgetName={widgetName}
|
||||
defaultdata={currWidgetsDetails}
|
||||
isOpen={isNameModal}
|
||||
handleClose={handleNameModal}
|
||||
handleData={handleWidgetdefaultdata}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Navigate, useNavigate } from "react-router-dom";
|
||||
import Parse from "parse";
|
||||
import { SaveFileSize } from "../constant/saveFileSize";
|
||||
@@ -6,6 +6,7 @@ import dp from "../assets/images/dp.png";
|
||||
import Title from "../components/Title";
|
||||
import sanitizeFileName from "../primitives/sanitizeFileName";
|
||||
import axios from "axios";
|
||||
|
||||
function UserProfile() {
|
||||
const navigate = useNavigate();
|
||||
let UserProfile = JSON.parse(localStorage.getItem("UserInformation"));
|
||||
@@ -17,9 +18,16 @@ function UserProfile() {
|
||||
const [Image, setImage] = useState(localStorage.getItem("profileImg"));
|
||||
const [isLoader, setIsLoader] = useState(false);
|
||||
const [percentage, setpercentage] = useState(0);
|
||||
const [isDisableDocId, setIsDisableDocId] = useState(false);
|
||||
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
useEffect(() => {
|
||||
const extClass = localStorage.getItem("Extand_Class");
|
||||
const jsonSender = JSON.parse(extClass);
|
||||
const HeaderDocId = jsonSender[0]?.HeaderDocId;
|
||||
if (HeaderDocId) {
|
||||
setIsDisableDocId(HeaderDocId);
|
||||
}
|
||||
}, []);
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setIsLoader(true);
|
||||
@@ -33,6 +41,7 @@ function UserProfile() {
|
||||
object.set("name", name);
|
||||
object.set("ProfilePic", Image);
|
||||
object.set("phone", phn);
|
||||
|
||||
object.save().then(
|
||||
async (response) => {
|
||||
if (response) {
|
||||
@@ -66,8 +75,12 @@ function UserProfile() {
|
||||
const extClass = localStorage.getItem("extended_class");
|
||||
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
const ExtUserId = extData[0].objectId;
|
||||
// console.log("UserId ", ExtUserId);
|
||||
const body = { Phone: obj.Phone, Name: obj.Name };
|
||||
|
||||
const body = {
|
||||
Phone: obj.Phone,
|
||||
Name: obj.Name,
|
||||
HeaderDocId: isDisableDocId
|
||||
};
|
||||
await axios.put(
|
||||
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
|
||||
body,
|
||||
@@ -137,6 +150,10 @@ function UserProfile() {
|
||||
return <Navigate to={_redirect} />;
|
||||
}
|
||||
|
||||
const handleDisableDocId = () => {
|
||||
setIsDisableDocId((prevChecked) => !prevChecked);
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Title title={"Profile"} />
|
||||
@@ -241,6 +258,22 @@ function UserProfile() {
|
||||
: "Not verified"}
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex justify-between items-center border-y-[1px] border-gray-300 py-2 break-all">
|
||||
<span className="font-semibold">Disable DocumentId :</span>{" "}
|
||||
<span>
|
||||
<label className="relative inline-flex items-center cursor-pointer mb-0">
|
||||
<input
|
||||
disabled={editmode ? false : true}
|
||||
checked={isDisableDocId}
|
||||
onChange={handleDisableDocId}
|
||||
type="checkbox"
|
||||
value=""
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
|
||||
</label>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="flex justify-center pt-2 pb-3 md:pt-3 md:pb-4">
|
||||
{editmode ? (
|
||||
@@ -124,7 +124,7 @@ function Webhook() {
|
||||
type="button"
|
||||
onClick={() =>
|
||||
openInNewTab(
|
||||
"https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"
|
||||
"https://docs.opensignlabs.com/docs/API-docs/save-update-webhook"
|
||||
)
|
||||
}
|
||||
className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-11 py-2 text-xs md:text-base focus:outline-none"
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Parse from "parse";
|
||||
import axios from "axios";
|
||||
import "../css/AddUser.css";
|
||||
import "../styles/AddUser.css";
|
||||
const AddUser = (props) => {
|
||||
const [name, setName] = useState("");
|
||||
const [phone, setPhone] = useState("");
|
||||
@@ -11,9 +11,6 @@ const AddUser = (props) => {
|
||||
const [isUserExist, setIsUserExist] = useState(false);
|
||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
|
||||
useEffect(() => {
|
||||
checkUserExist();
|
||||
}, []);
|
||||
@@ -50,8 +47,6 @@ const AddUser = (props) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsLoader(true);
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
try {
|
||||
const contactQuery = new Parse.Object("contracts_Contactbook");
|
||||
contactQuery.set("Name", name);
|
||||
@@ -158,10 +153,10 @@ const AddUser = (props) => {
|
||||
const res = await contactQuery.save();
|
||||
|
||||
const parseData = JSON.parse(JSON.stringify(res));
|
||||
if(props.details){
|
||||
if (props.details) {
|
||||
props.details(parseData);
|
||||
}
|
||||
|
||||
|
||||
if (props.closePopup) {
|
||||
props.closePopup();
|
||||
}
|
||||
@@ -18,7 +18,7 @@ const Alert = ({ children, type }) => {
|
||||
<>
|
||||
{children && (
|
||||
<div
|
||||
className={`z-40 fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm ${textcolor} rounded py-[.75rem] px-[1.25rem] `}
|
||||
className={`z-40 fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm ${textcolor} rounded py-[.75rem] px-[1.25rem] z-50`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,10 @@ import React, { useState, useEffect, useMemo } from "react";
|
||||
import pad from "../assets/images/pad.svg";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import "../styles/report.css";
|
||||
import ModalUi from "./ModalUi";
|
||||
import AppendFormInForm from "../components/AppendFormInForm";
|
||||
import AddSigner from "../components/AddSigner";
|
||||
import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const";
|
||||
import Alert from "./Alert";
|
||||
const ReportTable = ({
|
||||
ReportName,
|
||||
List,
|
||||
@@ -67,7 +67,7 @@ const ReportTable = ({
|
||||
const handlemicroapp = async (item, url, btnLabel) => {
|
||||
if (ReportName === "Templates") {
|
||||
if (btnLabel === "Edit") {
|
||||
navigate(`/asmf/${url}/${item.objectId}`);
|
||||
navigate(`/${url}/${item.objectId}`);
|
||||
} else {
|
||||
setActLoader({ [`${item.objectId}_${btnLabel}`]: true });
|
||||
try {
|
||||
@@ -149,7 +149,8 @@ const ReportTable = ({
|
||||
if (res.data && res.data.objectId) {
|
||||
setActLoader({});
|
||||
setIsAlert(true);
|
||||
navigate(`/asmf/${url}/${res.data.objectId}`, {
|
||||
setTimeout(() => setIsAlert(false), 1500);
|
||||
navigate(`/${url}/${res.data.objectId}`, {
|
||||
state: { title: "Use Template" }
|
||||
});
|
||||
}
|
||||
@@ -157,6 +158,7 @@ const ReportTable = ({
|
||||
console.log("Err", err);
|
||||
setIsAlert(true);
|
||||
setIsErr(true);
|
||||
setTimeout(() => setIsAlert(false), 1500);
|
||||
setActLoader({});
|
||||
}
|
||||
} else {
|
||||
@@ -166,18 +168,20 @@ const ReportTable = ({
|
||||
} else {
|
||||
setIsAlert(true);
|
||||
setIsErr(true);
|
||||
setTimeout(() => setIsAlert(false), 1500);
|
||||
setActLoader({});
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("err", err);
|
||||
setIsAlert(true);
|
||||
setIsErr(true);
|
||||
setTimeout(() => setIsAlert(false), 1500);
|
||||
setActLoader({});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
localStorage.removeItem("rowlevel");
|
||||
navigate("/rpmf/" + url);
|
||||
navigate(`/${url}`);
|
||||
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||
}
|
||||
|
||||
@@ -211,13 +215,15 @@ const ReportTable = ({
|
||||
setIsDeleteModal({});
|
||||
setActLoader({ [item.objectId]: true });
|
||||
try {
|
||||
const url =
|
||||
process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/";
|
||||
const serverUrl = process.env.REACT_APP_SERVERURL
|
||||
? process.env.REACT_APP_SERVERURL
|
||||
: window.location.origin + "/api/app";
|
||||
const url = serverUrl + "/classes/contracts_Contactbook/";
|
||||
const body = { IsDeleted: true };
|
||||
const res = await axios.put(url + item.objectId, body, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
});
|
||||
@@ -225,6 +231,7 @@ const ReportTable = ({
|
||||
if (res.data && res.data.updatedAt) {
|
||||
setActLoader({});
|
||||
setIsAlert(true);
|
||||
setTimeout(() => setIsAlert(false), 1500);
|
||||
const upldatedList = List.filter((x) => x.objectId !== item.objectId);
|
||||
setList(upldatedList);
|
||||
}
|
||||
@@ -232,6 +239,7 @@ const ReportTable = ({
|
||||
console.log("err", err);
|
||||
setIsAlert(true);
|
||||
setIsErr(true);
|
||||
setTimeout(() => setIsAlert(false), 1500);
|
||||
setActLoader({});
|
||||
}
|
||||
};
|
||||
@@ -240,17 +248,12 @@ const ReportTable = ({
|
||||
return (
|
||||
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
||||
{isAlert && (
|
||||
<div
|
||||
className={`alert alert-${isErr ? "danger" : "success"} alertBox`}
|
||||
role="alert"
|
||||
onAnimationEnd={() => setIsAlert(false)}
|
||||
>
|
||||
<Alert type={isErr ? "danger" : "success"}>
|
||||
{isErr
|
||||
? "Something went wrong, Please try again later!"
|
||||
: "Record deleted successfully!"}
|
||||
</div>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
||||
<div className="font-light">{ReportName}</div>
|
||||
{ReportName === "Templates" && (
|
||||
@@ -495,7 +498,7 @@ const ReportTable = ({
|
||||
isOpen={isContactform}
|
||||
handleClose={handleContactFormModal}
|
||||
>
|
||||
<AppendFormInForm
|
||||
<AddSigner
|
||||
handleUserData={handleUserData}
|
||||
closePopup={handleContactFormModal}
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,7 @@ function HandleError({ handleError }) {
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
height: "100vh"
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: "20px", color: "gray" }}>{handleError}</span>
|
||||
@@ -0,0 +1,47 @@
|
||||
import React from "react";
|
||||
import SelectSigners from "../components/shared/fields/SelectSigners";
|
||||
import AddUser from "./AddUser";
|
||||
import ModalUi from "./ModalUi";
|
||||
|
||||
const LinkUserModal = (props) => {
|
||||
return (
|
||||
<ModalUi
|
||||
title={"Add/Choose Signer"}
|
||||
isOpen={props.isAddUser[props.uniqueId]}
|
||||
handleClose={props.closePopup}
|
||||
>
|
||||
<SelectSigners
|
||||
details={props.handleAddUser}
|
||||
closePopup={props.closePopup}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 5,
|
||||
margin: "0 30%",
|
||||
color: "#808080"
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
height: 1,
|
||||
width: "100%",
|
||||
backgroundColor: "#ccc"
|
||||
}}
|
||||
></span>
|
||||
<span>or</span>
|
||||
<span
|
||||
style={{
|
||||
height: 1,
|
||||
width: "100%",
|
||||
backgroundColor: "#ccc"
|
||||
}}
|
||||
></span>
|
||||
</div>
|
||||
<AddUser details={props.handleAddUser} closePopup={props.closePopup} />
|
||||
</ModalUi>
|
||||
);
|
||||
};
|
||||
|
||||
export default LinkUserModal;
|
||||