mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-08 18:57:39 +02:00
Compare commits
61
Commits
v1.0.2
...
v1.0.5-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
068082f56f | ||
|
|
1ce8e2bbdf | ||
|
|
3cdc4116aa | ||
|
|
0b0c18d106 | ||
|
|
b4315b5e0a | ||
|
|
c326849b8d | ||
|
|
a92188d8e2 | ||
|
|
4055574785 | ||
|
|
9b295f784a | ||
|
|
bfae7f236c | ||
|
|
fe907116e2 | ||
|
|
ade39c2f46 | ||
|
|
31baefcce3 | ||
|
|
59eb4eb9c7 | ||
|
|
3b93f96479 | ||
|
|
dbff436bc2 | ||
|
|
c3cf9c891e | ||
|
|
4e7c8c63bb | ||
|
|
450a971ca9 | ||
|
|
5ba1f79f3b | ||
|
|
d255d5bfb2 | ||
|
|
f5e835cbc4 | ||
|
|
b40eb7119d | ||
|
|
f56faf3afd | ||
|
|
5fa60d8135 | ||
|
|
695345d911 | ||
|
|
3f60509254 | ||
|
|
6bd9ac0b8f | ||
|
|
ccecec5e59 | ||
|
|
2022df000e | ||
|
|
ec6e037422 | ||
|
|
d4be4aec2c | ||
|
|
4b11fe77e0 | ||
|
|
4caf7b8c1a | ||
|
|
c736bbce55 | ||
|
|
4bbf0d05d5 | ||
|
|
d42e11c5c1 | ||
|
|
f227b79316 | ||
|
|
d4b4e02b62 | ||
|
|
1e76cf5253 | ||
|
|
4b9088b252 | ||
|
|
820d6378f9 | ||
|
|
dfc816bdac | ||
|
|
0f62419d99 | ||
|
|
37af995aaa | ||
|
|
4c69971ba1 | ||
|
|
fe37f3e021 | ||
|
|
9047aa7dc8 | ||
|
|
d33df9b934 | ||
|
|
95558d1407 | ||
|
|
3164ee5824 | ||
|
|
6a98adebd2 | ||
|
|
015b752f5b | ||
|
|
11164a716f | ||
|
|
64638acd43 | ||
|
|
133769d5fd | ||
|
|
e330285e24 | ||
|
|
2acf851852 | ||
|
|
73978ebce4 | ||
|
|
96ae95a97c | ||
|
|
356d2e81c5 |
@@ -169,6 +169,15 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"bug"
|
"bug"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "lsprr",
|
||||||
|
"name": "Luis Parra",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/16653744?v=4",
|
||||||
|
"profile": "https://luisparra.dev",
|
||||||
|
"contributions": [
|
||||||
|
"a11y"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,3 +47,6 @@ MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
|||||||
|
|
||||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||||
PFX_BASE64=
|
PFX_BASE64=
|
||||||
|
|
||||||
|
# Provide Pass pharse of above PFX or p12 document
|
||||||
|
PASS_PHRASE=
|
||||||
|
|||||||
+57
-1
@@ -50,4 +50,60 @@ MAILGUN_DOMAIN=mail.yourdomain.com
|
|||||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||||
|
|
||||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||||
PFX_BASE64=
|
PFX_BASE64='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
|
||||||
|
3pXAXxZuvVvv9tsb4bdrBAhyb+KCIjp/gAICCAA='
|
||||||
|
|
||||||
|
# Provide Pass pharse of above PFX or p12 document
|
||||||
|
PASS_PHRASE=opensign
|
||||||
|
|||||||
@@ -22,3 +22,6 @@
|
|||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
apps/OpenSign/public/mfbuild/*
|
||||||
|
microfrontends/SignDocuments/build/*
|
||||||
|
apps/OpenSignServer/files/files/*
|
||||||
+59
-1
@@ -88,5 +88,63 @@ You can install all 3 components on digital ocean using the button below -
|
|||||||
|
|
||||||
## Localhost(Docker)
|
## Localhost(Docker)
|
||||||
|
|
||||||
Below are the steps to follow -
|
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 | http://localhost:3000 | Set it to the URL form where the app home page will be accessed |
|
||||||
|
| PUBLIC_URL | opensignstgn | A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API. |
|
||||||
|
| APP_ID | opensignstgn | A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App. |
|
||||||
|
| 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`
|
- Execute `make build`
|
||||||
|
|
||||||
|
Command to run project -
|
||||||
|
- Execute `make run`
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
build:
|
build:
|
||||||
|
cp .env.local_dev .env
|
||||||
|
rm -rf apps/OpenSign/public/mfbuild
|
||||||
|
cd microfrontends/SignDocuments && npm install && npm run build
|
||||||
|
docker compose up --build --force-recreate
|
||||||
|
|
||||||
|
run:
|
||||||
cp .env.local_dev .env
|
cp .env.local_dev .env
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
@@ -48,14 +48,18 @@ Welcome to OpenSign, an open-source document e-signing solution designed to prov
|
|||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- **Secure Signing**: Utilizes state-of-the-art cryptographic algorithms to ensure the security & integrity of your documents.
|
- **Secure PDF E-Signing:** With the help of Robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility.
|
||||||
- **User-Friendly Interface**: Designed with usability in mind, making it easy for both technical and non-technical users.
|
- **Annotate Documents:** OpenSign™ allows you to annotate PDF documents with an advanced signing pad that comes with hand drawn signatures support as well as uploaded images & saved signatures for the simplest signing experience.
|
||||||
- **Multi-Platform Support**: Compatible with various browsers and devices.
|
- **User-Friendly Interface:** OpenSign™ was built while keeping Intuitive design in mind for ease of use. Features like "Sign yourself", "One click signatures" and "OpenSign Drive" makes it stand out of the crowd and even makes it better than a lot of so-called industry leaders.
|
||||||
- **Invite & collaborate users**: Bring multiple people from your team into the signing process, all within your own infrastructure.
|
- **Multi-signer Support:** OpenSign's ability to invite multiple signers for signing along with the ability to invite witnesses & being able to enforce signing in a sequence makes it the only open source solution that is fully loaded and allows it to compete head-to-head with established players.
|
||||||
- **Secure**: Allows for the easy, secure and seamless organization of your documents using 'OpenSigDrive'.
|
- **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address.
|
||||||
- **Audit Trails**: Keeps a detailed log of all activities related to the document signing process including IP addresses and access timings.
|
- **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign it. Not just this, OpenSign also allows signers to reject signing a document.
|
||||||
- **Completion Certificate**: Generate secure completion certificate as soon as a document is signed by all participants.
|
- **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates.
|
||||||
- **API Support**: Provides a robust API for integration into other software and services.
|
- **PDF Template Creation(coming soon):** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time.
|
||||||
|
- **OpenSign™ Drive:** It is a centralised secure vault for your signed documents that makes storing, signing, organizing, sharing & achieving your docs a breeze.
|
||||||
|
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
|
||||||
|
- **API Support(coming soon):** OpenSign™ API allows seamless integration into existing systems and software. APIs will soon be available as a cloud hosted solution.
|
||||||
|
- **Integrations:** Seamless integrations with various Cloud storage systems, CRMs & enterprise platforms is coming soon.
|
||||||
|
|
||||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
|
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
|
||||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
||||||
@@ -124,6 +128,7 @@ We would like to thank all our contributors and users for their support and feed
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andrew-opensignlabs"><img src="https://avatars.githubusercontent.com/u/148278535?v=4?s=100" width="100px;" alt="Andrew"/><br /><sub><b>Andrew</b></sub></a><br /><a href="#code-andrew-opensignlabs" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andrew-opensignlabs"><img src="https://avatars.githubusercontent.com/u/148278535?v=4?s=100" width="100px;" alt="Andrew"/><br /><sub><b>Andrew</b></sub></a><br /><a href="#code-andrew-opensignlabs" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rishabjasrotia"><img src="https://avatars.githubusercontent.com/u/33950743?v=4?s=100" width="100px;" alt="Rishab"/><br /><sub><b>Rishab</b></sub></a><br /><a href="#code-rishabjasrotia" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rishabjasrotia"><img src="https://avatars.githubusercontent.com/u/33950743?v=4?s=100" width="100px;" alt="Rishab"/><br /><sub><b>Rishab</b></sub></a><br /><a href="#code-rishabjasrotia" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://session.it"><img src="https://avatars.githubusercontent.com/u/327285?v=4?s=100" width="100px;" alt="Maurizio Pillitu"/><br /><sub><b>Maurizio Pillitu</b></sub></a><br /><a href="#bug-maoo" title="Bug reports">🐛</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://session.it"><img src="https://avatars.githubusercontent.com/u/327285?v=4?s=100" width="100px;" alt="Maurizio Pillitu"/><br /><sub><b>Maurizio Pillitu</b></sub></a><br /><a href="#bug-maoo" title="Bug reports">🐛</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://luisparra.dev"><img src="https://avatars.githubusercontent.com/u/16653744?v=4?s=100" width="100px;" alt="Luis Parra"/><br /><sub><b>Luis Parra</b></sub></a><br /><a href="#a11y-lsprr" title="Accessibility">️️️️♿️</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -21,5 +21,5 @@ EXPOSE 3000
|
|||||||
# ENV NODE_ENV production
|
# ENV NODE_ENV production
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
CMD ["npm", "start"]
|
ENTRYPOINT npm run start-dev
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,8 @@
|
|||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "mf-cra start",
|
"start": "serve -s build",
|
||||||
"start-prod": "serve -s build",
|
"start-dev": "mf-cra start",
|
||||||
"build": "rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
"build": "rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
||||||
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
|
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import PageNotFound from "./routes/PageNotFound";
|
|||||||
import ForgetPassword from "./routes/ForgetPassword";
|
import ForgetPassword from "./routes/ForgetPassword";
|
||||||
import ChangePassword from "./routes/ChangePassword";
|
import ChangePassword from "./routes/ChangePassword";
|
||||||
import ReportMicroapp from "./components/ReportMicroapp";
|
import ReportMicroapp from "./components/ReportMicroapp";
|
||||||
|
import LoadMf from "./routes/LoadMf";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [isloading, setIsLoading] = useState(true);
|
const [isloading, setIsLoading] = useState(true);
|
||||||
@@ -59,6 +60,7 @@ function App() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route exact path="/" element={<Login />} />
|
<Route exact path="/" element={<Login />} />
|
||||||
<Route exact path="/signup" element={<Signup />} />
|
<Route exact path="/signup" element={<Signup />} />
|
||||||
|
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
||||||
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
||||||
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -141,6 +141,32 @@ const GoogleSignInBtn = ({
|
|||||||
alert("Please fill required details!");
|
alert("Please fill required details!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
setIsModal(false);
|
||||||
|
Parse.User.logOut();
|
||||||
|
|
||||||
|
let appdata = localStorage.getItem("userSettings");
|
||||||
|
let applogo = localStorage.getItem("appLogo");
|
||||||
|
let appName = localStorage.getItem("appName");
|
||||||
|
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
|
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");
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
localStorage.setItem("appLogo", applogo);
|
||||||
|
localStorage.setItem("appName", appName);
|
||||||
|
localStorage.setItem("_appName", _appName);
|
||||||
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
|
localStorage.setItem("domain", domain);
|
||||||
|
localStorage.setItem("userSettings", appdata);
|
||||||
|
localStorage.setItem("BaseUrl12", baseUrl);
|
||||||
|
localStorage.setItem("AppID12", appid);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div style={{ position: "relative" }}>
|
<div style={{ position: "relative" }}>
|
||||||
{thirdpartyLoader && (
|
{thirdpartyLoader && (
|
||||||
@@ -259,16 +285,16 @@ const GoogleSignInBtn = ({
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-secondary"
|
className="bg-[#6c757d] p-2 text-white rounded"
|
||||||
onClick={() => setIsModal(false)}
|
onClick={handleCloseModal}
|
||||||
style={{ marginRight: 10, width: 90 }}
|
style={{ marginRight: 10, width: 90 }}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
className="bg-[#17a2b8] p-2 text-white rounded"
|
||||||
onClick={() => handleSubmitbtn()}
|
onClick={() => handleSubmitbtn()}
|
||||||
className="btn btn-info"
|
|
||||||
>
|
>
|
||||||
Sign up
|
Sign up
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import useFederatedComponent from "mf-cra";
|
import useFederatedComponent from "mf-cra";
|
||||||
import React, { Suspense, useEffect } from "react";
|
import React, { Suspense, useEffect } from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
const MicroappModal = () => {
|
const MicroappModal = () => {
|
||||||
const { remoteApp } = useParams();
|
const { remoteApp } = useParams();
|
||||||
@@ -28,60 +28,36 @@ const MicroappModal = () => {
|
|||||||
}
|
}
|
||||||
// console.log("app ", remoteApp);
|
// console.log("app ", remoteApp);
|
||||||
const { Component: RemoteComponent } = useFederatedComponent(obj);
|
const { Component: RemoteComponent } = useFederatedComponent(obj);
|
||||||
const navigate = useNavigate();
|
|
||||||
// console.log("RemoteComponent ", RemoteComponent);
|
// console.log("RemoteComponent ", RemoteComponent);
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full flex items-center justify-center ">
|
<div className="w-full h-full flex items-center justify-center ">
|
||||||
{/* <!-- Modal Container --> */}
|
<div className="w-full">
|
||||||
<div className="bg-white rounded-lg shadow-lg w-full">
|
<Suspense
|
||||||
{/* <!-- Modal Header --> */}
|
fallback={
|
||||||
<div className="flex w-full items-center border-b-2 mb-2 p-2">
|
<div style={{ height: "300px" }}>
|
||||||
<button
|
<div
|
||||||
className="focus:outline-none bg-blue-500 text-white text-sm shadow px-2.5 py-1 rounded"
|
style={{
|
||||||
id="closeModal"
|
marginLeft: "45%",
|
||||||
onClick={(e) => {
|
marginTop: "150px",
|
||||||
e.preventDefault();
|
fontSize: "45px",
|
||||||
// setIsModal(false);
|
color: "#3dd3e0"
|
||||||
navigate(-1);
|
}}
|
||||||
|
className="loader-37"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#ffffff",
|
||||||
|
width: "100%",
|
||||||
|
overflow: "hidden",
|
||||||
|
minHeight: "50vh"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Back
|
{RemoteComponent && <RemoteComponent />}
|
||||||
</button>
|
</div>
|
||||||
{localStorage.getItem("domain") && (
|
</Suspense>
|
||||||
<p className="flex-1 w-full text-sm md:text-base text-black text-center">
|
|
||||||
{localStorage.getItem("domain") === "contracts" ? "Document" : ""}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{/* <!-- Modal Body --> */}
|
|
||||||
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ const FileUpload = (props) => {
|
|||||||
progress: (progressValue, loaded, total, { type }) => {
|
progress: (progressValue, loaded, total, { type }) => {
|
||||||
if (type === "upload" && progressValue !== null) {
|
if (type === "upload" && progressValue !== null) {
|
||||||
const percentCompleted = Math.round((loaded * 100) / total);
|
const percentCompleted = Math.round((loaded * 100) / total);
|
||||||
console.log("percentCompleted ", percentCompleted);
|
// console.log("percentCompleted ", percentCompleted);
|
||||||
setpercentage(percentCompleted);
|
setpercentage(percentCompleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Menu;
|
||||||
@@ -1,22 +1,28 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Link, NavLink } from "react-router-dom";
|
|
||||||
|
import Menu from './Menu';
|
||||||
import Submenu from "./SubMenu";
|
import Submenu from "./SubMenu";
|
||||||
import dp from "../../assets/images/dp.png";
|
import SocialMedia from './SocialMedia';
|
||||||
|
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
import dp from "../../assets/images/dp.png";
|
||||||
|
|
||||||
const Sidebar = ({ isOpen, closeSidebar }) => {
|
const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||||
|
const [menuList, setmenuList] = useState([]);
|
||||||
let username = localStorage.getItem("username");
|
let username = localStorage.getItem("username");
|
||||||
const image = localStorage.getItem("profileImg") || dp;
|
const image = localStorage.getItem("profileImg") || dp;
|
||||||
const tenantname = localStorage.getItem("TenantName");
|
const tenantname = localStorage.getItem("TenantName");
|
||||||
const [menuList, setmenuList] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("accesstoken")) {
|
if (localStorage.getItem("accesstoken")) {
|
||||||
menuItem();
|
menuItem();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const menuItem = async () => {
|
const menuItem = async () => {
|
||||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||||
const parseAppId = localStorage.getItem("parseAppId");
|
const parseAppId = localStorage.getItem("parseAppId");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Parse.serverURL = parseBaseUrl;
|
Parse.serverURL = parseBaseUrl;
|
||||||
Parse.initialize(parseAppId);
|
Parse.initialize(parseAppId);
|
||||||
@@ -26,90 +32,46 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
|
|
||||||
const results = await query.first();
|
const results = await query.first();
|
||||||
const resultjson = results.toJSON();
|
const resultjson = results.toJSON();
|
||||||
// console.log("resultjson ", resultjson);
|
|
||||||
let result = resultjson;
|
let result = resultjson;
|
||||||
setmenuList(result.menuItems);
|
setmenuList(result.menuItems);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Problem", e);
|
console.error("Problem", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<aside
|
||||||
className={`${
|
className={`${isOpen ? "block" : "hidden"
|
||||||
isOpen ? "block" : "hidden"
|
} bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 ${isOpen ? "translate-x-0" : "-translate-x-full"
|
||||||
} bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 ${
|
}`}
|
||||||
isOpen ? "translate-x-0" : "-translate-x-full"
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
|
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
|
||||||
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
|
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
|
||||||
<img className="w-full h-full object-contain" src={image} alt="img" />
|
<img className="w-full h-full object-cover" src={image} alt="Profile" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-[14px] font-bold">{username && username}</p>
|
<p className="text-[14px] font-bold">{username}</p>
|
||||||
<p
|
<p className={`text-[12px] ${tenantname ? "mt-2" : ""}`}>
|
||||||
className={`text-[12px] ${tenantname && tenantname ? "mt-2" : ""}`}
|
{tenantname}
|
||||||
>
|
|
||||||
{tenantname && tenantname}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul className="text-sm">
|
<nav aria-label="OpenSign Sidebar Navigation">
|
||||||
{menuList.length > 0 && (
|
<ul className="text-sm" role="menubar" aria-label="OpenSign Sidebar Navigation">
|
||||||
<>
|
{menuList.map((item) => (
|
||||||
{menuList.map((item) =>
|
!item.children ? (
|
||||||
!item.children ? (
|
<Menu key={item.title} item={item} isOpen={isOpen} closeSidebar={closeSidebar} />
|
||||||
<li key={item.title} onClick={() => closeSidebar()}>
|
) : (
|
||||||
<Link
|
<Submenu key={item.title} item={item} closeSidebar={closeSidebar} />
|
||||||
className={`mx-auto flex items-center hover:bg-[#eef1f5] p-3 lg:p-4 hover:no-underline cursor-pointer`}
|
)
|
||||||
to={`/${item.pageType}/${item.objectId}`}
|
))}
|
||||||
>
|
</ul>
|
||||||
<i className={item.icon + " text-[18px]"}></i>
|
</nav>
|
||||||
<span title={item.description} className="ml-3 lg:ml-4">
|
<footer className="mt-4 flex justify-center items-center text-[25px] text-black gap-3">
|
||||||
{item.title}
|
<SocialMedia />
|
||||||
</span>
|
</footer>
|
||||||
</Link>
|
</aside>
|
||||||
</li>
|
|
||||||
) : (
|
|
||||||
<Submenu key={item.title} icon={item.icon} title={item.title}>
|
|
||||||
{item.children.map((item) => (
|
|
||||||
<li key={item.title} onClick={() => closeSidebar()} className="pl-6 md:pl-8 hover:bg-[#eef1f5] cursor-pointer">
|
|
||||||
<Link
|
|
||||||
className={`mx-auto flex items-center p-2 lg:p-3 hover:no-underline`}
|
|
||||||
to={`/${item.pageType}/${item.objectId}`}
|
|
||||||
>
|
|
||||||
<i className={item.icon + " text-[18px]"}></i>
|
|
||||||
<span title={item.description} className="ml-3 lg:ml-4">
|
|
||||||
{item.title}
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</Submenu>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
<div className="mt-4 flex justify-center items-center text-[25px] text-black gap-3">
|
|
||||||
<NavLink to="https://github.com/opensignlabs/opensign" target="_blank">
|
|
||||||
<i className="fa-brands fa-github"></i>
|
|
||||||
</NavLink>
|
|
||||||
<NavLink
|
|
||||||
to="https://www.linkedin.com/company/opensign%E2%84%A2/"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<i className="fa-brands fa-linkedin"></i>
|
|
||||||
</NavLink>
|
|
||||||
<NavLink to="https://www.twitter.com/opensignlabs" target="_blank">
|
|
||||||
<i className="fa-brands fa-square-x-twitter"></i>
|
|
||||||
</NavLink>
|
|
||||||
<NavLink to="https://discord.com/invite/xe9TDuyAyj" target="_blank">
|
|
||||||
<i className="fa-brands fa-discord"></i>
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { NavLink } from "react-router-dom";
|
||||||
|
|
||||||
|
const SocialMedia = () => {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<NavLink to="https://github.com/opensignlabs/opensign" target="_blank" rel="noopener noreferrer">
|
||||||
|
<i aria-hidden="true" className="fa-brands fa-github"></i>
|
||||||
|
<span className="fa-sr-only">OpenSign's Github</span>
|
||||||
|
</NavLink>
|
||||||
|
<NavLink to="https://www.linkedin.com/company/opensign%E2%84%A2/" target="_blank" rel="noopener noreferrer">
|
||||||
|
<i aria-hidden="true" className="fa-brands fa-linkedin"></i>
|
||||||
|
<span className="fa-sr-only">OpenSign's LinkedIn</span>
|
||||||
|
</NavLink>
|
||||||
|
<NavLink to="https://www.twitter.com/opensignlabs" target="_blank" rel="noopener noreferrer">
|
||||||
|
<i aria-hidden="true" className="fa-brands fa-square-x-twitter"></i>
|
||||||
|
<span className="fa-sr-only">OpenSign's Twitter</span>
|
||||||
|
</NavLink>
|
||||||
|
<NavLink to="https://discord.com/invite/xe9TDuyAyj" target="_blank" rel="noopener noreferrer">
|
||||||
|
<i aria-hidden="true" className="fa-brands fa-discord"></i>
|
||||||
|
<span className="fa-sr-only">OpenSign's Discord</span>
|
||||||
|
</NavLink>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SocialMedia;
|
||||||
@@ -1,30 +1,52 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import { NavLink } from "react-router-dom";
|
||||||
|
|
||||||
const Submenu = ({ icon, title, children }) => {
|
const Submenu = ({ item, closeSidebar }) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [submenuOpen, setSubmenuOpen] = useState(false);
|
||||||
|
const { title, icon, children } = item;
|
||||||
|
|
||||||
const toggleSubmenu = () => {
|
const toggleSubmenu = () => {
|
||||||
setIsOpen(!isOpen);
|
setSubmenuOpen(!submenuOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<li role="none">
|
||||||
<button
|
<button
|
||||||
onClick={toggleSubmenu}
|
onClick={toggleSubmenu}
|
||||||
className="w-full mx-auto flex items-center text-left text-[#444] p-3 lg:p-4 hover:bg-[#eef1f5] focus:outline-none"
|
className="w-full flex items-center text-left text-[#444] p-3 lg:p-4 hover:bg-[#eef1f5] focus:ring-2 focus:ring-blue-600"
|
||||||
|
aria-expanded={submenuOpen}
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-controls={`submenu-${title}`}
|
||||||
>
|
>
|
||||||
<i className={icon + " text-[18px]"}></i>
|
<i className={`${icon} text-[18px]`}></i>
|
||||||
<div className="flex justify-between items-center w-full">
|
<div className="flex justify-between items-center w-full">
|
||||||
<span className="ml-3 lg:ml-4">{title}</span>
|
<span className="ml-3 lg:ml-4">{title}</span>
|
||||||
<i
|
<i
|
||||||
className={
|
className={`${submenuOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
|
||||||
isOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
|
}`}
|
||||||
}
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{isOpen && <ul>{children}</ul>}
|
{submenuOpen && (
|
||||||
</div>
|
<ul id={`submenu-${title}`} role="menu" aria-label={`${title} submenu`}>
|
||||||
|
{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"
|
||||||
|
onClick={closeSidebar}
|
||||||
|
role="menuitem"
|
||||||
|
tabIndex={submenuOpen ? 0 : -1}
|
||||||
|
>
|
||||||
|
<i className={`${childItem.icon} text-[18px]`} aria-hidden="true"></i>
|
||||||
|
<span className="ml-3 lg:ml-4">{childItem.title}</span>
|
||||||
|
</NavLink>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,37 @@
|
|||||||
import React from "react";
|
import React, { useState, useEffect, useMemo } from "react";
|
||||||
import pad from "../assets/images/pad.svg";
|
import pad from "../assets/images/pad.svg";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const ReportTable = ({ ReportName, List, actions }) => {
|
const ReportTable = ({
|
||||||
|
ReportName,
|
||||||
|
List,
|
||||||
|
actions,
|
||||||
|
setIsNextRecord,
|
||||||
|
isMoreDocs
|
||||||
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const docPerPage = 10;
|
||||||
|
// const pageNumbers = [];
|
||||||
|
|
||||||
|
// For loop is used to calculate page numbers visible below table
|
||||||
|
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
|
||||||
|
const pageNumbers = useMemo(() => {
|
||||||
|
const calculatedPageNumbers = [];
|
||||||
|
for (let i = 1; i <= Math.ceil(List.length / docPerPage); i++) {
|
||||||
|
calculatedPageNumbers.push(i);
|
||||||
|
}
|
||||||
|
return calculatedPageNumbers;
|
||||||
|
}, [List]);
|
||||||
|
// below useEffect reset currenpage to 1 if user change route
|
||||||
|
useEffect(() => {
|
||||||
|
return () => setCurrentPage(1);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// `formatRow` is used to show data in poper manner like
|
||||||
|
// if data is of array type then it will join array items with ","
|
||||||
|
// if data is of object type then it Name values will be show in row
|
||||||
|
// if no data available it will show hyphen "-"
|
||||||
const formatRow = (row) => {
|
const formatRow = (row) => {
|
||||||
if (Array.isArray(row)) {
|
if (Array.isArray(row)) {
|
||||||
let updateArr = row.map((x) => x.Name);
|
let updateArr = row.map((x) => x.Name);
|
||||||
@@ -14,24 +42,17 @@ const ReportTable = ({ ReportName, List, actions }) => {
|
|||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// below useEffect is used to render next record if IsMoreDoc is true
|
||||||
|
// second last value of pageNumber array is same as currentPage
|
||||||
|
useEffect(() => {
|
||||||
|
if (isMoreDocs && pageNumbers[pageNumbers.length - 1] === currentPage) {
|
||||||
|
setIsNextRecord(true);
|
||||||
|
}
|
||||||
|
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
||||||
|
|
||||||
|
// `handlemicroapp` is used to open microapp
|
||||||
const handlemicroapp = (item, url) => {
|
const handlemicroapp = (item, url) => {
|
||||||
localStorage.removeItem("rowlevel");
|
localStorage.removeItem("rowlevel");
|
||||||
// const params = new URLSearchParams(url);
|
|
||||||
// let arr = [];
|
|
||||||
// for (let [key, value] of params.entries()) {
|
|
||||||
// if (key === "remoteUrl") {
|
|
||||||
// arr.push(
|
|
||||||
// `${key}=${window.btoa(
|
|
||||||
// window.location.origin + "/mfbuild/remoteEntry.js"
|
|
||||||
// )}`
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// arr.push(`${key}=${value}`);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// const remoteUrl = arr.join("&");
|
|
||||||
// console.log("arr", remoteUrl);
|
|
||||||
|
|
||||||
navigate("/rpmf/" + url);
|
navigate("/rpmf/" + url);
|
||||||
localStorage.setItem("rowlevel", JSON.stringify(item));
|
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||||
// localStorage.setItem("rowlevelMicro");
|
// localStorage.setItem("rowlevelMicro");
|
||||||
@@ -39,6 +60,17 @@ const ReportTable = ({ ReportName, List, actions }) => {
|
|||||||
const handlebtn = () => {
|
const handlebtn = () => {
|
||||||
console.log("clicked");
|
console.log("clicked");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get current list
|
||||||
|
const indexOfLastDoc = currentPage * docPerPage;
|
||||||
|
const indexOfFirstDoc = indexOfLastDoc - docPerPage;
|
||||||
|
// `currentLists` is total record render on current page
|
||||||
|
const currentLists = List.slice(indexOfFirstDoc, indexOfLastDoc);
|
||||||
|
|
||||||
|
// Change page
|
||||||
|
const paginateFront = () => setCurrentPage(currentPage + 1);
|
||||||
|
const paginateBack = () => setCurrentPage(currentPage - 1);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
||||||
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
||||||
@@ -60,8 +92,8 @@ const ReportTable = ({ ReportName, List, actions }) => {
|
|||||||
<tbody className="text-[12px]">
|
<tbody className="text-[12px]">
|
||||||
{List?.length > 0 ? (
|
{List?.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
{List.map((item, index) => (
|
{currentLists.map((item, index) => (
|
||||||
<tr className="border-t-[1px]" key={index}>
|
<tr className="border-y-[1px]" key={index}>
|
||||||
<td className="px-4 py-2">{index + 1}</td>
|
<td className="px-4 py-2">{index + 1}</td>
|
||||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||||
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
||||||
@@ -121,8 +153,46 @@ const ReportTable = ({ ReportName, List, actions }) => {
|
|||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div className="flex flex-wrap items-center gap-2 p-2 ">
|
||||||
|
{List.length > 10 && (
|
||||||
|
<>
|
||||||
|
{currentPage > 1 && (
|
||||||
|
<button
|
||||||
|
onClick={() => paginateBack()}
|
||||||
|
className="bg-blue-400 text-white rounded px-3 py-2 focus:outline-none"
|
||||||
|
>
|
||||||
|
Prev
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{pageNumbers.map((x) => (
|
||||||
|
<button
|
||||||
|
key={x}
|
||||||
|
onClick={() => setCurrentPage(x)}
|
||||||
|
className=" bg-sky-400 text-white rounded px-3 py-2 focus:outline-none"
|
||||||
|
>
|
||||||
|
{x}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
{isMoreDocs && (
|
||||||
|
<button className="text-black rounded px-1 py-2">...</button>
|
||||||
|
)}
|
||||||
|
{List.length > 10 && (
|
||||||
|
<>
|
||||||
|
{pageNumbers.includes(currentPage + 1) && (
|
||||||
|
<button
|
||||||
|
onClick={() => paginateFront()}
|
||||||
|
className="bg-blue-400 text-white rounded px-3 py-2 focus:outline-none"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
{List?.length <= 0 && (
|
{List?.length <= 0 && (
|
||||||
<div className="flex flex-col items-center justify-center w-full bg-white roundedm py-4">
|
<div className="flex flex-col items-center justify-center w-full bg-white rounded py-4">
|
||||||
<div className="w-[60px] h-[60px] overflow-hidden">
|
<div className="w-[60px] h-[60px] overflow-hidden">
|
||||||
<img className="w-full h-full object-contain" src={pad} alt="img" />
|
<img className="w-full h-full object-contain" src={pad} alt="img" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import { Suspense } from "react";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import useFederatedComponent from "mf-cra";
|
||||||
|
import React from "react";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
function RemoteApp({ app }) {
|
||||||
|
// console.log("app ", app);
|
||||||
|
const { Component: RemoteComponent } = useFederatedComponent(app);
|
||||||
|
// console.log("RemoteComponent ", RemoteComponent);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Title title={app.remoteName} />
|
||||||
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<div style={{ height: "300px" }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginLeft: "45%",
|
||||||
|
marginTop: "150px",
|
||||||
|
fontSize: "45px",
|
||||||
|
color: "#3dd3e0"
|
||||||
|
}}
|
||||||
|
className="loader-37"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.33)",
|
||||||
|
backgroundColor: "#ffffff",
|
||||||
|
width: "100%",
|
||||||
|
overflow: "hidden",
|
||||||
|
borderRadius: 3,
|
||||||
|
minHeight: "70vh"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{RemoteComponent && <RemoteComponent />}
|
||||||
|
</div>
|
||||||
|
</Suspense>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function checkObjectProperties(obj) {
|
||||||
|
// Check if all three properties exist in the object
|
||||||
|
if (
|
||||||
|
obj &&
|
||||||
|
obj.remoteName !== undefined &&
|
||||||
|
obj.remoteUrl !== undefined &&
|
||||||
|
obj.moduleToLoad !== undefined
|
||||||
|
) {
|
||||||
|
return true; // All properties are present
|
||||||
|
} else {
|
||||||
|
return false; // At least one property is missing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default function RemoteAppContainer() {
|
||||||
|
const { remoteApp } = useParams();
|
||||||
|
|
||||||
|
const obj = {
|
||||||
|
remoteUrl: window.location.origin + "/mfbuild/remoteEntry.js",
|
||||||
|
moduleToLoad: "./AppRoutes",
|
||||||
|
remoteName: remoteApp
|
||||||
|
};
|
||||||
|
// console.log("obj ", obj);
|
||||||
|
const isMf = checkObjectProperties(obj);
|
||||||
|
if (isMf) {
|
||||||
|
const appToLoad = obj;
|
||||||
|
return <RemoteApp app={appToLoad} />;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||||
|
<div className="text-center">
|
||||||
|
<h1 className="text-[60px] lg:text-[120px] font-semibold text-black">
|
||||||
|
404
|
||||||
|
</h1>
|
||||||
|
<p className="text-[30px] lg:text-[50px] text-black">
|
||||||
|
Page Not Found
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+428
-299
@@ -21,17 +21,18 @@ function Login(props) {
|
|||||||
passwordVisible: false,
|
passwordVisible: false,
|
||||||
mobile: "",
|
mobile: "",
|
||||||
phone: "",
|
phone: "",
|
||||||
OTP: "",
|
|
||||||
hideNav: "",
|
hideNav: "",
|
||||||
scanResult: "",
|
scanResult: "",
|
||||||
baseUrl: localStorage.getItem("baseUrl"),
|
baseUrl: localStorage.getItem("baseUrl"),
|
||||||
parseAppId: localStorage.getItem("parseAppId"),
|
parseAppId: localStorage.getItem("parseAppId"),
|
||||||
loading: false,
|
loading: false,
|
||||||
thirdpartyLoader: false,
|
thirdpartyLoader: false
|
||||||
orgModal: false,
|
|
||||||
ReqOtp: ""
|
|
||||||
});
|
});
|
||||||
|
const [userDetails, setUserDetails] = useState({
|
||||||
|
Company: "",
|
||||||
|
Destination: ""
|
||||||
|
});
|
||||||
|
const [isModal, setIsModal] = useState(false);
|
||||||
const image = props?.appInfo?.applogo || undefined;
|
const image = props?.appInfo?.applogo || undefined;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -94,7 +95,6 @@ function Login(props) {
|
|||||||
} else {
|
} else {
|
||||||
localStorage.setItem("profileImg", "");
|
localStorage.setItem("profileImg", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check extended class user role and tenentId
|
// Check extended class user role and tenentId
|
||||||
try {
|
try {
|
||||||
let userRoles = [];
|
let userRoles = [];
|
||||||
@@ -114,44 +114,36 @@ function Login(props) {
|
|||||||
};
|
};
|
||||||
await axios
|
await axios
|
||||||
.post(url, JSON.stringify(body), { headers: headers })
|
.post(url, JSON.stringify(body), { headers: headers })
|
||||||
.then((roles) => {
|
.then((axiosRes) => {
|
||||||
|
const roles = axiosRes.data.result;
|
||||||
if (roles) {
|
if (roles) {
|
||||||
userRoles = roles.data.result;
|
userRoles = roles;
|
||||||
let _currentRole = "";
|
let _currentRole = "";
|
||||||
|
const valuesToExclude = [
|
||||||
|
"contracts_Guest",
|
||||||
|
`${localStorage.getItem("_appName")}_appeditor`
|
||||||
|
];
|
||||||
if (userRoles.length > 1) {
|
if (userRoles.length > 1) {
|
||||||
if (
|
const rolesfiltered = userRoles.filter(
|
||||||
userRoles[0] ===
|
(x) => !valuesToExclude.includes(x)
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
);
|
||||||
) {
|
if (rolesfiltered.length > 0) {
|
||||||
_currentRole = userRoles[1];
|
_currentRole = rolesfiltered[0];
|
||||||
} else {
|
|
||||||
const rolesfiltered = userRoles.filter(
|
|
||||||
(x) => x !== "contracts_Guest"
|
|
||||||
);
|
|
||||||
if (rolesfiltered.length > 0) {
|
|
||||||
_currentRole = rolesfiltered[0];
|
|
||||||
} else {
|
|
||||||
setThirdpartyLoader(false);
|
|
||||||
setState({
|
|
||||||
...state,
|
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription: `Does not have permissions to access this application.`
|
|
||||||
});
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
// _currentRole = userRoles[0];
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_currentRole = userRoles[0];
|
const rolesfiltered = userRoles.filter(
|
||||||
|
(x) => !valuesToExclude.includes(x)
|
||||||
|
);
|
||||||
|
if (rolesfiltered.length > 0) {
|
||||||
|
_currentRole = userRoles[0];
|
||||||
|
} else {
|
||||||
|
_currentRole = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
_currentRole &&
|
||||||
_currentRole !==
|
_currentRole !==
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
`${localStorage.getItem("_appName")}_appeditor`
|
||||||
) {
|
) {
|
||||||
userSettings.forEach(async (element) => {
|
userSettings.forEach(async (element) => {
|
||||||
if (element.role === _currentRole) {
|
if (element.role === _currentRole) {
|
||||||
@@ -178,7 +170,6 @@ function Login(props) {
|
|||||||
query.include("TenantId");
|
query.include("TenantId");
|
||||||
await query.find().then(
|
await query.find().then(
|
||||||
(results) => {
|
(results) => {
|
||||||
// console.log("results ", results);
|
|
||||||
let tenentInfo = [];
|
let tenentInfo = [];
|
||||||
if (results) {
|
if (results) {
|
||||||
let extendedInfo_stringify =
|
let extendedInfo_stringify =
|
||||||
@@ -339,25 +330,27 @@ function Login(props) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
/* alert(
|
const payload = {
|
||||||
"You dont have access to this application."
|
sessionToken: user.getSessionToken()
|
||||||
); */
|
};
|
||||||
setState({
|
handleSubmitbtn(payload);
|
||||||
...state,
|
// setState({
|
||||||
loading: false,
|
// ...state,
|
||||||
toastColor: "#d9534f",
|
// loading: false,
|
||||||
toastDescription:
|
// toastColor: "#d9534f",
|
||||||
"You dont have access to this application."
|
// toastDescription:
|
||||||
});
|
// "You dont have access to this application."
|
||||||
const x = document.getElementById("snackbar");
|
// });
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
// const x = document.getElementById("snackbar");
|
||||||
x.className = x.className.replace(
|
// x.className = "show";
|
||||||
"show",
|
// setTimeout(function () {
|
||||||
""
|
// x.className = x.className.replace(
|
||||||
);
|
// "show",
|
||||||
}, 2000);
|
// ""
|
||||||
localStorage.setItem("accesstoken", null);
|
// );
|
||||||
|
// }, 2000);
|
||||||
|
// localStorage.setItem("accesstoken", null);
|
||||||
console.error(
|
console.error(
|
||||||
"Error while fetching Follow",
|
"Error while fetching Follow",
|
||||||
error
|
error
|
||||||
@@ -367,45 +360,18 @@ function Login(props) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setState({ ...state, loading: false });
|
||||||
...state,
|
setIsModal(true);
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription: "User Role Not Found."
|
|
||||||
});
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setState({ ...state, loading: false });
|
||||||
...state,
|
setIsModal(true);
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription: "User Role Not Found."
|
|
||||||
});
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("err", err);
|
console.log("err", err);
|
||||||
setState({
|
setState({ ...state, loading: false });
|
||||||
...state,
|
setIsModal(true);
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription: `Does not have permissions to access this application.`
|
|
||||||
});
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -460,7 +426,6 @@ function Login(props) {
|
|||||||
await Parse.User.become(sessionToken).then(() => {
|
await Parse.User.become(sessionToken).then(() => {
|
||||||
window.localStorage.setItem("accesstoken", sessionToken);
|
window.localStorage.setItem("accesstoken", sessionToken);
|
||||||
});
|
});
|
||||||
// console.log("me res ", res);
|
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
let _user = res.data;
|
let _user = res.data;
|
||||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
@@ -492,25 +457,36 @@ function Login(props) {
|
|||||||
};
|
};
|
||||||
await axios
|
await axios
|
||||||
.post(url, JSON.stringify(body), { headers: headers })
|
.post(url, JSON.stringify(body), { headers: headers })
|
||||||
.then((roles) => {
|
.then((axiosRes) => {
|
||||||
|
const roles = axiosRes.data.result;
|
||||||
if (roles) {
|
if (roles) {
|
||||||
userRoles = roles.data.result;
|
userRoles = roles;
|
||||||
let _currentRole = "";
|
let _currentRole = "";
|
||||||
|
const valuesToExclude = [
|
||||||
|
"contracts_Guest",
|
||||||
|
`${localStorage.getItem("_appName")}_appeditor`
|
||||||
|
];
|
||||||
if (userRoles.length > 1) {
|
if (userRoles.length > 1) {
|
||||||
if (
|
const rolesfiltered = userRoles.filter(
|
||||||
userRoles[0] ===
|
(x) => !valuesToExclude.includes(x)
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
);
|
||||||
) {
|
if (rolesfiltered.length > 0) {
|
||||||
_currentRole = userRoles[1];
|
_currentRole = rolesfiltered[0];
|
||||||
} else {
|
|
||||||
_currentRole = userRoles[0];
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_currentRole = userRoles[0];
|
const rolesfiltered = userRoles.filter(
|
||||||
|
(x) => !valuesToExclude.includes(x)
|
||||||
|
);
|
||||||
|
if (rolesfiltered.length > 0) {
|
||||||
|
_currentRole = userRoles[0];
|
||||||
|
} else {
|
||||||
|
_currentRole = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
_currentRole &&
|
||||||
_currentRole !==
|
_currentRole !==
|
||||||
`${localStorage.getItem("_appName")}_appeditor`
|
`${localStorage.getItem("_appName")}_appeditor`
|
||||||
) {
|
) {
|
||||||
userSettings.forEach(async (element) => {
|
userSettings.forEach(async (element) => {
|
||||||
if (element.role === _currentRole) {
|
if (element.role === _currentRole) {
|
||||||
@@ -581,7 +557,7 @@ function Login(props) {
|
|||||||
);
|
);
|
||||||
setThirdpartyLoader(false);
|
setThirdpartyLoader(false);
|
||||||
setState({ ...state, loading: false });
|
setState({ ...state, loading: false });
|
||||||
navigate(`/`);
|
navigate("/");
|
||||||
} else {
|
} else {
|
||||||
extendedInfo.forEach((x) => {
|
extendedInfo.forEach((x) => {
|
||||||
if (x.TenantId) {
|
if (x.TenantId) {
|
||||||
@@ -619,6 +595,7 @@ function Login(props) {
|
|||||||
);
|
);
|
||||||
setThirdpartyLoader(false);
|
setThirdpartyLoader(false);
|
||||||
setState({ ...state, loading: false });
|
setState({ ...state, loading: false });
|
||||||
|
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||||
if (billingDate) {
|
if (billingDate) {
|
||||||
if (billingDate > new Date()) {
|
if (billingDate > new Date()) {
|
||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
@@ -632,6 +609,7 @@ function Login(props) {
|
|||||||
navigate(`/subscription`);
|
navigate(`/subscription`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem("PageLanding", element.pageId);
|
localStorage.setItem("PageLanding", element.pageId);
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@@ -641,6 +619,7 @@ function Login(props) {
|
|||||||
localStorage.setItem("pageType", element.pageType);
|
localStorage.setItem("pageType", element.pageType);
|
||||||
setState({ ...state, loading: false });
|
setState({ ...state, loading: false });
|
||||||
setThirdpartyLoader(false);
|
setThirdpartyLoader(false);
|
||||||
|
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||||
if (billingDate) {
|
if (billingDate) {
|
||||||
if (billingDate > new Date()) {
|
if (billingDate > new Date()) {
|
||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
@@ -654,27 +633,16 @@ function Login(props) {
|
|||||||
navigate(`/subscription`);
|
navigate(`/subscription`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
/* alert(
|
const payload = {
|
||||||
"You dont have access to this application."
|
sessionToken: sessionToken
|
||||||
); */
|
};
|
||||||
setThirdpartyLoader(false);
|
setThirdpartyLoader(false);
|
||||||
|
handleSubmitbtn(payload);
|
||||||
|
|
||||||
setState({
|
// localStorage.setItem("accesstoken", null);
|
||||||
...state,
|
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription:
|
|
||||||
"You dont have access to this application."
|
|
||||||
});
|
|
||||||
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
localStorage.setItem("accesstoken", null);
|
|
||||||
console.error("Error while fetching Follow", error);
|
console.error("Error while fetching Follow", error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -682,47 +650,17 @@ function Login(props) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setThirdpartyLoader(false);
|
setThirdpartyLoader(false);
|
||||||
setState({
|
setState({ ...state, loading: false });
|
||||||
...state,
|
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription: "User Role Not Found."
|
|
||||||
});
|
|
||||||
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setThirdpartyLoader(false);
|
setThirdpartyLoader(false);
|
||||||
setState({
|
setState({ ...state, loading: false });
|
||||||
...state,
|
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription: "User Role Not Found."
|
|
||||||
});
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch((err) => {
|
||||||
|
console.log("err", err);
|
||||||
setThirdpartyLoader(false);
|
setThirdpartyLoader(false);
|
||||||
setState({
|
setState({ ...state, loading: false });
|
||||||
...state,
|
|
||||||
loading: false,
|
|
||||||
toastColor: "#d9534f",
|
|
||||||
toastDescription: `Does not have permissions to access this application.`
|
|
||||||
});
|
|
||||||
const x = document.getElementById("snackbar");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 2000);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -744,7 +682,7 @@ function Login(props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const GetLoginData = async () => {
|
const GetLoginData = async () => {
|
||||||
setState({...state, loading: true})
|
setState({ ...state, loading: true });
|
||||||
try {
|
try {
|
||||||
Parse.serverURL = localStorage.getItem("baseUrl");
|
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||||
Parse.initialize(localStorage.getItem("parseAppId"));
|
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||||
@@ -920,11 +858,86 @@ function Login(props) {
|
|||||||
setState({ ...state, passwordVisible: !state.passwordVisible });
|
setState({ ...state, passwordVisible: !state.passwordVisible });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSubmitbtn = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (userDetails.Destination && userDetails.Company) {
|
||||||
|
setThirdpartyLoader(true);
|
||||||
|
// console.log("handelSubmit", userDetails);
|
||||||
|
// const payload = await Parse.User.logIn(state.email, state.password);
|
||||||
|
const payload = { sessionToken: localStorage.getItem("accesstoken") };
|
||||||
|
const userInformation = JSON.parse(
|
||||||
|
localStorage.getItem("UserInformation")
|
||||||
|
);
|
||||||
|
// console.log("payload ", payload);
|
||||||
|
if (payload && payload.sessionToken) {
|
||||||
|
const params = {
|
||||||
|
userDetails: {
|
||||||
|
name: userInformation.name,
|
||||||
|
email: userInformation.email,
|
||||||
|
phone: userInformation.phone,
|
||||||
|
role: "contracts_User",
|
||||||
|
company: userDetails.Company,
|
||||||
|
jobTitle: userDetails.Destination
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const userSignUp = await Parse.Cloud.run("usersignup", params);
|
||||||
|
// console.log("userSignUp ", userSignUp);
|
||||||
|
if (userSignUp && userSignUp.sessionToken) {
|
||||||
|
const LocalUserDetails = {
|
||||||
|
name: userInformation.name,
|
||||||
|
email: userInformation.email,
|
||||||
|
phone: userInformation.phone,
|
||||||
|
company: userDetails.Company,
|
||||||
|
jobTitle: userDetails.JobTitle
|
||||||
|
};
|
||||||
|
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||||
|
thirdpartyLoginfn(userSignUp.sessionToken);
|
||||||
|
} else {
|
||||||
|
alert(userSignUp.message);
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
payload &&
|
||||||
|
payload.message.replace(/ /g, "_") === "Internal_server_err"
|
||||||
|
) {
|
||||||
|
alert("Internal server error !");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("Please fill required details!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
setIsModal(false);
|
||||||
|
Parse.User.logOut();
|
||||||
|
|
||||||
|
let appdata = localStorage.getItem("userSettings");
|
||||||
|
let applogo = localStorage.getItem("appLogo");
|
||||||
|
let appName = localStorage.getItem("appName");
|
||||||
|
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||||
|
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");
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
localStorage.setItem("appLogo", applogo);
|
||||||
|
localStorage.setItem("appName", appName);
|
||||||
|
localStorage.setItem("_appName", _appName);
|
||||||
|
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||||
|
localStorage.setItem("PageLanding", PageLanding);
|
||||||
|
localStorage.setItem("domain", domain);
|
||||||
|
localStorage.setItem("userSettings", appdata);
|
||||||
|
localStorage.setItem("BaseUrl12", baseUrl);
|
||||||
|
localStorage.setItem("AppID12", appid);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="bg-white">
|
<div className="bg-white">
|
||||||
<Title title={"Login Page"} />
|
<Title title={"Login Page"} />
|
||||||
{state.loading && (
|
{state.loading && (
|
||||||
<div
|
<div
|
||||||
|
aria-live="assertive"
|
||||||
style={{
|
style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
width: "100vw",
|
width: "100vw",
|
||||||
@@ -936,145 +949,161 @@ function Login(props) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
role="status"
|
||||||
style={{
|
style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
fontSize: "50px",
|
fontSize: "50px",
|
||||||
color: "#3ac9d6",
|
color: "#3ac9d6",
|
||||||
top: "50%",
|
top: "50%",
|
||||||
left: "45%"
|
left: "50%",
|
||||||
|
transform: "translate(-50%, -50%)"
|
||||||
}}
|
}}
|
||||||
className="loader-37"
|
className="loader-37"
|
||||||
></div>
|
>
|
||||||
|
<span className="sr-only">Loading...</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{props.isloginVisible && props.isloginVisible ? (
|
{props.isloginVisible && props.isloginVisible ? (
|
||||||
<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 aria-labelledby="loginHeading" role="region">
|
||||||
<div className="w-[250px] h-[66px] inline-block">
|
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-4 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
||||||
{state.hideNav ? (
|
<div className="w-[250px] h-[66px] inline-block">
|
||||||
<img src={image} width="100%" alt="" />
|
<img
|
||||||
) : (
|
src={image}
|
||||||
<img src={image} width="100%" alt="" />
|
width="100%"
|
||||||
)}
|
alt="The image displays the OpenSign logo with a stylized blue square with an open corner, accompanied by the tagline Seal the Deal, Openly."
|
||||||
</div>
|
/>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
</div>
|
||||||
<div className="">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
||||||
<div>
|
<div>
|
||||||
<form onSubmit={handleSubmit}>
|
<div>
|
||||||
<h2 className="text-[30px] mt-6">Welcome Back !</h2>
|
<form onSubmit={handleSubmit} aria-label="Login Form">
|
||||||
<span className="text-[12px] text-[#878787]">
|
<h1 className="text-[30px] mt-6">Welcome Back!</h1>
|
||||||
Login to your account
|
<fieldset>
|
||||||
</span>
|
<legend className="text-[12px] text-[#878787]">
|
||||||
<div className="shadow-md rounded my-4">
|
Login to your account
|
||||||
<div className="px-6 py-4">
|
</legend>
|
||||||
<label className="block text-xs">Username</label>
|
<div className="px-6 py-4 outline outline-1 outline-slate-300/50 my-2 rounded shadow-md">
|
||||||
<input
|
<label className="block text-xs" htmlFor="email">
|
||||||
type="text"
|
Username
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
</label>
|
||||||
name="email"
|
|
||||||
value={state.email}
|
|
||||||
onChange={handleChange}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<hr className="my-2 border-none" />
|
|
||||||
<label className="block text-xs">Password</label>
|
|
||||||
<div className="relative">
|
|
||||||
<input
|
<input
|
||||||
type={state.passwordVisible ? "text" : "password"}
|
id="email"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
type="text"
|
||||||
name="password"
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded text-xs"
|
||||||
value={state.password}
|
name="email"
|
||||||
|
value={state.email}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<span
|
<hr className="my-2 border-none" />
|
||||||
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer ${
|
<label className="block text-xs" htmlFor="password">
|
||||||
state.passwordVisible
|
Password
|
||||||
? "text-[#007bff]"
|
</label>
|
||||||
: "text-black"
|
<div className="relative">
|
||||||
}`}
|
<input
|
||||||
onClick={togglePasswordVisibility}
|
id="password"
|
||||||
>
|
type={state.passwordVisible ? "text" : "password"}
|
||||||
{state.passwordVisible ? (
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded text-xs"
|
||||||
<i className="fa fa-eye-slash text-xs pb-1" /> // Close eye icon
|
name="password"
|
||||||
) : (
|
value={state.password}
|
||||||
<i className="fa fa-eye text-xs pb-1 " /> // Open eye icon
|
onChange={handleChange}
|
||||||
)}
|
required
|
||||||
</span>
|
/>
|
||||||
|
<span
|
||||||
|
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer ${
|
||||||
|
state.passwordVisible
|
||||||
|
? "text-[#007bff]"
|
||||||
|
: "text-black"
|
||||||
|
}`}
|
||||||
|
onClick={togglePasswordVisibility}
|
||||||
|
>
|
||||||
|
{state.passwordVisible ? (
|
||||||
|
<i className="fa fa-eye-slash text-xs pb-1" /> // Close eye icon
|
||||||
|
) : (
|
||||||
|
<i className="fa fa-eye text-xs pb-1 " /> // Open eye icon
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</fieldset>
|
||||||
</div>
|
<div className="flex flex-row justify-between items-center ml-4 py-2">
|
||||||
<div className="flex flex-row justify-between items-center text-xs px-4 py-2">
|
<div>
|
||||||
<div>
|
<label
|
||||||
<label className="form-check-label">
|
className="form-check-label inline-block cursor-pointer"
|
||||||
<input
|
htmlFor="rememberpassword"
|
||||||
type="checkbox"
|
>
|
||||||
className="form-check-input"
|
<input
|
||||||
value=""
|
type="checkbox"
|
||||||
/>
|
className="form-check-input mr-1"
|
||||||
<span className="text-center pl-1">
|
value=""
|
||||||
Remember Password
|
id="rememberpassword"
|
||||||
</span>
|
/>
|
||||||
</label>
|
<span className="text-[13px]">
|
||||||
</div>
|
Remember Password
|
||||||
<div>
|
</span>
|
||||||
<span className="text-[13px]">
|
</label>
|
||||||
<NavLink to={`/forgetpassword`}>
|
</div>
|
||||||
|
<div>
|
||||||
|
<NavLink
|
||||||
|
to="/forgetpassword"
|
||||||
|
className="text-[13px] underline focus:outline-none focus:ring-2 focus:ring-blue-600"
|
||||||
|
>
|
||||||
Forgot Password ?
|
Forgot Password ?
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
||||||
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
<button
|
||||||
<button
|
type="submit"
|
||||||
type="submit"
|
className="rounded-sm bg-[#3ac9d6] text-white w-full py-3 shadow outline-none uppercase focus:ring-2 focus:ring-blue-600"
|
||||||
className="rounded-sm bg-[#3ac9d6] text-white w-full py-3 shadow uppercase"
|
disabled={state.loading}
|
||||||
disabled={state.loading}
|
>
|
||||||
|
{state.loading ? "Loading..." : "Login"}
|
||||||
|
</button>
|
||||||
|
<NavLink
|
||||||
|
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
|
||||||
|
to="/signup"
|
||||||
|
style={state.hideNav ? { textAlign: "center" } : {}}
|
||||||
|
>
|
||||||
|
Create Account
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
{(props.appInfo.fbAppId || props.appInfo.googleClietId) && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center"
|
||||||
|
}}
|
||||||
|
className="text-sm"
|
||||||
>
|
>
|
||||||
{state.loading ? "Loading..." : "Login"}
|
<hr
|
||||||
</button>
|
className={"border-[1px] border-gray-300 w-full"}
|
||||||
<NavLink
|
style={{ color: "grey" }}
|
||||||
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
|
/>
|
||||||
to="/signup"
|
<span style={{ color: "grey" }} className="px-2 ">
|
||||||
style={state.hideNav ? { textAlign: "center" } : {}}
|
OR
|
||||||
>
|
</span>
|
||||||
Create Account
|
<hr
|
||||||
</NavLink>
|
className={"border-[1px] border-gray-300 w-full"}
|
||||||
</div>
|
style={{ color: "grey" }}
|
||||||
</form>
|
/>
|
||||||
<br />
|
</div>
|
||||||
{(props.appInfo.fbAppId || props.appInfo.googleClietId) && (
|
)}
|
||||||
|
<br />
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center"
|
justifyContent: "center"
|
||||||
}}
|
}}
|
||||||
className="text-sm"
|
|
||||||
>
|
>
|
||||||
<hr
|
{/* {props.appInfo.fbAppId && props.appInfo.fbAppId !== "" ? (
|
||||||
className={"border-[1px] border-gray-300 w-full"}
|
|
||||||
style={{ color: "grey" }}
|
|
||||||
/>
|
|
||||||
<span style={{ color: "grey" }} className="px-2 ">
|
|
||||||
OR
|
|
||||||
</span>
|
|
||||||
<hr
|
|
||||||
className={"border-[1px] border-gray-300 w-full"}
|
|
||||||
style={{ color: "grey" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<br />
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
textAlign: "center",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* {props.appInfo.fbAppId && props.appInfo.fbAppId !== "" ? (
|
|
||||||
<LoginFacebook
|
<LoginFacebook
|
||||||
FBCred={props.appInfo.fbAppId}
|
FBCred={props.appInfo.fbAppId}
|
||||||
thirdpartyLoginfn={thirdpartyLoginfn}
|
thirdpartyLoginfn={thirdpartyLoginfn}
|
||||||
@@ -1082,42 +1111,143 @@ function Login(props) {
|
|||||||
setThirdpartyLoader={setThirdpartyLoader}
|
setThirdpartyLoader={setThirdpartyLoader}
|
||||||
/>
|
/>
|
||||||
) : null} */}
|
) : null} */}
|
||||||
|
</div>
|
||||||
|
<div style={{ margin: "10px 0" }}></div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.appInfo.googleClietId &&
|
||||||
|
props.appInfo.googleClietId !== "" ? (
|
||||||
|
<GoogleSignInBtn
|
||||||
|
GoogleCred={props.appInfo.googleClietId}
|
||||||
|
thirdpartyLoginfn={thirdpartyLoginfn}
|
||||||
|
thirdpartyLoader={state.thirdpartyLoader}
|
||||||
|
setThirdpartyLoader={setThirdpartyLoader}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ margin: "10px 0" }}></div>
|
</div>
|
||||||
<div
|
{!state.hideNav && (
|
||||||
style={{
|
<div className="self-center">
|
||||||
textAlign: "center",
|
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
||||||
display: "flex",
|
<img
|
||||||
alignItems: "center",
|
src={login_img}
|
||||||
justifyContent: "center"
|
alt="The image illustrates a person from behind, seated at a desk with a four-monitor computer setup, in an environment with a light blue and white color scheme, featuring a potted plant to the right."
|
||||||
}}
|
width="100%"
|
||||||
>
|
|
||||||
{props.appInfo.googleClietId &&
|
|
||||||
props.appInfo.googleClietId !== "" ? (
|
|
||||||
<GoogleSignInBtn
|
|
||||||
GoogleCred={props.appInfo.googleClietId}
|
|
||||||
thirdpartyLoginfn={thirdpartyLoginfn}
|
|
||||||
thirdpartyLoader={state.thirdpartyLoader}
|
|
||||||
setThirdpartyLoader={setThirdpartyLoader}
|
|
||||||
/>
|
/>
|
||||||
) : null}
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="snackbar"
|
||||||
|
role="alert"
|
||||||
|
style={{ backgroundColor: state.toastColor }}
|
||||||
|
>
|
||||||
|
{state.toastDescription}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{isModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show"
|
||||||
|
id="exampleModal"
|
||||||
|
tabIndex="-1"
|
||||||
|
role="dialog"
|
||||||
|
style={{
|
||||||
|
display: "block",
|
||||||
|
zIndex: 1,
|
||||||
|
backgroundColor: "rgba(0,0,0,0.5)"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog" role="document">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h5 className="modal-title font-semibold">Additional Info</h5>
|
||||||
|
<span>
|
||||||
|
<span></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<form className="text-sm">
|
||||||
|
<div className="form-group">
|
||||||
|
<label
|
||||||
|
htmlFor="Company"
|
||||||
|
style={{ display: "flex" }}
|
||||||
|
className="col-form-label"
|
||||||
|
>
|
||||||
|
Company{" "}
|
||||||
|
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="Company"
|
||||||
|
value={userDetails.Company}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
Company: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label
|
||||||
|
htmlFor="Destination"
|
||||||
|
style={{ display: "flex" }}
|
||||||
|
className="col-form-label"
|
||||||
|
>
|
||||||
|
Destination{" "}
|
||||||
|
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="Destination"
|
||||||
|
value={userDetails.Destination}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
Destination: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="bg-[#17a2b8] text-sm p-2 text-white rounded uppercase"
|
||||||
|
onClick={(e) => handleSubmitbtn(e)}
|
||||||
|
style={{ marginRight: 10 }}
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="bg-[#6c757d] text-sm p-2 text-white rounded uppercase"
|
||||||
|
onClick={handleCloseModal}
|
||||||
|
style={{ width: 90 }}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!state.hideNav && (
|
|
||||||
<div className="self-center">
|
|
||||||
<div className="mx-auto md:w-[300px] lg:w-[500px]">
|
|
||||||
<img src={login_img} alt="bisec" width="100%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
</>
|
||||||
<div id="snackbar" style={{ backgroundColor: state.toastColor }}>
|
|
||||||
{state.toastDescription}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -1132,7 +1262,6 @@ function Login(props) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
const mapStateToProps = (state) => {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const PlanSubscriptions = () => {
|
|||||||
: "";
|
: "";
|
||||||
const phone =
|
const phone =
|
||||||
userDetails && userDetails.phone ? "&mobile=" + userDetails.phone : "";
|
userDetails && userDetails.phone ? "&mobile=" + userDetails.phone : "";
|
||||||
const details = "?" + name + email + company + phone;
|
const details = "?shipping_country_code=US&" + name + email + company + phone;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("accesstoken")) {
|
if (localStorage.getItem("accesstoken")) {
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
@@ -64,7 +64,7 @@ const PlanSubscriptions = () => {
|
|||||||
style={{
|
style={{
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
overflowY: "auto",
|
overflowY: "auto",
|
||||||
maxHeight: "600px",
|
maxHeight: "100%",
|
||||||
"--theme-color": "#7952b3",
|
"--theme-color": "#7952b3",
|
||||||
"--plan-width": 30
|
"--plan-width": 30
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -12,14 +12,37 @@ const Report = () => {
|
|||||||
const [isLoader, setIsLoader] = useState(true);
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
const [reportName, setReportName] = useState("");
|
const [reportName, setReportName] = useState("");
|
||||||
const [actions, setActions] = useState([]);
|
const [actions, setActions] = useState([]);
|
||||||
|
const [isNextRecord, setIsNextRecord] = useState(false);
|
||||||
|
const [isMoreDocs, setIsMoreDocs] = useState(true);
|
||||||
|
const abortController = new AbortController();
|
||||||
|
|
||||||
|
// below useEffect is call when id param change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setReportName("");
|
setReportName("");
|
||||||
|
setList([]);
|
||||||
getReportData();
|
getReportData();
|
||||||
|
|
||||||
|
// Function returned from useEffect is called on unmount
|
||||||
|
return () => {
|
||||||
|
setIsLoader(true);
|
||||||
|
setList([]);
|
||||||
|
setIsNextRecord(false);
|
||||||
|
// Here it'll abort the fetch
|
||||||
|
abortController.abort();
|
||||||
|
};
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
const getReportData = async () => {
|
// below useEffect call when isNextRecord state is true and fetch next record
|
||||||
setIsLoader(true);
|
useEffect(() => {
|
||||||
|
if (isNextRecord) {
|
||||||
|
getReportData(List.length, 200);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isNextRecord]);
|
||||||
|
|
||||||
|
const getReportData = async (skipUserRecord = 0, limit = 200) => {
|
||||||
|
// setIsLoader(true);
|
||||||
const json = reportJson(id);
|
const json = reportJson(id);
|
||||||
if (json) {
|
if (json) {
|
||||||
setActions(json.actions);
|
setActions(json.actions);
|
||||||
@@ -39,8 +62,11 @@ const Report = () => {
|
|||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&include=AuditTrail.UserPtr`;
|
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skipUserRecord}&limit=${limit}&include=AuditTrail.UserPtr`;
|
||||||
const res = await axios.get(url, { headers: headers });
|
const res = await axios.get(url, {
|
||||||
|
headers: headers,
|
||||||
|
signal: abortController.signal // is used to cancel fetch query
|
||||||
|
});
|
||||||
if (id === "4Hhwbp482K") {
|
if (id === "4Hhwbp482K") {
|
||||||
const listData = res.data?.results.filter(
|
const listData = res.data?.results.filter(
|
||||||
(x) => x.Signers.length > 0
|
(x) => x.Signers.length > 0
|
||||||
@@ -66,14 +92,35 @@ const Report = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setList(arr);
|
if (arr.length === 10) {
|
||||||
|
setIsMoreDocs(true);
|
||||||
|
} else {
|
||||||
|
setIsMoreDocs(false);
|
||||||
|
}
|
||||||
|
setList((prevRecord) =>
|
||||||
|
prevRecord.length > 0 ? [...prevRecord, ...arr] : arr
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
setList(res.data?.results);
|
if (res.data.results.length === 10) {
|
||||||
|
setIsMoreDocs(true);
|
||||||
|
console.log("here");
|
||||||
|
} else {
|
||||||
|
setIsMoreDocs(false);
|
||||||
|
}
|
||||||
|
setIsNextRecord(false);
|
||||||
|
setList((prevRecord) =>
|
||||||
|
prevRecord.length > 0
|
||||||
|
? [...prevRecord, ...res.data.results]
|
||||||
|
: res.data.results
|
||||||
|
);
|
||||||
}
|
}
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err ", err);
|
const isCancel = axios.isCancel(err);
|
||||||
setIsLoader(false);
|
if (!isCancel) {
|
||||||
|
console.log("err ", err);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
@@ -106,6 +153,8 @@ const Report = () => {
|
|||||||
ReportName={reportName}
|
ReportName={reportName}
|
||||||
List={List}
|
List={List}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
|
setIsNextRecord={setIsNextRecord}
|
||||||
|
isMoreDocs={isMoreDocs}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||||
|
|||||||
@@ -99,9 +99,38 @@ const Signup = (props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch(async (err) => {
|
||||||
alert(err.message);
|
if (err.code === 202) {
|
||||||
setState({ loading: false });
|
const userQuery = new Parse.Query("contracts_Users");
|
||||||
|
userQuery.equalTo("Email", email);
|
||||||
|
const res = await userQuery.first();
|
||||||
|
// console.log("Res ", res);
|
||||||
|
if (res) {
|
||||||
|
alert("User already exists with this username!");
|
||||||
|
setState({ loading: false });
|
||||||
|
} else {
|
||||||
|
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||||
|
let parseAppId = localStorage.getItem("AppID12");
|
||||||
|
// console.log("state.email ", email);
|
||||||
|
try {
|
||||||
|
Parse.serverURL = baseUrl;
|
||||||
|
Parse.initialize(parseAppId);
|
||||||
|
await Parse.User.requestPasswordReset(email).then(
|
||||||
|
async function (res1) {
|
||||||
|
if (res1.data === undefined) {
|
||||||
|
alert("Verification mail has been sent to your E-mail!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
setState({ loading: false });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert(err.message);
|
||||||
|
setState({ loading: false });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("err ", error);
|
console.log("err ", error);
|
||||||
@@ -251,7 +280,7 @@ const Signup = (props) => {
|
|||||||
element.pageType
|
element.pageType
|
||||||
);
|
);
|
||||||
setState({ loading: false });
|
setState({ loading: false });
|
||||||
navigate("/login");
|
navigate("/");
|
||||||
} else {
|
} else {
|
||||||
extendedInfo.forEach((x) => {
|
extendedInfo.forEach((x) => {
|
||||||
if (x.TenantId) {
|
if (x.TenantId) {
|
||||||
@@ -453,7 +482,7 @@ const Signup = (props) => {
|
|||||||
<div className="">
|
<div className="">
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<h2 className="text-[30px] mt-6">Create Account !</h2>
|
<h2 className="text-[30px] mt-6">Create Account !</h2>
|
||||||
<div className="shadow-md rounded my-4">
|
<div className="outline outline-1 outline-slate-300/50 shadow-md rounded my-4">
|
||||||
<div className="px-6 py-4 text-xs">
|
<div className="px-6 py-4 text-xs">
|
||||||
<label className="block ">
|
<label className="block ">
|
||||||
Name{" "}
|
Name{" "}
|
||||||
@@ -472,6 +501,7 @@ const Signup = (props) => {
|
|||||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
id="email"
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
value={email}
|
value={email}
|
||||||
@@ -563,7 +593,7 @@ const Signup = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
{!state.hideNav && (
|
{!state.hideNav && (
|
||||||
<div className="self-center">
|
<div className="self-center">
|
||||||
<div className="mx-auto md:w-[300px] lg:w-[500px]">
|
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
||||||
<img src={login_img} alt="bisec" width="100%" />
|
<img src={login_img} alt="bisec" width="100%" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ import multerS3 from 'multer-s3';
|
|||||||
import aws from 'aws-sdk';
|
import aws from 'aws-sdk';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
function sanitizeFileName(fileName) {
|
||||||
|
// Remove spaces and invalid characters
|
||||||
|
return fileName.replace(/[^a-zA-Z0-9._-]/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
async function uploadFile(req, res) {
|
async function uploadFile(req, res) {
|
||||||
try {
|
try {
|
||||||
//--size extended to 100 mb
|
//--size extended to 100 mb
|
||||||
@@ -50,16 +56,28 @@ async function uploadFile(req, res) {
|
|||||||
region: process.env.DO_REGION,
|
region: process.env.DO_REGION,
|
||||||
});
|
});
|
||||||
|
|
||||||
// const s3 = new aws.S3();
|
const parseBaseUrl = process.env.SERVER_URL;
|
||||||
const upload = multer({
|
const parseAppId = process.env.APP_ID;
|
||||||
fileFilter: function (req, file, cb) {
|
|
||||||
if (accepted_extensions.some(ext => file.originalname.toLowerCase().endsWith('.' + ext))) {
|
if (process.env.USE_LOCAL == "TRUE") {
|
||||||
return cb(null, true);
|
var fileStorage = multer.diskStorage({
|
||||||
|
destination: function(req, file, cb) {
|
||||||
|
cb(null, "files/files");
|
||||||
|
},
|
||||||
|
metadata: function (req, file, cb) {
|
||||||
|
cb(null, { fieldName: 'OPENSIGN_METADATA' });
|
||||||
|
},
|
||||||
|
filename: function(req, file, cb) {
|
||||||
|
let filename = file.originalname;
|
||||||
|
let newFileName = filename.split('.')[0];
|
||||||
|
let extension = filename.split('.')[1];
|
||||||
|
newFileName = sanitizeFileName(newFileName + '_' + new Date().toISOString() + '.' + extension)
|
||||||
|
console.log(newFileName);
|
||||||
|
cb(null, newFileName);
|
||||||
}
|
}
|
||||||
// otherwise, return error
|
});
|
||||||
return cb('Only ' + accepted_extensions.join(', ') + ' files are allowed!');
|
} else {
|
||||||
},
|
var fileStorage = multerS3({
|
||||||
storage: multerS3({
|
|
||||||
acl: 'public-read',
|
acl: 'public-read',
|
||||||
s3,
|
s3,
|
||||||
bucket: DO_SPACE,
|
bucket: DO_SPACE,
|
||||||
@@ -69,14 +87,25 @@ async function uploadFile(req, res) {
|
|||||||
key: function (req, file, cb) {
|
key: function (req, file, cb) {
|
||||||
//console.log(file);
|
//console.log(file);
|
||||||
let filename = file.originalname;
|
let filename = file.originalname;
|
||||||
let filenam = filename.split('.')[0];
|
let newFileName = filename.split('.')[0];
|
||||||
let extension = filename.split('.')[1];
|
let extension = filename.split('.')[1];
|
||||||
filenam = filenam + '_' + new Date().toISOString() + '.' + extension;
|
newFileName = sanitizeFileName(newFileName + '_' + new Date().toISOString() + '.' + extension)
|
||||||
console.log(filenam);
|
console.log(newFileName);
|
||||||
cb(null, filenam);
|
cb(null, newFileName);
|
||||||
},
|
}
|
||||||
}),
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// const s3 = new aws.S3();
|
||||||
|
const upload = multer({
|
||||||
|
fileFilter: function (req, file, cb) {
|
||||||
|
if (accepted_extensions.some(ext => file.originalname.toLowerCase().endsWith('.' + ext))) {
|
||||||
|
return cb(null, true);
|
||||||
|
}
|
||||||
|
// otherwise, return error
|
||||||
|
return cb('Only ' + accepted_extensions.join(', ') + ' files are allowed!');
|
||||||
|
},
|
||||||
|
storage: fileStorage,
|
||||||
limits: { fileSize: size },
|
limits: { fileSize: size },
|
||||||
}).single('file');
|
}).single('file');
|
||||||
|
|
||||||
@@ -93,7 +122,14 @@ async function uploadFile(req, res) {
|
|||||||
const status = 'Success';
|
const status = 'Success';
|
||||||
//res.header("Access-Control-Allow-Headers", "Content-Type");
|
//res.header("Access-Control-Allow-Headers", "Content-Type");
|
||||||
//res.setHeader("Access-Control-Allow-Origin", "*");
|
//res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
return res.json({ status, imageUrl: req.file.location });
|
if (process.env.USE_LOCAL == "TRUE") {
|
||||||
|
console.log(req.file);
|
||||||
|
var fileUrl = `${parseBaseUrl}/files/${parseAppId}/${req.file.filename}`;
|
||||||
|
} else {
|
||||||
|
var fileUrl = req.file.location;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json({ status, imageUrl: fileUrl });
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Exeption in query ' + err.stack);
|
console.log('Exeption in query ' + err.stack);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
const signer=require("node-signpdf").default;class SignPDF{constructor(e,t){this.pdfDoc=e,this.certificate=t}async signPDF(){return signer.sign(this.pdfDoc,this.certificate,{passphrase:"emudhra"})}static unit8ToBuffer(e){var t=Buffer.alloc(e.byteLength),r=new Uint8Array(e);for(let e=0;e<t.length;++e)t[e]=r[e];return t}}module.exports=SignPDF;
|
const signer=require("node-signpdf").default;class SignPDF{constructor(e,t){this.pdfDoc=e,this.certificate=t}async signPDF(){return signer.sign(this.pdfDoc,this.certificate, process.env.PASS_PHRASE ? {passphrase : process.env.PASS_PHRASE}: null)}static unit8ToBuffer(e){var t=Buffer.alloc(e.byteLength),r=new Uint8Array(e);for(let e=0;e<t.length;++e)t[e]=r[e];return t}}module.exports=SignPDF;
|
||||||
@@ -123,6 +123,9 @@ export default async function (request) {
|
|||||||
if (userDetails && userDetails.company) {
|
if (userDetails && userDetails.company) {
|
||||||
newObj.set("Company", userDetails.company);
|
newObj.set("Company", userDetails.company);
|
||||||
}
|
}
|
||||||
|
if (userDetails && userDetails.jobTitle) {
|
||||||
|
newObj.set("JobTitle", userDetails.jobTitle);
|
||||||
|
}
|
||||||
if (planDetails && planDetails.customer_id) {
|
if (planDetails && planDetails.customer_id) {
|
||||||
newObj.set("Next_billing_date", new Date(planDetails.nextBillingDate));
|
newObj.set("Next_billing_date", new Date(planDetails.nextBillingDate));
|
||||||
newObj.set("Plan", planDetails.plan);
|
newObj.set("Plan", planDetails.plan);
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,54 @@
|
|||||||
|
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
|
||||||
|
3pXAXxZuvVvv9tsb4bdrBAhyb+KCIjp/gAICCAA=
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDxTCCAq2gAwIBAgIUAZQ9QST2eBZz5k9pCa//mHQVm1QwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwcjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQKDA1P
|
||||||
|
cGVuU2lnbiBMYWJzMREwDwYDVQQDDAhPcGVuU2lnbjElMCMGCSqGSIb3DQEJARYW
|
||||||
|
aGVsbG9Ab3BlbnNpZ25sYWJzLmNvbTAeFw0yMzExMTcxOTQ0MzZaFw0yNDExMTYx
|
||||||
|
OTQ0MzZaMHIxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEWMBQGA1UE
|
||||||
|
CgwNT3BlblNpZ24gTGFiczERMA8GA1UEAwwIT3BlblNpZ24xJTAjBgkqhkiG9w0B
|
||||||
|
CQEWFmhlbGxvQG9wZW5zaWdubGFicy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||||
|
DwAwggEKAoIBAQDLRKLjCSrvV1zAY2leWxCvdKTUaThpQO8nWPE/4v5ilMU2aRON
|
||||||
|
krAnli0LUfQ/tIRWNurxwVjJ7HrW3ICLn05GBLjm2AUCfuMbJCvOEEdmFJqRY04n
|
||||||
|
12fBZWz2KtzbZEIBVxLhc4E4g+Rz68hQA2fqwNuFdyGkkIbhVXpZIePEppqRmw+2
|
||||||
|
uuDvIzJ77rdDaLqwwPoHWenZ2uZTedKXx7PGYs98psg35GvcpssqAJGAIAi9Rzg/
|
||||||
|
ZV4oSpGXCjn/TJy61zTDbmPFCS/rC1XBWzBQfwDeBPDI18W6gPVX6N4dp0Ao+n8Q
|
||||||
|
txeI6g4FzMH91KPbdbZXxm8rZqXj87VQs9trAgMBAAGjUzBRMB0GA1UdDgQWBBRN
|
||||||
|
NtRPagnqovdmbrdhSUON9Rwd3TAfBgNVHSMEGDAWgBRNNtRPagnqovdmbrdhSUON
|
||||||
|
9Rwd3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBrcPyA7GHq
|
||||||
|
+ol9qjy9HijpoU5MaEiV9v9H8/0v7KoXUND3rMl37yFyjxGN8uda8WxpEhE2eFnk
|
||||||
|
Xjtm2NgPrv8qeYHor/A3y5RfQhnlCY4kE1bREZGhcuKihR4rOtmComwFjx4Ibwwj
|
||||||
|
4nKsflj6rXcWKSfSNHLkXFXHPYwyqRsKdtClrD/8YJn6LeeMlMjIYGGP4qyi2WwS
|
||||||
|
Z8hExWGEMaMWiA9rxTMX6iu/parGH/pWU/55Os3WlcHPhlvqchBkQFJ+f8b+NYz0
|
||||||
|
vIHQgwn4K5WMsZVLxoiUcU7cSqE/qhnP+pzBf8lRaYwd+zUznDvzpKKz6nFgeHok
|
||||||
|
s8BK7JAKkIsl
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: DES-EDE3-CBC,5932FA9F02938D1B
|
||||||
|
|
||||||
|
6gkkZP80WrVnR3dVwkimtfirSeYNXZlrXXBv+Ddjyq7FScqca7svJFd8ObC0xXjg
|
||||||
|
nbxChDKS8SXcSjsNCTzixG0QReO5vaqovrpQoYbkSQ9GRMIVV8WuWNzlyMnypNJ4
|
||||||
|
Z6hdpd5nkc1hIP8A6WcY3lA8msyHceU9IidEEb75CE743qsvUMko+XvqntZx/LNe
|
||||||
|
0uK8Bs+cXeDzolpNX8ORKBTAOMii+WPlN2l+9ldsWTECEk4GmWa51QfpKouLxz5E
|
||||||
|
u7fuGuku/nPKGb4Yj7sCgaD91UabRksDLS9UGDBqeNL+mogG3gY/Iu0/q2cUs6XR
|
||||||
|
x1W6KW1eJHnOf1pAp7+G/zNqzdsxI3pnoR+nsV6/G0glBLar+Xqc99B568lnUWWv
|
||||||
|
5NGN3Buz1axx1jPKIknDcT4Skmvt6TcmgrjoCQ9XvmNKVClpExQ+dKPmJI/EVNoU
|
||||||
|
jjDZyfghcJ6BEMcTgoOBDiUrPM0273sb89u/AzyUA1tTciW2KARz6cOUTPWVRSRn
|
||||||
|
4yXpkA4BJDpxRmK68BXorZLNxtvHk+on80c9tu5e+IVa3Gu1K7gc269TPmlIolAM
|
||||||
|
v//i+jpwJ4Pe2IGVYdojMr15useUv7JC6/Kconnkx4q9rkMriguuXoQt8qW3kvEs
|
||||||
|
Ur8KuibtDqhz2zGbsKboQFMOd6cdd+63dJCGAUqk4hFrSikTw3LhkXNcg9GZHq1z
|
||||||
|
WFAfaA3x2jd+kJJ5xg8xMVEHax5IAOXDL2ektyPFpI1UZOuTc2i7FK6Y0NnXPkSN
|
||||||
|
G/+DsKdLWT943mPfZj01mTRi3MgseDXsHMHGmmPxW9J4jv+WW4OdpHvd474QzJ8b
|
||||||
|
vQmyiKq4XPHsuQUkzHVPbTrGe1B9z4p97YQKdEfXP2ChGFsUHCYQdpHyXwie2+pq
|
||||||
|
E2rc7Bai0OuL0anYMSIvDrJ0DE8mVVaFur1b2Uz6ieCDlrOXnzD1BrcleiZem7og
|
||||||
|
on/3oCUK+qxibCCcd5Hg2HtPusa43U0/UbCrqb2sww9iN36DLdtef/jlozKNiBx9
|
||||||
|
e8ZztF6GtAKhIdgGW/M9TXMUZOYr7aaXO71MsqhwpVWZ5dNqagOBzhmd7Etokf1H
|
||||||
|
O0WxJZ5XPDsnlKwYq86ssK+2RCNYAuvZoM3dRCysPvXoBFmsmHDzKdbKcckd8Vxr
|
||||||
|
6P1yaCkB/iX55dUqwKfIuqxY3m4MA2Us9DD0BRxZOSUqHhzHHSogsLhqLQEQENA4
|
||||||
|
U9N/v/za81UaU8nfkAswsGlTdTKjWH6Fzc0NeagbEFtpUaG/WIHPesUzU7ZNvMzR
|
||||||
|
SQACVWl62Dley2g2eAgcrsIn78MbwNJI2YN5eXIw0K2MiMlGXWOEvkjIIVfjc0/d
|
||||||
|
QxLFJwqShZBVO+jnAJ8jti7mP6PgskjtfHNAIphRJ4fm9h/Ns1YMpipBRVBDhbwY
|
||||||
|
AOVT4bRw9Q3O5I0pe10ZdViAhexegQ8yGt3pUlKaUf9GRwIFEknjZ5Pc98V/R/wC
|
||||||
|
INSIOZzDHj2uyZ3p7ToF1Z6kVVbbyfqDOnxUiV2ykR8ZqQMXNWcEJKH8qRqI+VHf
|
||||||
|
oszD2BQvXgkWdrJtHuHjJCdDl03Y+daS5yP8IKTDucHvRv4ZSMghZ34SJTw5MaBP
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
Binary file not shown.
+7
-1
@@ -221,13 +221,19 @@ function PdfFileComponent({
|
|||||||
// console.log("download")
|
// console.log("download")
|
||||||
const pdfName = data && data.Name;
|
const pdfName = data && data.Name;
|
||||||
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
|
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
|
||||||
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`);
|
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||||
} else if (selectType === "Rename") {
|
} else if (selectType === "Rename") {
|
||||||
// console.log("rename")
|
// console.log("rename")
|
||||||
setRenameValue(data.Name);
|
setRenameValue(data.Name);
|
||||||
setRename(data.objectId);
|
setRename(data.objectId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sanitizeFileName = (pdfName) => {
|
||||||
|
// Replace spaces with underscore
|
||||||
|
return pdfName.replace(/ /g, '_');
|
||||||
|
}
|
||||||
|
|
||||||
const handleEnterPress = (e, data) => {
|
const handleEnterPress = (e, data) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
handledRenameDoc(data);
|
handledRenameDoc(data);
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const PageNotFound = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||||
|
<div className="text-center">
|
||||||
|
<h1 className="text-[60px] lg:text-[120px] font-semibold text-black">
|
||||||
|
404
|
||||||
|
</h1>
|
||||||
|
<p className="text-[30px] lg:text-[50px] text-black">Page Not Found</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PageNotFound;
|
||||||
@@ -11,15 +11,13 @@ import { HTML5Backend } from "react-dnd-html5-backend";
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import SignPad from "./component/signPad";
|
import SignPad from "./component/signPad";
|
||||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||||
import {
|
import { getBase64FromIMG, getBase64FromUrl } from "../utils/Utils";
|
||||||
getBase64FromIMG,
|
|
||||||
getBase64FromUrl
|
|
||||||
} from "../utils/Utils";
|
|
||||||
import Loader from "./component/loader";
|
import Loader from "./component/loader";
|
||||||
import HandleError from "./component/HandleError";
|
import HandleError from "./component/HandleError";
|
||||||
import Nodata from "./component/Nodata";
|
import Nodata from "./component/Nodata";
|
||||||
import Header from "./component/header";
|
import Header from "./component/header";
|
||||||
import RenderPdf from "./component/renderPdf";
|
import RenderPdf from "./component/renderPdf";
|
||||||
|
import CustomModal from "./component/CustomModal";
|
||||||
|
|
||||||
function PdfRequestFiles() {
|
function PdfRequestFiles() {
|
||||||
const { docId } = useParams();
|
const { docId } = useParams();
|
||||||
@@ -64,7 +62,8 @@ function PdfRequestFiles() {
|
|||||||
const [isSigned, setIsSigned] = useState(false);
|
const [isSigned, setIsSigned] = useState(false);
|
||||||
const [isExpired, setIsExpired] = useState(false);
|
const [isExpired, setIsExpired] = useState(false);
|
||||||
const [alreadySign, setAlreadySign] = useState(false);
|
const [alreadySign, setAlreadySign] = useState(false);
|
||||||
|
const [containerWH, setContainerWH] = useState({});
|
||||||
|
const divRef = useRef(null);
|
||||||
const rowLevel =
|
const rowLevel =
|
||||||
localStorage.getItem("rowlevel") &&
|
localStorage.getItem("rowlevel") &&
|
||||||
JSON.parse(localStorage.getItem("rowlevel"));
|
JSON.parse(localStorage.getItem("rowlevel"));
|
||||||
@@ -96,6 +95,14 @@ function PdfRequestFiles() {
|
|||||||
getDocumentDetails();
|
getDocumentDetails();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
if (divRef.current) {
|
||||||
|
setContainerWH({
|
||||||
|
width: divRef.current.offsetWidth,
|
||||||
|
height: divRef.current.offsetHeight
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [divRef.current]);
|
||||||
|
|
||||||
//function for get document details for perticular signer with signer'object id
|
//function for get document details for perticular signer with signer'object id
|
||||||
const getDocumentDetails = async () => {
|
const getDocumentDetails = async () => {
|
||||||
@@ -912,6 +919,7 @@ function PdfRequestFiles() {
|
|||||||
|
|
||||||
//function for set decline true on press decline button
|
//function for set decline true on press decline button
|
||||||
const declineDoc = async () => {
|
const declineDoc = async () => {
|
||||||
|
setIsDecline({ isDeclined: false });
|
||||||
const data = {
|
const data = {
|
||||||
IsDeclined: true
|
IsDeclined: true
|
||||||
};
|
};
|
||||||
@@ -983,7 +991,39 @@ function PdfRequestFiles() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="signatureContainer">
|
<div className="signatureContainer" ref={divRef}>
|
||||||
|
{/* this modal is used to show decline alert */}
|
||||||
|
<CustomModal
|
||||||
|
containerWH={containerWH}
|
||||||
|
show={isDecline.isDeclined}
|
||||||
|
headMsg="Document Declined Alert!"
|
||||||
|
bodyMssg={
|
||||||
|
isDecline.currnt === "Sure" ? (
|
||||||
|
<p 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>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
footerMessage={isDecline.currnt === "Sure"}
|
||||||
|
declineDoc={declineDoc}
|
||||||
|
setIsDecline={setIsDecline}
|
||||||
|
/>
|
||||||
|
{/* this modal is used for show expired alert */}
|
||||||
|
<CustomModal
|
||||||
|
containerWH={containerWH}
|
||||||
|
show={isExpired}
|
||||||
|
headMsg="Document Expired!"
|
||||||
|
bodyMssg="This Document is no longer available."
|
||||||
|
/>
|
||||||
{/* this component used to render all pdf pages in left side */}
|
{/* this component used to render all pdf pages in left side */}
|
||||||
<RenderAllPdfPage
|
<RenderAllPdfPage
|
||||||
signPdfUrl={pdfDetails[0].URL}
|
signPdfUrl={pdfDetails[0].URL}
|
||||||
@@ -999,66 +1039,6 @@ function PdfRequestFiles() {
|
|||||||
marginRight: pdfOriginalWidth > 500 && "20px"
|
marginRight: pdfOriginalWidth > 500 && "20px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Modal show={isExpired}>
|
|
||||||
<ModalHeader className="bg-danger">
|
|
||||||
<span className="spanTagHead">Document Expired!</span>
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<Modal.Body>
|
|
||||||
<p className="pTagBody">
|
|
||||||
This Document is no longer available.
|
|
||||||
</p>
|
|
||||||
</Modal.Body>
|
|
||||||
</Modal>
|
|
||||||
{/* this modal is used for show decline alert */}
|
|
||||||
<Modal show={isDecline.isDeclined}>
|
|
||||||
<ModalHeader className="bg-danger">
|
|
||||||
<span className="spanTagHead">Document Declined Alert!</span>
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<Modal.Body>
|
|
||||||
{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>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</Modal.Body>
|
|
||||||
<Modal.Footer>
|
|
||||||
{isDecline.currnt === "Sure" && (
|
|
||||||
<>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "black"
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="finishBtn"
|
|
||||||
onClick={() => setIsDecline({ isDeclined: false })}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
background: "#de4337"
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="finishBtn"
|
|
||||||
onClick={() => declineDoc()}
|
|
||||||
>
|
|
||||||
Yes
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Modal.Footer>
|
|
||||||
</Modal>
|
|
||||||
{/* this modal is used show this document is already sign */}
|
{/* this modal is used show this document is already sign */}
|
||||||
|
|
||||||
<Modal show={isCompleted.isModal}>
|
<Modal show={isCompleted.isModal}>
|
||||||
|
|||||||
@@ -500,7 +500,6 @@ function SignYourSelf() {
|
|||||||
removeBase64Fromjpeg,
|
removeBase64Fromjpeg,
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
//function for call to embed signature in pdf and get digital signature pdf
|
//function for call to embed signature in pdf and get digital signature pdf
|
||||||
signPdfFun(newImgUrl, documentId, data, pdfBase64, pageNo);
|
signPdfFun(newImgUrl, documentId, data, pdfBase64, pageNo);
|
||||||
})
|
})
|
||||||
@@ -575,14 +574,18 @@ function SignYourSelf() {
|
|||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||||
|
|
||||||
const posY = () => {
|
const posY = () => {
|
||||||
if (id === 0) {
|
if (isMobile) {
|
||||||
return (
|
if (id === 0) {
|
||||||
page.getHeight() -
|
return (
|
||||||
imgUrlList[id].yPosition * scale -
|
page.getHeight() -
|
||||||
imgHeight
|
imgUrlList[id].yPosition * scale -
|
||||||
);
|
imgHeight
|
||||||
} else if (id > 0) {
|
);
|
||||||
return page.getHeight() - imgUrlList[id].yPosition * scale;
|
} else if (id > 0) {
|
||||||
|
return page.getHeight() - imgUrlList[id].yPosition * scale;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return page.getHeight() - imgUrlList[id].yPosition - imgHeight;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
page.drawImage(img, {
|
page.drawImage(img, {
|
||||||
@@ -596,7 +599,6 @@ function SignYourSelf() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||||
|
|
||||||
signPdfFun(pdfBytes, documentId);
|
signPdfFun(pdfBytes, documentId);
|
||||||
}
|
}
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
@@ -615,10 +617,11 @@ function SignYourSelf() {
|
|||||||
pageNo
|
pageNo
|
||||||
) => {
|
) => {
|
||||||
let singleSign;
|
let singleSign;
|
||||||
|
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const newWidth = window.innerWidth;
|
const newWidth = window.innerWidth;
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||||
const imgWidth = xyPosData.Width.Width ? xyPosData.Width.Width : 150;
|
const imgWidth = xyPosData ? xyPosData.Width : 150;
|
||||||
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
||||||
const height = xyPosData.Height ? xyPosData.Height : 60;
|
const height = xyPosData.Height ? xyPosData.Height : 60;
|
||||||
const bottomY = xyPosData.isDrag
|
const bottomY = xyPosData.isDrag
|
||||||
@@ -1115,6 +1118,8 @@ function SignYourSelf() {
|
|||||||
pdfDetails={pdfDetails}
|
pdfDetails={pdfDetails}
|
||||||
isShowHeader={true}
|
isShowHeader={true}
|
||||||
currentSigner={true}
|
currentSigner={true}
|
||||||
|
alreadySign={pdfUrl ? true : false}
|
||||||
|
isSignYourself={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* className="hidePdf" */}
|
{/* className="hidePdf" */}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import React from "react";
|
||||||
|
import "../../css/customModal.css";
|
||||||
|
import "../../css/signature.css";
|
||||||
|
|
||||||
|
function CustomModal({
|
||||||
|
show,
|
||||||
|
headMsg,
|
||||||
|
bodyMssg,
|
||||||
|
footerMessage,
|
||||||
|
declineDoc,
|
||||||
|
setIsDecline,
|
||||||
|
containerWH
|
||||||
|
}) {
|
||||||
|
const isMobile = window.innerWidth < 767;
|
||||||
|
return (
|
||||||
|
show && (
|
||||||
|
<div
|
||||||
|
className="parentDiv"
|
||||||
|
style={{
|
||||||
|
width: containerWH && containerWH.width,
|
||||||
|
height: isMobile ? "100%" : containerWH && containerWH.height
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="childDiv">
|
||||||
|
<div className="modalHeadDiv bg-danger">{headMsg && headMsg}</div>
|
||||||
|
<div className="modalBodyDIv">
|
||||||
|
<p className="pTagBody">{bodyMssg && bodyMssg}</p>
|
||||||
|
</div>
|
||||||
|
{footerMessage && (
|
||||||
|
<div className="modalFooterDiv">
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "black"
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn"
|
||||||
|
onClick={() => setIsDecline({ isDeclined: false })}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
background: "#de4337"
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="finishBtn"
|
||||||
|
onClick={() => declineDoc()}
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CustomModal;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect } from "react";
|
import React from "react";
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
function DefaultSignature({
|
function DefaultSignature({
|
||||||
themeColor,
|
themeColor,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function EmailComponent({
|
|||||||
//function for send email
|
//function for send email
|
||||||
const sendEmail = async () => {
|
const sendEmail = async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
let sendMail, recipent;
|
let sendMail;
|
||||||
for (let i = 0; i < emailCount.length; i++) {
|
for (let i = 0; i < emailCount.length; i++) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -109,16 +109,30 @@ function EmailComponent({
|
|||||||
const handleToPrint = async (event) => {
|
const handleToPrint = async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const base64 = await getBase64FromUrl(pdfUrl);
|
const pdf = await getBase64FromUrl(pdfUrl);
|
||||||
printModule({ printable: base64, type: "pdf", base64: true });
|
const isAndroidDevice = navigator.userAgent.match(/Android/i);
|
||||||
|
const isAppleDevice = (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) && !window.MSStream
|
||||||
|
if (isAndroidDevice || isAppleDevice) {
|
||||||
|
const byteArray = Uint8Array.from(atob(pdf).split('').map(char => char.charCodeAt(0)));
|
||||||
|
const blob = new Blob([byteArray], { type: 'application/pdf' });
|
||||||
|
const blobUrl = URL.createObjectURL(blob);
|
||||||
|
window.open(blobUrl, '_blank');
|
||||||
|
} else {
|
||||||
|
printModule({ printable: pdf, type: "pdf", base64: true });
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//handle download signed pdf
|
//handle download signed pdf
|
||||||
const handleDownloadPdf = () => {
|
const handleDownloadPdf = () => {
|
||||||
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`);
|
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sanitizeFileName = (pdfName) => {
|
||||||
|
// Replace spaces with underscore
|
||||||
|
return pdfName.replace(/ /g, '_');
|
||||||
|
}
|
||||||
|
|
||||||
const isAndroid = /Android/i.test(navigator.userAgent);
|
const isAndroid = /Android/i.test(navigator.userAgent);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ function Header({
|
|||||||
}) {
|
}) {
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||||
//for go to previous page
|
//for go to previous page
|
||||||
function previousPage() {
|
function previousPage() {
|
||||||
changePage(-1);
|
changePage(-1);
|
||||||
@@ -60,27 +60,43 @@ function Header({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const pdf = await getBase64FromUrl(pdfUrl);
|
const pdf = await getBase64FromUrl(pdfUrl);
|
||||||
|
const isAndroidDevice = navigator.userAgent.match(/Android/i);
|
||||||
printModule({ printable: pdf, type: "pdf", base64: true });
|
const isAppleDevice = (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) && !window.MSStream
|
||||||
|
if (isAndroidDevice || isAppleDevice) {
|
||||||
|
const byteArray = Uint8Array.from(atob(pdf).split('').map(char => char.charCodeAt(0)));
|
||||||
|
const blob = new Blob([byteArray], { type: 'application/pdf' });
|
||||||
|
const blobUrl = URL.createObjectURL(blob);
|
||||||
|
window.open(blobUrl, '_blank');
|
||||||
|
} else {
|
||||||
|
printModule({ printable: pdf, type: "pdf", base64: true });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//handle download signed pdf
|
//handle download signed pdf
|
||||||
const handleDownloadPdf = () => {
|
const handleDownloadPdf = () => {
|
||||||
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
|
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
|
||||||
|
|
||||||
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`);
|
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sanitizeFileName = (pdfName) => {
|
||||||
|
// Replace spaces with underscore
|
||||||
|
return pdfName.replace(/ /g, '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ paddingBottom: "5px", paddingTop: "5px" }}
|
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
|
||||||
className="mobileHead"
|
className="mobileHead"
|
||||||
>
|
>
|
||||||
{isMobile && isShowHeader ? (
|
{isMobile && isShowHeader ? (
|
||||||
<div
|
<div
|
||||||
id="navbar"
|
id="navbar"
|
||||||
className="stickyHead"
|
className={isGuestSigner ? "stickySignerHead" : "stickyHead"}
|
||||||
style={{ width: window.innerWidth - 30 + "px" }}
|
style={{
|
||||||
|
width: isGuestSigner ? window.innerWidth : window.innerWidth - 30 + "px"
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="preBtn2">
|
<div className="preBtn2">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -42,8 +42,42 @@ function RenderPdf({
|
|||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const newWidth = window.innerWidth;
|
const newWidth = window.innerWidth;
|
||||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||||
//function for render placeholder block over pdf document
|
|
||||||
|
|
||||||
|
// handle signature block width and height according to screen
|
||||||
|
const posWidth = (pos) => {
|
||||||
|
let width;
|
||||||
|
if (isMobile) {
|
||||||
|
if (!pos.isMobile) {
|
||||||
|
width = pos.Width / scale ? pos.Width / scale : 150 / scale;
|
||||||
|
return width;
|
||||||
|
} else {
|
||||||
|
width = pos.Width ? pos.Width : 150;
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
width = pos.Width ? pos.Width : 150;
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const posHeight = (pos) => {
|
||||||
|
let width;
|
||||||
|
if (isMobile) {
|
||||||
|
if (!pos.isMobile) {
|
||||||
|
width = pos.Height / scale ? pos.Height / scale : 60 / scale;
|
||||||
|
return width;
|
||||||
|
} else {
|
||||||
|
width = pos.Height ? pos.Height : 60;
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
width = pos.Height ? pos.Height : 60;
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
|
||||||
|
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||||
|
|
||||||
|
//function for render placeholder block over pdf document
|
||||||
const checkSignedSignes = (data) => {
|
const checkSignedSignes = (data) => {
|
||||||
const checkSign = signedSigners.filter(
|
const checkSign = signedSigners.filter(
|
||||||
(sign) => sign.objectId === data.signerObjId
|
(sign) => sign.objectId === data.signerObjId
|
||||||
@@ -56,7 +90,7 @@ function RenderPdf({
|
|||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||||
if (!pos.isMobile) {
|
if (!pos.isMobile) {
|
||||||
return pos.xPosition / scale;
|
return pos.xPosition / scale - 20;
|
||||||
}
|
}
|
||||||
//pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale
|
//pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale
|
||||||
else {
|
else {
|
||||||
@@ -134,8 +168,8 @@ function RenderPdf({
|
|||||||
borderWidth: "0.2px"
|
borderWidth: "0.2px"
|
||||||
}}
|
}}
|
||||||
size={{
|
size={{
|
||||||
width: pos.Width ? pos.Width : 150,
|
width: posWidth(pos),
|
||||||
height: pos.Height ? pos.Height : 60
|
height: posHeight(pos)
|
||||||
}}
|
}}
|
||||||
lockAspectRatio={pos.Width && 2.5}
|
lockAspectRatio={pos.Width && 2.5}
|
||||||
default={{
|
default={{
|
||||||
@@ -205,8 +239,8 @@ function RenderPdf({
|
|||||||
y: yPos(pos)
|
y: yPos(pos)
|
||||||
}}
|
}}
|
||||||
size={{
|
size={{
|
||||||
width: pos.Width ? pos.Width : 150,
|
width: posWidth(pos),
|
||||||
height: pos.Height ? pos.Height : 60
|
height: posHeight(pos)
|
||||||
}}
|
}}
|
||||||
lockAspectRatio={pos.Width ? pos.Width / pos.Height : 2.5}
|
lockAspectRatio={pos.Width ? pos.Width / pos.Height : 2.5}
|
||||||
>
|
>
|
||||||
@@ -235,7 +269,8 @@ function RenderPdf({
|
|||||||
{isMobile && scale ? (
|
{isMobile && scale ? (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: "0.1px solid #ebe8e8"
|
border: "0.1px solid #ebe8e8",
|
||||||
|
marginTop: isGuestSigner && "30px"
|
||||||
}}
|
}}
|
||||||
ref={drop}
|
ref={drop}
|
||||||
id="container"
|
id="container"
|
||||||
@@ -294,12 +329,11 @@ function RenderPdf({
|
|||||||
borderWidth: "0.2px"
|
borderWidth: "0.2px"
|
||||||
}}
|
}}
|
||||||
size={{
|
size={{
|
||||||
width: pos.Width ? pos.Width : 150,
|
width: posWidth(pos),
|
||||||
height: pos.Height ? pos.Height : 60
|
height: posHeight(pos)
|
||||||
}}
|
}}
|
||||||
lockAspectRatio={pos.Width && 2.5}
|
lockAspectRatio={pos.Width && 2.5}
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divide by scale
|
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divide by scale
|
||||||
|
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||||
default={{
|
default={{
|
||||||
x: !pos.isMobile
|
x: !pos.isMobile
|
||||||
@@ -361,14 +395,13 @@ function RenderPdf({
|
|||||||
borderWidth: "0.2px"
|
borderWidth: "0.2px"
|
||||||
}}
|
}}
|
||||||
size={{
|
size={{
|
||||||
width: pos.Width ? pos.Width : 150,
|
width: posWidth(pos),
|
||||||
height: pos.Height ? pos.Height : 60
|
height: posHeight(pos)
|
||||||
}}
|
}}
|
||||||
disableDragging={true}
|
disableDragging={true}
|
||||||
default={{
|
default={{
|
||||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divide by scale
|
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divide by scale
|
||||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||||
|
|
||||||
x: !pos.isMobile
|
x: !pos.isMobile
|
||||||
? pos.xPosition / scale
|
? pos.xPosition / scale
|
||||||
: pos.xPosition * (pos.scale / scale) - 50,
|
: pos.xPosition * (pos.scale / scale) - 50,
|
||||||
|
|||||||
@@ -38,19 +38,15 @@ function Login() {
|
|||||||
|
|
||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
const { value } = event.target;
|
const { value } = event.target;
|
||||||
|
|
||||||
setOTP(value);
|
setOTP(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
//send email OTP function
|
//send email OTP function
|
||||||
|
|
||||||
const SendOtp = async (e) => {
|
const SendOtp = async (e) => {
|
||||||
const serverUrl =
|
const serverUrl =
|
||||||
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
||||||
|
|
||||||
const parseId =
|
const parseId =
|
||||||
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
||||||
|
|
||||||
if (serverUrl && localStorage) {
|
if (serverUrl && localStorage) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -84,13 +80,10 @@ function Login() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const serverUrl =
|
const serverUrl =
|
||||||
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
||||||
|
|
||||||
const parseId =
|
const parseId =
|
||||||
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
||||||
|
|
||||||
if (OTP) {
|
if (OTP) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let url = `${serverUrl}functions/AuthLoginAsMail/`;
|
let url = `${serverUrl}functions/AuthLoginAsMail/`;
|
||||||
const headers = {
|
const headers = {
|
||||||
@@ -102,7 +95,6 @@ function Login() {
|
|||||||
otp: OTP
|
otp: OTP
|
||||||
};
|
};
|
||||||
let user = await axios.post(url, body, { headers: headers });
|
let user = await axios.post(url, body, { headers: headers });
|
||||||
|
|
||||||
if (user.data.result === "Invalid Otp") {
|
if (user.data.result === "Invalid Otp") {
|
||||||
alert("Invalid Otp");
|
alert("Invalid Otp");
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -114,9 +106,12 @@ function Login() {
|
|||||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
localStorage.setItem("username", _user.name);
|
localStorage.setItem("username", _user.name);
|
||||||
localStorage.setItem("accesstoken", _user.sessionToken);
|
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||||
|
//save isGuestSigner true in local to handle login flow header in mobile view
|
||||||
|
localStorage.setItem("isGuestSigner", true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
//navigate user to on signature page
|
navigate(
|
||||||
navigate(`/recipientSignPdf/${id}/${contactBookId}`);
|
`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
} else {
|
} else {
|
||||||
@@ -172,9 +167,7 @@ function Login() {
|
|||||||
<span className="KNLO">
|
<span className="KNLO">
|
||||||
Verification code is sent to your email
|
Verification code is sent to your email
|
||||||
</span>
|
</span>
|
||||||
<div className="card card-box"
|
<div className="card card-box" style={{ borderRadius: "0px" }}>
|
||||||
style={{borderRadius:"0px"}}
|
|
||||||
>
|
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
@@ -189,7 +182,6 @@ function Login() {
|
|||||||
<div className="btnContainer">
|
<div className="btnContainer">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<button
|
<button
|
||||||
// className="btn btn-info loadinBtn "
|
|
||||||
type="button"
|
type="button"
|
||||||
style={{
|
style={{
|
||||||
background: themeColor(),
|
background: themeColor(),
|
||||||
@@ -213,15 +205,7 @@ function Login() {
|
|||||||
color: "white",
|
color: "white",
|
||||||
marginLeft: "0px !important"
|
marginLeft: "0px !important"
|
||||||
}}
|
}}
|
||||||
// className="btn btn-sm otpButton"
|
|
||||||
onClick={(e) => SendOtp(e)}
|
onClick={(e) => SendOtp(e)}
|
||||||
// style={{
|
|
||||||
// marginBottom: "4px",
|
|
||||||
// width: "210px",
|
|
||||||
// background: themeColor(),
|
|
||||||
// color: "white",
|
|
||||||
// fontWeight: "600"
|
|
||||||
// }}
|
|
||||||
>
|
>
|
||||||
Send OTP
|
Send OTP
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -679,7 +679,7 @@ function PlaceHolderSign() {
|
|||||||
year: "numeric"
|
year: "numeric"
|
||||||
});
|
});
|
||||||
let sender = signersdata.ExtUserPtr.Email;
|
let sender = signersdata.ExtUserPtr.Email;
|
||||||
const signerMail = signersdata.Signers;
|
const signerMail = signersdata.Signers;
|
||||||
|
|
||||||
for (let i = 0; i < signerMail.length; i++) {
|
for (let i = 0; i < signerMail.length; i++) {
|
||||||
try {
|
try {
|
||||||
@@ -698,7 +698,8 @@ function PlaceHolderSign() {
|
|||||||
"parseAppId"
|
"parseAppId"
|
||||||
)}&${localStorage.getItem("_appName")}`;
|
)}&${localStorage.getItem("_appName")}`;
|
||||||
|
|
||||||
let signPdf = `https://qik-ai-org.github.io/Sign-MicroappV2/#/login/${signersdata.objectId}/${signerMail[i].Email}/${objectId}/${serverParams}`;
|
const hostUrl = window.location.origin + "/loadmf/signmicroapp";
|
||||||
|
let signPdf = `${hostUrl}/login/${signersdata.objectId}/${signerMail[i].Email}/${objectId}/${serverParams}`;
|
||||||
|
|
||||||
const themeBGcolor = themeColor();
|
const themeBGcolor = themeColor();
|
||||||
let params = {
|
let params = {
|
||||||
@@ -951,7 +952,7 @@ function PlaceHolderSign() {
|
|||||||
background: themeColor()
|
background: themeColor()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span style={{ color: "white" }}>Send Mail </span>
|
<span style={{ color: "white" }}>Mails Sent</span>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
|
|
||||||
{/* signature modal */}
|
{/* signature modal */}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ import Loader from "./component/loader";
|
|||||||
import HandleError from "./component/HandleError";
|
import HandleError from "./component/HandleError";
|
||||||
import Nodata from "./component/Nodata";
|
import Nodata from "./component/Nodata";
|
||||||
import Header from "./component/header";
|
import Header from "./component/header";
|
||||||
import ModalComponent from "./component/modalComponent";
|
|
||||||
import RenderPdf from "./component/renderPdf";
|
import RenderPdf from "./component/renderPdf";
|
||||||
|
import CustomModal from "./component/CustomModal";
|
||||||
function EmbedPdfImage() {
|
function EmbedPdfImage() {
|
||||||
const { id, contactBookId } = useParams();
|
const { id, contactBookId } = useParams();
|
||||||
const [isSignPad, setIsSignPad] = useState(false);
|
const [isSignPad, setIsSignPad] = useState(false);
|
||||||
@@ -67,13 +67,15 @@ function EmbedPdfImage() {
|
|||||||
status: false,
|
status: false,
|
||||||
type: "load"
|
type: "load"
|
||||||
});
|
});
|
||||||
|
const [containerWH, setContainerWH] = useState({});
|
||||||
const docId = id && id;
|
const docId = id && id;
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const index = xyPostion.findIndex((object) => {
|
const index = xyPostion.findIndex((object) => {
|
||||||
return object.pageNumber === pageNumber;
|
return object.pageNumber === pageNumber;
|
||||||
});
|
});
|
||||||
|
const divRef = useRef(null);
|
||||||
|
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
|
||||||
|
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const clientWidth = window.innerWidth;
|
const clientWidth = window.innerWidth;
|
||||||
const pdfWidth = clientWidth - 160 - 220 - 30;
|
const pdfWidth = clientWidth - 160 - 220 - 30;
|
||||||
@@ -82,6 +84,14 @@ function EmbedPdfImage() {
|
|||||||
setPdfNewWidth(pdfWidth);
|
setPdfNewWidth(pdfWidth);
|
||||||
getDocumentDetails();
|
getDocumentDetails();
|
||||||
}, []);
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
if (divRef.current) {
|
||||||
|
setContainerWH({
|
||||||
|
width: divRef.current.offsetWidth,
|
||||||
|
height: divRef.current.offsetHeight
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [divRef.current]);
|
||||||
|
|
||||||
//function for get document details for perticular signer with signer'object id
|
//function for get document details for perticular signer with signer'object id
|
||||||
const getDocumentDetails = async () => {
|
const getDocumentDetails = async () => {
|
||||||
@@ -952,7 +962,37 @@ function EmbedPdfImage() {
|
|||||||
) : noData ? (
|
) : noData ? (
|
||||||
<Nodata />
|
<Nodata />
|
||||||
) : (
|
) : (
|
||||||
<div className="signatureContainer">
|
<div className="signatureContainer" ref={divRef}>
|
||||||
|
{/* this modal is used to show decline alert */}
|
||||||
|
<CustomModal
|
||||||
|
containerWH={containerWH}
|
||||||
|
show={isDecline.isDeclined}
|
||||||
|
headMsg="Document Declined Alert!"
|
||||||
|
bodyMssg={
|
||||||
|
isDecline.currnt === "Sure" ? (
|
||||||
|
<p>Are you sure want to decline this document ?</p>
|
||||||
|
) : isDecline.currnt === "YouDeclined" ? (
|
||||||
|
<p>You have declined this document!</p>
|
||||||
|
) : (
|
||||||
|
isDecline.currnt === "another" && (
|
||||||
|
<p>
|
||||||
|
You cannot sign this document as it has been declined by one
|
||||||
|
or more person(s).
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
footerMessage={isDecline.currnt === "Sure"}
|
||||||
|
declineDoc={declineDoc}
|
||||||
|
setIsDecline={setIsDecline}
|
||||||
|
/>
|
||||||
|
{/* this modal is used for show expired alert */}
|
||||||
|
<CustomModal
|
||||||
|
containerWH={containerWH}
|
||||||
|
show={isExpired}
|
||||||
|
headMsg="Document Expired!"
|
||||||
|
bodyMssg="This Document is no longer available."
|
||||||
|
/>
|
||||||
{/* this component used for UI interaction and show their functionality */}
|
{/* this component used for UI interaction and show their functionality */}
|
||||||
{pdfLoadFail.status &&
|
{pdfLoadFail.status &&
|
||||||
!isExpired &&
|
!isExpired &&
|
||||||
@@ -971,61 +1011,10 @@ function EmbedPdfImage() {
|
|||||||
{/* pdf render view */}
|
{/* pdf render view */}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
marginLeft: pdfOriginalWidth > 500 && "20px",
|
marginLeft: !isGuestSigner && pdfOriginalWidth > 500 && "20px",
|
||||||
marginRight: pdfOriginalWidth > 500 && "20px"
|
marginRight: !isGuestSigner && pdfOriginalWidth > 500 && "20px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* this modal is used for show decline alert */}
|
|
||||||
<Modal show={isDecline.isDeclined}>
|
|
||||||
<ModalHeader className="bg-danger" style={{ color: "white" }}>
|
|
||||||
Document Declined Alert!
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<Modal.Body>
|
|
||||||
{isDecline.currnt === "Sure" ? (
|
|
||||||
<p>Are you sure want to decline this document ?</p>
|
|
||||||
) : isDecline.currnt === "YouDeclined" ? (
|
|
||||||
<p>You have declined this document!</p>
|
|
||||||
) : (
|
|
||||||
isDecline.currnt === "another" && (
|
|
||||||
<p>
|
|
||||||
You cannot sign this document as it has been declined by
|
|
||||||
one or more person(s).
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</Modal.Body>
|
|
||||||
<Modal.Footer>
|
|
||||||
{isDecline.currnt === "Sure" && (
|
|
||||||
<>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "black"
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="finishBtn"
|
|
||||||
onClick={() => setIsDecline({ isDeclined: false })}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
background: "#de4337"
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="finishBtn"
|
|
||||||
onClick={() => declineDoc()}
|
|
||||||
>
|
|
||||||
Yes
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Modal.Footer>
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
{/* this modal component is used for show expired document */}
|
|
||||||
<ModalComponent isShow={isExpired} type={"expire"} />
|
|
||||||
|
|
||||||
{/* this modal is used show this document is already sign */}
|
{/* this modal is used show this document is already sign */}
|
||||||
<Modal show={isAlreadySign.status}>
|
<Modal show={isAlreadySign.status}>
|
||||||
<ModalHeader style={{ background: themeColor() }}>
|
<ModalHeader style={{ background: themeColor() }}>
|
||||||
@@ -1138,7 +1127,7 @@ function EmbedPdfImage() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* ndD5gdaxqw */}
|
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import Login from "./Component/login";
|
|||||||
import DraftDocument from "./Component/DraftDocument";
|
import DraftDocument from "./Component/DraftDocument";
|
||||||
import PdfRequestFiles from "./Component/PdfRequestFiles";
|
import PdfRequestFiles from "./Component/PdfRequestFiles";
|
||||||
import LegaDrive from "./Component/LegaDrive/LegaDrive";
|
import LegaDrive from "./Component/LegaDrive/LegaDrive";
|
||||||
|
import PageNotFound from "./Component/PageNotFound";
|
||||||
|
|
||||||
// `AppRoutes` is used to define route path of app and
|
// `AppRoutes` is used to define route path of app and
|
||||||
// it expose to host app, check moduleFederation.config.js for more
|
// it expose to host app, check moduleFederation.config.js for more
|
||||||
@@ -33,7 +34,10 @@ function AppRoutes() {
|
|||||||
{/*Add default signature of user route */}
|
{/*Add default signature of user route */}
|
||||||
<Route path="/managesign" element={<ManageSign />} />
|
<Route path="/managesign" element={<ManageSign />} />
|
||||||
{/* login page route */}
|
{/* login page route */}
|
||||||
<Route path="/login/:id/:userMail/:contactBookId/:serverUrl" element={<Login />} />
|
<Route
|
||||||
|
path="/login/:id/:userMail/:contactBookId/:serverUrl"
|
||||||
|
element={<Login />}
|
||||||
|
/>
|
||||||
{/* draft document route to handle and navigate route page accordiing to document status */}
|
{/* draft document route to handle and navigate route page accordiing to document status */}
|
||||||
<Route path="/draftDocument" element={<DraftDocument />} />
|
<Route path="/draftDocument" element={<DraftDocument />} />
|
||||||
{/* for user signature (need your sign route) with row level data */}
|
{/* for user signature (need your sign route) with row level data */}
|
||||||
@@ -42,6 +46,8 @@ function AppRoutes() {
|
|||||||
<Route path="/pdfRequestFiles/:docId" element={<PdfRequestFiles />} />
|
<Route path="/pdfRequestFiles/:docId" element={<PdfRequestFiles />} />
|
||||||
{/* lega drive route */}
|
{/* lega drive route */}
|
||||||
<Route path="/legadrive" element={<LegaDrive />} />
|
<Route path="/legadrive" element={<LegaDrive />} />
|
||||||
|
{/* Page Not Found */}
|
||||||
|
<Route path="*" element={<PageNotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
.parentDiv {
|
||||||
|
background: gray;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 20;
|
||||||
|
background-color: rgba(0, 0, 0, 0.75);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.childDiv {
|
||||||
|
width: 50%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 30px 20px;
|
||||||
|
border: 0px 1px 1px 1px solid rgba(0, 0, 0, .2);
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalHeadDiv {
|
||||||
|
padding: 10px;
|
||||||
|
color: #fff;
|
||||||
|
border-top-left-radius: 0.3rem;
|
||||||
|
border-top-right-radius: 0.3rem;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalBodyDIv {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spanTagHead {
|
||||||
|
color: white !important;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pTagBody {
|
||||||
|
|
||||||
|
font-size: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalFooterDiv {
|
||||||
|
margin: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width:500px) {
|
||||||
|
.childDiv {
|
||||||
|
margin: 50px 7px;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -58,36 +58,40 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
|||||||
data.key === signKey && data.Width && data.Height && data.SignUrl
|
data.key === signKey && data.Width && data.Height && data.SignUrl
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if (updateFilter.length > 0) {
|
if (updateFilter.length > 0) {
|
||||||
let newWidth, nweHeight;
|
let newWidth, newHeight;
|
||||||
const aspectRatio = imgWH.width / imgWH.height;
|
const aspectRatio = imgWH.width / imgWH.height;
|
||||||
|
|
||||||
const getXYdata = xyPostion[index].pos;
|
const getXYdata = xyPostion[index].pos;
|
||||||
|
|
||||||
if (aspectRatio === 1) {
|
if (aspectRatio === 1) {
|
||||||
newWidth = aspectRatio * 100;
|
newWidth = aspectRatio * 100;
|
||||||
nweHeight = aspectRatio * 100;
|
newHeight = aspectRatio * 100;
|
||||||
} else if (aspectRatio < 2) {
|
} else if (aspectRatio < 2) {
|
||||||
newWidth = aspectRatio * 100;
|
newWidth = aspectRatio * 100;
|
||||||
nweHeight = 100;
|
newHeight = 100;
|
||||||
} else if (aspectRatio > 2 && aspectRatio < 4) {
|
} else if (aspectRatio > 2 && aspectRatio < 4) {
|
||||||
newWidth = aspectRatio * 70;
|
newWidth = aspectRatio * 70;
|
||||||
nweHeight = 70;
|
newHeight = 70;
|
||||||
} else if (aspectRatio > 4) {
|
} else if (aspectRatio > 4) {
|
||||||
newWidth = aspectRatio * 40;
|
newWidth = aspectRatio * 40;
|
||||||
nweHeight = 40;
|
newHeight = 40;
|
||||||
} else if (aspectRatio > 5) {
|
} else if (aspectRatio > 5) {
|
||||||
newWidth = aspectRatio * 10;
|
newWidth = aspectRatio * 10;
|
||||||
nweHeight = 10;
|
newHeight = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
let getPosData = xyPostion[index].pos.filter((data) => data.key === signKey);
|
let getPosData = xyPostion[index].pos.filter(
|
||||||
|
(data) => data.key === signKey
|
||||||
|
);
|
||||||
|
|
||||||
const addSign = getXYdata.map((url, ind) => {
|
const addSign = getXYdata.map((url, ind) => {
|
||||||
if (url.key === signKey) {
|
if (url.key === signKey) {
|
||||||
return {
|
return {
|
||||||
...url,
|
...url,
|
||||||
Width: getPosData[0].Width ? getPosData[0].Width : 150,
|
Width: getPosData[0].Width ? getPosData[0].Width : newWidth,
|
||||||
Height: getPosData[0].Height ? getPosData[0].Height : 60,
|
Height: getPosData[0].Height ? getPosData[0].Height : newHeight,
|
||||||
SignUrl: image.src,
|
SignUrl: image.src,
|
||||||
ImageType: image.imgType
|
ImageType: image.imgType
|
||||||
};
|
};
|
||||||
@@ -106,7 +110,9 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
|||||||
} else {
|
} else {
|
||||||
const getXYdata = xyPostion[index].pos;
|
const getXYdata = xyPostion[index].pos;
|
||||||
|
|
||||||
let getPosData = xyPostion[index].pos.filter((data) => data.key === signKey);
|
let getPosData = xyPostion[index].pos.filter(
|
||||||
|
(data) => data.key === signKey
|
||||||
|
);
|
||||||
const aspectRatio = imgWH.width / imgWH.height;
|
const aspectRatio = imgWH.width / imgWH.height;
|
||||||
|
|
||||||
let newWidth, newHeight;
|
let newWidth, newHeight;
|
||||||
@@ -131,9 +137,9 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
|||||||
if (url.key === signKey) {
|
if (url.key === signKey) {
|
||||||
return {
|
return {
|
||||||
...url,
|
...url,
|
||||||
Width: getPosData[0].Width ? getPosData[0].Width : 150,
|
Width: getPosData[0].Width ? getPosData[0].Width : newWidth,
|
||||||
Height: getPosData[0].Height ? getPosData[0].Height : 60,
|
Height: getPosData[0].Height ? getPosData[0].Height : newHeight,
|
||||||
SignUrl: image.src,
|
SignUrl: image.src,
|
||||||
ImageType: image.imgType
|
ImageType: image.imgType
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user