mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-04 00:38:57 +02:00
Compare commits
38
Commits
v1.0.3
...
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 | ||
|
|
4b11fe77e0 | ||
|
|
d42e11c5c1 | ||
|
|
fe37f3e021 | ||
|
|
95558d1407 | ||
|
|
73978ebce4 | ||
|
|
96ae95a97c | ||
|
|
356d2e81c5 |
+55
-2
@@ -50,7 +50,60 @@ MAILGUN_DOMAIN=mail.yourdomain.com
|
||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||
|
||||
# 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=
|
||||
PASS_PHRASE=opensign
|
||||
|
||||
@@ -22,3 +22,6 @@
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
apps/OpenSign/public/mfbuild/*
|
||||
microfrontends/SignDocuments/build/*
|
||||
apps/OpenSignServer/files/files/*
|
||||
+60
-2
@@ -88,5 +88,63 @@ You can install all 3 components on digital ocean using the button below -
|
||||
|
||||
## Localhost(Docker)
|
||||
|
||||
Below are the steps to follow -
|
||||
- Execute `make build`
|
||||
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`
|
||||
|
||||
Command to run project -
|
||||
- Execute `make run`
|
||||
@@ -1,3 +1,9 @@
|
||||
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
|
||||
docker compose up -d
|
||||
@@ -48,14 +48,18 @@ Welcome to OpenSign, an open-source document e-signing solution designed to prov
|
||||
|
||||
### Features
|
||||
|
||||
- **Secure Signing**: Utilizes state-of-the-art cryptographic algorithms to ensure the security & integrity of your documents.
|
||||
- **User-Friendly Interface**: Designed with usability in mind, making it easy for both technical and non-technical users.
|
||||
- **Multi-Platform Support**: Compatible with various browsers and devices.
|
||||
- **Invite & collaborate users**: Bring multiple people from your team into the signing process, all within your own infrastructure.
|
||||
- **Secure**: Allows for the easy, secure and seamless organization of your documents using 'OpenSigDrive'.
|
||||
- **Audit Trails**: Keeps a detailed log of all activities related to the document signing process including IP addresses and access timings.
|
||||
- **Completion Certificate**: Generate secure completion certificate as soon as a document is signed by all participants.
|
||||
- **API Support**: Provides a robust API for integration into other software and services.
|
||||
- **Secure PDF E-Signing:** With the help of Robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility.
|
||||
- **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.
|
||||
- **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.
|
||||
- **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.
|
||||
- **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address.
|
||||
- **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign it. Not just this, OpenSign also allows signers to reject signing a document.
|
||||
- **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates.
|
||||
- **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/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
||||
|
||||
@@ -21,5 +21,5 @@ EXPOSE 3000
|
||||
# ENV NODE_ENV production
|
||||
|
||||
# Run the application
|
||||
CMD ["npm", "start"]
|
||||
ENTRYPOINT npm run start-dev
|
||||
|
||||
|
||||
@@ -141,6 +141,32 @@ const GoogleSignInBtn = ({
|
||||
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 (
|
||||
<div style={{ position: "relative" }}>
|
||||
{thirdpartyLoader && (
|
||||
@@ -259,16 +285,16 @@ const GoogleSignInBtn = ({
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={() => setIsModal(false)}
|
||||
className="bg-[#6c757d] p-2 text-white rounded"
|
||||
onClick={handleCloseModal}
|
||||
style={{ marginRight: 10, width: 90 }}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-[#17a2b8] p-2 text-white rounded"
|
||||
onClick={() => handleSubmitbtn()}
|
||||
className="btn btn-info"
|
||||
>
|
||||
Sign up
|
||||
</button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import useFederatedComponent from "mf-cra";
|
||||
import React, { Suspense, useEffect } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
const MicroappModal = () => {
|
||||
const { remoteApp } = useParams();
|
||||
@@ -28,60 +28,36 @@ const MicroappModal = () => {
|
||||
}
|
||||
// console.log("app ", remoteApp);
|
||||
const { Component: RemoteComponent } = useFederatedComponent(obj);
|
||||
const navigate = useNavigate();
|
||||
// console.log("RemoteComponent ", RemoteComponent);
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center ">
|
||||
{/* <!-- Modal Container --> */}
|
||||
<div className="bg-white rounded-lg shadow-lg w-full">
|
||||
{/* <!-- Modal Header --> */}
|
||||
<div className="flex w-full items-center border-b-2 mb-2 p-2">
|
||||
<button
|
||||
className="focus:outline-none bg-blue-500 text-white text-sm shadow px-2.5 py-1 rounded"
|
||||
id="closeModal"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
// setIsModal(false);
|
||||
navigate(-1);
|
||||
<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"
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
{localStorage.getItem("domain") && (
|
||||
<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>
|
||||
{RemoteComponent && <RemoteComponent />}
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
+418
-297
@@ -21,17 +21,18 @@ function Login(props) {
|
||||
passwordVisible: false,
|
||||
mobile: "",
|
||||
phone: "",
|
||||
OTP: "",
|
||||
hideNav: "",
|
||||
scanResult: "",
|
||||
baseUrl: localStorage.getItem("baseUrl"),
|
||||
parseAppId: localStorage.getItem("parseAppId"),
|
||||
loading: false,
|
||||
thirdpartyLoader: false,
|
||||
orgModal: false,
|
||||
ReqOtp: ""
|
||||
thirdpartyLoader: false
|
||||
});
|
||||
|
||||
const [userDetails, setUserDetails] = useState({
|
||||
Company: "",
|
||||
Destination: ""
|
||||
});
|
||||
const [isModal, setIsModal] = useState(false);
|
||||
const image = props?.appInfo?.applogo || undefined;
|
||||
|
||||
useEffect(() => {
|
||||
@@ -94,7 +95,6 @@ function Login(props) {
|
||||
} else {
|
||||
localStorage.setItem("profileImg", "");
|
||||
}
|
||||
|
||||
// Check extended class user role and tenentId
|
||||
try {
|
||||
let userRoles = [];
|
||||
@@ -114,44 +114,36 @@ function Login(props) {
|
||||
};
|
||||
await axios
|
||||
.post(url, JSON.stringify(body), { headers: headers })
|
||||
.then((roles) => {
|
||||
.then((axiosRes) => {
|
||||
const roles = axiosRes.data.result;
|
||||
if (roles) {
|
||||
userRoles = roles.data.result;
|
||||
userRoles = roles;
|
||||
let _currentRole = "";
|
||||
const valuesToExclude = [
|
||||
"contracts_Guest",
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
];
|
||||
if (userRoles.length > 1) {
|
||||
if (
|
||||
userRoles[0] ===
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
) {
|
||||
_currentRole = userRoles[1];
|
||||
} 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];
|
||||
const rolesfiltered = userRoles.filter(
|
||||
(x) => !valuesToExclude.includes(x)
|
||||
);
|
||||
if (rolesfiltered.length > 0) {
|
||||
_currentRole = rolesfiltered[0];
|
||||
}
|
||||
} else {
|
||||
_currentRole = userRoles[0];
|
||||
const rolesfiltered = userRoles.filter(
|
||||
(x) => !valuesToExclude.includes(x)
|
||||
);
|
||||
if (rolesfiltered.length > 0) {
|
||||
_currentRole = userRoles[0];
|
||||
} else {
|
||||
_currentRole = "";
|
||||
}
|
||||
}
|
||||
if (
|
||||
_currentRole &&
|
||||
_currentRole !==
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
) {
|
||||
userSettings.forEach(async (element) => {
|
||||
if (element.role === _currentRole) {
|
||||
@@ -178,7 +170,6 @@ function Login(props) {
|
||||
query.include("TenantId");
|
||||
await query.find().then(
|
||||
(results) => {
|
||||
// console.log("results ", results);
|
||||
let tenentInfo = [];
|
||||
if (results) {
|
||||
let extendedInfo_stringify =
|
||||
@@ -339,25 +330,27 @@ function Login(props) {
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
/* alert(
|
||||
"You dont have access to this application."
|
||||
); */
|
||||
setState({
|
||||
...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);
|
||||
const payload = {
|
||||
sessionToken: user.getSessionToken()
|
||||
};
|
||||
handleSubmitbtn(payload);
|
||||
// setState({
|
||||
// ...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
|
||||
@@ -367,45 +360,18 @@ function Login(props) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setState({
|
||||
...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);
|
||||
setState({ ...state, loading: false });
|
||||
setIsModal(true);
|
||||
}
|
||||
} else {
|
||||
setState({
|
||||
...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);
|
||||
setState({ ...state, loading: false });
|
||||
setIsModal(true);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("err", err);
|
||||
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);
|
||||
setState({ ...state, loading: false });
|
||||
setIsModal(true);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -460,7 +426,6 @@ function Login(props) {
|
||||
await Parse.User.become(sessionToken).then(() => {
|
||||
window.localStorage.setItem("accesstoken", sessionToken);
|
||||
});
|
||||
// console.log("me res ", res);
|
||||
if (res.data) {
|
||||
let _user = res.data;
|
||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||
@@ -492,25 +457,36 @@ function Login(props) {
|
||||
};
|
||||
await axios
|
||||
.post(url, JSON.stringify(body), { headers: headers })
|
||||
.then((roles) => {
|
||||
.then((axiosRes) => {
|
||||
const roles = axiosRes.data.result;
|
||||
if (roles) {
|
||||
userRoles = roles.data.result;
|
||||
userRoles = roles;
|
||||
let _currentRole = "";
|
||||
const valuesToExclude = [
|
||||
"contracts_Guest",
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
];
|
||||
if (userRoles.length > 1) {
|
||||
if (
|
||||
userRoles[0] ===
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
) {
|
||||
_currentRole = userRoles[1];
|
||||
} else {
|
||||
_currentRole = userRoles[0];
|
||||
const rolesfiltered = userRoles.filter(
|
||||
(x) => !valuesToExclude.includes(x)
|
||||
);
|
||||
if (rolesfiltered.length > 0) {
|
||||
_currentRole = rolesfiltered[0];
|
||||
}
|
||||
} else {
|
||||
_currentRole = userRoles[0];
|
||||
const rolesfiltered = userRoles.filter(
|
||||
(x) => !valuesToExclude.includes(x)
|
||||
);
|
||||
if (rolesfiltered.length > 0) {
|
||||
_currentRole = userRoles[0];
|
||||
} else {
|
||||
_currentRole = "";
|
||||
}
|
||||
}
|
||||
if (
|
||||
_currentRole &&
|
||||
_currentRole !==
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
`${localStorage.getItem("_appName")}_appeditor`
|
||||
) {
|
||||
userSettings.forEach(async (element) => {
|
||||
if (element.role === _currentRole) {
|
||||
@@ -581,7 +557,7 @@ function Login(props) {
|
||||
);
|
||||
setThirdpartyLoader(false);
|
||||
setState({ ...state, loading: false });
|
||||
navigate(`/`);
|
||||
navigate("/");
|
||||
} else {
|
||||
extendedInfo.forEach((x) => {
|
||||
if (x.TenantId) {
|
||||
@@ -619,6 +595,7 @@ function Login(props) {
|
||||
);
|
||||
setThirdpartyLoader(false);
|
||||
setState({ ...state, loading: false });
|
||||
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||
if (billingDate) {
|
||||
if (billingDate > new Date()) {
|
||||
localStorage.removeItem("userDetails");
|
||||
@@ -632,6 +609,7 @@ function Login(props) {
|
||||
navigate(`/subscription`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
localStorage.setItem("PageLanding", element.pageId);
|
||||
localStorage.setItem(
|
||||
@@ -641,6 +619,7 @@ function Login(props) {
|
||||
localStorage.setItem("pageType", element.pageType);
|
||||
setState({ ...state, loading: false });
|
||||
setThirdpartyLoader(false);
|
||||
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||
if (billingDate) {
|
||||
if (billingDate > new Date()) {
|
||||
localStorage.removeItem("userDetails");
|
||||
@@ -654,27 +633,16 @@ function Login(props) {
|
||||
navigate(`/subscription`);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
/* alert(
|
||||
"You dont have access to this application."
|
||||
); */
|
||||
const payload = {
|
||||
sessionToken: sessionToken
|
||||
};
|
||||
setThirdpartyLoader(false);
|
||||
handleSubmitbtn(payload);
|
||||
|
||||
setState({
|
||||
...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);
|
||||
// localStorage.setItem("accesstoken", null);
|
||||
console.error("Error while fetching Follow", error);
|
||||
}
|
||||
);
|
||||
@@ -682,47 +650,17 @@ function Login(props) {
|
||||
});
|
||||
} else {
|
||||
setThirdpartyLoader(false);
|
||||
setState({
|
||||
...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);
|
||||
setState({ ...state, loading: false });
|
||||
}
|
||||
} else {
|
||||
setThirdpartyLoader(false);
|
||||
setState({
|
||||
...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);
|
||||
setState({ ...state, loading: false });
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((err) => {
|
||||
console.log("err", err);
|
||||
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);
|
||||
setState({ ...state, loading: false });
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -744,7 +682,7 @@ function Login(props) {
|
||||
};
|
||||
|
||||
const GetLoginData = async () => {
|
||||
setState({ ...state, loading: true })
|
||||
setState({ ...state, loading: true });
|
||||
try {
|
||||
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||
@@ -920,6 +858,80 @@ function Login(props) {
|
||||
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 (
|
||||
<div className="bg-white">
|
||||
<Title title={"Login Page"} />
|
||||
@@ -944,7 +956,7 @@ function Login(props) {
|
||||
color: "#3ac9d6",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: 'translate(-50%, -50%)'
|
||||
transform: "translate(-50%, -50%)"
|
||||
}}
|
||||
className="loader-37"
|
||||
>
|
||||
@@ -953,132 +965,145 @@ function Login(props) {
|
||||
</div>
|
||||
)}
|
||||
{props.isloginVisible && props.isloginVisible ? (
|
||||
<div aria-labelledby="loginHeading" role="region">
|
||||
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
||||
<div className="w-[250px] h-[66px] inline-block">
|
||||
{state.hideNav ? (
|
||||
<img src={image} 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." />
|
||||
) : (
|
||||
<img src={image} 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 aria-labelledby="loginHeading" role="region">
|
||||
<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 ">
|
||||
<div className="w-[250px] h-[66px] inline-block">
|
||||
<img
|
||||
src={image}
|
||||
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>
|
||||
<form onSubmit={handleSubmit} aria-label="Login Form">
|
||||
<h1 className="text-[30px] mt-6">Welcome Back!</h1>
|
||||
<fieldset className="outline outline-1 outline-slate-300/50 my-4">
|
||||
<legend className="text-xs font-bold px-6 mt-4">Login to your account</legend>
|
||||
<div className="px-6 py-4">
|
||||
<label className="block text-xs" htmlFor="email">Username</label>
|
||||
<input
|
||||
id="email"
|
||||
type="text"
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded text-xs"
|
||||
name="email"
|
||||
value={state.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
<hr className="my-2 border-none" />
|
||||
<label className="block text-xs" htmlFor="password">Password</label>
|
||||
<div className="relative">
|
||||
<div>
|
||||
<form onSubmit={handleSubmit} aria-label="Login Form">
|
||||
<h1 className="text-[30px] mt-6">Welcome Back!</h1>
|
||||
<fieldset>
|
||||
<legend className="text-[12px] text-[#878787]">
|
||||
Login to your account
|
||||
</legend>
|
||||
<div className="px-6 py-4 outline outline-1 outline-slate-300/50 my-2 rounded shadow-md">
|
||||
<label className="block text-xs" htmlFor="email">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
type={state.passwordVisible ? "text" : "password"}
|
||||
id="email"
|
||||
type="text"
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded text-xs"
|
||||
name="password"
|
||||
value={state.password}
|
||||
name="email"
|
||||
value={state.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
<span
|
||||
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer ${state.passwordVisible
|
||||
? "text-[#007bff]"
|
||||
: "text-black"
|
||||
<hr className="my-2 border-none" />
|
||||
<label className="block text-xs" htmlFor="password">
|
||||
Password
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
id="password"
|
||||
type={state.passwordVisible ? "text" : "password"}
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded text-xs"
|
||||
name="password"
|
||||
value={state.password}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
<span
|
||||
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer ${
|
||||
state.passwordVisible
|
||||
? "text-[#007bff]"
|
||||
: "text-black"
|
||||
}`}
|
||||
onClick={togglePasswordVisibility}
|
||||
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>
|
||||
</fieldset>
|
||||
<div className="flex flex-row justify-between items-center ml-4 py-2">
|
||||
<div>
|
||||
<label
|
||||
className="form-check-label inline-block cursor-pointer"
|
||||
htmlFor="rememberpassword"
|
||||
>
|
||||
{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>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input mr-1"
|
||||
value=""
|
||||
id="rememberpassword"
|
||||
/>
|
||||
<span className="text-[13px]">
|
||||
Remember Password
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<NavLink
|
||||
to="/forgetpassword"
|
||||
className="text-[13px] underline focus:outline-none focus:ring-2 focus:ring-blue-600"
|
||||
>
|
||||
Forgot Password ?
|
||||
</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div className="flex flex-row justify-between items-center px-4 py-2">
|
||||
<div>
|
||||
<label className="form-check-label inline-block cursor-pointer" htmlFor="rememberpassword">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input mr-2"
|
||||
value=""
|
||||
id="rememberpassword"
|
||||
/>
|
||||
<span className="text-[13px] pl-1">Remember Password</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<NavLink
|
||||
to="/forgetpassword"
|
||||
className="text-[13px] underline focus:outline-none focus:ring-2 focus:ring-blue-600"
|
||||
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-sm bg-[#3ac9d6] text-white w-full py-3 shadow outline-none uppercase focus:ring-2 focus:ring-blue-600"
|
||||
disabled={state.loading}
|
||||
>
|
||||
Forgot Password?
|
||||
{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>
|
||||
</div>
|
||||
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-sm bg-[#3ac9d6] text-white w-full py-3 shadow outline-none uppercase focus:ring-2 focus:ring-blue-600"
|
||||
disabled={state.loading}
|
||||
</form>
|
||||
<br />
|
||||
{(props.appInfo.fbAppId || props.appInfo.googleClietId) && (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
className="text-sm"
|
||||
>
|
||||
{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) && (
|
||||
<hr
|
||||
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"
|
||||
}}
|
||||
className="text-sm"
|
||||
>
|
||||
<hr
|
||||
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 !== "" ? (
|
||||
{/* {props.appInfo.fbAppId && props.appInfo.fbAppId !== "" ? (
|
||||
<LoginFacebook
|
||||
FBCred={props.appInfo.fbAppId}
|
||||
thirdpartyLoginfn={thirdpartyLoginfn}
|
||||
@@ -1086,46 +1111,143 @@ function Login(props) {
|
||||
setThirdpartyLoader={setThirdpartyLoader}
|
||||
/>
|
||||
) : null} */}
|
||||
</div>
|
||||
<div style={{ margin: "10px 0" }}></div>
|
||||
<div
|
||||
style={{
|
||||
textAlign: "center",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
{props.appInfo.googleClietId &&
|
||||
</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}
|
||||
<GoogleSignInBtn
|
||||
GoogleCred={props.appInfo.googleClietId}
|
||||
thirdpartyLoginfn={thirdpartyLoginfn}
|
||||
thirdpartyLoader={state.thirdpartyLoader}
|
||||
setThirdpartyLoader={setThirdpartyLoader}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!state.hideNav && (
|
||||
<div className="self-center">
|
||||
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
||||
<img
|
||||
src={login_img}
|
||||
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%"
|
||||
/>
|
||||
) : 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>
|
||||
{!state.hideNav && (
|
||||
<div className="self-center">
|
||||
<div className="mx-auto md:w-[300px] lg:w-[500px]">
|
||||
<img src={login_img} 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%" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="snackbar"
|
||||
role="alert"
|
||||
style={{ backgroundColor: state.toastColor }}
|
||||
>
|
||||
{state.toastDescription}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
@@ -1140,7 +1262,6 @@ function Login(props) {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
// }
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
|
||||
@@ -28,7 +28,7 @@ const PlanSubscriptions = () => {
|
||||
: "";
|
||||
const phone =
|
||||
userDetails && userDetails.phone ? "&mobile=" + userDetails.phone : "";
|
||||
const details = "?" + name + email + company + phone;
|
||||
const details = "?shipping_country_code=US&" + name + email + company + phone;
|
||||
useEffect(() => {
|
||||
if (localStorage.getItem("accesstoken")) {
|
||||
setIsLoader(false);
|
||||
|
||||
@@ -99,9 +99,38 @@ const Signup = (props) => {
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
alert(err.message);
|
||||
setState({ loading: false });
|
||||
.catch(async (err) => {
|
||||
if (err.code === 202) {
|
||||
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) {
|
||||
console.log("err ", error);
|
||||
@@ -453,7 +482,7 @@ const Signup = (props) => {
|
||||
<div className="">
|
||||
<form onSubmit={handleSubmit}>
|
||||
<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">
|
||||
<label className="block ">
|
||||
Name{" "}
|
||||
@@ -472,6 +501,7 @@ const Signup = (props) => {
|
||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="text"
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
value={email}
|
||||
@@ -563,7 +593,7 @@ const Signup = (props) => {
|
||||
</div>
|
||||
{!state.hideNav && (
|
||||
<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%" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,12 @@ import multerS3 from 'multer-s3';
|
||||
import aws from 'aws-sdk';
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
function sanitizeFileName(fileName) {
|
||||
// Remove spaces and invalid characters
|
||||
return fileName.replace(/[^a-zA-Z0-9._-]/g, '');
|
||||
}
|
||||
|
||||
async function uploadFile(req, res) {
|
||||
try {
|
||||
//--size extended to 100 mb
|
||||
@@ -50,16 +56,28 @@ async function uploadFile(req, res) {
|
||||
region: process.env.DO_REGION,
|
||||
});
|
||||
|
||||
// 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);
|
||||
const parseBaseUrl = process.env.SERVER_URL;
|
||||
const parseAppId = process.env.APP_ID;
|
||||
|
||||
if (process.env.USE_LOCAL == "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!');
|
||||
},
|
||||
storage: multerS3({
|
||||
});
|
||||
} else {
|
||||
var fileStorage = multerS3({
|
||||
acl: 'public-read',
|
||||
s3,
|
||||
bucket: DO_SPACE,
|
||||
@@ -69,14 +87,25 @@ async function uploadFile(req, res) {
|
||||
key: function (req, file, cb) {
|
||||
//console.log(file);
|
||||
let filename = file.originalname;
|
||||
let filenam = filename.split('.')[0];
|
||||
let newFileName = filename.split('.')[0];
|
||||
let extension = filename.split('.')[1];
|
||||
filenam = filenam + '_' + new Date().toISOString() + '.' + extension;
|
||||
console.log(filenam);
|
||||
cb(null, filenam);
|
||||
},
|
||||
}),
|
||||
newFileName = sanitizeFileName(newFileName + '_' + new Date().toISOString() + '.' + extension)
|
||||
console.log(newFileName);
|
||||
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 },
|
||||
}).single('file');
|
||||
|
||||
@@ -93,7 +122,14 @@ async function uploadFile(req, res) {
|
||||
const status = 'Success';
|
||||
//res.header("Access-Control-Allow-Headers", "Content-Type");
|
||||
//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) {
|
||||
console.log('Exeption in query ' + err.stack);
|
||||
|
||||
@@ -123,6 +123,9 @@ export default async function (request) {
|
||||
if (userDetails && userDetails.company) {
|
||||
newObj.set("Company", userDetails.company);
|
||||
}
|
||||
if (userDetails && userDetails.jobTitle) {
|
||||
newObj.set("JobTitle", userDetails.jobTitle);
|
||||
}
|
||||
if (planDetails && planDetails.customer_id) {
|
||||
newObj.set("Next_billing_date", new Date(planDetails.nextBillingDate));
|
||||
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.
+8
-2
@@ -99,7 +99,7 @@ function PdfFileComponent({
|
||||
|
||||
//function for navigate user to microapp-signature component
|
||||
const checkPdfStatus = async (data) => {
|
||||
|
||||
|
||||
const hostUrl = getHostUrl();
|
||||
const expireDate = data.ExpiryDate.iso;
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
@@ -221,13 +221,19 @@ function PdfFileComponent({
|
||||
// console.log("download")
|
||||
const pdfName = data && data.Name;
|
||||
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") {
|
||||
// console.log("rename")
|
||||
setRenameValue(data.Name);
|
||||
setRename(data.objectId);
|
||||
}
|
||||
};
|
||||
|
||||
const sanitizeFileName = (pdfName) => {
|
||||
// Replace spaces with underscore
|
||||
return pdfName.replace(/ /g, '_');
|
||||
}
|
||||
|
||||
const handleEnterPress = (e, data) => {
|
||||
if (e.key === "Enter") {
|
||||
handledRenameDoc(data);
|
||||
|
||||
@@ -11,15 +11,13 @@ import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { useParams } from "react-router-dom";
|
||||
import SignPad from "./component/signPad";
|
||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||
import {
|
||||
getBase64FromIMG,
|
||||
getBase64FromUrl
|
||||
} from "../utils/Utils";
|
||||
import { getBase64FromIMG, getBase64FromUrl } from "../utils/Utils";
|
||||
import Loader from "./component/loader";
|
||||
import HandleError from "./component/HandleError";
|
||||
import Nodata from "./component/Nodata";
|
||||
import Header from "./component/header";
|
||||
import RenderPdf from "./component/renderPdf";
|
||||
import CustomModal from "./component/CustomModal";
|
||||
|
||||
function PdfRequestFiles() {
|
||||
const { docId } = useParams();
|
||||
@@ -64,7 +62,8 @@ function PdfRequestFiles() {
|
||||
const [isSigned, setIsSigned] = useState(false);
|
||||
const [isExpired, setIsExpired] = useState(false);
|
||||
const [alreadySign, setAlreadySign] = useState(false);
|
||||
|
||||
const [containerWH, setContainerWH] = useState({});
|
||||
const divRef = useRef(null);
|
||||
const rowLevel =
|
||||
localStorage.getItem("rowlevel") &&
|
||||
JSON.parse(localStorage.getItem("rowlevel"));
|
||||
@@ -96,6 +95,14 @@ function PdfRequestFiles() {
|
||||
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
|
||||
const getDocumentDetails = async () => {
|
||||
@@ -191,7 +198,7 @@ function PdfRequestFiles() {
|
||||
//comparison auditTrail user details with signers user details
|
||||
for (let i = 0; i < signerRes.length; i++) {
|
||||
const signerId = signerRes[i].objectId;
|
||||
|
||||
|
||||
let isSigned = false;
|
||||
for (let j = 0; j < checkDocIdExist.length; j++) {
|
||||
const signedExist =
|
||||
@@ -912,6 +919,7 @@ function PdfRequestFiles() {
|
||||
|
||||
//function for set decline true on press decline button
|
||||
const declineDoc = async () => {
|
||||
setIsDecline({ isDeclined: false });
|
||||
const data = {
|
||||
IsDeclined: true
|
||||
};
|
||||
@@ -983,7 +991,39 @@ function PdfRequestFiles() {
|
||||
</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 */}
|
||||
<RenderAllPdfPage
|
||||
signPdfUrl={pdfDetails[0].URL}
|
||||
@@ -999,66 +1039,6 @@ function PdfRequestFiles() {
|
||||
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 */}
|
||||
|
||||
<Modal show={isCompleted.isModal}>
|
||||
|
||||
@@ -500,7 +500,6 @@ function SignYourSelf() {
|
||||
removeBase64Fromjpeg,
|
||||
""
|
||||
);
|
||||
|
||||
//function for call to embed signature in pdf and get digital signature pdf
|
||||
signPdfFun(newImgUrl, documentId, data, pdfBase64, pageNo);
|
||||
})
|
||||
@@ -575,14 +574,18 @@ function SignYourSelf() {
|
||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||
|
||||
const posY = () => {
|
||||
if (id === 0) {
|
||||
return (
|
||||
page.getHeight() -
|
||||
imgUrlList[id].yPosition * scale -
|
||||
imgHeight
|
||||
);
|
||||
} else if (id > 0) {
|
||||
return page.getHeight() - imgUrlList[id].yPosition * scale;
|
||||
if (isMobile) {
|
||||
if (id === 0) {
|
||||
return (
|
||||
page.getHeight() -
|
||||
imgUrlList[id].yPosition * scale -
|
||||
imgHeight
|
||||
);
|
||||
} else if (id > 0) {
|
||||
return page.getHeight() - imgUrlList[id].yPosition * scale;
|
||||
}
|
||||
} else {
|
||||
return page.getHeight() - imgUrlList[id].yPosition - imgHeight;
|
||||
}
|
||||
};
|
||||
page.drawImage(img, {
|
||||
@@ -596,7 +599,6 @@ function SignYourSelf() {
|
||||
});
|
||||
}
|
||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||
|
||||
signPdfFun(pdfBytes, documentId);
|
||||
}
|
||||
setIsSignPad(false);
|
||||
@@ -615,10 +617,11 @@ function SignYourSelf() {
|
||||
pageNo
|
||||
) => {
|
||||
let singleSign;
|
||||
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = window.innerWidth;
|
||||
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) {
|
||||
const height = xyPosData.Height ? xyPosData.Height : 60;
|
||||
const bottomY = xyPosData.isDrag
|
||||
@@ -1115,6 +1118,8 @@ function SignYourSelf() {
|
||||
pdfDetails={pdfDetails}
|
||||
isShowHeader={true}
|
||||
currentSigner={true}
|
||||
alreadySign={pdfUrl ? true : false}
|
||||
isSignYourself={true}
|
||||
/>
|
||||
|
||||
{/* 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 axios from "axios";
|
||||
import React from "react";
|
||||
|
||||
|
||||
function DefaultSignature({
|
||||
themeColor,
|
||||
|
||||
@@ -26,11 +26,11 @@ function EmailComponent({
|
||||
//function for send email
|
||||
const sendEmail = async () => {
|
||||
setIsLoading(true);
|
||||
let sendMail, recipent;
|
||||
let sendMail;
|
||||
for (let i = 0; i < emailCount.length; i++) {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
|
||||
const imgPng =
|
||||
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
||||
// "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png";
|
||||
@@ -41,7 +41,7 @@ function EmailComponent({
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
|
||||
|
||||
const themeBGcolor = themeColor();
|
||||
let params = {
|
||||
pdfName: pdfName,
|
||||
@@ -125,12 +125,17 @@ function EmailComponent({
|
||||
|
||||
//handle download signed pdf
|
||||
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);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* isEmail */}
|
||||
@@ -248,13 +253,13 @@ function EmailComponent({
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
|
||||
|
||||
flexWrap: "wrap"
|
||||
}}
|
||||
>
|
||||
{emailCount.map((data, ind) => {
|
||||
return (
|
||||
<div className="emailChip"
|
||||
<div className="emailChip"
|
||||
style={{display:"flex", flexDirection:"row", alignItems:"center"}}
|
||||
key={ind}>
|
||||
<span
|
||||
|
||||
@@ -37,7 +37,7 @@ function Header({
|
||||
}) {
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const navigate = useNavigate();
|
||||
|
||||
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||
//for go to previous page
|
||||
function previousPage() {
|
||||
changePage(-1);
|
||||
@@ -76,19 +76,27 @@ function Header({
|
||||
const handleDownloadPdf = () => {
|
||||
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 (
|
||||
<div
|
||||
style={{ paddingBottom: "5px", paddingTop: "5px" }}
|
||||
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
|
||||
className="mobileHead"
|
||||
>
|
||||
{isMobile && isShowHeader ? (
|
||||
<div
|
||||
id="navbar"
|
||||
className="stickyHead"
|
||||
style={{ width: window.innerWidth - 30 + "px" }}
|
||||
className={isGuestSigner ? "stickySignerHead" : "stickyHead"}
|
||||
style={{
|
||||
width: isGuestSigner ? window.innerWidth : window.innerWidth - 30 + "px"
|
||||
}}
|
||||
>
|
||||
<div className="preBtn2">
|
||||
<div
|
||||
@@ -215,7 +223,7 @@ function Header({
|
||||
</DropdownMenu.Root>
|
||||
) : (
|
||||
<div style={{ display: "flex", justifyContent: "space-around" }}>
|
||||
{/* current signer is checking user send request and check status of pdf sign than if current
|
||||
{/* current signer is checking user send request and check status of pdf sign than if current
|
||||
user exist than show finish button else no
|
||||
*/}
|
||||
{currentSigner && (
|
||||
|
||||
@@ -42,8 +42,42 @@ function RenderPdf({
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = window.innerWidth;
|
||||
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 checkSign = signedSigners.filter(
|
||||
(sign) => sign.objectId === data.signerObjId
|
||||
@@ -56,7 +90,7 @@ function RenderPdf({
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
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
|
||||
else {
|
||||
@@ -134,8 +168,8 @@ function RenderPdf({
|
||||
borderWidth: "0.2px"
|
||||
}}
|
||||
size={{
|
||||
width: pos.Width ? pos.Width : 150,
|
||||
height: pos.Height ? pos.Height : 60
|
||||
width: posWidth(pos),
|
||||
height: posHeight(pos)
|
||||
}}
|
||||
lockAspectRatio={pos.Width && 2.5}
|
||||
default={{
|
||||
@@ -205,8 +239,8 @@ function RenderPdf({
|
||||
y: yPos(pos)
|
||||
}}
|
||||
size={{
|
||||
width: pos.Width ? pos.Width : 150,
|
||||
height: pos.Height ? pos.Height : 60
|
||||
width: posWidth(pos),
|
||||
height: posHeight(pos)
|
||||
}}
|
||||
lockAspectRatio={pos.Width ? pos.Width / pos.Height : 2.5}
|
||||
>
|
||||
@@ -235,7 +269,8 @@ function RenderPdf({
|
||||
{isMobile && scale ? (
|
||||
<div
|
||||
style={{
|
||||
border: "0.1px solid #ebe8e8"
|
||||
border: "0.1px solid #ebe8e8",
|
||||
marginTop: isGuestSigner && "30px"
|
||||
}}
|
||||
ref={drop}
|
||||
id="container"
|
||||
@@ -294,12 +329,11 @@ function RenderPdf({
|
||||
borderWidth: "0.2px"
|
||||
}}
|
||||
size={{
|
||||
width: pos.Width ? pos.Width : 150,
|
||||
height: pos.Height ? pos.Height : 60
|
||||
width: posWidth(pos),
|
||||
height: posHeight(pos)
|
||||
}}
|
||||
lockAspectRatio={pos.Width && 2.5}
|
||||
//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
|
||||
default={{
|
||||
x: !pos.isMobile
|
||||
@@ -361,14 +395,13 @@ function RenderPdf({
|
||||
borderWidth: "0.2px"
|
||||
}}
|
||||
size={{
|
||||
width: pos.Width ? pos.Width : 150,
|
||||
height: pos.Height ? pos.Height : 60
|
||||
width: posWidth(pos),
|
||||
height: posHeight(pos)
|
||||
}}
|
||||
disableDragging={true}
|
||||
default={{
|
||||
//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
|
||||
|
||||
x: !pos.isMobile
|
||||
? pos.xPosition / scale
|
||||
: pos.xPosition * (pos.scale / scale) - 50,
|
||||
@@ -1281,4 +1314,4 @@ function RenderPdf({
|
||||
);
|
||||
}
|
||||
|
||||
export default RenderPdf;
|
||||
export default RenderPdf;
|
||||
@@ -38,19 +38,15 @@ function Login() {
|
||||
|
||||
const handleChange = (event) => {
|
||||
const { value } = event.target;
|
||||
|
||||
setOTP(value);
|
||||
};
|
||||
|
||||
//send email OTP function
|
||||
|
||||
const SendOtp = async (e) => {
|
||||
const serverUrl =
|
||||
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
||||
|
||||
const parseId =
|
||||
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
||||
|
||||
if (serverUrl && localStorage) {
|
||||
setLoading(true);
|
||||
e.preventDefault();
|
||||
@@ -84,13 +80,10 @@ function Login() {
|
||||
e.preventDefault();
|
||||
const serverUrl =
|
||||
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
||||
|
||||
const parseId =
|
||||
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
||||
|
||||
if (OTP) {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
let url = `${serverUrl}functions/AuthLoginAsMail/`;
|
||||
const headers = {
|
||||
@@ -102,7 +95,6 @@ function Login() {
|
||||
otp: OTP
|
||||
};
|
||||
let user = await axios.post(url, body, { headers: headers });
|
||||
|
||||
if (user.data.result === "Invalid Otp") {
|
||||
alert("Invalid Otp");
|
||||
setLoading(false);
|
||||
@@ -114,10 +106,12 @@ function Login() {
|
||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||
localStorage.setItem("username", _user.name);
|
||||
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||
//save isGuestSigner true in local to handle login flow header in mobile view
|
||||
localStorage.setItem("isGuestSigner", true);
|
||||
setLoading(false);
|
||||
//navigate user to on signature page
|
||||
// navigate(`/recipientSignPdf/${id}/${contactBookId}`);
|
||||
navigate(`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`);
|
||||
navigate(
|
||||
`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`
|
||||
);
|
||||
}
|
||||
} catch (error) {}
|
||||
} else {
|
||||
@@ -173,9 +167,7 @@ function Login() {
|
||||
<span className="KNLO">
|
||||
Verification code is sent to your email
|
||||
</span>
|
||||
<div className="card card-box"
|
||||
style={{borderRadius:"0px"}}
|
||||
>
|
||||
<div className="card card-box" style={{ borderRadius: "0px" }}>
|
||||
<div className="card-body">
|
||||
<input
|
||||
type="email"
|
||||
@@ -190,7 +182,6 @@ function Login() {
|
||||
<div className="btnContainer">
|
||||
{loading ? (
|
||||
<button
|
||||
// className="btn btn-info loadinBtn "
|
||||
type="button"
|
||||
style={{
|
||||
background: themeColor(),
|
||||
@@ -214,15 +205,7 @@ function Login() {
|
||||
color: "white",
|
||||
marginLeft: "0px !important"
|
||||
}}
|
||||
// className="btn btn-sm otpButton"
|
||||
onClick={(e) => SendOtp(e)}
|
||||
// style={{
|
||||
// marginBottom: "4px",
|
||||
// width: "210px",
|
||||
// background: themeColor(),
|
||||
// color: "white",
|
||||
// fontWeight: "600"
|
||||
// }}
|
||||
>
|
||||
Send OTP
|
||||
</button>
|
||||
|
||||
@@ -952,7 +952,7 @@ function PlaceHolderSign() {
|
||||
background: themeColor()
|
||||
}}
|
||||
>
|
||||
<span style={{ color: "white" }}>Send Mail </span>
|
||||
<span style={{ color: "white" }}>Mails Sent</span>
|
||||
</Modal.Header>
|
||||
|
||||
{/* signature modal */}
|
||||
|
||||
@@ -23,8 +23,8 @@ import Loader from "./component/loader";
|
||||
import HandleError from "./component/HandleError";
|
||||
import Nodata from "./component/Nodata";
|
||||
import Header from "./component/header";
|
||||
import ModalComponent from "./component/modalComponent";
|
||||
import RenderPdf from "./component/renderPdf";
|
||||
import CustomModal from "./component/CustomModal";
|
||||
function EmbedPdfImage() {
|
||||
const { id, contactBookId } = useParams();
|
||||
const [isSignPad, setIsSignPad] = useState(false);
|
||||
@@ -67,13 +67,15 @@ function EmbedPdfImage() {
|
||||
status: false,
|
||||
type: "load"
|
||||
});
|
||||
|
||||
const [containerWH, setContainerWH] = useState({});
|
||||
const docId = id && id;
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const index = xyPostion.findIndex((object) => {
|
||||
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(() => {
|
||||
const clientWidth = window.innerWidth;
|
||||
const pdfWidth = clientWidth - 160 - 220 - 30;
|
||||
@@ -82,6 +84,14 @@ function EmbedPdfImage() {
|
||||
setPdfNewWidth(pdfWidth);
|
||||
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
|
||||
const getDocumentDetails = async () => {
|
||||
@@ -952,7 +962,37 @@ function EmbedPdfImage() {
|
||||
) : 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 */}
|
||||
{pdfLoadFail.status &&
|
||||
!isExpired &&
|
||||
@@ -971,61 +1011,10 @@ function EmbedPdfImage() {
|
||||
{/* pdf render view */}
|
||||
<div
|
||||
style={{
|
||||
marginLeft: pdfOriginalWidth > 500 && "20px",
|
||||
marginRight: pdfOriginalWidth > 500 && "20px"
|
||||
marginLeft: !isGuestSigner && 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 */}
|
||||
<Modal show={isAlreadySign.status}>
|
||||
<ModalHeader style={{ background: themeColor() }}>
|
||||
@@ -1138,9 +1127,9 @@ function EmbedPdfImage() {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{/* ndD5gdaxqw */}
|
||||
|
||||
</DndProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default EmbedPdfImage;
|
||||
export default EmbedPdfImage;
|
||||
@@ -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
@@ -57,37 +57,41 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
||||
(data, ind) =>
|
||||
data.key === signKey && data.Width && data.Height && data.SignUrl
|
||||
);
|
||||
|
||||
|
||||
if (updateFilter.length > 0) {
|
||||
let newWidth, nweHeight;
|
||||
let newWidth, newHeight;
|
||||
const aspectRatio = imgWH.width / imgWH.height;
|
||||
|
||||
const getXYdata = xyPostion[index].pos;
|
||||
|
||||
|
||||
if (aspectRatio === 1) {
|
||||
newWidth = aspectRatio * 100;
|
||||
nweHeight = aspectRatio * 100;
|
||||
newHeight = aspectRatio * 100;
|
||||
} else if (aspectRatio < 2) {
|
||||
newWidth = aspectRatio * 100;
|
||||
nweHeight = 100;
|
||||
newHeight = 100;
|
||||
} else if (aspectRatio > 2 && aspectRatio < 4) {
|
||||
newWidth = aspectRatio * 70;
|
||||
nweHeight = 70;
|
||||
newHeight = 70;
|
||||
} else if (aspectRatio > 4) {
|
||||
newWidth = aspectRatio * 40;
|
||||
nweHeight = 40;
|
||||
newHeight = 40;
|
||||
} else if (aspectRatio > 5) {
|
||||
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) => {
|
||||
if (url.key === signKey) {
|
||||
return {
|
||||
...url,
|
||||
Width: getPosData[0].Width ? getPosData[0].Width : 150,
|
||||
Height: getPosData[0].Height ? getPosData[0].Height : 60,
|
||||
Width: getPosData[0].Width ? getPosData[0].Width : newWidth,
|
||||
Height: getPosData[0].Height ? getPosData[0].Height : newHeight,
|
||||
SignUrl: image.src,
|
||||
ImageType: image.imgType
|
||||
};
|
||||
@@ -106,7 +110,9 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
||||
} else {
|
||||
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;
|
||||
|
||||
let newWidth, newHeight;
|
||||
@@ -131,9 +137,9 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
||||
if (url.key === signKey) {
|
||||
return {
|
||||
...url,
|
||||
Width: getPosData[0].Width ? getPosData[0].Width : 150,
|
||||
Height: getPosData[0].Height ? getPosData[0].Height : 60,
|
||||
SignUrl: image.src,
|
||||
Width: getPosData[0].Width ? getPosData[0].Width : newWidth,
|
||||
Height: getPosData[0].Height ? getPosData[0].Height : newHeight,
|
||||
SignUrl: image.src,
|
||||
ImageType: image.imgType
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user