Merge pull request #473 from OpenSignLabs/staging

v1.3.0-beta
This commit is contained in:
Amol
2024-03-08 20:34:25 +05:30
committed by GitHub
177 changed files with 13584 additions and 31779 deletions
+3 -4
View File
@@ -1,6 +1,5 @@
# Frontend config ************************************************************************************************************************************************************************************************
# Set CI to false while running the app locally
CI=false
# Set it to the URL form where the app home page will be accessed
PUBLIC_URL=https://app.opensignlabs.com/
# Set it to true if you want to generate the Sourcemap for debugging
@@ -8,13 +7,13 @@ GENERATE_SOURCEMAP=false
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
REACT_APP_SERVERURL=https://app.opensignlabs.com/api/app
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
REACT_APP_APPID=aDsADsqweqwe
REACT_APP_APPID=opensign
# Google tag manager container id for configuring GTM on all pages of the app
REACT_APP_GTM=GTM-123N7LD
# Backend ExpressJS config ****************************************************************************************************************************************************************************************
# A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App.
APP_ID=aDsADsqweqwe
APP_ID=opensign
# Name of the app. It will be visible in the verification emails sent out.
appName=open_sign_server
# A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database.
+1 -3
View File
@@ -2,8 +2,6 @@
# When used as it is, this env config will connect to our hosted UAT backend
# Note that any data in staging will get cleared from time to time and you may have to sign up again and again
# Set CI to false while running the app locally
CI=false
# Set it to the URL form where the app home page will be accessed
PUBLIC_URL=http://localhost:3000
# Set it to true if you want to generate the Sourcemap for debugging
@@ -11,4 +9,4 @@ GENERATE_SOURCEMAP=false
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
REACT_APP_SERVERURL=https://staging-app.opensignlabs.com/api/app
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
REACT_APP_APPID=opensignstgn
REACT_APP_APPID=opensign
+2 -4
View File
@@ -2,8 +2,6 @@
# When used as it is, this env config will connect to our hosted UAT backend
# Note that any data in staging will get cleared from time to time and you may have to sign up again and again
# Set CI to false while running the app locally
CI=false
# Set it to the URL form where the app home page will be accessed
PUBLIC_URL=http://localhost:3000
# Set it to true if you want to generate the Sourcemap for debugging
@@ -11,12 +9,12 @@ GENERATE_SOURCEMAP=false
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
REACT_APP_SERVERURL=http://localhost:8080/app
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
REACT_APP_APPID=opensignstgn
REACT_APP_APPID=opensign
# Backend ExpressJS config ****************************************************************************************************************************************************************************************
# A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App.
APP_ID=opensignstgn
APP_ID=opensign
# Name of the app. It will be visible in the verification emails sent out.
appName=open_sign_server
# A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database.
+1 -2
View File
@@ -1,7 +1,6 @@
build:
cp .env.local_dev .env
rm -rf apps/OpenSign/public/mfbuild
cd microfrontends/SignDocuments && npm install && npm run build
cd apps/OpenSign && npm install && npm run build
docker compose up --build --force-recreate
run:
-1
View File
@@ -12,7 +12,6 @@ RUN npm install
# Copy the current directory contents into the container
COPY apps/OpenSign/ .
COPY microfrontends/ .
COPY apps/OpenSign/.husky .
# Make port 3000 available to the world outside this container
-25
View File
@@ -1,25 +0,0 @@
const { dependencies } = require("./package.json");
module.exports = {
name: "shell_app", // change me
filename: "remoteEntry.js",
exposes: {},
remotes: {},
shared: {
...dependencies,
react: {
singleton: true,
import: "react", // fallback is also react
shareScope: "default",
requiredVersion: dependencies.react
},
"react-dom": {
singleton: true,
requiredVersion: dependencies["react-dom"]
},
"react-router-dom": {
singleton: true,
requiredVersion: dependencies["react-router-dom"]
}
}
};
+2860 -158
View File
File diff suppressed because it is too large Load Diff
+22 -12
View File
@@ -3,46 +3,56 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@reduxjs/toolkit": "^1.9.7",
"@radix-ui/themes": "^2.0.3",
"@react-pdf/renderer": "^3.3.8",
"@reduxjs/toolkit": "^2.2.1",
"axios": "^1.6.0",
"daisyui": "^3.9.2",
"file-saver": "^2.0.5",
"html-react-parser": "^4.2.2",
"json-rules-engine-simplified": "^0.1.17",
"jwt-decode": "^4.0.0",
"mf-cra": "^0.0.5",
"moment": "^2.29.4",
"parse": "^4.3.1",
"pdf-lib": "^1.17.1",
"print-js": "^1.6.0",
"radix-ui": "^1.0.1",
"react": "^18.2.0",
"react-bootstrap": "^2.9.0",
"react-bootstrap": "^2.10.1",
"react-datepicker": "^6.2.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dnd-multi-backend": "^8.0.3",
"react-dnd-touch-backend": "^16.0.1",
"react-dom": "^18.2.0",
"react-drag-listview": "^2.0.0",
"react-draggable": "^4.4.6",
"react-gtm-module": "^2.0.11",
"react-helmet": "^6.1.0",
"react-konva": "^18.2.10",
"react-modal": "^3.16.1",
"react-pdf": "^7.7.1",
"react-redux": "^8.1.3",
"react-router-dom": "^6.16.0",
"react-rnd": "^10.4.1",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
"react-select": "^5.7.7",
"react-scrollbars-custom": "^4.1.1",
"react-select": "^5.8.0",
"react-signature-canvas": "^1.0.6",
"reactour": "^1.19.2",
"redux": "^4.2.1",
"redux-thunk": "^2.4.2",
"regex-parser": "^2.3.0",
"serve": "^14.2.1",
"styled-components": "^4.4.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "serve -s build",
"start-dev": "mf-cra start",
"start-dev" :"react-scripts start",
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
"build": "npm run version && rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
"docker-build": "npm run version && rm -rf public/mfbuild && npm run docker-micro && CI=false && mf-cra build",
"docker-micro": "cd ./SignDocuments && npm install && npm run docker-build",
"version-win": "powershell -Command \"Invoke-RestMethod -Uri 'https://api.github.com/repos/opensignlabs/opensign/releases/latest' | Select-Object -ExpandProperty tag_name | Out-File -FilePath ./public/version.txt\"",
"build": "npm run version && react-scripts build",
"build-win": "npm run version-win && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"release": "standard-version",
@@ -73,7 +83,7 @@
},
"devDependencies": {
"@babel/runtime-corejs2": "^7.23.9",
"autoprefixer": "^10.4.16",
"autoprefixer": "^10.4.18",
"commitizen": "^4.3.0",
"eslint": "^8.51.0",
"eslint-plugin-prettier": "^4.2.1",
Binary file not shown.
+131 -67
View File
@@ -1,25 +1,53 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, Suspense, lazy } from "react";
import { Routes, Route, BrowserRouter } from "react-router-dom";
import Pgsignup from "./routes/Pgsignup";
import Login from "./routes/Login";
import Microapp from "./routes/RemoteApp";
import Signup from "./routes/Signup";
import Form from "./routes/Form";
import Report from "./routes/Report";
import Dashboard from "./routes/Dashboard";
import Subscriptions from "./routes/PlanSubscriptions";
import { pdfjs } from "react-pdf";
import Login from "./pages/Login";
import Form from "./pages/Form";
import Report from "./pages/Report";
import Dashboard from "./pages/Dashboard";
import HomeLayout from "./layout/HomeLayout";
import UserProfile from "./routes/UserProfile";
import PageNotFound from "./routes/PageNotFound";
import ForgetPassword from "./routes/ForgetPassword";
import ChangePassword from "./routes/ChangePassword";
import ReportMicroapp from "./components/ReportMicroapp";
import LoadMf from "./routes/LoadMf";
import GenerateToken from "./routes/GenerateToken";
import PageNotFound from "./pages/PageNotFound";
import ValidateRoute from "./primitives/ValidateRoute";
import Webhook from "./routes/Webhook";
import Validate from "./primitives/Validate";
import ManageSign from "./pages/Managesign";
import TemplatePlaceholder from "./pages/TemplatePlaceholder";
import SignYourSelf from "./pages/SignyourselfPdf";
import DraftDocument from "./components/pdf/DraftDocument";
import PlaceHolderSign from "./pages/PlaceHolderSign";
import PdfRequestFiles from "./pages/PdfRequestFiles";
const DebugPdf = lazy(() => import("./pages/DebugPdf"));
const ForgetPassword = lazy(() => import("./pages/ForgetPassword"));
const GuestLogin = lazy(() => import("./pages/GuestLogin"));
const Pgsignup = lazy(() => import("./pages/Pgsignup"));
const Subscriptions = lazy(() => import("./pages/PlanSubscriptions"));
const ChangePassword = lazy(() => import("./pages/ChangePassword"));
const UserProfile = lazy(() => import("./pages/UserProfile"));
const Signup = lazy(() => import("./pages/Signup"));
const GenerateToken = lazy(() => import("./pages/GenerateToken"));
const Webhook = lazy(() => import("./pages/Webhook"));
const Opensigndrive = lazy(() => import("./pages/Opensigndrive"));
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
const Loader = () => {
return (
<div
style={{
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
<div
style={{
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
);
};
function App() {
const [isloading, setIsLoading] = useState(true);
useEffect(() => {
@@ -27,12 +55,16 @@ function App() {
}, []);
const handleCredentials = () => {
const appId = process.env.REACT_APP_APPID;
const baseurl = process.env.REACT_APP_SERVERURL;
const appId = process.env.REACT_APP_APPID
? process.env.REACT_APP_APPID
: "opensign";
const baseurl = process.env.REACT_APP_SERVERURL
? process.env.REACT_APP_SERVERURL
: window.location.origin + "/api/app";
const appName = "contracts";
try {
localStorage.setItem("BaseUrl12", `${baseurl}/`);
localStorage.setItem("AppID12", appId);
localStorage.setItem("baseUrl", `${baseurl}/`);
localStorage.setItem("parseAppId", appId);
localStorage.setItem("domain", appName);
setIsLoading(false);
} catch (error) {
@@ -43,54 +75,86 @@ function App() {
return (
<div className="bg-[#eef1f5]">
{isloading ? (
<div
style={{
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
<div
style={{
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
<Loader />
) : (
<BrowserRouter>
<Routes>
<Route element={<ValidateRoute />}>
<Route exact path="/" element={<Login />} />
<Route exact path="/signup" element={<Signup />} />
</Route>
<Route element={<Validate />}>
<Route exact path="/load/:remoteApp/*" element={<LoadMf />} />
</Route>
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
<>
<Route exact path="/pgsignup" element={<Pgsignup />} />
<Route exact path="/subscription" element={<Subscriptions />} />
</>
)}
<Route element={<HomeLayout />}>
<Route path="/changepassword" element={<ChangePassword />} />
<Route path="/mf/:remoteApp/*" element={<Microapp />} />
<Route path="/asmf/:remoteApp/*" element={<Microapp />} />
<Route path="/rpmf/:remoteApp/*" element={<ReportMicroapp />} />
<Route path="/form/:id" element={<Form />} />
<Route path="/report/:id" element={<Report />} />
<Route path="/dashboard/:id" element={<Dashboard />} />
<Route path="/profile" element={<UserProfile />} />
<Route path="/generatetoken" element={<GenerateToken />} />
<Route path="/webhook" element={<Webhook />} />
</Route>
<Route path="*" element={<PageNotFound />} />
</Routes>
<Suspense fallback={<Loader />}>
<Routes>
<Route element={<ValidateRoute />}>
<Route exact path="/" element={<Login />} />
<Route exact path="/signup" element={<Signup />} />
</Route>
<Route element={<Validate />}>
<Route
path="/load/template/:templateId"
element={<TemplatePlaceholder />}
/>
<Route
exact
path="/load/placeholdersign/:docId"
element={<PlaceHolderSign />}
/>
<Route
exact
path="/load/recipientSignPdf/:docId/:contactBookId"
element={<PdfRequestFiles />}
/>
</Route>
<Route
path="/loadmf/signmicroapp/login/:id/:userMail/:contactBookId/:serverUrl"
element={<GuestLogin />}
/>
<Route
path="/login/:id/:userMail/:contactBookId/:serverUrl"
element={<GuestLogin />}
/>
<Route path="/debugpdf" element={<DebugPdf />} />
<Route path="/forgetpassword" element={<ForgetPassword />} />
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
<>
<Route exact path="/pgsignup" element={<Pgsignup />} />
<Route path="/subscription" element={<Subscriptions />} />
</>
)}
<Route element={<HomeLayout />}>
<Route path="/changepassword" element={<ChangePassword />} />
<Route path="/form/:id" element={<Form />} />
<Route path="/report/:id" element={<Report />} />
<Route path="/dashboard/:id" element={<Dashboard />} />
<Route path="/profile" element={<UserProfile />} />
<Route path="/generatetoken" element={<GenerateToken />} />
<Route path="/webhook" element={<Webhook />} />
<Route path="/managesign" element={<ManageSign />} />
<Route path="/opensigndrive" element={<Opensigndrive />} />
<Route
path="/template/:templateId"
element={<TemplatePlaceholder />}
/>
{/* signyouself route with no rowlevel data using docId from url */}
<Route path="/signaturePdf/:docId" element={<SignYourSelf />} />
{/* draft document route to handle and navigate route page accordiing to document status */}
<Route path="/draftDocument" element={<DraftDocument />} />
{/* recipient placeholder set route with no rowlevel data using docId from url*/}
<Route
path="/placeHolderSign/:docId"
element={<PlaceHolderSign />}
/>
{/* for user signature (need your sign route) with row level data */}
<Route path="/pdfRequestFiles" element={<PdfRequestFiles />} />
{/* for user signature (need your sign route) with no row level data */}
<Route
path="/pdfRequestFiles/:docId"
element={<PdfRequestFiles />}
/>
{/* recipient signature route with no rowlevel data using docId from url */}
<Route
path="/recipientSignPdf/:docId/:contactBookId"
element={<PdfRequestFiles />}
/>
</Route>
<Route path="*" element={<PageNotFound />} />
</Routes>
</Suspense>
</BrowserRouter>
)}
</div>
-62
View File
@@ -1,62 +0,0 @@
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import { store } from "./redux/store";
import { HTML5Backend } from "react-dnd-html5-backend";
import { TouchBackend } from "react-dnd-touch-backend";
import {
DndProvider,
TouchTransition,
MouseTransition,
Preview
} from "react-dnd-multi-backend";
import DragElement from "./microappComponent/DragElement";
import TagManager from "react-gtm-module";
const HTML5toTouch = {
backends: [
{
id: "html5",
backend: HTML5Backend,
transition: MouseTransition
},
{
id: "touch",
backend: TouchBackend,
options: { enableMouseEvents: true },
preview: true,
transition: TouchTransition
}
]
};
const generatePreview = (props) => {
const { item, style } = props;
const newStyle = {
...style
};
return (
<div style={newStyle}>
<DragElement {...item} />
</div>
);
};
if (process.env.REACT_APP_GTM) {
const tagManagerArgs = {
gtmId: process.env.REACT_APP_GTM
};
TagManager.initialize(tagManagerArgs);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<DndProvider options={HTML5toTouch}>
<Preview>{generatePreview}</Preview>
<App />
</DndProvider>
</Provider>
);

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 234 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@@ -3,7 +3,7 @@ import Parse from "parse";
import axios from "axios";
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
const AppendFormInForm = (props) => {
const AddSigner = (props) => {
const [name, setName] = useState("");
const [phone, setPhone] = useState("");
const [email, setEmail] = useState("");
@@ -49,8 +49,6 @@ const AppendFormInForm = (props) => {
e.preventDefault();
e.stopPropagation();
setIsLoader(true);
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
try {
const contactQuery = new Parse.Object("contracts_Contactbook");
contactQuery.set("Name", name);
@@ -314,4 +312,4 @@ const AppendFormInForm = (props) => {
);
};
export default AppendFormInForm;
export default AddSigner;
-2
View File
@@ -12,8 +12,6 @@ const AddUser = (props) => {
const [isUserExist, setIsUserExist] = useState(false);
const parseBaseUrl = localStorage.getItem("baseUrl");
const parseAppId = localStorage.getItem("parseAppId");
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
const checkUserExist = async () => {
try {
@@ -1,49 +0,0 @@
import React, { Component } from "react";
export class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return {
hasError: true
};
}
componentDidCatch(error, info) {
console.log(error);
console.log(info);
}
render() {
if (this.state.hasError) {
return (
<div className="p-2">
<div
style={{
height: "100vh",
display: "flex",
flexFlow: "column"
}}
>
<h1
style={{
fontSize: "2em",
fontFamily: "sans-serif",
textShadow: "0 0 20px black"
}}
>
Something went wrong.
</h1>
</div>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundary;
+4 -8
View File
@@ -11,8 +11,6 @@ const Header = ({ showSidebar }) => {
let applogo = localStorage.getItem("appLogo") || "";
let username = localStorage.getItem("username");
const image = localStorage.getItem("profileImg") || dp;
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
const [isOpen, setIsOpen] = useState(false);
@@ -22,8 +20,6 @@ const Header = ({ showSidebar }) => {
const closeDropdown = () => {
setIsOpen(false);
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
Parse.User.logOut();
let appdata = localStorage.getItem("userSettings");
let applogo = localStorage.getItem("appLogo");
@@ -32,8 +28,8 @@ const Header = ({ showSidebar }) => {
let PageLanding = localStorage.getItem("PageLanding");
let domain = localStorage.getItem("domain");
let _appName = localStorage.getItem("_appName");
let baseUrl = localStorage.getItem("BaseUrl12");
let appid = localStorage.getItem("AppID12");
let baseUrl = localStorage.getItem("baseUrl");
let appid = localStorage.getItem("parseAppId");
localStorage.clear();
@@ -44,8 +40,8 @@ const Header = ({ showSidebar }) => {
localStorage.setItem("PageLanding", PageLanding);
localStorage.setItem("domain", domain);
localStorage.setItem("userSettings", appdata);
localStorage.setItem("BaseUrl12", baseUrl);
localStorage.setItem("AppID12", appid);
localStorage.setItem("baseUrl", baseUrl);
localStorage.setItem("parseAppId", appid);
navigation("/");
};
+8 -8
View File
@@ -48,8 +48,8 @@ const GoogleSignInBtn = ({
if (Parse.User.current()) {
await Parse.User.logOut();
}
let baseUrl = localStorage.getItem("BaseUrl12");
let appid = localStorage.getItem("AppID12");
let baseUrl = localStorage.getItem("baseUrl");
let appid = localStorage.getItem("parseAppId");
let applogo = localStorage.getItem("appLogo");
let domain = localStorage.getItem("domain");
let appversion = localStorage.getItem("appVersion");
@@ -63,8 +63,8 @@ const GoogleSignInBtn = ({
localStorage.clear();
localStorage.setItem("BaseUrl12", baseUrl);
localStorage.setItem("AppID12", appid);
localStorage.setItem("baseUrl", baseUrl);
localStorage.setItem("parseAppId", appid);
localStorage.setItem("appLogo", applogo);
localStorage.setItem("domain", domain);
localStorage.setItem("appversion", appversion);
@@ -191,8 +191,8 @@ const GoogleSignInBtn = ({
let PageLanding = localStorage.getItem("PageLanding");
let domain = localStorage.getItem("domain");
let _appName = localStorage.getItem("_appName");
let baseUrl = localStorage.getItem("BaseUrl12");
let appid = localStorage.getItem("AppID12");
let baseUrl = localStorage.getItem("baseUrl");
let appid = localStorage.getItem("parseAppId");
localStorage.clear();
@@ -203,8 +203,8 @@ const GoogleSignInBtn = ({
localStorage.setItem("PageLanding", PageLanding);
localStorage.setItem("domain", domain);
localStorage.setItem("userSettings", appdata);
localStorage.setItem("BaseUrl12", baseUrl);
localStorage.setItem("AppID12", appid);
localStorage.setItem("baseUrl", baseUrl);
localStorage.setItem("parseAppId", appid);
};
return (
<div style={{ position: "relative" }}>
@@ -1,9 +1,7 @@
import React from "react";
import { Document, Page, pdfjs } from "react-pdf";
import { Document, Page } from "react-pdf";
import { Stage, Layer, Rect } from "react-konva";
const RenderDebugPdf = (props) => {
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
return (
<div>
<div
@@ -29,7 +27,7 @@ const RenderDebugPdf = (props) => {
onMouseMove={props.handleMouseMoveDiv}
>
<Document
onLoadError={(e) => {
onLoadError={() => {
const load = {
status: false,
type: "failed"
@@ -66,6 +64,7 @@ const RenderDebugPdf = (props) => {
.map((value) => {
return (
<Rect
key={value.key}
x={value.x}
y={value.y}
width={value.width}
@@ -1,66 +0,0 @@
import useFederatedComponent from "mf-cra";
import React, { Suspense, useEffect } from "react";
import { useParams } from "react-router-dom";
const MicroappModal = () => {
const { remoteApp } = useParams();
useEffect(() => {
return () => localStorage.removeItem("rowlevel");
}, []);
let paramString = remoteApp;
let queryString = new URLSearchParams(paramString);
let obj = {};
for (const [key, value] of queryString.entries()) {
// console.log("value ", key + ":" + value);
if (key === "remoteUrl") {
const url = window.location.origin + "/mfbuild/remoteEntry.js";
// console.log("atob(value) ", atob(value))
obj = { ...obj, [key]: url };
} else {
if (key === "moduleToLoad") {
obj = { ...obj, [key]: "./" + value };
} else {
obj = { ...obj, [key]: value };
}
}
}
// console.log("app ", remoteApp);
const { Component: RemoteComponent } = useFederatedComponent(obj);
// console.log("RemoteComponent ", RemoteComponent);
return (
<div className="w-full h-full flex items-center justify-center ">
<div className="w-full">
<Suspense
fallback={
<div style={{ height: "300px" }}>
<div
style={{
marginLeft: "45%",
marginTop: "150px",
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
}
>
<div
style={{
backgroundColor: "#ffffff",
width: "100%",
overflow: "hidden",
minHeight: "50vh"
}}
>
{RemoteComponent && <RemoteComponent />}
</div>
</Suspense>
</div>
</div>
);
};
export default MicroappModal;
+3 -13
View File
@@ -1,21 +1,11 @@
import React from "react";
import { Helmet } from "react-helmet";
function Title(props) {
function Title({ title, drive }) {
return (
<Helmet>
<title>{`${props.title} - OpenSign™`}</title>
{/* <title>
{`${localStorage.getItem("appTitle") ? localStorage.getItem("appTitle") : ""} - ${props.title}`}
</title> */}
<meta
name="description"
content={`${props.title} - OpenSign™`}
/>
{/* <meta
name="description"
content={`${localStorage.getItem("appTitle")} - ${props.title}`}
/> */}
<title>{drive ? title : `${title} - OpenSign™`}</title>
<meta name="description" content={`${title} - OpenSign™`} />
<link
rel="icon"
type="image/png"
@@ -24,9 +24,6 @@ const DashboardCard = (props) => {
};
let body = {};
let currentUser;
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
let currentUser1 = Parse.User.current();
currentUser = currentUser1.id;
let res;
@@ -82,8 +79,6 @@ const DashboardCard = (props) => {
} else {
setLoading(true);
try {
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
const currentUser = Parse.User.current();
let reg1 = /(\#.*?\#)/gi; // eslint-disable-line
let _query = props.Data.query;
@@ -223,8 +218,6 @@ const DashboardCard = (props) => {
if (restr.includes("#")) {
try {
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
const currentUser = Parse.User.current();
let res;
if (localStorage.getItem("Extand_Class")) {
@@ -45,18 +45,16 @@ function DashboardReport(props) {
setActions(json.actions);
setReportName(json.reportName);
setHeading(json.heading);
Parse.serverURL = localStorage.getItem("BaseUrl12");
Parse.initialize(localStorage.getItem("AppID12"));
const currentUser = Parse.User.current().id;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
sessiontoken: localStorage.getItem("accesstoken")
};
try {
const params = { reportId: id, skip: skipUserRecord, limit: limit };
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
const url = `${localStorage.getItem("baseUrl")}/functions/getReport`;
const res = await axios.post(url, params, {
headers: headers,
signal: abortController.signal // is used to cancel fetch query
@@ -1,8 +1,5 @@
import React, { Suspense, lazy } from "react";
import ErrorBoundary from "../ErrorBoundary";
const DashboardCard = lazy(() => import("./DashboardCard"));
const DashboardReport = lazy(() => import("./DashboardReport"));
const GetDashboard = (props) => {
@@ -15,7 +12,21 @@ const GetDashboard = (props) => {
data-tut={col.widget.data.tourSection}
style={{ background: col.widget.bgColor }}
>
<Suspense fallback={<div>please wait</div>}>
<Suspense
fallback={
<div style={{ height: "300px" }}>
<div
style={{
marginLeft: "45%",
marginTop: "150px",
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
}
>
<DashboardCard
Icon={col.widget.icon}
Label={col.widget.label}
@@ -76,25 +87,23 @@ const GetDashboard = (props) => {
}
};
return (
<ErrorBoundary>
<div>
{props.dashboard.map((val, key) => (
<div key={"a" + key} className="row">
{val.columns.map((col, i) =>
col.widget.data && col.widget.data.tourSection ? (
<div key={i} className={props.classnameArray[key][i]}>
{renderSwitchWithTour(col)}
</div>
) : (
<div key={i} className={props.classnameArray[key][i]}>
{renderSwitch(col)}
</div>
)
)}
</div>
))}
</div>
</ErrorBoundary>
<div>
{props.dashboard.map((val, key) => (
<div key={"a" + key} className="row">
{val.columns.map((col, i) =>
col.widget.data && col.widget.data.tourSection ? (
<div key={i} className={props.classnameArray[key][i]}>
{renderSwitchWithTour(col)}
</div>
) : (
<div key={i} className={props.classnameArray[key][i]}>
{renderSwitch(col)}
</div>
)
)}
</div>
))}
</div>
);
};
@@ -1,20 +1,18 @@
import React, { useState, useEffect, useRef } from "react";
import folder from "../../../assests/folder.png";
import "../LegaDrive.css";
import draftDoc from "../../../assests/draftDoc1.png";
import pdfLogo from "../../../assests/pdf3.png";
import folder from "../../assets/images/folder.png";
import "../../styles/opensigndrive.css";
import pdfLogo from "../../assets/images/pdf3.png";
import axios from "axios";
import * as ContextMenu from "@radix-ui/react-context-menu";
import { saveAs } from "file-saver";
import { getHostUrl } from "../../../utils/Utils";
import { useNavigate } from "react-router-dom";
import Table from "react-bootstrap/Table";
import * as HoverCard from "@radix-ui/react-hover-card";
import SelectFolder from "../../../premitives/SelectFolder";
import ModalUi from "../../../premitives/ModalUi";
import { themeColor } from "../../../utils/ThemeColor/backColor";
import SelectFolder from "../shared/fields/SelectFolder"; //check this one
import ModalUi from "../../primitives/ModalUi";
import { themeColor } from "../../constant/const";
function PdfFileComponent({
function DriveBody({
pdfData,
setFolderName,
setDocId,
@@ -40,7 +38,6 @@ function PdfFileComponent({
//to focus input box on press rename to change doc name
useEffect(() => {
if (rename && inputRef.current) {
// console.log("ref", inputRef.current)
setTimeout(() => {
inputRef.current.focus();
}, 10);
@@ -99,11 +96,12 @@ function PdfFileComponent({
}
}
)
.then((result) => {
.then(() => {
// const res = result.data;
// console.log("res", res);
})
.catch((err) => {
console.log("Err ", err);
setIsAlert({
isShow: true,
alertMessage: "something went wrong"
@@ -114,57 +112,66 @@ function PdfFileComponent({
//function for navigate user to microapp-signature component
const checkPdfStatus = async (data) => {
const hostUrl = getHostUrl();
const signerExist = data.Signers && data.Signers;
const isDecline = data.IsDeclined && data.IsDeclined;
const isPlaceholder = data.Placeholders && data.Placeholders;
const signedUrl = data.SignedUrl;
//checking if document has completed and request signature flow
if (data?.IsCompleted && signerExist?.length > 0) {
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
navigate(`/pdfRequestFiles/${data.objectId}`);
}
//checking if document has completed and signyour-self flow
else if (!signerExist && !isPlaceholder) {
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
navigate(`/signaturePdf/${data.objectId}`);
}
//checking if document has declined by someone
else if (isDecline) {
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
navigate(`/pdfRequestFiles/${data.objectId}`);
//checking draft type document
} else if (
signerExist?.length > 0 &&
isPlaceholder?.length > 0 &&
!signedUrl
) {
navigate(`/placeHolderSign/${data.objectId}`);
}
//Inprogress document
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
navigate(`/pdfRequestFiles/${data.objectId}`);
} //placeholder draft document
else if (
(signerExist?.length > 0 &&
(!isPlaceholder || isPlaceholder?.length === 0)) ||
((!signerExist || signerExist?.length === 0) && isPlaceholder?.length > 0)
) {
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
navigate(`/placeHolderSign/${data.objectId}`);
}
};
const handleMenuItemClick = (selectType, data) => {
switch (selectType) {
case "Download":
case "Download": {
const pdfName = data && data.Name;
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
break;
case "Rename":
}
case "Rename": {
setRenameValue(data.Name);
setRename(data.objectId);
break;
case "Delete":
}
case "Delete": {
setIsDeleteDoc(true);
setSelectDoc(data);
break;
case "Move":
}
case "Move": {
handleMoveDocument(data);
break;
}
default:
null;
}
};
//function for delete document
@@ -197,6 +204,7 @@ function PdfFileComponent({
}
})
.catch((err) => {
console.log("Err ", err);
setIsAlert({
isShow: true,
alertMessage: "something went wrong"
@@ -282,10 +290,6 @@ function PdfFileComponent({
}
};
const handleDraftDoc = (data) => {
window.location.hash = `/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9MZWdhR2VuaWUtTWljcm9hcHBWMi9yZW1vdGVFbnRyeS5qcw==&moduleToLoad=AppRoutes&remoteName=legageniemicroapp/legagenie?${data.objectId}`;
};
//component to handle type of document and render according to type
const handleFolderData = (data, ind, listType) => {
let createddate, status, isDecline, signerExist, isComplete, isPlaceholder;
@@ -297,6 +301,7 @@ function PdfFileComponent({
isDecline = data.IsDeclined && data.IsDeclined;
isPlaceholder = data.Placeholders && data.Placeholders;
signerExist = data.Signers && data.Signers;
const signedUrl = data.SignedUrl;
const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime();
@@ -316,6 +321,12 @@ function PdfFileComponent({
(!isPlaceholder || isPlaceholder?.length === 0)
) {
status = "Draft";
} else if (
signerExist?.length > 0 &&
isPlaceholder?.length > 0 &&
!signedUrl
) {
status = "Draft";
} else if (isExpire) {
status = "Expired";
} else {
@@ -357,25 +368,6 @@ function PdfFileComponent({
<td>_</td>
<td>_</td>
</tr>
) : data.Type === "AIDoc" ? (
<tr onClick={() => handleDraftDoc(data)}>
<td
style={{ cursor: "pointer", display: "flex", alignItems: "center" }}
>
<i
className="fa fa-file-text"
style={{ color: "#0ea3ed", marginRight: "8px", fontSize: "26px" }}
></i>
<span style={{ fontSize: "12px", fontWeight: "500" }}>
{data.Name}
</span>
</td>
<td>{createddate}</td>
<td>LegaGenie Draft</td>
<td>_</td>
<td>_</td>
</tr>
) : (
<tr onClick={() => checkPdfStatus(data)}>
<td
@@ -464,72 +456,7 @@ function PdfFileComponent({
onClick={() => handleMenuItemClick("Rename", data)}
className="ContextMenuItem"
>
<i class="fa-solid fa-font"></i>
<span style={{ marginLeft: "8px" }}>Rename</span>
</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu.Portal>
</ContextMenu.Root>
</div>
) : data.Type === "AIDoc" ? (
<div key={ind} className="folderBox">
<ContextMenu.Root>
<ContextMenu.Trigger className="ContextMenuTrigger">
<div
style={{
display: "flex",
flexDirection: "column",
cursor: "pointer"
}}
>
<img
alt="no img"
onClick={() => handleDraftDoc(data)}
src={draftDoc}
width={100}
height={103}
/>
{rename === data.objectId ? (
<input
onFocus={() => {
inputRef.current.setSelectionRange(0, 0);
const input = inputRef.current;
if (input) {
input.select();
}
}}
autoFocus={true}
type="text"
onBlur={() => handledRenameDoc(data)}
onKeyDown={(e) => handleEnterPress(e, data)}
ref={inputRef}
defaultValue={renameValue}
// value={renameValue}
onChange={(e) => setRenameValue(e.target.value)}
style={{
width: "100px",
border: "1.5px solid black",
borderRadius: "2px",
fontSize: "10px"
}}
/>
) : (
<span className="foldName">{data.Name}</span>
)}
</div>
</ContextMenu.Trigger>
<ContextMenu.Portal>
<ContextMenu.Content
className="ContextMenuContent"
sideOffset={5}
align="end"
>
<ContextMenu.Item
onClick={() => handleMenuItemClick("Rename", data)}
className="ContextMenuItem"
>
<i class="fa-solid fa-font"></i>
<i className="fa-solid fa-font"></i>
<span style={{ marginLeft: "8px" }}>Rename</span>
</ContextMenu.Item>
</ContextMenu.Content>
@@ -615,7 +542,7 @@ function PdfFileComponent({
onClick={() => handleMenuItemClick(menu.type, data)}
className="ContextMenuItem"
>
<i class={menu.icon}></i>
<i className={menu.icon}></i>
<span style={{ marginLeft: "8px" }}>{menu.type}</span>
</ContextMenu.Item>
);
@@ -702,7 +629,7 @@ function PdfFileComponent({
)}
<ModalUi
isOpen={isDeleteDoc}
headerColor={themeColor()}
headerColor={themeColor}
title={"Delete Document"}
handleClose={() => {
setIsDeleteDoc(false);
@@ -726,7 +653,7 @@ function PdfFileComponent({
handleDeleteDocument(selectDoc);
}}
style={{
background: themeColor(),
background: themeColor,
color: "white"
}}
type="button"
@@ -749,4 +676,4 @@ function PdfFileComponent({
);
}
export default PdfFileComponent;
export default DriveBody;
@@ -1,5 +1,5 @@
import React from "react";
import ModalUi from "../../premitives/ModalUi";
import ModalUi from "../../primitives/ModalUi";
const AddRoleModal = (props) => {
return (
@@ -1,7 +1,5 @@
import React, { useEffect, useState } from "react";
import "./certificate.css";
import opensignLogo from "../../assests/open-sign-logo.png";
import opensignLogo from "../../assets/images/logo.png";
import {
Page,
Text,
@@ -18,6 +16,7 @@ function Certificate({ pdfData }) {
useEffect(() => {
handleSignerData();
// eslint-disable-next-line
}, []);
const handleSignerData = () => {
@@ -1,11 +1,6 @@
import React from "react";
function DefaultSignature({
themeColor,
defaultSignImg,
xyPostion,
setDefaultSignAlert
}) {
import { themeColor } from "../../constant/const";
function DefaultSignature({ defaultSignImg, xyPostion, setDefaultSignAlert }) {
const confirmToaddDefaultSign = () => {
if (xyPostion.length > 0) {
setDefaultSignAlert({
@@ -25,7 +20,7 @@ function DefaultSignature({
<div>
<div
style={{
background: themeColor(),
background: themeColor,
color: "white",
padding: "5px",
fontFamily: "sans-serif",
@@ -58,7 +53,7 @@ function DefaultSignature({
</div>
<button
style={{
background: themeColor(),
background: themeColor,
color: "white",
marginTop: "20px",
cursor: "pointer",
@@ -1,12 +1,12 @@
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import Loader from "./component/loader";
import { contractDocument, getHostUrl } from "../utils/Utils";
import Loader from "../../primitives/LoaderWithMsg";
import { contractDocument } from "../../constant/Utils";
import HandleError from "../../primitives/HandleError";
function DraftDocument() {
const navigate = useNavigate();
const [pdfDetails, setPdfDetails] = useState([]);
const [isLoading, setIsLoading] = useState({
isLoad: true,
isLoader: true,
message: "This might take some time"
});
@@ -19,68 +19,77 @@ function DraftDocument() {
: rowLevel?.objectId && rowLevel.objectId;
useEffect(() => {
if (docId) {
getDocumentDetails();
}
getDocumentDetails();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
//get document details
const getDocumentDetails = async () => {
//getting document details
const documentData = await contractDocument(docId);
if (documentData && documentData.length > 0) {
setPdfDetails(documentData);
const loadObj = {
isLoad: false
};
setIsLoading(loadObj);
handleDraftDoc(documentData);
} else if (
documentData === "Error: Something went wrong!" ||
(documentData.result && documentData.result.error)
) {
alert("Error: Something went wrong!");
setIsLoading({
isLoader: false,
message: "Error: Something went wrong!"
});
} else {
alert("No data found!");
setIsLoading({
isLoader: false,
message: "No data found!"
});
}
};
//check document type and render on signyour self and placeholder route
const handleDraftDoc = () => {
const data = pdfDetails[0];
const hostUrl = getHostUrl();
const handleDraftDoc = (documentData) => {
const data = documentData[0];
const signerExist = data.Signers && data.Signers;
const isDecline = data.IsDeclined && data.IsDeclined;
const isPlaceholder = data.Placeholders && data.Placeholders;
const signedUrl = data.SignedUrl;
//checking if document has completed and request signature flow
if (data?.IsCompleted && signerExist?.length > 0) {
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
navigate(`/pdfRequestFiles/${data.objectId}`);
}
//checking if document has completed and signyour-self flow
else if (!signerExist && !isPlaceholder) {
navigate(`${hostUrl}signaturePdf/${data.objectId}`);
navigate(`/signaturePdf/${data.objectId}`);
}
//checking if document has declined by someone
else if (isDecline) {
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
navigate(`/pdfRequestFiles/${data.objectId}`);
//checking draft type document
} else if (
signerExist?.length > 0 &&
isPlaceholder?.length > 0 &&
!signedUrl
) {
navigate(`/placeHolderSign/${data.objectId}`);
}
//Inprogress document
else if (isPlaceholder?.length > 0 && signerExist?.length > 0) {
navigate(`${hostUrl}pdfRequestFiles/${data.objectId}`);
navigate(`/pdfRequestFiles/${data.objectId}`);
} //placeholder draft document
else if (
(signerExist?.length > 0 &&
(!isPlaceholder || isPlaceholder?.length === 0)) ||
((!signerExist || signerExist?.length === 0) && isPlaceholder?.length > 0)
) {
navigate(`${hostUrl}placeHolderSign/${data.objectId}`);
navigate(`/placeHolderSign/${data.objectId}`);
}
};
return (
<div>
{isLoading.isLoad ? <Loader isLoading={isLoading} /> : handleDraftDoc()}
{isLoading.isLoader ? (
<Loader isLoading={isLoading} />
) : (
<HandleError handleError={isLoading.message} />
)}
</div>
);
}
@@ -0,0 +1,13 @@
import React from "react";
import { getWidgetType, widgets } from "../../constant/Utils";
function DragElement(item) {
const getWidgets = widgets;
const filterWidgetPreview = getWidgets.filter(
(data) => data.type === item?.text
);
return <div>{getWidgetType(filterWidgetPreview[0])}</div>;
}
export default DragElement;
@@ -0,0 +1,402 @@
import React, { useEffect, useState } from "react";
import { themeColor } from "../../constant/const";
import ModalUi from "../../primitives/ModalUi";
function DropdownWidgetOption(props) {
const [dropdownOptionList, setDropdownOptionList] = useState([
"option-1",
"option-2"
]);
const [minCount, setMinCount] = useState(0);
const [maxCount, setMaxCount] = useState(0);
const [dropdownName, setDropdownName] = useState(props.type);
const [isReadOnly, setIsReadOnly] = useState(false);
const [status, setStatus] = useState("required");
const [defaultValue, setDefaultValue] = useState("");
const statusArr = ["required", "optional"];
const [defaultCheckbox, setDefaultCheckbox] = useState([]);
const resetState = () => {
setDropdownOptionList(["option-1", "option-2"]);
setDropdownName(props.type);
setIsReadOnly(false);
setMinCount(0);
setMaxCount(0);
setDefaultCheckbox([]);
setDefaultValue("");
};
useEffect(() => {
if (
props.currWidgetsDetails?.options?.name &&
props.currWidgetsDetails?.options?.values
) {
setDropdownName(props.currWidgetsDetails?.options?.name);
setDropdownOptionList(props.currWidgetsDetails?.options?.values);
setMinCount(
props.currWidgetsDetails?.options?.validation?.minRequiredCount
);
setMaxCount(
props.currWidgetsDetails?.options?.validation?.maxRequiredCount
);
setIsReadOnly(props.currWidgetsDetails?.options?.isReadOnly);
setStatus(props.currWidgetsDetails?.options?.status || "required");
setDefaultValue(props.currWidgetsDetails?.options?.defaultValue || "");
setDefaultCheckbox(props.currWidgetsDetails?.options?.defaultValue || []);
} else {
setStatus("required");
resetState();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.currWidgetsDetails]);
const handleInputChange = (index, value) => {
setDropdownOptionList((prevInputs) => {
const newInputs = [...prevInputs];
newInputs[index] = value;
return newInputs;
});
};
//function add add checkbox option and add width of checkbox
const handleAddInput = () => {
const deleteOption = false;
const addOption = true;
setDropdownOptionList((prevInputs) => [...prevInputs, ""]);
props.handleSaveWidgetsOptions(
null,
null,
null,
null,
null,
addOption,
deleteOption
);
};
//function add add checkbox option and delete width of checkbox
const handleDeleteInput = (ind) => {
const deleteOption = true;
const addOption = false;
const getUpdatedOptions = dropdownOptionList.filter(
(data, index) => index !== ind
);
setDropdownOptionList(getUpdatedOptions);
props.handleSaveWidgetsOptions(
null,
null,
null,
null,
null,
addOption,
deleteOption
);
};
const handleSaveOption = () => {
const defaultData =
defaultCheckbox && defaultCheckbox.length > 0
? defaultCheckbox
: defaultValue;
props.handleSaveWidgetsOptions(
dropdownName,
dropdownOptionList,
minCount,
maxCount,
isReadOnly,
null,
null,
status,
defaultData
);
// props.setShowDropdown(false);
setDropdownOptionList(["option-1", "option-2"]);
setDropdownName(props.type);
// props.setCurrWidgetsDetails({});
setIsReadOnly(false);
setMinCount(0);
setMaxCount(0);
setDefaultCheckbox([]);
setDefaultValue("");
};
const handleSetMinMax = (e) => {
const minValue = e.target.value;
if (minValue > dropdownOptionList.length) {
return "";
} else {
return minValue;
}
};
const handleDefaultCheck = (index) => {
const getDefaultCheck = defaultCheckbox.includes(index);
if (getDefaultCheck) {
return true;
} else {
return false;
}
};
return (
//props.showDropdown
<ModalUi
// styleClass={"dropdownModal"}
isOpen={props.showDropdown}
title={props.title}
closeOff={true}
>
<div style={{ height: "100%", padding: 20 }}>
<form
onSubmit={(e) => {
e.preventDefault();
handleSaveOption();
}}
>
<div className="dropdownContainer">
{["checkbox", "radio"].includes(props.type) &&
!props.isSignYourself && (
<div>
<input
type="checkbox"
checked={isReadOnly}
onChange={(e) => {
setIsReadOnly(e.target.checked);
}}
/>
<label style={{ marginLeft: "10px" }}>Is read only</label>
</div>
)}
<label style={{ fontSize: "13px", fontWeight: "600" }}>
Name<span style={{ color: "red", fontSize: 13 }}> *</span>
</label>
<input
required
defaultValue={dropdownName}
value={dropdownName}
onChange={(e) => setDropdownName(e.target.value)}
className="drodown-input"
/>
{props.type === "checkbox" && !props.isSignYourself && (
<>
<label style={{ fontSize: "13px", fontWeight: "600" }}>
Minimun check
</label>
<input
required
defaultValue={0}
value={minCount}
onChange={(e) => {
const count = handleSetMinMax(e);
setMinCount(count);
}}
className="drodown-input"
/>
<label style={{ fontSize: "13px", fontWeight: "600" }}>
Maximum check
</label>
<input
required
defaultValue={0}
value={maxCount}
onChange={(e) => {
const count = handleSetMinMax(e);
setMaxCount(count);
}}
className="drodown-input"
/>
</>
)}
<label
style={{ fontSize: "13px", fontWeight: "600", marginTop: "5px" }}
>
Options
</label>
<div
style={{
display: "flex",
flexDirection: "column"
}}
>
{dropdownOptionList.map((option, index) => (
<div
key={index}
style={{
display: "flex",
flexDirection: "row",
marginBottom: "5px",
alignItems: "center"
}}
>
{props.type === "checkbox" && !props.isSignYourself && (
<input
type="checkbox"
checked={handleDefaultCheck(index)}
onChange={(e) => {
if (e.target.checked) {
const getDefaultCheck =
defaultCheckbox?.includes(index);
if (!getDefaultCheck) {
setDefaultCheckbox((prev) => [...prev, index]);
}
} else {
const removeOption = defaultCheckbox.filter(
(data) => data !== index
);
setDefaultCheckbox(removeOption);
}
}}
style={{
width: "23px",
height: "19px",
marginRight: "5px"
}}
/>
)}
<input
required
className="drodown-input"
type="text"
value={option}
onChange={(e) => handleInputChange(index, e.target.value)}
/>
<i
className="fa-solid fa-rectangle-xmark"
onClick={() => handleDeleteInput(index)}
style={{
color: "red",
fontSize: "25px",
marginLeft: "10px"
}}
></i>
</div>
))}
<i
onClick={handleAddInput}
style={{
cursor: "pointer",
color: themeColor,
fontSize: "25px",
marginLeft: "10px"
}}
className="fa-solid fa-square-plus"
></i>
</div>
{["dropdown", "radio"].includes(props.type) && (
<>
<label
style={{
fontSize: "13px",
fontWeight: "600",
marginTop: "5px"
}}
>
Default value
</label>
<select
onChange={(e) => setDefaultValue(e.target.value)}
className="drodown-input"
name="defaultvalue"
value={defaultValue}
placeholder="select default value"
>
<option value="" disabled hidden style={{ fontSize: "13px" }}>
Select...
</option>
{dropdownOptionList.map((data, ind) => {
return (
<option
style={{ fontSize: "13px" }}
key={ind}
value={data}
>
{data}
</option>
);
})}
</select>
</>
)}
{props.type !== "checkbox" && props.type !== "radio" && (
<>
<div
style={{
display: "flex",
flexDirection: "row",
gap: 10,
marginTop: "0.5rem"
}}
>
{statusArr.map((data, ind) => {
return (
<div
key={ind}
style={{
display: "flex",
flexDirection: "row",
gap: 5,
alignItems: "center"
}}
>
<input
style={{ accentColor: "red" }}
type="radio"
name="status"
onChange={() => setStatus(data.toLowerCase())}
checked={status.toLowerCase() === data.toLowerCase()}
/>
<div style={{ fontSize: "13px", fontWeight: "500" }}>
{data}
</div>
</div>
);
})}
</div>
</>
)}
</div>
<div
style={{
height: "1px",
backgroundColor: "#9f9f9f",
width: "100%",
marginTop: "15px",
marginBottom: "15px"
}}
></div>
<button
// onClick={() => handleSaveOption()}
disabled={dropdownOptionList.length === 0 && true}
style={{
background: themeColor,
color: "white"
}}
type="submit"
className={"finishBtn"}
>
Save
</button>
{props.currWidgetsDetails?.options?.values?.length > 0 && (
<button
type="submit"
className="finishBtn cancelBtn"
onClick={() => {
props.handleClose && props.handleClose();
resetState();
}}
>
Cancel
</button>
)}
</form>
</div>
</ModalUi>
);
}
export default DropdownWidgetOption;
@@ -1,5 +1,5 @@
import React, { useState } from "react";
import "../../css/AddUser.css";
import "../../styles/AddUser.css";
// import SelectFolder from "../../premitives/SelectFolder";
const EditTemplate = ({ template, onSuccess }) => {
@@ -45,7 +45,7 @@ const EditTemplate = ({ template, onSuccess }) => {
fontWeight: "700"
}}
>
{template.URL?.split("/")[3]?.split("_")[1]}
{template.URL?.split("/")?.pop()?.split("_")[1]}
</div>
</div>
<div className="form-section">
@@ -1,11 +1,11 @@
import React, { useState } from "react";
import { saveAs } from "file-saver";
import celebration from "../../assests/newCeleb.gif";
import celebration from "../../assets/images/newCeleb.gif";
import axios from "axios";
import { getBase64FromUrl } from "../../utils/Utils";
import { themeColor } from "../../utils/ThemeColor/backColor";
import { getBase64FromUrl } from "../../constant/Utils";
import { themeColor } from "../../constant/const";
import printModule from "print-js";
import loader from "../../assests/loader2.gif";
import loader from "../../assets/images/loader2.gif";
function EmailComponent({
isEmail,
@@ -28,7 +28,6 @@ function EmailComponent({
try {
const imgPng =
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
// "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png";
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3/`;
const headers = {
@@ -37,7 +36,7 @@ function EmailComponent({
sessionToken: localStorage.getItem("accesstoken")
};
const openSignUrl = "https://www.opensignlabs.com/contact-us";
const themeBGcolor = themeColor();
const themeBGcolor = themeColor;
let params = {
pdfName: pdfName,
url: pdfUrl,
@@ -362,7 +361,7 @@ function EmailComponent({
>
<i
style={{
backgroundColor: themeColor(),
backgroundColor: themeColor,
padding: "5px 7px",
marginTop: "10px",
color: "white",
@@ -399,7 +398,7 @@ function EmailComponent({
<button
disabled={emailList.length === 0 && true}
style={{
background: themeColor(),
background: themeColor,
color: "white"
}}
type="button"
@@ -1,14 +1,14 @@
import React from "react";
import PrevNext from "./prevNext";
import PrevNext from "./PrevNext";
import { PDFDownloadLink } from "@react-pdf/renderer";
import Certificate from "../Certificate/Certificate";
import Certificate from "./Certificate";
import printModule from "print-js";
import { getBase64FromUrl } from "../../utils/Utils";
import { getBase64FromUrl } from "../../constant/Utils";
import { saveAs } from "file-saver";
import "../../css/signature.css";
import "../../styles/signature.css";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { useNavigate } from "react-router-dom";
import { themeColor } from "../../utils/ThemeColor/backColor";
import { themeColor } from "../../constant/const";
function Header({
isPdfRequestFiles,
@@ -21,7 +21,7 @@ function Header({
changePage,
pdfUrl,
documentStatus,
embedImages,
embedWidgetsData,
pdfDetails,
signerPos,
signersdata,
@@ -38,6 +38,8 @@ function Header({
completeBtnTitle,
setIsEditTemplate
}) {
const filterPrefill =
signerPos && signerPos?.filter((data) => data.Role !== "prefill");
const isMobile = window.innerWidth < 767;
const navigate = useNavigate();
const isGuestSigner = localStorage.getItem("isGuestSigner");
@@ -119,7 +121,7 @@ function Header({
style={{ textDecoration: "none", zIndex: "35" }}
document={<Certificate pdfData={pdfDetails} />}
>
{({ blob, url, loading, error }) => (
{({ blob, loading }) => (
<>
{loading ? (
<div
@@ -129,20 +131,15 @@ function Header({
}}
>
<i
className="fa fa-certificate"
style={{
marginRight: "2px"
}}
className="fa-solid fa-award"
style={{ marginRight: "2px" }}
aria-hidden="true"
></i>
Certificate
</div>
) : (
<div
style={{
border: "none",
backgroundColor: "#fff"
}}
style={{ border: "none", backgroundColor: "#fff" }}
onClick={() =>
handleDownload(
blob,
@@ -153,10 +150,8 @@ function Header({
}
>
<i
className="fa fa-certificate"
style={{
marginRight: "2px"
}}
className="fa-solid fa-award"
style={{ marginRight: "2px" }}
aria-hidden="true"
></i>
Certificate
@@ -176,51 +171,29 @@ function Header({
pdfDetails[0] && pdfDetails[0].Name
}.pdf`}
>
{({ blob, url, loading, error }) =>
loading ? (
<button
type="button"
className="defaultBtn certificateBtn"
{({ loading }) => (
<button
type="button"
className="defaultBtn certificateBtn"
disabled={loading}
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
>
<i
className="fa-solid fa-award"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
) : (
<button
type="button"
className="defaultBtn certificateBtn"
style={{
display: "flex",
flexDirection: "row",
alignItems: "center"
}}
>
<i
className="fa fa-certificate"
style={{
color: "white",
fontSize: "15px",
marginRight: "3px"
}}
aria-hidden="true"
></i>
Certificate
</button>
)
}
aria-hidden="true"
></i>
Certificate
</button>
)}
</PDFDownloadLink>
);
};
@@ -245,7 +218,7 @@ function Header({
<i
className="fa fa-arrow-left"
aria-hidden="true"
style={{ color: themeColor(), cursor: "pointer" }}
style={{ color: themeColor, cursor: "pointer" }}
></i>
</div>
<div>
@@ -283,7 +256,7 @@ function Header({
<DropdownMenu.Trigger asChild>
<div
style={{
color: themeColor(),
color: themeColor,
border: "none",
fontWeight: "650",
fontSize: "16px",
@@ -407,7 +380,7 @@ function Header({
}
}}
style={{
color: isMailSend ? "gray" : themeColor(),
color: isMailSend ? "gray" : themeColor,
border: "none",
fontWeight: "650",
fontSize: "16px"
@@ -421,13 +394,13 @@ function Header({
data-tut="reactourThird"
onClick={() => {
if (!pdfUrl) {
embedImages();
embedWidgetsData();
} else if (isPdfRequestFiles) {
embedImages();
embedWidgetsData();
}
}}
style={{
color: themeColor(),
color: themeColor,
border: "none",
fontWeight: "650",
fontSize: "16px"
@@ -453,7 +426,7 @@ function Header({
{recipient ? (
pdfUrl || isAlreadySign.mssg ? (
<div style={{ display: "flex", flexDirection: "row" }}>
{pdfDetails[0] && pdfDetails.length > 0 && (
{pdfDetails && pdfDetails.length > 0 && (
<CertificateComponent />
)}
<button
@@ -521,7 +494,7 @@ function Header({
className="finishBtn sendHover"
onClick={() => {
if (!pdfUrl) {
embedImages();
embedWidgetsData();
}
}}
>
@@ -533,16 +506,16 @@ function Header({
<>
{!isMailSend &&
signersdata.length > 0 &&
signersdata.length !== signerPos.length && (
signersdata.length !== filterPrefill.length && (
<div>
{signerPos.length === 0 ? (
{filterPrefill.length === 0 ? (
<span style={{ fontSize: "13px", color: "#f5405e" }}>
Add {signersdata.length - signerPos.length} recipients
signature
Add {signersdata.length - filterPrefill.length}{" "}
recipients signature
</span>
) : (
<span style={{ fontSize: "13px", color: "#f5405e" }}>
Add {signersdata.length - signerPos.length} more
Add {signersdata.length - filterPrefill.length} more
recipients signature
</span>
)}
@@ -667,7 +640,7 @@ function Header({
type="button"
className="finishBtn sendHover"
onClick={() => {
embedImages();
embedWidgetsData();
}}
>
Finish
@@ -765,7 +738,7 @@ function Header({
className="finishBtn sendHover"
onClick={() => {
if (!pdfUrl) {
embedImages();
embedWidgetsData();
}
}}
>
@@ -0,0 +1,653 @@
import React, { useState, useEffect } from "react";
import BorderResize from "./BorderResize";
import PlaceholderBorder from "./PlaceholderBorder";
import { Rnd } from "react-rnd";
import { defaultWidthHeight, isMobile } from "../../constant/Utils";
import PlaceholderType from "./PlaceholderType";
import moment from "moment";
import "../../styles/opensigndrive.css";
function Placeholder(props) {
const [isDraggingEnabled, setDraggingEnabled] = useState(true);
const [isShowDateFormat, setIsShowDateFormat] = useState(false);
const [selectDate, setSelectDate] = useState();
const [dateFormat, setDateFormat] = useState([]);
const [saveDateFormat, setSaveDateFormat] = useState("");
const dateFormatArr = [
"L",
"DD-MM-YYYY",
"YYYY-MM-DD",
"MM.DD.YYYY",
"MM-DD-YYYY",
"MMM DD, YYYY",
"LL",
"DD MMM, YYYY",
"DD MMMM, YYYY"
];
const selectFormat = (data) => {
switch (data) {
case "L":
return "MM/dd/yyyy";
case "DD-MM-YYYY":
return "dd-MM-yyyy";
case "DD/MM/YYYY":
return "dd/MM/yyyy";
case "LL":
return "MMMM dd, yyyy";
case "DD MMM, YYYY":
return "dd MMM, YYYY";
case "YYYY-MM-DD":
return "YYYY-MM-dd";
case "MM-DD-YYYY":
return "MM-dd-YYYY";
case "MM.DD.YYYY":
return "MM.dd.YYYY";
case "MMM DD, YYYY":
return "MMM dd, YYYY";
case "DD MMMM, YYYY":
return "dd MMMM, YYYY";
default:
return "dd/MM/yyyy";
}
};
useEffect(() => {
//set default current date and default format MM/dd/yyyy
if (props.isSignYourself) {
const date = new Date();
const milliseconds = date.getTime();
const newDate = moment(milliseconds).format("MM/DD/YYYY");
const dateObj = {
date: newDate,
format: "MM/dd/YYYY"
};
setSelectDate(dateObj);
} else {
const defaultRes = props?.pos?.options?.response;
const defaultFormat = props.pos?.options?.validation?.format;
const updateDate = defaultRes
? new Date(props?.pos?.options?.response)
: new Date();
const dateFormat = defaultFormat ? defaultFormat : "MM/DD/YYYY";
const milliseconds = updateDate.getTime();
const newDate = moment(milliseconds).format(dateFormat);
const dateObj = {
date: newDate,
format: props.pos?.options?.validation?.format
? props.pos?.options?.validation?.format
: "MM/dd/YYYY"
};
setSelectDate(dateObj);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
//function for add selected date and format in selectFormat
const changeDateFormat = () => {
const updateDate = [];
dateFormatArr.map((data) => {
let date;
if (selectDate.format === "dd-MM-yyyy") {
const [day, month, year] = selectDate.date.split("-");
date = new Date(`${year}-${month}-${day}`);
} else {
date = new Date(selectDate?.date);
}
const milliseconds = date.getTime();
const newDate = moment(milliseconds).format(data);
const dateObj = {
date: newDate,
format: selectFormat(data)
};
updateDate.push(dateObj);
});
setDateFormat(updateDate);
};
useEffect(() => {
if (props.isPlaceholder || props.isSignYourself) {
selectDate && changeDateFormat();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectDate]);
//handle to close drop down menu onclick screen
useEffect(() => {
const closeMenuOnOutsideClick = (e) => {
if (isShowDateFormat && !e.target.closest("#menu-container")) {
setIsShowDateFormat(!isShowDateFormat);
}
};
document.addEventListener("click", closeMenuOnOutsideClick);
return () => {
// Cleanup the event listener when the component unmounts
document.removeEventListener("click", closeMenuOnOutsideClick);
};
}, [isShowDateFormat]);
//onclick placeholder function to open signature pad
const handlePlaceholderClick = () => {
if (props.setSelectWidgetId) {
props.setSelectWidgetId(props.pos.key);
}
const widgetTypeExist = [
"text",
"checkbox",
"name",
"company",
"job title",
"date",
"email"
].includes(props.pos.type);
if (widgetTypeExist) {
setDraggingEnabled(false);
}
if ((props.isNeedSign || props.isSignYourself) && !props.isDragging) {
if (props.pos.type) {
if (
props.pos.type === "signature" ||
props.pos.type === "stamp" ||
props.pos.type === "image"
) {
props.setIsSignPad(true);
props.setSignKey(props.pos.key);
props.setIsStamp(props.pos.isStamp);
} else if (props.pos.type === "initials") {
props.setIsSignPad(true);
props.setSignKey(props.pos.key);
props.setIsStamp(props.pos.isStamp);
props.setIsInitial(true);
}
} else {
props.setIsSignPad(true);
props.setSignKey(props.pos.key);
props.setIsStamp(props.pos?.isStamp ? props.pos.isStamp : false);
}
} else if (
props.isPlaceholder &&
!props.isDragging &&
props.pos.type !== "label"
) {
if (props.pos.key === props.selectWidgetId) {
props.handleLinkUser(props.data.Id);
props.setUniqueId(props.data.Id);
}
} else if (!props.pos.type) {
if (
!props.pos.type &&
props.isNeedSign &&
props.data.signerObjId === props.signerObjId
) {
props.setIsSignPad(true);
props.setSignKey(props.pos.key);
props.setIsStamp(props.pos.isStamp);
} else if (
(props.isNeedSign && props.pos.type === "signature") ||
props.pos.type === "stamp"
) {
props.setIsSignPad(true);
props.setSignKey(props.pos.key);
props.setIsStamp(props.pos.isStamp);
} else if (props.isNeedSign && props.pos.type === "dropdown") {
props.setSignKey(props.pos.key);
}
}
};
const handleWidgetsOnclick = () => {
if (props.pos.type === "radio") {
props.setIsRadio(true);
} else if (props.pos.type === "dropdown") {
props?.setShowDropdown(true);
} else if (props.pos.type === "checkbox") {
props?.setIsCheckbox(true);
} else {
props?.handleNameModal(true);
}
if (props.isPlaceholder) {
props.setUniqueId(props.data.Id);
}
props.setSignKey(props.pos.key);
props.setWidgetType(props.pos.type);
props.setCurrWidgetsDetails(props.pos);
};
const PlaceholderIcon = () => {
return (
props.isShowBorder && (
<>
{(props.isPlaceholder || props.isSignYourself) && (
<>
{props.pos.type === "checkbox" && props.isSignYourself ? (
<i
onClick={(e) => {
e.stopPropagation();
handleWidgetsOnclick();
}}
onTouchEnd={(e) => {
e.stopPropagation();
handleWidgetsOnclick();
}}
className="fa-solid fa-gear settingIcon"
style={{
color: "#188ae2",
right: "9px",
top: "-28px"
}}
></i>
) : (
props.pos.type !== "date" &&
props.pos.type !== "label" &&
props.pos.type !== "signature" &&
!props.isSignYourself && (
<i
onClick={(e) => {
e.stopPropagation();
handleWidgetsOnclick();
}}
onTouchEnd={(e) => {
e.stopPropagation();
handleWidgetsOnclick();
}}
className="fa-solid fa-gear settingIcon"
style={{
color: "#188ae2",
right: ["checkbox", "radio"].includes(props.pos.type)
? "24px"
: "47px",
top: ["checkbox", "radio"].includes(props.pos.type)
? "-28px"
: "-19px"
}}
></i>
)
)}
{props.pos.type !== "label" && !props.isSignYourself && (
<i
data-tut="reactourLinkUser"
className="fa-regular fa-user signUserIcon"
onClick={(e) => {
e.stopPropagation();
props.handleLinkUser(props.data.Id);
props.setUniqueId(props.data.Id);
}}
onTouchEnd={(e) => {
e.stopPropagation();
props.handleLinkUser(props.data.Id);
props.setUniqueId(props.data.Id);
}}
style={{
color: "#188ae2",
right:
props.pos.type === "checkbox" ||
props.pos.type === "radio"
? "8px"
: "32px",
top:
props.pos.type === "checkbox" ||
props.pos.type === "radio"
? "-28px"
: "-18px"
}}
></i>
)}
</>
)}
{props.pos.type === "date" && selectDate && (
<div
id="menu-container"
style={{
zIndex: "99",
top: "-19px",
right: props.isPlaceholder ? "60px" : "44px"
}}
className={
isShowDateFormat
? "dropdown signUserIcon show"
: "dropdown signUserIcon"
}
onClick={(e) => {
setIsShowDateFormat(!isShowDateFormat);
e.stopPropagation();
if (props.data) {
props.setSignKey(props.pos.key);
props.setUniqueId(props.data.Id);
}
}}
onTouchEnd={(e) => {
e.stopPropagation();
setIsShowDateFormat(!isShowDateFormat);
if (props.data) {
props.setSignKey(props.pos.key);
props.setUniqueId(props.data.Id);
}
}}
>
<i
className="fa-solid fa-gear settingIcon"
style={{
color: "#188ae2",
fontSize: "14px"
}}
></i>
<div
className={
isShowDateFormat ? "dropdown-menu show" : "dropdown-menu"
}
aria-labelledby="dropdownMenuButton"
aria-expanded={isShowDateFormat ? "true" : "false"}
>
{dateFormat.map((data, ind) => {
return (
<span
key={ind}
onTouchEnd={(e) => {
e.stopPropagation();
setIsShowDateFormat(!isShowDateFormat);
setSelectDate(data);
}}
onClick={() => {
setIsShowDateFormat(!isShowDateFormat);
setSelectDate(data);
}}
className="dropdown-item itemColor"
style={{ fontSize: "12px" }}
>
{data?.date ? data?.date : "nodata"}
</span>
);
})}
</div>
</div>
)}
<i
className="fa-regular fa-copy signCopy"
onClick={(e) => {
if (props.data) {
props.setSignerObjId(props.data.signerObjId);
props.setUniqueId(props.data.Id);
}
e.stopPropagation();
props.setIsPageCopy(true);
props.setSignKey(props.pos.key);
}}
onTouchEnd={(e) => {
if (props.data) {
props.setSignerObjId(props.data.signerObjId);
props.setUniqueId(props.data.Id);
}
e.stopPropagation();
props.setIsPageCopy(true);
props.setSignKey(props.pos.key);
}}
style={{
color: "#188ae2",
right:
props.pos.type === "checkbox" || props.pos.type === "radio"
? "-9px"
: "12px",
top:
props.pos.type === "checkbox" || props.pos.type === "radio"
? "-28px"
: "-18px"
}}
></i>
<i
className="fa-regular fa-circle-xmark signCloseBtn"
onClick={(e) => {
e.stopPropagation();
if (props.data) {
props.handleDeleteSign(props.pos.key, props.data.Id);
} else {
props.handleDeleteSign(props.pos.key);
props.setIsStamp(false);
}
}}
onTouchEnd={(e) => {
e.stopPropagation();
if (props.data) {
props.handleDeleteSign(props.pos.key, props.data?.Id);
} else {
props.handleDeleteSign(props.pos.key);
props.setIsStamp(false);
}
}}
style={{
color: "#188ae2",
right:
props.pos.type === "checkbox" || props.pos.type === "radio"
? "-27px"
: "-8px",
top:
props.pos.type === "checkbox" || props.pos.type === "radio"
? "-28px"
: "-18px"
}}
></i>
</>
)
);
};
return (
<Rnd
data-tut={props.pos.key === props.unSignedWidgetId ? "IsSigned" : ""}
//ref={nodeRef}
key={props.pos.key}
lockAspectRatio={
props.pos.type !== "label" &&
(props.pos.Width
? props.pos.Width / props.pos.Height
: defaultWidthHeight(props.pos.type).width /
defaultWidthHeight(props.pos.type).height)
}
enableResizing={{
top: false,
right: false,
bottom: false,
left: false,
topRight: false,
bottomRight:
props.data && props.isNeedSign
? props.data?.signerObjId === props.signerObjId &&
props.pos.type !== "checkbox" &&
props.pos.type !== "radio"
? true
: false
: props.pos.type !== "radio" &&
props.pos.type !== "checkbox" &&
props.pos.key === props.selectWidgetId &&
true,
bottomLeft: false,
topLeft: false
}}
bounds="parent"
className="signYourselfBlock"
style={{
border: props.pos.type !== "checkbox" && "1px solid #007bff",
borderRadius: props.pos.type !== "checkbox" && "2px",
textAlign:
props.pos.type !== "name" &&
props.pos.type !== "company" &&
props.pos.type !== "job title" &&
"center",
cursor:
props.data && props.isNeedSign
? props.data?.signerObjId === props.signerObjId
? "pointer"
: "not-allowed"
: "all-scroll",
zIndex:
props.pos.type === "date"
? "99"
: props?.pos?.zIndex
? props.pos.zIndex
: "5",
background: props.data
? props.data.blockColor
: props.pos.type !== "checkbox" && "rgb(203 233 237)"
}}
onDrag={() => {
setDraggingEnabled(true);
props.handleTabDrag && props.handleTabDrag(props.pos.key);
}}
size={{
width: props.posWidth(props.pos, props.isSignYourself),
height: props.posHeight(props.pos, props.isSignYourself)
}}
onResizeStart={() => {
setDraggingEnabled(true);
props.setIsResize && props.setIsResize(true);
}}
onResizeStop={() => {
props.setIsResize && props.setIsResize(false);
}}
disableDragging={
props.isNeedSign
? true
: props.isPlaceholder && props.pos.type !== "date"
? false
: !isDraggingEnabled
}
onDragStop={(event, dragElement) =>
props.handleStop &&
props.handleStop(event, dragElement, props.data?.Id, props.pos?.key)
}
default={{
x: props.xPos(props.pos, props.isSignYourself),
y: props.yPos(props.pos, props.isSignYourself)
}}
onResize={(e, direction, ref) => {
props.handleSignYourselfImageResize &&
props.handleSignYourselfImageResize(
ref,
props.pos.key,
props.xyPostion,
props.setXyPostion,
props.index,
props.data && props.data.Id,
false
);
}}
onClick={() => {
!props.isNeedSign && props.setWidgetType(props.pos.type);
props.isNeedSign && props.data?.signerObjId === props.signerObjId
? handlePlaceholderClick()
: props.isPlaceholder
? handlePlaceholderClick()
: props.isSignYourself && handlePlaceholderClick();
}}
>
{props.isShowBorder &&
props.pos.type !== "radio" &&
props.pos.type !== "checkbox" &&
props.pos.key === props.selectWidgetId ? (
<BorderResize
right={
props.pos.type === "checkbox" || props.pos.type === "radio"
? -21
: -12
}
top={
props.pos.type === "checkbox" || props.pos.type === "radio"
? -21
: -11
}
/>
) : props.data && props.isNeedSign && props.pos.type !== "checkbox" ? (
props.data?.signerObjId === props.signerObjId &&
props.pos.type !== "radio" &&
props.pos.type !== "checkbox" ? (
<BorderResize />
) : (
<></>
)
) : (
props.pos.type !== "radio" &&
props.pos.type !== "checkbox" &&
props.pos.key === props.selectWidgetId && <BorderResize />
)}
{props.isShowBorder && props.pos.key === props.selectWidgetId && (
<PlaceholderBorder
setDraggingEnabled={setDraggingEnabled}
pos={props.pos}
isPlaceholder={props.isPlaceholder}
/>
)}
{isMobile ? (
<div
style={{
left: props.xPos(props.pos, props.isSignYourself),
top: props.yPos(props.pos, props.isSignYourself),
width: props.posWidth(props.pos, props.isSignYourself),
// height: props.posHeight(props.pos, props.isSignYourself),
zIndex: "10"
}}
onTouchEnd={() => {
!props.isNeedSign && props.setWidgetType(props.pos.type);
props.isNeedSign && props.data?.signerObjId === props.signerObjId
? handlePlaceholderClick()
: props.isPlaceholder
? handlePlaceholderClick()
: props.isSignYourself && handlePlaceholderClick();
}}
>
{props.pos.key === props.selectWidgetId && <PlaceholderIcon />}
<PlaceholderType
pos={props.pos}
xyPostion={props.xyPostion}
index={props.index}
setXyPostion={props.setXyPostion}
data={props.data}
setSignKey={props.setSignKey}
isShowDropdown={props?.isShowDropdown}
isPlaceholder={props.isPlaceholder}
isSignYourself={props.isSignYourself}
signerObjId={props.signerObjId}
handleUserName={props.handleUserName}
setDraggingEnabled={setDraggingEnabled}
pdfDetails={props?.pdfDetails && props?.pdfDetails[0]}
isNeedSign={props.isNeedSign}
setSelectDate={setSelectDate}
selectDate={selectDate}
setSaveDateFormat={setSaveDateFormat}
saveDateFormat={saveDateFormat}
setValidateAlert={props.setValidateAlert}
/>
</div>
) : (
<>
{props.pos.key === props.selectWidgetId && <PlaceholderIcon />}
<PlaceholderType
pos={props.pos}
xyPostion={props.xyPostion}
index={props.index}
setXyPostion={props.setXyPostion}
data={props.data}
setSignKey={props.setSignKey}
isShowDropdown={props?.isShowDropdown}
isPlaceholder={props.isPlaceholder}
isSignYourself={props.isSignYourself}
signerObjId={props.signerObjId}
handleUserName={props.handleUserName}
setDraggingEnabled={setDraggingEnabled}
pdfDetails={props?.pdfDetails && props?.pdfDetails[0]}
isNeedSign={props.isNeedSign}
setSelectDate={setSelectDate}
selectDate={selectDate}
setSaveDateFormat={setSaveDateFormat}
saveDateFormat={saveDateFormat}
setValidateAlert={props.setValidateAlert}
/>
</>
)}
</Rnd>
);
}
export default Placeholder;
@@ -0,0 +1,36 @@
import React from "react";
import { themeColor } from "../../constant/const";
import {
defaultWidthHeight,
resizeBorderExtraWidth
} from "../../constant/Utils";
function PlaceholderBorder(props) {
const getResizeBorderExtraWidth =
props.pos.type === "checkbox" || props.pos.type === "radio"
? 38
: resizeBorderExtraWidth();
const defaultWidth = defaultWidthHeight(props.pos.type).width;
const defaultHeight = defaultWidthHeight(props.pos.type).height;
return (
<div
onMouseEnter={props?.setDraggingEnabled(true)}
className="borderResize"
style={{
borderColor: themeColor,
borderStyle: "dashed",
width: props.pos.Width
? props.pos.Width + getResizeBorderExtraWidth
: defaultWidth + getResizeBorderExtraWidth,
height: props.pos.Height
? props.pos.Height + getResizeBorderExtraWidth
: defaultHeight + getResizeBorderExtraWidth,
borderWidth: "0.2px",
overflow: "hidden"
}}
></div>
);
}
export default PlaceholderBorder;
@@ -1,62 +1,55 @@
import React, { useState } from "react";
import { themeColor } from "../../utils/ThemeColor/backColor";
import ModalUi from "../../premitives/ModalUi";
import { themeColor } from "../../constant/const";
import ModalUi from "../../primitives/ModalUi";
import { randomId } from "../../constant/Utils";
function PlaceholderCopy(props) {
const copyType = ["All pages", "All pages but last", "All pages but first"];
const [selectCopyType, setSelectCopyType] = useState("");
//get RandomKey Id
const randomKey = () => {
const randomId = Math.floor(1000 + Math.random() * 9000);
return randomId;
};
//function for get copy placeholder position
const getCopyPlaceholderPosition = (
type,
rest,
currentPlaceholder,
newPageNumber,
existPlaceholderPosition
) => {
let obj;
const filterPosition =
existPlaceholderPosition &&
existPlaceholderPosition.filter(
(data) => data.xPosition !== rest.xPosition
(data) => data.xPosition !== currentPlaceholder.xPosition
);
//copy all page placeholder at requested position except first page
if (newPageNumber === 1 && type === "first") {
if (filterPosition && filterPosition.length > 0) {
return (obj = {
return {
pageNumber: newPageNumber,
pos: [...filterPosition]
});
};
}
}
//copy all page placeholder at requested position except last page
else if (newPageNumber === props.allPages && type === "last") {
if (existPlaceholderPosition) {
return (obj = {
return {
pageNumber: newPageNumber,
pos: [...filterPosition]
});
};
}
}
//copy all page placeholder at requested position with existing placeholder position
else if (existPlaceholderPosition) {
return (obj = {
return {
pageNumber: newPageNumber,
pos: [...filterPosition, rest]
});
pos: [...filterPosition, currentPlaceholder]
};
}
//copy all page placeholder at requested position
else {
return (obj = {
return {
pageNumber: newPageNumber,
pos: [rest]
});
pos: [currentPlaceholder]
};
}
};
@@ -66,6 +59,7 @@ function PlaceholderCopy(props) {
let newPageNumber = 1;
const signerPosition = props.xyPostion;
const signerId = props.signerObjId ? props.signerObjId : props.Id;
//handle placeholder array and copy for multiple signers placeholder at requested location
if (signerId) {
//get current signers data
@@ -84,13 +78,13 @@ function PlaceholderCopy(props) {
(data) => data.pageNumber === props.pageNumber
);
//get current placeholder position data which user want to copy
const currentPlaceholder = placeholderPosition[0].pos.filter(
const currentPlaceholder = placeholderPosition[0].pos.find(
(position) => position.key === props.signKey
);
const { key, ...rest } = currentPlaceholder[0];
for (let i = 0; i < props.allPages; i++) {
const newId = randomKey();
rest.key = newId;
const newId = randomId();
currentPlaceholder.key = newId;
//get exist placeholder position for particular page
const existPlaceholder = filterSignerPosition[0].placeHolder.filter(
(data) => data.pageNumber === newPageNumber
@@ -101,7 +95,7 @@ function PlaceholderCopy(props) {
//function for get copy to requested location of placeholder position
const getPlaceholderObj = getCopyPlaceholderPosition(
type,
rest,
currentPlaceholder,
newPageNumber,
existPlaceholderPosition
);
@@ -112,7 +106,7 @@ function PlaceholderCopy(props) {
}
let updatedSignerPlaceholder;
if (props?.signerObjId) {
updatedSignerPlaceholder = signerPosition.map((signersData, ind) => {
updatedSignerPlaceholder = signerPosition.map((signersData) => {
if (signersData.signerObjId === props.signerObjId) {
return {
...signersData,
@@ -122,7 +116,7 @@ function PlaceholderCopy(props) {
return signersData;
});
} else {
updatedSignerPlaceholder = signerPosition.map((signersData, ind) => {
updatedSignerPlaceholder = signerPosition.map((signersData) => {
if (signersData.Id === props.Id) {
return {
...signersData,
@@ -132,17 +126,6 @@ function PlaceholderCopy(props) {
return signersData;
});
}
// const updatedSignerPlaceholder = signerPosition.map(
// (signersData, ind) => {
// if (signersData.signerObjId === props.signerObjId) {
// return {
// ...signersData,
// placeHolder: newPlaceholderPosition
// };
// }
// return signersData;
// }
// );
const signersData = signerPosition;
signersData.splice(0, signerPosition.length, ...updatedSignerPlaceholder);
@@ -156,10 +139,10 @@ function PlaceholderCopy(props) {
(data) => data.pageNumber === props.pageNumber
);
//get current placeholder position data which user want to copy
const currentPlaceholder = placeholderPosition[0].pos.filter(
const currentPlaceholder = placeholderPosition[0].pos.find(
(pos) => pos.key === props.signKey
);
const { key, ...rest } = currentPlaceholder[0];
for (let i = 0; i < props.allPages; i++) {
//get exist placeholder position for particular page
const existPlaceholder = xyPostion.filter(
@@ -168,12 +151,12 @@ function PlaceholderCopy(props) {
const existPlaceholderPosition =
existPlaceholder[0] && existPlaceholder[0].pos;
const newId = randomKey();
rest.key = newId;
const newId = randomId();
currentPlaceholder.key = newId;
//function for get copy to requested location of placeholder position
const getPlaceholderObj = getCopyPlaceholderPosition(
type,
rest,
currentPlaceholder,
newPageNumber,
existPlaceholderPosition
);
@@ -239,9 +222,7 @@ function PlaceholderCopy(props) {
handleApplyCopy();
props.setIsPageCopy(false);
}}
style={{
background: themeColor()
}}
style={{ background: themeColor }}
type="button"
disabled={!selectCopyType}
className="finishBtn"
@@ -0,0 +1,805 @@
import React, { useEffect, useState, forwardRef, useRef } from "react";
import { getMonth, getYear, onChangeInput, range } from "../../constant/Utils";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import "../../styles/signature.css";
import RegexParser from "regex-parser";
function PlaceholderType(props) {
const type = props?.pos?.type;
const [selectOption, setSelectOption] = useState(
props.pos?.options?.defaultValue ? props.pos?.options?.defaultValue : ""
);
const [startDate, setStartDate] = useState(new Date());
const [validatePlaceholder, setValidatePlaceholder] = useState("");
const inputRef = useRef(null);
const [textValue, setTextValue] = useState();
const [selectedCheckbox, setSelectedCheckbox] = useState([]);
const years = range(1990, getYear(new Date()) + 16, 1);
const months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
];
const validateExpression = (regexValidation) => {
let regexObject = regexValidation;
if (props.pos?.options.validation.type === "regex") {
regexObject = RegexParser(regexValidation);
}
// new RegExp(regexValidation);
let isValidate = regexObject.test(textValue);
if (!isValidate) {
props?.setValidateAlert(true);
inputRef.current.focus();
}
};
const handleInputBlur = () => {
props.setDraggingEnabled(true);
const validateType = props.pos?.options?.validation?.type;
let regexValidation;
if (validateType) {
switch (validateType) {
case "email":
regexValidation = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
validateExpression(regexValidation);
break;
case "number":
regexValidation = /^\d+$/;
validateExpression(regexValidation);
break;
case "text":
regexValidation = /^[a-zA-Z\s]+$/;
validateExpression(regexValidation);
break;
default:
regexValidation = props.pos?.options.validation.pattern;
validateExpression(regexValidation);
}
}
};
const handleTextValid = (e) => {
const textInput = e.target.value;
setTextValue(textInput);
};
function checkRegularExpress(validateType) {
switch (validateType) {
case "email":
setValidatePlaceholder("demo@gmail.com");
break;
case "number":
setValidatePlaceholder("12345");
break;
case "text":
setValidatePlaceholder("enter text");
break;
default:
setValidatePlaceholder("enter text");
}
}
useEffect(() => {
if (props.isNeedSign && type === "date") {
const updateDate = new Date();
setStartDate(updateDate);
} else if (type && type === "checkbox" && props.isNeedSign) {
const isDefaultValue = props.pos.options?.defaultValue;
if (isDefaultValue) {
setSelectedCheckbox(isDefaultValue);
}
} else if (props.pos?.options?.hint) {
setValidatePlaceholder(props.pos?.options.hint);
} else if (props.pos?.options?.validation?.type) {
checkRegularExpress(props.pos?.options?.validation?.type);
}
setTextValue(
props.pos?.options?.defaultValue ? props.pos?.options?.defaultValue : ""
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if (
["name", "email", "job title", "company"].includes(props.pos?.type) &&
props.isNeedSign &&
props.data?.signerObjId === props?.signerObjId
) {
const defaultData = props.pos?.options?.defaultValue;
if (defaultData) {
setTextValue(defaultData);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.pos?.options?.defaultValue]);
useEffect(() => {
if (type && type === "date") {
if (props.selectDate) {
let updateDate;
if (props.selectDate.format === "dd-MM-yyyy") {
const [day, month, year] = props.saveDateFormat.split("-");
updateDate = new Date(`${year}-${month}-${day}`);
} else {
if (props?.saveDateFormat) {
updateDate = new Date(props.saveDateFormat);
}
}
// const updateDate = new Date(props.saveDateFormat);
setStartDate(updateDate);
const dateObj = {
date: props.saveDateFormat,
format: props.selectDate
? props.selectDate?.format
: props.pos?.options?.validation?.format
? props.pos?.options?.validation?.format
: "MM/dd/YYYY"
};
props.setSelectDate(dateObj);
onChangeInput(
props.saveDateFormat,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data.Id,
false,
props.selectDate?.format
? props.selectDate.format
: props.pos?.options?.validation?.format
? props.pos?.options?.validation?.format
: "MM/dd/YYYY"
);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.saveDateFormat]);
const dateValue = (value) => {
props.setSaveDateFormat(value);
return <span>{value}</span>;
};
const ExampleCustomInput = forwardRef(({ value, onClick }, ref) => (
<div
className="inputPlaceholder"
style={{ overflow: "hidden", fontSize: calculateFontSize() }}
onClick={onClick}
ref={ref}
>
{dateValue(value)}
<i className="fa-regular fa-calendar" style={{ marginLeft: "5px" }}></i>
</div>
));
ExampleCustomInput.displayName = "ExampleCustomInput";
useEffect(() => {
if (
["name", "email", "job title", "company"].includes(type) &&
props.isNeedSign &&
props.data?.signerObjId === props.signerObjId
) {
const isDefault = true;
const senderUser = localStorage.getItem(`Extand_Class`);
const jsonSender = JSON.parse(senderUser);
onChangeInput(
jsonSender && jsonSender[0],
null,
props.xyPostion,
null,
props.setXyPostion,
props.data.Id,
isDefault
);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [type]);
const calculateFontSize = () => {
const fontSize = 10 + Math.min(props.pos.Width, props.pos.Height) * 0.1;
const size = fontSize ? fontSize : 12;
return size + "px";
};
//function for show checked checkbox
const selectCheckbox = (ind) => {
const res = props.pos.options?.response;
const defaultCheck = props.pos.options?.defaultValue;
if (res && res?.length > 0) {
const isSelectIndex = res.indexOf(ind);
if (isSelectIndex > -1) {
return true;
} else {
return false;
}
// }
} else if (defaultCheck) {
const isSelectIndex = defaultCheck.indexOf(ind);
if (isSelectIndex > -1) {
return true;
} else {
return false;
}
} else {
return false;
}
};
const handleRadioCheck = (data) => {
const defaultData = props.pos.options?.defaultValue;
if (textValue === data) {
return true;
} else if (defaultData === data) {
return true;
} else {
return false;
}
};
//function for set checked and unchecked value of checkbox
const handleCheckboxValue = (isChecked, ind) => {
let updateSelectedCheckbox = [],
checkedList;
let isDefaultValue, isDefaultEmpty;
if (type === "checkbox") {
updateSelectedCheckbox = selectedCheckbox ? selectedCheckbox : [];
if (isChecked) {
updateSelectedCheckbox.push(ind);
setSelectedCheckbox(updateSelectedCheckbox);
} else {
checkedList = selectedCheckbox.filter((data) => data !== ind);
setSelectedCheckbox(checkedList);
}
if (props.isNeedSign) {
isDefaultValue = props.pos.options?.defaultValue;
}
if (isDefaultValue && isDefaultValue.length > 0) {
isDefaultEmpty = true;
}
onChangeInput(
checkedList ? checkedList : updateSelectedCheckbox,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data.Id,
false,
null,
isDefaultEmpty
);
}
};
//function to handle select radio widget and set value seletced by user
const handleCheckRadio = (isChecked, data) => {
let isDefaultValue,
isDefaultEmpty,
isRadio = true;
if (props.isNeedSign) {
isDefaultValue = props.pos.options?.defaultValue;
}
if (isDefaultValue) {
isDefaultEmpty = true;
}
if (isChecked) {
setTextValue(data);
} else {
setTextValue("");
}
onChangeInput(
data,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data.Id,
false,
null,
isDefaultEmpty,
isRadio
);
};
switch (type) {
case "signature":
return props.pos.SignUrl ? (
<img
alt="signimg"
src={props.pos.SignUrl}
style={{
width: "99%",
height: "100%",
objectFit: "contain"
}}
/>
) : (
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
{props?.handleUserName &&
props?.handleUserName(
props?.data?.Id,
props?.data?.Role,
props?.pos?.type
)}
</div>
);
case "stamp":
return props.pos.SignUrl ? (
<img
alt="signimg"
src={props.pos.SignUrl}
style={{
width: "99%",
height: "100%",
objectFit: "contain"
}}
/>
) : (
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
{props?.handleUserName &&
props?.handleUserName(
props?.data?.Id,
props?.data?.Role,
props?.pos?.type
)}
</div>
);
case "checkbox":
return (
<div style={{ zIndex: props.isSignYourself && "99" }}>
{props.pos.options?.values?.map((data, ind) => {
return (
<input
key={ind}
style={{
width: props.pos.Width,
display: "flex",
justifyContent: "center",
marginBottom: "6px",
marginTop: "5px"
}}
onBlur={handleInputBlur}
disabled={
props.isNeedSign &&
(props.pos.options?.isReadOnly ||
props.data?.signerObjId !== props.signerObjId)
}
type="checkbox"
checked={selectCheckbox(ind)}
onChange={(e) => {
if (e.target.checked) {
if (!props.isPlaceholder) {
const maxRequired =
props.pos.options?.validation?.maxRequiredCount;
const maxCountInt = maxRequired && parseInt(maxRequired);
if (maxCountInt > 0) {
if (
selectedCheckbox &&
selectedCheckbox?.length <= maxCountInt - 1
) {
handleCheckboxValue(e.target.checked, ind);
}
} else {
handleCheckboxValue(e.target.checked, ind);
}
}
} else {
handleCheckboxValue(e.target.checked, ind);
}
}}
/>
);
})}
</div>
);
case "text":
return props.isSignYourself ||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<input
className="inputPlaceholder"
ref={inputRef}
placeholder={validatePlaceholder}
style={{ fontSize: calculateFontSize() }}
value={textValue}
type="text"
tabIndex="0"
disabled={
props.isNeedSign && props.data?.signerObjId !== props.signerObjId
? true
: props.isPlaceholder
}
onBlur={handleInputBlur}
onChange={(e) => {
setTextValue(e.target.value);
onChangeInput(
e.target.value,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data?.Id,
false
);
}}
/>
) : (
<div
style={{
color: "black",
fontSize: calculateFontSize()
}}
>
<span>{type}</span>
</div>
);
case "dropdown":
return props.data?.signerObjId === props.signerObjId ? (
<select
className="inputPlaceholder"
id="myDropdown"
style={{ fontSize: "12px" }}
value={selectOption}
onChange={(e) => {
setSelectOption(e.target.value);
onChangeInput(
e.target.value,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data?.Id,
false
);
}}
>
{/* Default/Title option */}
<option value="" disabled hidden>
{props.pos.options.name}
</option>
{props.pos?.options?.values.map((data, ind) => {
return (
<option key={ind} value={data}>
{data}
</option>
);
})}
</select>
) : (
<div
className="inputPlaceholder"
style={{ fontSize: calculateFontSize() }}
>
{props.pos?.options?.name ? props.pos.options.name : type}
</div>
);
case "initials":
return props.pos.SignUrl ? (
<img
alt="signimg"
src={props.pos.SignUrl}
style={{
width: "99%",
height: "100%",
objectFit: "contain"
}}
/>
) : (
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
{props?.handleUserName &&
props?.handleUserName(
props?.data?.Id,
props?.data?.Role,
props?.pos?.type
)}
</div>
);
case "name":
return props.isSignYourself ||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<input
tabIndex="0"
ref={inputRef}
placeholder={"name"}
style={{ fontSize: calculateFontSize() }}
className="inputPlaceholder"
type="text"
value={textValue}
onBlur={handleInputBlur}
onChange={(e) => {
const isDefault = false;
handleTextValid(e);
onChangeInput(
e.target.value,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data?.Id,
isDefault
);
}}
/>
) : (
<div
style={{
color: "black",
fontSize: calculateFontSize()
}}
>
<span>{type}</span>
</div>
);
case "company":
return props.isSignYourself ||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<input
className="inputPlaceholder"
type="text"
ref={inputRef}
placeholder={"company"}
style={{ fontSize: calculateFontSize() }}
value={textValue}
onBlur={handleInputBlur}
onChange={(e) => {
handleTextValid(e);
onChangeInput(
e.target.value,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data?.Id,
false
);
}}
/>
) : (
<div
style={{
color: "black",
fontSize: calculateFontSize()
}}
>
<span>{type}</span>
</div>
);
case "job title":
return props.isSignYourself ||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<input
className="inputPlaceholder"
type="text"
ref={inputRef}
placeholder={"job title"}
style={{ fontSize: calculateFontSize() }}
value={textValue}
onBlur={handleInputBlur}
onChange={(e) => {
handleTextValid(e);
onChangeInput(
e.target.value,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data?.Id,
false
);
}}
/>
) : (
<div
style={{
color: "black",
fontSize: calculateFontSize()
}}
>
<span>{type}</span>
</div>
);
case "date":
return (
<div>
<DatePicker
renderCustomHeader={({ date, changeYear, changeMonth }) => (
<div className="flex justify-start ml-2 ">
<select
className="bg-transparent outline-none"
value={months[getMonth(date)]}
onChange={({ target: { value } }) =>
changeMonth(months.indexOf(value))
}
>
{months.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
<select
className="bg-transparent outline-none"
value={getYear(date)}
onChange={({ target: { value } }) => changeYear(value)}
>
{years.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
</div>
)}
disabled={
props.isNeedSign && props.data?.signerObjId !== props.signerObjId
}
onBlur={handleInputBlur}
closeOnScroll={true}
className="inputPlaceholder"
style={{ outlineColor: "#007bff" }}
selected={
startDate
? startDate
: props.pos.options?.response &&
new Date(props.pos.options.response)
}
onChange={(date) => {
setStartDate(date);
}}
popperPlacement="top-end"
customInput={<ExampleCustomInput />}
dateFormat={
props.selectDate
? props.selectDate?.format
: props.pos?.options?.validation?.format
? props.pos?.options?.validation?.format
: "MM/dd/YYYY"
}
/>
</div>
);
case "image":
return props.pos.SignUrl ? (
<img
alt="signimg"
src={props.pos.SignUrl}
style={{
width: "99%",
height: "100%",
objectFit: "contain"
}}
/>
) : (
<div style={{ fontSize: 11, color: "black", justifyContent: "center" }}>
{props?.handleUserName &&
props?.handleUserName(
props?.data?.Id,
props?.data?.Role,
props?.pos?.type
)}
</div>
);
case "email":
return props.isSignYourself ||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
<input
className="inputPlaceholder"
type="text"
ref={inputRef}
placeholder={"email"}
style={{ fontSize: calculateFontSize() }}
value={textValue}
onBlur={handleInputBlur}
onChange={(e) => {
handleTextValid(e);
onChangeInput(
e.target.value,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data?.Id,
false
);
}}
/>
) : (
<div
style={{
color: "black",
fontSize: calculateFontSize()
}}
>
<span>{type}</span>
</div>
);
case "radio":
return (
<div>
{props.pos.options?.values.map((data, ind) => {
return (
<input
key={ind}
style={{
width: props.pos.Width,
display: "flex",
justifyContent: "center",
marginBottom: "6px",
marginTop: "5px"
}}
type="radio"
disabled={
props.isNeedSign &&
(props.pos.options?.isReadOnly ||
props.data?.signerObjId !== props.signerObjId)
}
checked={handleRadioCheck(data)}
onChange={(e) => {
if (!props.isPlaceholder) {
handleCheckRadio(e.target.checked, data);
}
}}
/>
);
})}
</div>
);
case "label":
return (
<textarea
placeholder="Enter label"
rows={1}
onChange={(e) => {
onChangeInput(
e.target.value,
props.pos.key,
props.xyPostion,
props.index,
props.setXyPostion,
props.data && props.data?.Id,
false
);
}}
className="labelTextArea"
style={{ whiteSpace: "pre-wrap" }}
cols="50"
/>
);
default:
return props.pos.SignUrl ? (
<div style={{ pointerEvents: "none" }}>
<img
alt="signimg"
src={props.pos.SignUrl}
style={{
width: "99%",
height: "100%",
objectFit: "contain"
}}
/>
</div>
) : (
<div
style={{
fontSize: "10px",
color: "black",
justifyContent: "center"
}}
>
{props.pos.isStamp ? <div>stamp</div> : <div>signature</div>}
{props?.handleUserName &&
props?.handleUserName(props?.data?.Id, props?.data?.Role)}
</div>
);
}
}
export default PlaceholderType;
@@ -21,7 +21,7 @@ function PrevNext({ pageNumber, allPages, changePage }) {
fontWeight: "600",
border: "0px",
marginRight: "5px",
marginRight: "5px"
}}
disabled={pageNumber <= 1}
onClick={previousPage}
@@ -31,7 +31,7 @@ function PrevNext({ pageNumber, allPages, changePage }) {
<span
style={{
fontSize: "13px",
fontWeight: "600",
fontWeight: "600"
}}
>
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
@@ -43,7 +43,7 @@ function PrevNext({ pageNumber, allPages, changePage }) {
background: "#d3edeb",
fontWeight: "600",
marginLeft: "5px",
border: "0px",
border: "0px"
}}
disabled={pageNumber >= allPages}
onClick={nextPage}
@@ -1,6 +1,5 @@
import React, { useRef, useState } from "react";
import "../css/signerListPlace.css";
import { darkenColor, getFirstLetter } from "../utils/Utils";
import { darkenColor, getFirstLetter } from "../../constant/Utils";
const RecipientList = (props) => {
const color = [
@@ -49,7 +48,7 @@ const RecipientList = (props) => {
return style;
};
//function for onhover signer name remove background color
const nonHoverStyle = (ind) => {
const nonHoverStyle = () => {
const style = {
padding: "10px",
marginTop: "2px",
@@ -85,8 +84,8 @@ const RecipientList = (props) => {
props.setContractName(obj?.className || "");
props.setUniqueId(obj.Id);
props.setRoleName(obj.Role);
if(props.handleModal){
props.handleModal()
if (props.handleModal) {
props.handleModal();
}
}}
>
@@ -1,7 +1,7 @@
import React from "react";
import RSC from "react-scrollbars-custom";
import { Document, Page, pdfjs } from "react-pdf";
import { themeColor } from "../../utils/ThemeColor/backColor";
import { Document, Page } from "react-pdf";
import { themeColor } from "../../constant/const";
function RenderAllPdfPage({
pdfUrl,
@@ -12,8 +12,6 @@ function RenderAllPdfPage({
setSignBtnPosition,
pageNumber
}) {
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
//set all number of pages after load pdf
function onDocumentLoad({ numPages }) {
setAllPages(numPages);
@@ -33,7 +31,7 @@ function RenderAllPdfPage({
<div style={{ width: "140px" }}>
<div
style={{
background: themeColor()
background: themeColor
// color:"white"
}}
className="signedStyle"
@@ -0,0 +1,685 @@
import React from "react";
import RSC from "react-scrollbars-custom";
import { Document, Page } from "react-pdf";
import {
defaultWidthHeight,
handleImageResize,
handleSignYourselfImageResize
} from "../../constant/Utils";
import Placeholder from "./Placeholder";
import Alert from "../../primitives/Alert";
function RenderPdf({
pageNumber,
pdfOriginalWidth,
pdfNewWidth,
drop,
signerPos,
successEmail,
handleTabDrag,
handleStop,
isDragging,
setIsSignPad,
setIsStamp,
handleDeleteSign,
setSignKey,
pdfDetails,
xyPostion,
pdfUrl,
numPages,
pageDetails,
pdfRequest,
setCurrentSigner,
signerObjectId,
signedSigners,
setPdfLoadFail,
placeholder,
pdfLoadFail,
setSignerPos,
setXyPostion,
index,
containerWH,
setIsResize,
handleLinkUser,
setUniqueId,
signersdata,
setIsPageCopy,
setSignerObjId,
setShowDropdown,
setIsInitial,
setIsValidate,
setWidgetType,
setValidateAlert,
setIsRadio,
setCurrWidgetsDetails,
setSelectWidgetId,
selectWidgetId,
unSignedWidgetId,
setIsCheckbox,
handleNameModal
}) {
const isMobile = window.innerWidth < 767;
const newWidth = containerWH.width;
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
const isGuestSigner = localStorage.getItem("isGuestSigner");
// handle signature block width and height according to screen
const posWidth = (pos, signYourself) => {
const defaultWidth = defaultWidthHeight(pos.type).width;
const posWidth = pos.Width ? pos.Width : defaultWidth;
let width;
if (signYourself) {
width = posWidth;
return width;
} else {
if (isMobile) {
if (!pos.isMobile) {
if (pos.IsResize) {
width = posWidth ? posWidth : defaultWidth;
return width;
} else {
width = (posWidth || defaultWidth) / scale;
return width;
}
} else {
width = posWidth;
return width;
}
} else {
if (pos.isMobile) {
if (pos.IsResize) {
width = posWidth ? posWidth : defaultWidth;
return width;
} else {
width = (posWidth || defaultWidth) * pos.scale;
return width;
}
} else {
width = posWidth ? posWidth : defaultWidth;
return width;
}
}
}
};
const posHeight = (pos, signYourself) => {
let height;
const posHeight = pos.Height;
const defaultHeight = defaultWidthHeight(pos.type).height;
if (signYourself) {
height = posHeight ? posHeight : defaultHeight;
return height;
} else {
if (isMobile) {
if (!pos.isMobile) {
if (pos.IsResize) {
height = posHeight ? posHeight : defaultHeight;
return height;
} else {
height = (posHeight || defaultHeight) / scale;
return height;
}
} else {
height = posHeight ? posHeight : defaultHeight;
return height;
}
} else {
if (pos.isMobile) {
if (pos.IsResize) {
height = posHeight ? posHeight : defaultHeight;
return height;
} else {
height = (posHeight || defaultHeight) * pos.scale;
return height;
}
} else {
height = posHeight ? posHeight : defaultHeight;
return height;
}
}
}
};
const xPos = (pos, signYourself) => {
const resizePos = pos.xPosition;
if (signYourself) {
return resizePos;
} else {
//checking both condition mobile and desktop view
if (isMobile) {
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
if (!pos.isMobile) {
return resizePos / scale;
}
//pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale
else {
return resizePos * (pos.scale / scale);
}
} else {
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
if (pos.isMobile) {
return pos.scale && resizePos * pos.scale;
}
//else placeholder save from desktop(bigscreen) and show in desktop(bigscreen)
else {
return resizePos;
}
}
}
};
const yPos = (pos, signYourself) => {
const resizePos = pos.yPosition;
if (signYourself) {
return resizePos;
} else {
//checking both condition mobile and desktop view
if (isMobile) {
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
if (!pos.isMobile) {
return resizePos / scale;
}
//pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale
else {
return resizePos * (pos.scale / scale);
}
} else {
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
if (pos.isMobile) {
return pos.scale && resizePos * pos.scale;
}
//else placeholder save from desktop(bigscreen) and show in desktop(bigscreen)
else {
return resizePos;
}
}
}
};
//function for render placeholder block over pdf document
const checkSignedSignes = (data) => {
const checkSign = signedSigners.filter(
(sign) => sign.objectId === data.signerObjId
);
if (data.signerObjId === signerObjectId) {
setCurrentSigner(true);
}
const handleAllUserName = (Id, Role, type) => {
return pdfDetails[0].Signers.map((signerData, key) => {
return (
signerData.objectId === data.signerObjId && (
<React.Fragment key={key}>
{signerData?.Name && (
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
{signerData.Name}
</div>
)}
{type && (
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
)}
{Role && (
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
{`(${Role})`}
</div>
)}
</React.Fragment>
)
);
});
};
return (
checkSign.length === 0 &&
data.placeHolder.map((placeData, key) => {
return (
<React.Fragment key={key}>
{placeData.pageNumber === pageNumber &&
placeData.pos.map((pos) => {
return (
pos && (
<React.Fragment key={pos.key}>
<Placeholder
pos={pos}
setSignKey={setSignKey}
setIsSignPad={setIsSignPad}
setIsStamp={setIsStamp}
handleSignYourselfImageResize={handleImageResize}
index={pageNumber}
xyPostion={signerPos}
setXyPostion={setSignerPos}
data={data}
setIsResize={setIsResize}
isShowBorder={false}
signerObjId={signerObjectId}
isShowDropdown={true}
isNeedSign={true}
isSignYourself={false}
xPos={xPos}
yPos={yPos}
posWidth={posWidth}
posHeight={posHeight}
handleUserName={handleAllUserName}
isDragging={false}
pdfDetails={pdfDetails}
setIsInitial={setIsInitial}
setValidateAlert={setValidateAlert}
unSignedWidgetId={unSignedWidgetId}
/>
</React.Fragment>
)
);
})}
</React.Fragment>
);
})
);
};
const handleUserName = (Id, Role, type) => {
if (Id) {
const checkSign = signersdata.find((sign) => sign.Id === Id);
if (checkSign?.Name) {
return (
<>
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
{checkSign?.Name}
</div>
{type && (
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
)}
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
{`(${Role})`}
</div>
</>
);
} else {
return (
<>
{type && (
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
)}
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
{Role}
</div>
</>
);
}
} else {
return (
<>
{type && (
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
)}
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
{Role}
</div>
</>
);
}
};
return (
<>
{successEmail && <Alert type={"success"}>Email sent successfully!</Alert>}
{isMobile && scale ? (
<div
style={{
border: "0.1px solid #ebe8e8",
marginTop: isGuestSigner && "30px"
}}
ref={drop}
id="container"
>
{pdfLoadFail.status &&
(pdfRequest
? signerPos.map((data, key) => {
return (
<React.Fragment key={key}>
{checkSignedSignes(data)}
</React.Fragment>
);
})
: placeholder // placeholder mobile
? signerPos.map((data, ind) => {
return (
<React.Fragment key={ind}>
{data.placeHolder.map((placeData, index) => {
return (
<React.Fragment key={index}>
{placeData.pageNumber === pageNumber &&
placeData.pos.map((pos) => {
return (
<React.Fragment key={pos.key}>
<Placeholder
pos={pos}
setIsPageCopy={setIsPageCopy}
setSignKey={setSignKey}
handleDeleteSign={handleDeleteSign}
setIsStamp={setIsStamp}
handleTabDrag={handleTabDrag}
handleStop={handleStop}
handleSignYourselfImageResize={
handleImageResize
}
index={pageNumber}
xyPostion={signerPos}
setXyPostion={setSignerPos}
setSignerObjId={setSignerObjId}
data={data}
setIsResize={setIsResize}
setShowDropdown={setShowDropdown}
isShowBorder={true}
isPlaceholder={true}
setUniqueId={setUniqueId}
handleLinkUser={handleLinkUser}
handleUserName={handleUserName}
isSignYourself={false}
xPos={xPos}
yPos={yPos}
posWidth={posWidth}
posHeight={posHeight}
isDragging={isDragging}
setIsValidate={setIsValidate}
setWidgetType={setWidgetType}
setIsRadio={setIsRadio}
setIsCheckbox={setIsCheckbox}
setCurrWidgetsDetails={
setCurrWidgetsDetails
}
setSelectWidgetId={setSelectWidgetId}
selectWidgetId={selectWidgetId}
handleNameModal={handleNameModal}
/>
</React.Fragment>
);
})}
</React.Fragment>
);
})}
</React.Fragment>
);
})
: xyPostion.map((data, ind) => {
return (
<React.Fragment key={ind}>
{data.pageNumber === pageNumber &&
data.pos.map((pos) => {
return (
pos && (
<Placeholder
pos={pos}
setIsPageCopy={setIsPageCopy}
setSignKey={setSignKey}
handleDeleteSign={handleDeleteSign}
setIsStamp={setIsStamp}
handleTabDrag={handleTabDrag}
handleStop={handleStop}
handleSignYourselfImageResize={
handleSignYourselfImageResize
}
index={index}
xyPostion={xyPostion}
setXyPostion={setXyPostion}
pdfOriginalWidth={pdfOriginalWidth}
containerWH={containerWH}
setIsSignPad={setIsSignPad}
isShowBorder={true}
isSignYourself={true}
xPos={xPos}
yPos={yPos}
posWidth={posWidth}
posHeight={posHeight}
pdfDetails={pdfDetails[0]}
isDragging={isDragging}
setIsInitial={setIsInitial}
setWidgetType={setWidgetType}
setSelectWidgetId={setSelectWidgetId}
selectWidgetId={selectWidgetId}
handleUserName={handleUserName}
setIsCheckbox={setIsCheckbox}
setValidateAlert={setValidateAlert}
setCurrWidgetsDetails={setCurrWidgetsDetails}
/>
)
);
})}
</React.Fragment>
);
}))}
{/* this component for render pdf document is in middle of the component */}
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center"
}}
>
<Document
onLoadError={() => {
setPdfLoadFail(true);
}}
loading={"Loading Document.."}
onLoadSuccess={pageDetails}
// ref={pdfRef}'
onClick={() => {
if (setSelectWidgetId) {
setSelectWidgetId("");
}
}}
file={
pdfUrl
? pdfUrl
: pdfDetails[0] && pdfDetails[0].SignedUrl
? pdfDetails[0].SignedUrl
: pdfDetails[0].URL
}
>
{Array.from(new Array(numPages), (el, index) => (
<Page
key={index}
pageNumber={pageNumber}
width={containerWH.width}
height={containerWH.height}
renderAnnotationLayer={false}
renderTextLayer={false}
onGetAnnotationsError={(error) => {
console.log("annotation error", error);
}}
/>
))}
</Document>
</div>
</div>
) : (
<RSC
style={{
position: "relative",
boxShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px",
width:
pdfOriginalWidth > pdfNewWidth ? pdfNewWidth : pdfOriginalWidth,
height: window.innerHeight - 110 + "px"
}}
noScrollY={false}
noScrollX={pdfNewWidth < pdfOriginalWidth ? false : true}
>
<div
style={{
border: "0.1px solid #ebe8e8",
width: pdfOriginalWidth
}}
ref={drop}
id="container"
>
{pdfLoadFail.status &&
(pdfRequest
? signerPos.map((data, key) => {
return (
<React.Fragment key={key}>
{checkSignedSignes(data)}
</React.Fragment>
);
})
: placeholder
? signerPos.map((data, ind) => {
return (
<React.Fragment key={ind}>
{data.placeHolder.map((placeData, index) => {
return (
<React.Fragment key={index}>
{placeData.pageNumber === pageNumber &&
placeData.pos.map((pos) => {
return (
<React.Fragment key={pos.key}>
<Placeholder
pos={pos}
setIsPageCopy={setIsPageCopy}
setSignKey={setSignKey}
handleDeleteSign={handleDeleteSign}
setIsStamp={setIsStamp}
handleTabDrag={handleTabDrag}
handleStop={handleStop}
handleSignYourselfImageResize={
handleImageResize
}
index={pageNumber}
xyPostion={signerPos}
setXyPostion={setSignerPos}
setSignerObjId={setSignerObjId}
data={data}
setIsResize={setIsResize}
setShowDropdown={setShowDropdown}
isShowBorder={true}
isPlaceholder={true}
setUniqueId={setUniqueId}
handleLinkUser={handleLinkUser}
handleUserName={handleUserName}
isSignYourself={false}
xPos={xPos}
yPos={yPos}
posWidth={posWidth}
posHeight={posHeight}
isDragging={isDragging}
setIsValidate={setIsValidate}
setWidgetType={setWidgetType}
setIsRadio={setIsRadio}
setIsCheckbox={setIsCheckbox}
setCurrWidgetsDetails={
setCurrWidgetsDetails
}
setSelectWidgetId={setSelectWidgetId}
selectWidgetId={selectWidgetId}
handleNameModal={handleNameModal}
/>
</React.Fragment>
);
})}
</React.Fragment>
);
})}
</React.Fragment>
);
})
: xyPostion.map((data, ind) => {
return (
<React.Fragment key={ind}>
{data.pageNumber === pageNumber &&
data.pos.map((pos) => {
return (
pos && (
<React.Fragment key={pos.key}>
<Placeholder
pos={pos}
setIsPageCopy={setIsPageCopy}
setSignKey={setSignKey}
handleDeleteSign={handleDeleteSign}
setIsStamp={setIsStamp}
handleTabDrag={handleTabDrag}
handleStop={(event, dragElement) =>
handleStop(event, dragElement, pos.type)
}
handleSignYourselfImageResize={
handleSignYourselfImageResize
}
index={index}
xyPostion={xyPostion}
setXyPostion={setXyPostion}
pdfOriginalWidth={pdfOriginalWidth}
containerWH={containerWH}
setIsSignPad={setIsSignPad}
isShowBorder={true}
isSignYourself={true}
xPos={xPos}
yPos={yPos}
posWidth={posWidth}
posHeight={posHeight}
pdfDetails={pdfDetails[0]}
isDragging={isDragging}
setIsInitial={setIsInitial}
setWidgetType={setWidgetType}
setSelectWidgetId={setSelectWidgetId}
selectWidgetId={selectWidgetId}
handleUserName={handleUserName}
setIsCheckbox={setIsCheckbox}
setValidateAlert={setValidateAlert}
setCurrWidgetsDetails={
setCurrWidgetsDetails
}
/>
</React.Fragment>
)
);
})}
</React.Fragment>
);
}))}
{/* this component for render pdf document is in middle of the component */}
<Document
onLoadError={() => {
const load = {
status: false,
type: "failed"
};
setPdfLoadFail(load);
}}
loading={"Loading Document.."}
onLoadSuccess={pageDetails}
onClick={() => {
if (setSelectWidgetId) {
setSelectWidgetId("");
}
}}
// ref={pdfRef}
file={
pdfUrl
? pdfUrl
: pdfDetails[0] && pdfDetails[0].SignedUrl
? pdfDetails[0].SignedUrl
: pdfDetails[0].URL
}
>
{Array.from(new Array(numPages), (el, index) => (
<Page
key={index}
pageNumber={pageNumber}
renderAnnotationLayer={false}
renderTextLayer={false}
onGetAnnotationsError={(error) => {
console.log("annotation error", error);
}}
/>
))}
</Document>
</div>
</RSC>
)}
</>
);
}
export default RenderPdf;
@@ -1,11 +1,6 @@
import React from "react";
import { useRef, useState } from "react";
import React, { useRef, useState, useEffect } from "react";
import SignatureCanvas from "react-signature-canvas";
import redPen from "../../assests/redPen.png";
import bluePen from "../../assests/bluePen.png";
import blackPen from "../../assests/blackPen.png";
import { themeColor } from "../../utils/ThemeColor/backColor";
import { useEffect } from "react";
import { themeColor } from "../../constant/const";
function SignPad({
isSignPad,
@@ -20,10 +15,15 @@ function SignPad({
onSaveImage,
image,
defaultSign,
setSignature
setSignature,
myInitial,
isInitial,
setIsInitial,
setIsStamp,
widgetType
}) {
const [penColor, setPenColor] = useState("blue");
const allColor = [bluePen, redPen, blackPen];
const allColor = ["blue", "red", "black"];
const canvasRef = useRef(null);
const [isDefaultSign, setIsDefaultSign] = useState(false);
const [isTab, setIsTab] = useState("draw");
@@ -40,20 +40,24 @@ function SignPad({
];
const [fontSelect, setFontSelect] = useState(fontOptions[0].value);
useEffect(() => {
const senderUser =
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
) &&
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
);
const jsonSender = JSON.parse(senderUser);
const senderUser =
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
) &&
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
);
const jsonSender = JSON.parse(senderUser);
const currentUserName = jsonSender && jsonSender.name;
//function for clear signature
setSignValue(currentUserName);
const currentUserName = jsonSender && jsonSender.name;
useEffect(() => {
const trimmedName = currentUserName.trim();
const firstCharacter = trimmedName.charAt(0);
const userName = isInitial ? firstCharacter : currentUserName;
setSignValue(userName);
setFontSelect("Fasthand");
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
//function for clear signature image
const handleClear = () => {
@@ -66,11 +70,12 @@ function SignPad({
setIsSignImg("");
} else if (isTab === "uploadImage") {
setImage("");
setImage("");
}
setIsInitial(false);
};
//function for set signature url
const handleSignatureChange = (dataURL) => {
const handleSignatureChange = () => {
// canvasRef.current.backgroundColor = 'rgb(165, 26, 26)'
setSignature(canvasRef.current.toDataURL());
setIsSignImg(canvasRef.current.toDataURL());
@@ -97,9 +102,13 @@ function SignPad({
<button
onClick={() => {
if (!image) {
if (isDefaultSign) {
if (isTab === "mysignature") {
setIsSignImg("");
onSaveSign(isDefaultSign);
if (isInitial) {
onSaveSign("initials");
} else {
onSaveSign("default");
}
} else {
if (isTab === "type") {
setIsSignImg("");
@@ -116,14 +125,16 @@ function SignPad({
onSaveImage();
}
setIsSignPad(false);
setIsInitial(false);
setIsImageSelect(false);
setIsDefaultSign(false);
setImage();
setIsTab("draw");
setSignValue("");
setIsStamp(false);
}}
style={{
background: themeColor(),
background: themeColor,
color: "white"
}}
disabled={
@@ -156,6 +167,7 @@ function SignPad({
};
loadFont();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fontSelect]);
useEffect(() => {
@@ -164,9 +176,15 @@ function SignPad({
canvasRef.current.fromDataURL(isSignImg);
}
if (isTab === "type") {
convertToImg(fontSelect, signValue);
const trimmedName = signValue ? signValue.trim() : currentUserName.trim();
const firstCharacter = trimmedName.charAt(0);
const userName = isInitial ? firstCharacter : signValue;
setSignValue(userName);
convertToImg(fontSelect, userName);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isTab]);
//function for convert input text value in image
const convertToImg = async (fontStyle, text) => {
//get text content to convert in image
@@ -246,8 +264,10 @@ function SignPad({
}}
>
{isStamp ? (
<span style={{ color: themeColor() }} className="signTab">
Upload stamp image
<span style={{ color: themeColor }} className="signTab">
{widgetType === "image"
? "Upload image"
: "Upload stamp image"}
</span>
) : (
<>
@@ -260,9 +280,7 @@ function SignPad({
setImage();
}}
style={{
color:
isTab === "draw" ? themeColor() : "#515252",
color: isTab === "draw" ? themeColor : "#515252",
marginLeft: "2px"
}}
className="signTab"
@@ -288,9 +306,7 @@ function SignPad({
}}
style={{
color:
isTab === "uploadImage"
? themeColor()
: "#515252"
isTab === "uploadImage" ? themeColor : "#515252"
}}
className="signTab"
>
@@ -314,9 +330,7 @@ function SignPad({
setImage();
}}
style={{
color:
isTab === "type" ? themeColor() : "#515252",
color: isTab === "type" ? themeColor : "#515252",
marginLeft: "2px"
}}
className="signTab"
@@ -333,7 +347,7 @@ function SignPad({
}}
></div>
</div>
{defaultSign && (
{!isInitial && defaultSign ? (
<div>
<span
onClick={() => {
@@ -345,7 +359,7 @@ function SignPad({
style={{
color:
isTab === "mysignature"
? themeColor()
? themeColor
: "#515252"
}}
className="signTab"
@@ -361,6 +375,37 @@ function SignPad({
}}
></div>
</div>
) : (
isInitial &&
myInitial && (
<div>
<span
onClick={() => {
setIsDefaultSign(true);
setIsImageSelect(true);
setIsTab("mysignature");
setImage();
}}
style={{
color:
isTab === "mysignature"
? themeColor
: "#515252"
}}
className="signTab"
>
My Initials
</span>
<div
style={{
border:
isTab === "mysignature"
? "1.5px solid #108783"
: "1.5px solid #ffffff"
}}
></div>
</div>
)
)}
</>
)}
@@ -373,11 +418,13 @@ function SignPad({
onClick={() => {
setPenColor("blue");
setIsSignPad(false);
setIsInitial(false);
setIsImageSelect(false);
setIsDefaultSign(false);
setImage();
setIsTab("draw");
setSignValue("");
setIsStamp(false);
}}
>
&times;
@@ -386,28 +433,33 @@ function SignPad({
<div style={{ height: "100%", padding: 20 }}>
{isDefaultSign ? (
<>
<div
style={{
border: "1px solid black",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
marginBottom: 6,
cursor: "pointer"
}}
className="signatureCanvas"
>
<img
alt="stamp img"
<div style={{ display: "flex", justifyContent: "center" }}>
<div
style={{
width: "100%",
height: "100%",
background: "rgb(255, 255, 255)",
objectFit: "contain"
border: "1.3px solid #007bff",
borderRadius: "2px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
marginBottom: 6,
cursor: "pointer"
}}
src={defaultSign}
/>
className={
isInitial ? "intialSignatureCanvas" : "signatureCanvas"
}
>
<img
alt="stamp img"
style={{
width: "100%",
height: "100%",
background: "rgb(255, 255, 255)",
objectFit: "contain"
}}
src={isInitial ? myInitial : defaultSign}
/>
</div>
</div>
<div style={{ display: "flex", justifyContent: "flex-end" }}>
<SaveBtn />
@@ -415,52 +467,63 @@ function SignPad({
</>
) : isImageSelect || isStamp ? (
!image ? (
<div
style={{
border: "1px solid black",
<div style={{ display: "flex", justifyContent: "center" }}>
<div
style={{
border: "1.3px solid #007bff",
borderRadius: "2px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
marginBottom: 6,
cursor: "pointer"
}}
className="signatureCanvas"
onClick={() => imageRef.current.click()}
>
<input
type="file"
onChange={onImageChange}
className="filetype"
accept="image/*"
ref={imageRef}
hidden
/>
<i className="fas fa-cloud-upload-alt uploadImgLogo"></i>
<div className="uploadImg">Upload</div>
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
marginBottom: 6,
cursor: "pointer"
}}
className={
isInitial ? "intialSignatureCanvas" : "signatureCanvas"
}
onClick={() => imageRef.current.click()}
>
<input
type="file"
onChange={onImageChange}
className="filetype"
accept="image/*"
ref={imageRef}
hidden
/>
<i className="fas fa-cloud-upload-alt uploadImgLogo"></i>
<div className="uploadImg">Upload</div>
</div>
</div>
) : (
<>
<div
style={{
border: "1px solid black",
marginBottom: 6,
overflow: "hidden"
}}
className="signatureCanvas"
>
<img
alt="print img"
ref={imageRef}
src={image.src}
<div style={{ display: "flex", justifyContent: "center" }}>
<div
style={{
objectFit: "contain",
height: "100%",
width: "100%"
border: "1.3px solid #007bff",
borderRadius: "2px",
marginBottom: 6,
overflow: "hidden"
}}
/>
className={
isInitial
? "intialSignatureCanvas"
: "signatureCanvas"
}
>
<img
alt="print img"
ref={imageRef}
src={image.src}
style={{
objectFit: "contain",
height: "100%",
width: "100%"
}}
/>
</div>
</div>
<div
style={{ display: "flex", justifyContent: "flex-end" }}
@@ -478,10 +541,12 @@ function SignPad({
alignItems: "center"
}}
>
<span className="signatureText">Signature:</span>
<span className="signatureText">
{isInitial ? "Initials" : "Signature"}:
</span>
<input
maxLength={30}
maxLength={isInitial ? 3 : 30}
style={{ fontFamily: fontSelect }}
type="text"
className="signatureInput"
@@ -529,19 +594,26 @@ function SignPad({
</div>
) : (
<>
<SignatureCanvas
ref={canvasRef}
penColor={penColor}
canvasProps={{
className: "signatureCanvas"
}}
backgroundColor="rgb(255, 255, 255)"
onEnd={() =>
handleSignatureChange(canvasRef.current.toDataURL())
}
dotSize={1}
/>
<div style={{ display: "flex", justifyContent: "center" }}>
<SignatureCanvas
ref={canvasRef}
penColor={penColor}
canvasProps={{
className: isInitial
? "intialSignatureCanvas"
: "signatureCanvas",
style: {
border: "1.6px solid #007bff",
borderRadius: "2px"
}
}}
backgroundColor="rgb(255, 255, 255)"
onEnd={() =>
handleSignatureChange(canvasRef.current.toDataURL())
}
dotSize={1}
/>
</div>
<div
style={{
display: "flex",
@@ -553,12 +625,10 @@ function SignPad({
<div style={{ display: "flex", flexDirection: "row" }}>
{allColor.map((data, key) => {
return (
<img
key={key}
alt="pen img"
<i
style={{
border: "none",
margin: "5px",
color: data,
borderBottom:
key === 0 && penColor === "blue"
? "2px solid blue"
@@ -577,14 +647,14 @@ function SignPad({
setPenColor("black");
}
}}
src={data}
key={key}
className="fa solid fa-pen-nib"
width={20}
height={20}
/>
></i>
);
})}
</div>
<SaveBtn />
</div>
</>
@@ -0,0 +1,64 @@
import React from "react";
import { themeColor } from "../../constant/const";
import "../../styles/signature.css";
function Signedby({ pdfDetails }) {
const getFirstLetter = (name) => {
const firstLetter = name.charAt(0);
return firstLetter;
};
return (
<div className="signerComponent">
<div
style={{
background: themeColor,
color: "white"
}}
className="signedStyle"
>
Signed By
</div>
<div style={{ marginTop: "2px", background: "white" }}>
<div
style={{
display: "flex",
flexDirection: "row",
padding: "10px",
background: "#93a3db"
}}
>
<div
className="signerStyle"
style={{
background: "#abd1d0",
width: 20,
height: 20,
display: "flex",
borderRadius: 30 / 2,
justifyContent: "center",
alignItems: "center",
marginRight: "20px",
marginTop: "5px"
}}
>
<span
style={{
fontSize: "8px",
textAlign: "center",
fontWeight: "bold"
}}
>
{getFirstLetter(pdfDetails.ExtUserPtr.Name)}
</span>
</div>
<div style={{ display: "flex", flexDirection: "column" }}>
<span className="userName">{pdfDetails.ExtUserPtr.Name}</span>
<span className="useEmail">{pdfDetails.ExtUserPtr.Email}</span>
</div>
</div>
</div>
</div>
);
}
export default Signedby;
@@ -1,14 +1,13 @@
import React from "react";
import { themeColor } from "../../utils/ThemeColor/backColor";
import "../../css/signerListPlace.css";
import RecipientList from "../../premitives/RecipientList";
import { themeColor } from "../../constant/const";
import RecipientList from "./RecipientList";
function SignerListPlace(props) {
return (
<div>
<div
style={{
background: themeColor(),
background: themeColor,
padding: "5px"
}}
>
@@ -22,7 +21,7 @@ function SignerListPlace(props) {
{props.handleAddSigner && (
<div
data-tut="reactourAddbtn"
className="addSignerBtn"
className="p-[10px] my-[2px] flex flex-row items-center justify-center border-[1px] border-[#47a3ad] hover:bg-[#47a3ad] text-[#47a3ad] hover:text-white cursor-pointer"
onClick={() => props.handleAddSigner()}
>
<i className="fa-solid fa-plus"></i>
@@ -0,0 +1,419 @@
import React, { useState, useRef, useEffect } from "react";
import ModalUi from "../../primitives/ModalUi";
import RecipientList from "./RecipientList";
import { useDrag } from "react-dnd";
import WidgetList from "./WidgetList";
import { widgets } from "../../constant/Utils";
import { themeColor } from "../../constant/const";
function WidgetComponent({
dragSignature,
signRef,
handleDivClick,
handleMouseLeave,
dragStamp,
isSignYourself,
addPositionOfSignature,
signersdata,
isSelectListId,
setSignerObjId,
setIsSelectId,
setContractName,
isSigners,
dataTut,
isMailSend,
handleAddSigner,
setUniqueId,
setRoleName,
handleDeleteUser,
signerPos,
handleRoleChange,
handleOnBlur,
title,
isTemplateFlow
}) {
const [isSignersModal, setIsSignersModal] = useState(false);
const [, dropdown] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 5,
text: "dropdown"
},
collect: (monitor) => ({
isDragDropdown: !!monitor.isDragging()
})
});
const [, checkbox] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 6,
text: "checkbox"
},
collect: (monitor) => ({
isDragCheck: !!monitor.isDragging()
})
});
const [, text] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 7,
text: "text"
},
collect: (monitor) => ({
isDragText: !!monitor.isDragging()
})
});
const [, initials] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 8,
text: "initials"
},
collect: (monitor) => ({
isDragInitial: !!monitor.isDragging()
})
});
const [, name] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 9,
text: "name"
},
collect: (monitor) => ({
isDragName: !!monitor.isDragging()
})
});
const [, company] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 10,
text: "company"
},
collect: (monitor) => ({
isDragCompany: !!monitor.isDragging()
})
});
const [, jobTitle] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 11,
text: "job title"
},
collect: (monitor) => ({
isDragJobtitle: !!monitor.isDragging()
})
});
const [, date] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 12,
text: "date"
},
collect: (monitor) => ({
isDragDate: !!monitor.isDragging()
})
});
const [, image] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 13,
text: "image"
},
collect: (monitor) => ({
isDragImage: !!monitor.isDragging()
})
});
const [, email] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 14,
text: "email"
},
collect: (monitor) => ({
isDragEmail: !!monitor.isDragging()
})
});
const [, radio] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 15,
text: "radio"
},
collect: (monitor) => ({
isDragRadio: !!monitor.isDragging()
})
});
const [, label] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 16,
text: "label"
},
collect: (monitor) => ({
isDragLabel: !!monitor.isDragging()
})
});
const isMobile = window.innerWidth < 767;
const scrollContainerRef = useRef(null);
const [widget, setWidget] = useState([]);
const color = [
"#93a3db",
"#e6c3db",
"#c0e3bc",
"#bce3db",
"#b8ccdb",
"#ceb8db",
"#ffccff",
"#99ffcc",
"#cc99ff",
"#ffcc99",
"#66ccff",
"#ffffcc"
];
const handleModal = () => {
setIsSignersModal(!isSignersModal);
};
useEffect(() => {
const widgetRef = [
dragSignature,
dragStamp,
initials,
label,
text,
checkbox,
dropdown,
radio,
image,
date,
name,
email,
company,
jobTitle
];
const getWidgetArray = widgets;
const newUpdateSigner = getWidgetArray.map((obj, ind) => {
return { ...obj, ref: widgetRef[ind] };
});
setWidget(newUpdateSigner);
// eslint-disable-next-line
}, []);
const filterWidgets = widget.filter(
(data) =>
data.type !== "dropdown" && data.type !== "radio" && data.type !== "label"
);
const labelWidget = widget.filter((data) => data.type !== "label");
const updateWidgets = isSignYourself
? filterWidgets
: isTemplateFlow
? labelWidget
: widget;
return (
<>
{isMobile ? (
!isMailSend && (
<div
data-tut={dataTut}
id="navbar"
className="stickyfooter"
style={{ width: window.innerWidth + "px" }}
>
{isSigners && (
<div
data-tut={dataTut}
style={{
background: isSelectListId
? color[isSelectListId % color.length]
: color[0],
padding: "10px 20px",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
onClick={() => {
// if (signersdata?.length) {
handleModal();
// }
}}
>
<span
style={{
fontSize: "13px",
fontWeight: "700",
textAlign: "center"
}}
>
{title ? title : "Recipient"}
</span>
<span
style={{
fontSize: "13px",
fontWeight: "700",
display: "flex",
alignItems: "center"
}}
>
{signersdata[isSelectListId]?.Role && (
<div>
{signersdata[isSelectListId]?.Name ? (
<>
:{" "}
{signersdata[isSelectListId]?.Name?.length > 12
? `${signersdata[isSelectListId].Name.slice(
0,
12
)}...`
: signersdata[isSelectListId]?.Name}
</>
) : (
<>
:{" "}
{signersdata[isSelectListId]?.Role?.length > 12
? `${signersdata[isSelectListId].Role.slice(
0,
12
)}...`
: signersdata[isSelectListId]?.Role}
</>
)}
</div>
)}
<div style={{ marginLeft: 6, fontSize: 16 }}>
<i className="fa-solid fa-angle-down"></i>
</div>
</span>
</div>
)}
{handleAddSigner && (
<div
data-tut="reactourAddbtn"
style={{
margin: "5px 0 5px 0",
backgroundColor: themeColor,
color: "white"
}}
className="p-[10px] my-[2px] flex flex-row items-center justify-center border-[1px] border-[#47a3ad] hover:bg-[#47a3ad] text-[#47a3ad] hover:text-white cursor-pointer"
onClick={() => handleAddSigner()}
>
<i className="fa-solid fa-plus"></i>
<span style={{ marginLeft: 2 }}>Add role</span>
</div>
)}
<div
ref={scrollContainerRef}
style={{
background: "white",
borderTop: `2px solid ${themeColor}`
}}
>
<div
style={{
display: "flex",
overflowX: "scroll",
whiteSpace: "nowrap",
padding: "10px"
}}
>
<WidgetList
updateWidgets={updateWidgets}
handleDivClick={handleDivClick}
handleMouseLeave={handleMouseLeave}
signRef={signRef}
marginLeft={5}
addPositionOfSignature={addPositionOfSignature}
isMobile={isMobile}
/>
</div>
</div>
</div>
)
) : (
<div data-tut={dataTut} className="signerComponent">
<div
style={{
background: themeColor,
padding: "5px"
}}
>
<span className="signedStyle">Fields</span>
</div>
<div className="signLayoutContainer1">
<WidgetList
updateWidgets={updateWidgets}
handleDivClick={handleDivClick}
handleMouseLeave={handleMouseLeave}
signRef={signRef}
/>
</div>
</div>
)}
{isSignersModal && (
<ModalUi
title={"Roles"}
isOpen={isSignersModal}
handleClose={handleModal}
>
{signersdata.length > 0 ? (
<RecipientList
signerPos={signerPos}
signersdata={signersdata}
isSelectListId={isSelectListId}
setSignerObjId={setSignerObjId}
setIsSelectId={setIsSelectId}
setContractName={setContractName}
setUniqueId={setUniqueId}
setRoleName={setRoleName}
handleDeleteUser={handleDeleteUser}
handleRoleChange={handleRoleChange}
handleOnBlur={handleOnBlur}
handleModal={handleModal}
/>
) : (
<div
style={{
padding: 20,
fontSize: 15,
fontWeight: "500",
textAlign: "center"
}}
>
Please add a role
</div>
)}
</ModalUi>
)}
</>
);
}
export default WidgetComponent;
@@ -0,0 +1,36 @@
import React from "react";
import { getWidgetType } from "../../constant/Utils";
function WidgetList(props) {
return props.updateWidgets.map((item, ind) => {
return (
<div key={ind} style={{ marginBottom: "10px" }}>
<div
className="widgets"
onClick={() => {
props.addPositionOfSignature &&
props.addPositionOfSignature("onclick", item);
}}
ref={(element) => {
if (!props.isMobile) {
item.ref(element);
if (element) {
if (props?.signRef) {
props.signRef.current = element;
}
}
}
}}
onMouseMove={props?.handleDivClick}
onMouseDown={() => {
props?.handleMouseLeave();
}}
>
{item.ref && getWidgetType(item, props?.marginLeft)}
</div>
</div>
);
});
}
export default WidgetList;
@@ -0,0 +1,284 @@
import React, { useEffect, useState } from "react";
import ModalUi from "../../primitives/ModalUi";
import "../../styles/AddUser.css";
import RegexParser from "regex-parser";
const WidgetNameModal = (props) => {
const [formdata, setFormdata] = useState({
name: "",
defaultValue: "",
status: "required",
hint: "",
textvalidate: "text"
});
const [isValid, setIsValid] = useState(true);
const statusArr = ["Required", "Optional"];
const inputOpt = ["email", "number"];
useEffect(() => {
if (props.defaultdata) {
setFormdata({
name: props.defaultdata?.options?.name || props?.widgetName || "",
defaultValue: props.defaultdata?.options?.defaultValue || "",
status: props.defaultdata?.options?.status || "required",
hint: props.defaultdata?.options?.hint || "",
textvalidate:
props.defaultdata?.options?.validation?.type === "regex"
? props.defaultdata?.options?.validation?.pattern
: props.defaultdata?.options?.validation?.type || ""
});
} else {
setFormdata({
...formdata,
name: props.defaultdata?.options?.name || props?.widgetName || ""
});
}
// eslint-disable-next-line
}, [props.defaultdata, props.widgetName]);
const handleSubmit = (e) => {
e.preventDefault();
if (props.handleData) {
props.handleData(formdata);
setFormdata({
name: "",
defaultValue: "",
status: "required",
hint: "",
textvalidate: "text"
});
}
};
const handleChange = (e) => {
setFormdata({ ...formdata, [e.target.name]: e.target.value });
};
const handledefaultChange = (e) => {
if (formdata.textvalidate) {
const regexObject = RegexParser(handleValidation(formdata.textvalidate));
const isValidate = regexObject?.test(e.target.value);
setIsValid(isValidate);
} else {
setIsValid(true);
}
setFormdata({ ...formdata, [e.target.name]: e.target.value });
};
function handleValidation(type) {
switch (type) {
case "email":
return "/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/";
case "number":
return "/^\\d+$/";
case "text":
return "/^[a-zA-Zs]+$/";
default:
return type;
}
}
function handleBlurRegex() {
if (!formdata.textvalidate) {
setFormdata({ ...formdata, textvalidate: "text" });
} else {
if (formdata.defaultValue) {
const regexObject = RegexParser(
handleValidation(formdata.textvalidate)
);
const isValidate = regexObject?.test(formdata.defaultValue);
if (isValidate === false) {
setFormdata({ ...formdata, defaultValue: "" });
}
}
}
}
return (
<ModalUi
isOpen={props.isOpen}
handleClose={props.handleClose && props.handleClose}
title={"Widget info"}
>
<form onSubmit={handleSubmit} style={{ padding: 20 }}>
<div className="form-section">
<label htmlFor="name" style={{ fontSize: 13 }}>
Name
<span style={{ color: "red", fontSize: 13 }}> *</span>
</label>
<input
className="addUserInput"
name="name"
value={formdata.name}
onChange={(e) => handleChange(e)}
required
/>
</div>
{(props.defaultdata?.type === "text" ||
props.widgetName === "text") && (
<>
<div className="form-section">
<label htmlFor="textvalidate" style={{ fontSize: 13 }}>
Validation
</label>
<div
style={{
display: "flex",
flexDirection: "row",
gap: 10,
marginBottom: "0.5rem"
}}
>
<div style={{ width: "100%", position: "relative" }}>
<input
style={{
padding: "0.5rem 0.75rem",
width: "92%",
borderWidth: "1px",
borderColor: "#d1d5db",
borderTopLeftRadius: "0.375rem",
borderBottomLeftRadius: "0.375rem",
outline: "none",
fontSize: "0.75rem",
position: "relative",
zIndex: 2
}}
name="textvalidate"
placeholder="Enter custom expression"
value={formdata.textvalidate}
onChange={(e) => handleChange(e)}
// onBlur={() => handleBlurRegex()}
/>
<select
style={{ position: "absolute", left: 0, zIndex: 1 }}
className="addUserInput"
name="textvalidate"
value={formdata.textvalidate}
onChange={(e) => handleChange(e)}
onBlur={() => handleBlurRegex()}
>
<option disabled style={{ fontSize: "13px" }}>
Select...
</option>
{inputOpt.map((data, ind) => {
return (
<option
style={{ fontSize: "13px" }}
key={ind}
value={data}
>
{data}
</option>
);
})}
</select>
</div>
</div>
</div>
<div className="form-section">
<label htmlFor="name" style={{ fontSize: 13 }}>
Default value
</label>
<input
className="addUserInput"
name="defaultValue"
value={formdata.defaultValue}
onChange={(e) => handledefaultChange(e)}
onBlur={() =>
isValid === false &&
setFormdata({ ...formdata, defaultValue: "" })
}
/>
{isValid === false ? (
<p style={{ color: "Red", fontSize: 8 }}>
invalid default value
</p>
) : (
<p
style={{
color: "transparent",
fontSize: 10,
margin: "3px 8px"
}}
>
.
</p>
)}
</div>
</>
)}
<div className="form-section">
<div
style={{
display: "flex",
flexDirection: "row",
gap: 10,
marginBottom: "0.5rem"
}}
>
{statusArr.map((data, ind) => {
return (
<div
key={ind}
style={{
display: "flex",
flexDirection: "row",
gap: 5,
alignItems: "center"
}}
>
<input
style={{ accentColor: "red", marginRight: "10px" }}
type="radio"
name="status"
onChange={() =>
setFormdata({ ...formdata, status: data.toLowerCase() })
}
checked={
formdata.status.toLowerCase() === data.toLowerCase()
}
/>
<div style={{ fontSize: "13px", fontWeight: "500" }}>
{data}
</div>
</div>
);
})}
</div>
</div>
{(props.defaultdata?.type === "text" ||
props?.widgetName === "text") && (
<div className="form-section">
<label htmlFor="hint" style={{ fontSize: 13 }}>
Hint
</label>
<input
className="addUserInput"
name="hint"
value={formdata.hint}
onChange={(e) => handleChange(e)}
/>
</div>
)}
<div
style={{
height: 1,
backgroundColor: "#b7b3b3",
width: "100%",
marginBottom: "16px"
}}
></div>
<button
style={{
color: "white",
padding: "5px 20px",
backgroundColor: "#32a3ac"
}}
type="submit"
className="finishBtn"
>
Save
</button>
</form>
</ModalUi>
);
};
export default WidgetNameModal;
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import Parse from "parse";
import Alert from "../../primitives/Alert";
import Alert from "../../../primitives/Alert";
const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
const folderPtr = {
@@ -1,5 +1,5 @@
import React, { useCallback, useMemo } from "react";
import { useDropScript } from "../../hook/useScript";
import { useDropScript } from "../../../hook/useScript";
const DROPBOX_APP_KEY = process.env.REACT_APP_DROPBOX_API_KEY; // App key
const DROPBOX_SDK_URL = "https://www.dropbox.com/static/api/2/dropins.js";
@@ -41,12 +41,15 @@ export default function DropboxChooser({ children, onSuccess, onCancel }) {
[onSuccess, onCancel]
);
const handleChoose = useCallback((e) => {
e.preventDefault()
if (window.Dropbox) {
window.Dropbox.choose(options);
}
}, [options]);
const handleChoose = useCallback(
(e) => {
e.preventDefault();
if (window.Dropbox) {
window.Dropbox.choose(options);
}
},
[options]
);
return (
<div onClick={handleChoose}>
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import Parse from "parse";
import CreateFolder from "./CreateFolder";
import ModalUi from "../../primitives/ModalUi";
import ModalUi from "../../../primitives/ModalUi";
const SelectFolder = ({ required, onSuccess, folderCls }) => {
const [isOpen, SetIsOpen] = useState(false);
@@ -1,6 +1,6 @@
import React, { useState } from "react";
import Parse from "parse";
import "../css/AddUser.css";
import "../../../styles/AddUser.css";
import AsyncSelect from "react-select/async";
const customStyles = {
@@ -17,12 +17,7 @@ const SelectSigners = (props) => {
const [userList, setUserList] = useState([]);
const [selected, setSelected] = useState();
const [userData, setUserData] = useState({});
const [isError, setIsError]= useState(false)
const parseBaseUrl = localStorage.getItem("baseUrl");
const parseAppId = localStorage.getItem("parseAppId");
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
const [isError, setIsError] = useState(false);
// `handleOptions` is used to set just save from quick form to selected option in dropdown
const handleOptions = (item) => {
setSelected(item);
@@ -32,14 +27,14 @@ const SelectSigners = (props) => {
}
};
const handleAdd = () => {
if(userData && userData.objectId){
if (userData && userData.objectId) {
props.details(userData);
if (props.closePopup) {
props.closePopup();
}
}else{
setIsError(true)
setTimeout(()=> setIsError(false), 1000)
} else {
setIsError(true);
setTimeout(() => setIsError(false), 1000);
}
};
@@ -73,8 +68,8 @@ const SelectSigners = (props) => {
return (
<div className="addusercontainer">
<div className="form-wrapper">
<div className="form-section" style={{marginBottom: 0}}>
<label style={{ fontSize: 14 , fontWeight: "700"}}>Choose User</label>
<div className="form-section" style={{ marginBottom: 0 }}>
<label style={{ fontSize: 14, fontWeight: "700" }}>Choose User</label>
<AsyncSelect
cacheOptions
defaultOptions
@@ -86,7 +81,15 @@ const SelectSigners = (props) => {
styles={customStyles}
/>
</div>
{isError ? <p style={{color:'red', fontSize: "12px", margin:"5px"}}>Please select signer</p>: <p style={{color:'transparent', fontSize: "12px", margin:"5px"}}>.</p>}
{isError ? (
<p style={{ color: "red", fontSize: "12px", margin: "5px" }}>
Please select signer
</p>
) : (
<p style={{ color: "transparent", fontSize: "12px", margin: "5px" }}>
.
</p>
)}
<div>
<button className="submitbutton" onClick={() => handleAdd()}>
Submit
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from "react";
import Select from "react-select";
import AppendFormInForm from "../AppendFormInForm";
import AddSigner from "../../AddSigner";
import Modal from "react-modal";
import Parse from "parse";
function arrayMove(array, from, to) {
@@ -172,7 +172,7 @@ const SignersInput = (props) => {
</div>
{isModal && (
<AppendFormInForm
<AddSigner
valueKey={"objectId"}
displayKey={"Name"}
details={handleNewDetails}
+20 -16
View File
@@ -2,20 +2,24 @@ import React from "react";
import { NavLink } from "react-router-dom";
const Menu = ({ item, isOpen, closeSidebar }) => {
return (
<li key={item.title} role="none">
<NavLink
to={`/${item.pageType}/${item.objectId}`}
className="mx-auto flex items-center hover:bg-[#eef1f5] p-3 lg:p-4"
onClick={closeSidebar}
tabIndex={isOpen ? 0 : -1}
role="menuitem"
>
<i className={`${item.icon} text-[18px]`} aria-hidden="true"></i>
<span className="ml-3 lg:ml-4">{item.title}</span>
</NavLink>
</li>
)
}
return (
<li key={item.title} role="none">
<NavLink
to={
item.pageType
? `/${item.pageType}/${item.objectId}`
: `/${item.objectId}`
}
className="mx-auto flex items-center hover:bg-[#eef1f5] p-3 lg:p-4 cursor-pointer"
onClick={closeSidebar}
tabIndex={isOpen ? 0 : -1}
role="menuitem"
>
<i className={`${item.icon} text-[18px]`} aria-hidden="true"></i>
<span className="ml-3 lg:ml-4">{item.title}</span>
</NavLink>
</li>
);
};
export default Menu;
export default Menu;
+25 -15
View File
@@ -1,8 +1,8 @@
import React, { useState, useEffect } from "react";
import Menu from './Menu';
import Menu from "./Menu";
import Submenu from "./SubMenu";
import SocialMedia from './SocialMedia';
import SocialMedia from "./SocialMedia";
import Parse from "parse";
import dp from "../../assets/images/dp.png";
@@ -20,16 +20,10 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
}, []);
const menuItem = async () => {
const parseBaseUrl = localStorage.getItem("baseUrl");
const parseAppId = localStorage.getItem("parseAppId");
try {
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
var sideMenu = Parse.Object.extend("w_menu");
var query = new Parse.Query(sideMenu);
query.equalTo("objectId", localStorage.getItem("defaultmenuid"));
const results = await query.first();
const resultjson = results.toJSON();
let result = resultjson;
@@ -37,7 +31,6 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
} catch (e) {
console.error("Problem", e);
}
};
return (
@@ -47,7 +40,11 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
>
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
<img className="w-full h-full object-cover" src={image} alt="Profile" />
<img
className="w-full h-full object-cover"
src={image}
alt="Profile"
/>
</div>
<div>
<p className="text-[14px] font-bold">{username}</p>
@@ -57,14 +54,27 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
</div>
</div>
<nav aria-label="OpenSign Sidebar Navigation">
<ul className="text-sm" role="menubar" aria-label="OpenSign Sidebar Navigation">
{menuList.map((item) => (
<ul
className="text-sm"
role="menubar"
aria-label="OpenSign Sidebar Navigation"
>
{menuList.map((item) =>
!item.children ? (
<Menu key={item.title} item={item} isOpen={isOpen} closeSidebar={closeSidebar} />
<Menu
key={item.title}
item={item}
isOpen={isOpen}
closeSidebar={closeSidebar}
/>
) : (
<Submenu key={item.title} item={item} closeSidebar={closeSidebar} />
<Submenu
key={item.title}
item={item}
closeSidebar={closeSidebar}
/>
)
))}
)}
</ul>
</nav>
<footer className="mt-4 flex justify-center items-center text-[25px] text-black gap-3">
@@ -22,8 +22,9 @@ const Submenu = ({ item, closeSidebar }) => {
<div className="flex justify-between items-center w-full">
<span className="ml-3 lg:ml-4">{title}</span>
<i
className={`${submenuOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
}`}
className={`${
submenuOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
}`}
aria-hidden="true"
></i>
</div>
@@ -33,13 +34,20 @@ const Submenu = ({ item, closeSidebar }) => {
{children.map((childItem) => (
<li key={childItem.title} role="none">
<NavLink
to={`/${childItem.pageType}/${childItem.objectId}`}
className="block pl-6 md:pl-8 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white"
to={
childItem.pageType
? `/${childItem.pageType}/${childItem.objectId}`
: `/${childItem.objectId}`
}
className="block pl-6 md:pl-8 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white cursor-pointer"
onClick={closeSidebar}
role="menuitem"
tabIndex={submenuOpen ? 0 : -1}
>
<i className={`${childItem.icon} text-[18px]`} aria-hidden="true"></i>
<i
className={`${childItem.icon} text-[18px]`}
aria-hidden="true"
></i>
<span className="ml-3 lg:ml-4">{childItem.title}</span>
</NavLink>
</li>
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -3,7 +3,10 @@ export const appInfo = {
appTitle: "contracts",
applogo: logo,
appname: "contracts",
baseurl: process.env.REACT_APP_SERVERURL,
appId: process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign",
baseUrl: process.env.REACT_APP_SERVERURL
? process.env.REACT_APP_SERVERURL
: window.location.origin + "/api/app",
defaultRole: "contracts_User",
fbAppId: process.env.REACT_APP_FBAPPID
? `${process.env.REACT_APP_FBAPPID}`
+2
View File
@@ -7,3 +7,5 @@ export const submitBtn =
"bg-[#32a3ac] rounded-sm shadow-md text-[12px] font-semibold uppercase text-white py-1.5 px-4 focus:outline-none text-center";
export const modalSubmitBtnColor = "#17a2b8";
export const modalCancelBtnColor = "white";
export const themeColor = "#47a3ad";
export const iconColor = "#686968";
+2 -5
View File
@@ -1,9 +1,6 @@
import axios from "axios";
import Parse from "parse";
const parseAppId = localStorage.getItem("AppID12");
const serverUrl = localStorage.getItem("BaseUrl12");
Parse.serverURL = serverUrl;
Parse.initialize(parseAppId);
const parseAppId = localStorage.getItem("parseAppId");
const serverUrl = localStorage.getItem("baseUrl");
export const SaveFileSize = async (size, imageUrl) => {
//checking server url and save file's size
+71 -1
View File
@@ -1 +1,71 @@
import("./Bootstrap");
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import { store } from "./redux/store";
import { HTML5Backend } from "react-dnd-html5-backend";
import { TouchBackend } from "react-dnd-touch-backend";
import {
DndProvider,
TouchTransition,
MouseTransition,
Preview
} from "react-dnd-multi-backend";
import DragElement from "./components/pdf/DragElement";
import TagManager from "react-gtm-module";
import Parse from "parse";
const appId = process.env.REACT_APP_APPID
? process.env.REACT_APP_APPID
: "opensign";
const serverUrl = process.env.REACT_APP_SERVERURL
? process.env.REACT_APP_SERVERURL
: window.location.origin + "/api/app";
Parse.initialize(appId);
Parse.serverURL = serverUrl;
const HTML5toTouch = {
backends: [
{
id: "html5",
backend: HTML5Backend,
transition: MouseTransition
},
{
id: "touch",
backend: TouchBackend,
options: { enableMouseEvents: true },
preview: true,
transition: TouchTransition
}
]
};
const generatePreview = (props) => {
const { item, style } = props;
const newStyle = {
...style
};
return (
<div style={newStyle}>
<DragElement {...item} />
</div>
);
};
if (process.env.REACT_APP_GTM) {
const tagManagerArgs = {
gtmId: process.env.REACT_APP_GTM
};
TagManager.initialize(tagManagerArgs);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<DndProvider options={HTML5toTouch}>
<Preview>{generatePreview}</Preview>
<App />
</DndProvider>
</Provider>
);
+11 -22
View File
@@ -16,8 +16,7 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-plus",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
redirectUrl: "draftDocument"
}
]
};
@@ -32,8 +31,7 @@ export default function reportJson(id) {
btnColor: "#3ac9d6",
textColor: "white",
btnIcon: "fa fa-eye",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
redirectUrl: "pdfRequestFiles"
}
]
};
@@ -48,8 +46,7 @@ export default function reportJson(id) {
btnColor: "#3ac9d6",
textColor: "white",
btnIcon: "fa fa-eye",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
redirectUrl: "pdfRequestFiles"
}
]
};
@@ -64,8 +61,7 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-eye",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
redirectUrl: "draftDocument"
}
]
};
@@ -80,8 +76,7 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-eye",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
redirectUrl: "draftDocument"
}
]
};
@@ -96,8 +91,7 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-eye",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
redirectUrl: "draftDocument"
}
]
};
@@ -112,8 +106,7 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-eye",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
redirectUrl: "pdfRequestFiles"
}
]
};
@@ -128,8 +121,7 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-eye",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
redirectUrl: "pdfRequestFiles"
}
]
};
@@ -144,8 +136,7 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-plus",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
redirectUrl: "draftDocument"
}
]
};
@@ -175,16 +166,14 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-plus",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/placeHolderSign"
redirectUrl: "placeHolderSign"
},
{
btnLabel: "Edit",
btnColor: "#00c9d5",
textColor: "white",
btnIcon: "fa fa-plus",
redirectUrl:
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/template"
redirectUrl: "template"
}
]
};
+1 -1
View File
@@ -110,7 +110,7 @@ const HomeLayout = () => {
// console.log("closeTour");
setIsTour(false);
const serverUrl = localStorage.getItem("baseUrl");
const appId = localStorage.getItem("AppID12");
const appId = localStorage.getItem("parseAppId");
const extUserClass = localStorage.getItem("extended_class");
const json = JSON.parse(localStorage.getItem("Extand_Class"));
const extUserId = json && json.length > 0 && json[0].objectId;
@@ -1,58 +0,0 @@
import React from "react";
import stamp from "./stamp2.png";
import sign from "./sign3.png";
import { themeColor } from "./IconColor.js";
function DragElement({ id }) {
const selectedId = id;
return (
<div>
{selectedId === 3 ? (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
userSelect: "none"
}}
>
<img
alt="sign img"
style={{
width: "25px",
height: "23px",
background: themeColor()
}}
src={sign}
/>
<span style={{ color: themeColor(), fontSize: "12px" }}>
Signature
</span>
</div>
) : (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
userSelect: "none"
}}
>
<img
alt="stamp img"
style={{
width: "25px",
height: "23px",
background: themeColor()
}}
src={stamp}
/>
<span style={{ color: themeColor(), fontSize: "12px" }}>Stamp</span>
</div>
)}
</div>
);
}
export default DragElement;
@@ -1,3 +0,0 @@
export const themeColor = () => {
return "#47a3ad";
};
Binary file not shown.

Before

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 B

@@ -11,8 +11,6 @@ function ChangePassword() {
evt.preventDefault();
try {
if (newpassword === confirmpassword) {
Parse.serverURL = localStorage.getItem("baseUrl");
Parse.initialize(localStorage.getItem("parseAppId"));
Parse.User.logIn(localStorage.getItem("userEmail"), currentpassword)
.then(async (user) => {
if (user) {
@@ -12,8 +12,6 @@ const Dashboard = (props) => {
const [dashboard, setdashboard] = useState([]);
const [classnameArray, setclassnameArray] = useState([]);
const [loading, setloading] = useState(false);
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
const [defaultQuery, setDefaultQuery] = useState("");
useEffect(() => {
@@ -32,8 +30,6 @@ const Dashboard = (props) => {
const getDashboard = async (id) => {
setloading(true);
try {
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
var forms = Parse.Object.extend("w_dashboard");
var query = new Parse.Query(forms);
query.equalTo("objectId", id);
@@ -1,13 +1,13 @@
import React, { useEffect, useState } from "react";
import RenderAllPdfPage from "./component/renderAllPdfPage";
import "../css/./signature.css";
import "../css/AddUser.css";
import Title from "./component/Title";
import ModalUi from "../premitives/ModalUi";
import RenderDebugPdf from "./component/RenderDebugPdf";
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
import "../styles/signature.css";
import "../styles/AddUser.css";
import Title from "../components/Title";
import RenderDebugPdf from "../components/RenderDebugPdf";
import { pdfjs } from "react-pdf";
import Alert from "../premitives/Alert";
import HandleError from "./component/HandleError";
import ModalUi from "../primitives/ModalUi";
import Alert from "../primitives/Alert";
import HandleError from "../primitives/HandleError";
import { useWindowSize } from "../hook/useWindowSize";
function processDimensions(x, y, width, height) {
@@ -28,7 +28,7 @@ function processDimensions(x, y, width, height) {
height: Math.floor(height)
};
}
const DebugUi = () => {
const DebugPdf = () => {
const { width } = useWindowSize();
const [pdf, setPdf] = useState("");
const [isModal, setIsModal] = useState(true);
@@ -426,4 +426,4 @@ const DebugUi = () => {
);
};
export default DebugUi;
export default DebugPdf;
@@ -37,11 +37,7 @@ function ForgotPassword(props) {
);
if (state.email) {
const username = state.email;
let baseUrl = localStorage.getItem("BaseUrl12");
let parseAppId = localStorage.getItem("AppID12");
try {
Parse.serverURL = baseUrl;
Parse.initialize(parseAppId);
await Parse.User.requestPasswordReset(username);
setSentStatus("success");
} catch (err) {
@@ -54,7 +50,7 @@ function ForgotPassword(props) {
};
useEffect(() => {
props.fetchAppInfo(localStorage.getItem("domain"));
props.fetchAppInfo();
resize();
window.addEventListener("resize", resize);
return () => window.removeEventListener("resize", resize);
@@ -4,10 +4,10 @@ import { formJson } from "../json/FormJson";
import AddUser from "../components/AddUser";
import sanitizeFileName from "../primitives/sanitizeFileName";
import Parse from "parse";
import DropboxChooser from "../components/fields/DropboxChoose";
import DropboxChooser from "../components/shared/fields/DropboxChoose";
import Alert from "../primitives/Alert";
import SelectFolder from "../components/fields/SelectFolder";
import SignersInput from "../components/fields/SignersInput";
import SelectFolder from "../components/shared/fields/SelectFolder";
import SignersInput from "../components/shared/fields/SignersInput";
import Title from "../components/Title";
import PageNotFound from "./PageNotFound";
@@ -74,8 +74,6 @@ const Forms = (props) => {
};
const handleFileUpload = async (file) => {
Parse.serverURL = process.env.REACT_APP_SERVERURL;
Parse.initialize(process.env.REACT_APP_APPID);
setfileload(true);
const fileName = file.name;
const name = sanitizeFileName(fileName);
@@ -195,9 +193,7 @@ const Forms = (props) => {
});
setFileUpload([]);
setpercentage(0);
navigate(
`/asmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/${props?.redirectRoute}/${res.id}`
);
navigate(`/${props?.redirectRoute}/${res.id}`);
}
} catch (err) {
console.log("err ", err);
@@ -280,7 +276,8 @@ const Forms = (props) => {
<div className="flex gap-2 justify-center items-center">
<div className="flex justify-between items-center px-2 py-2 w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]">
<div className="break-all">
file selected : {fileupload?.split("/")?.pop()?.split("_")[1]}
file selected :{" "}
{fileupload?.split("/")?.pop()?.split("_")[1]}
</div>
<div
onClick={() => {
@@ -1,13 +1,11 @@
import React, { useState } from "react";
import "../css/LoginPage.css";
import loader from "../assests/loader2.gif";
import React, { useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import "../styles/loginPage.css";
import loader from "../assets/images/loader2.gif";
import axios from "axios";
import { useParams } from "react-router-dom";
import { themeColor } from "../utils/ThemeColor/backColor";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { themeColor } from "../constant/const";
function Login() {
function GuestLogin() {
const { id, userMail, contactBookId, serverUrl } = useParams();
let navigate = useNavigate();
const [email, setEmail] = useState(userMail);
@@ -18,6 +16,7 @@ function Login() {
useEffect(() => {
handleServerUrl();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
//function generate serverUrl and parseAppId from url and save it in local storage
@@ -114,18 +113,18 @@ function Login() {
//save isGuestSigner true in local to handle login flow header in mobile view
localStorage.setItem("isGuestSigner", true);
setLoading(false);
navigate(
`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`
);
navigate(`/load/recipientSignPdf/${id}/${contactBookId}`);
}
} catch (error) {}
} catch (error) {
console.log("err ", error);
}
} else {
alert("Please Enter OTP!");
}
};
return (
<div style={{ padding: "2rem" }}>
<div style={{ padding: "2rem", background: "white" }}>
{isLoading ? (
<div
style={{
@@ -189,7 +188,7 @@ function Login() {
<button
type="button"
style={{
background: themeColor(),
background: themeColor,
color: "white"
}}
className="verifyBtn"
@@ -206,7 +205,7 @@ function Login() {
<button
className="verifyBtn"
style={{
background: themeColor(),
background: themeColor,
color: "white",
marginLeft: "0px !important"
}}
@@ -242,7 +241,7 @@ function Login() {
{loading ? (
<button
style={{
background: themeColor(),
background: themeColor,
color: "white"
}}
className="verifyBtn"
@@ -261,7 +260,7 @@ function Login() {
type="button"
onClick={(e) => VerifyOTP(e)}
style={{
background: themeColor(),
background: themeColor,
color: "white"
}}
className="verifyBtn"
@@ -279,4 +278,4 @@ function Login() {
);
}
export default Login;
export default GuestLogin;
@@ -1,6 +1,5 @@
import React, { useEffect, useState } from "react";
import Parse from "parse";
import "../styles/toast.css";
import "../styles/loader.css";
import { connect } from "react-redux";
import { fetchAppInfo, showTenantName } from "../redux/actions";
@@ -13,6 +12,7 @@ import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
import ModalUi from "../primitives/ModalUi";
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
import Alert from "../primitives/Alert";
function Login(props) {
const navigate = useNavigate();
@@ -20,8 +20,8 @@ function Login(props) {
const { width } = useWindowSize();
const [state, setState] = useState({
email: "",
toastColor: "#5cb85c",
toastDescription: "",
alertType: "success",
alertMsg: "",
password: "",
passwordVisible: false,
mobile: "",
@@ -44,11 +44,7 @@ function Login(props) {
setState({ ...state, loading: true });
GetLoginData();
}
props.fetchAppInfo(
localStorage.getItem("domain"),
localStorage.getItem("BaseUrl12"),
localStorage.getItem("AppID12")
);
props.fetchAppInfo();
// eslint-disable-next-line
}, []);
const handleChange = (event) => {
@@ -67,8 +63,6 @@ function Login(props) {
let parseAppId = localStorage.getItem("parseAppId");
localStorage.setItem("appLogo", props.appInfo.applogo);
localStorage.setItem("appName", props.appInfo.appname);
Parse.serverURL = localStorage.getItem("baseUrl");
Parse.initialize(localStorage.getItem("parseAppId"));
// Pass the username and password to logIn function
await Parse.User.logIn(email, password)
.then(async (user) => {
@@ -149,11 +143,6 @@ function Login(props) {
"extended_class",
element.extended_class
);
localStorage.setItem(
"userpointer",
element.userpointer
);
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
@@ -354,13 +343,16 @@ function Login(props) {
setState({
...state,
loading: false,
toastColor: "#d9534f",
toastDescription: `${error.message}`
alertType: "danger",
alertMsg: `${error.message}`
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
...state,
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
console.log(error);
}
@@ -370,13 +362,16 @@ function Login(props) {
setState({
...state,
loading: false,
toastColor: "#d9534f",
toastDescription: "Login failed: Invalid username or password."
alertType: "danger",
alertMsg: "Invalid username or password!"
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
...state,
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
console.error("Error while logging in user", error);
});
@@ -391,8 +386,8 @@ function Login(props) {
setState({ ...state, thirdpartyLoader: value });
};
const thirdpartyLoginfn = async (sessionToken, billingDate) => {
const baseUrl = localStorage.getItem("BaseUrl12");
const parseAppId = localStorage.getItem("AppID12");
const baseUrl = localStorage.getItem("baseUrl");
const parseAppId = localStorage.getItem("parseAppId");
const res = await axios.get(baseUrl + "users/me", {
headers: {
"X-Parse-Session-Token": sessionToken,
@@ -480,7 +475,6 @@ function Login(props) {
"extended_class",
element.extended_class
);
localStorage.setItem("userpointer", element.userpointer);
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
@@ -647,13 +641,16 @@ function Login(props) {
setState({
...state,
loading: false,
toastColor: "#d9534f",
toastDescription: `${error.message}`
alertType: "danger",
alertMsg: `${error.message}`
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
...state,
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
console.log(error);
}
@@ -663,8 +660,6 @@ function Login(props) {
const GetLoginData = async () => {
setState({ ...state, loading: true });
try {
Parse.serverURL = localStorage.getItem("baseUrl");
Parse.initialize(localStorage.getItem("parseAppId"));
const user = await Parse.User.become(localStorage.getItem("accesstoken"));
let _usss = user.toJSON();
localStorage.setItem("UserInformation", JSON.stringify(_usss));
@@ -717,13 +712,17 @@ function Login(props) {
setState({
...state,
loading: false,
toastColor: "#d9534f",
toastDescription: `Does not have permissions to access this application.`
alertType: "danger",
alertMsg:
"Does not have permissions to access this application!"
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
...state,
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
}
// _currentRole = userRoles[0];
@@ -802,14 +801,16 @@ function Login(props) {
setState({
...state,
loading: false,
toastColor: "#d9534f",
toastDescription:
"You don`t have access to this application."
alertType: "danger",
alertMsg: "You don`t have access to this application!"
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
...state,
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
localStorage.setItem("accesstoken", null);
console.error("Error while fetching Follow", error);
@@ -895,8 +896,8 @@ function Login(props) {
let PageLanding = localStorage.getItem("PageLanding");
let domain = localStorage.getItem("domain");
let _appName = localStorage.getItem("_appName");
let baseUrl = localStorage.getItem("BaseUrl12");
let appid = localStorage.getItem("AppID12");
let baseUrl = localStorage.getItem("baseUrl");
let appid = localStorage.getItem("parseAppId");
localStorage.clear();
@@ -907,8 +908,8 @@ function Login(props) {
localStorage.setItem("PageLanding", PageLanding);
localStorage.setItem("domain", domain);
localStorage.setItem("userSettings", appdata);
localStorage.setItem("BaseUrl12", baseUrl);
localStorage.setItem("AppID12", appid);
localStorage.setItem("baseUrl", baseUrl);
localStorage.setItem("parseAppId", appid);
};
return (
<div className="bg-white">
@@ -1124,14 +1125,7 @@ function Login(props) {
)}
</div>
</div>
<div
id="snackbar"
role="alert"
style={{ backgroundColor: state.toastColor }}
>
{state.toastDescription}
</div>
<Alert type={state.alertType}>{state.alertMsg}</Alert>
</div>
<ModalUi isOpen={isModal} title="Additional Info" showClose={false}>
<form className="px-4 py-3">
@@ -1,16 +1,12 @@
import React, { useState, useRef, useEffect } from "react";
import SignatureCanvas from "react-signature-canvas";
import redPen from "../assests/redPen.png";
import bluePen from "../assests/bluePen.png";
import blackPen from "../assests/blackPen.png";
import "../css/custom.css";
import "../css/signature.css";
import axios from "axios";
import { toDataUrl } from "../utils/toDataUrl";
import "../styles/managesign.css";
import "../styles/signature.css";
import { toDataUrl } from "../constant/Utils";
import Parse from "parse";
import { appInfo } from "../constant/appinfo";
const ManageSign = () => {
let appName;
const appName = appInfo.appname;
const [penColor, setPenColor] = useState("blue");
const [initialPen, setInitialPen] = useState("blue");
const [image, setImage] = useState();
@@ -19,7 +15,7 @@ const ManageSign = () => {
const [warning, setWarning] = useState(false);
const [nameWarning, setNameWarning] = useState(false);
const [isvalue, setIsValue] = useState(false);
const allColor = [bluePen, redPen, blackPen];
const allColor = ["blue", "red", "black"];
const [isLoader, setIsLoader] = useState(true);
const [isSuccess, setIsSuccess] = useState(false);
const [Initials, setInitials] = useState("");
@@ -29,59 +25,40 @@ const ManageSign = () => {
const imageRef = useRef(null);
const initailsRef = useRef(null);
useEffect(() => {
getLocalStorageValue();
fetchUserSign();
// eslint-disable-next-line
}, []);
//function for get localstorage value first and than call another function.
const getLocalStorageValue = () => {
let User = JSON.parse(
localStorage.getItem(
"Parse/" + localStorage.getItem("parseAppId") + "/currentUser"
)
);
appName =
localStorage.getItem("_appName") && localStorage.getItem("_appName");
const fetchUserSign = async () => {
const User = Parse.User.current();
if (User) {
fetchUserSign(User);
}
};
const fetchUserSign = async (User) => {
const userId = {
__type: "Pointer",
className: "_User",
objectId: User.objectId,
};
const strObj = JSON.stringify(userId);
const url =
localStorage.getItem("baseUrl") +
`classes/${appName}_Signature?where={"UserId":${strObj}}&limit=1`;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
// "X-Parse-Session-Token": localStorage.getItem("accesstoken"),
};
const res = await axios
.get(url, { headers: headers })
.then((res) => {
if (res.data.results.length > 0) {
setId(res.data.results[0].objectId);
setSignName(res.data.results[0].SignatureName);
setImage(res.data.results[0].ImageURL);
if (res.data.results[0] && res.data.results[0].Initials) {
setInitials(res.data.results[0].Initials);
const userId = {
__type: "Pointer",
className: "_User",
objectId: User.id
};
try {
const signCls = `${appName}_Signature`;
const signQuery = new Parse.Query(signCls);
signQuery.equalTo("UserId", userId);
const signRes = await signQuery.first();
if (signRes) {
const res = signRes.toJSON();
setId(res.objectId);
setSignName(res?.SignatureName);
setImage(res.ImageURL);
if (res && res.Initials) {
setInitials(res.Initials);
setIsInitials(true);
}
} else {
setSignName(User?.get("name") || "");
}
setIsLoader(false);
return res;
})
.catch((error) => {
console.log(error);
alert(`${error.message}`);
});
return res;
} catch (err) {
console.log("Err", err);
alert(`${err.message}`);
}
}
};
const handleSignatureChange = () => {
if (imageRef.current) {
@@ -112,18 +89,6 @@ const ManageSign = () => {
setIsInitials(false);
};
// const handleReset = () => {
// if (canvasRef.current) {
// canvasRef.current.clear();
// }
// if (imageRef.current) {
// imageRef.current.value = "";
// }
// setImage("");
// setSignature("");
// setIsValue(false);
// setSignName("");
// };
const onImageChange = async (event) => {
if (canvasRef.current) {
canvasRef.current.clear();
@@ -142,7 +107,6 @@ const ManageSign = () => {
if (!signName) {
setNameWarning(true);
} else if (!isvalue) {
setWarning(true);
setTimeout(() => setWarning(false), 1000);
@@ -151,29 +115,32 @@ const ManageSign = () => {
const replaceSpace = signName.replace(/ /g, "_");
let file;
if (signature) {
file = base64StringtoFile(signature, `${replaceSpace}.png`);
file = base64StringtoFile(signature, `${replaceSpace}_sign.png`);
} else {
if (!isUrl) {
file = base64StringtoFile(image, `${replaceSpace}.png`);
file = base64StringtoFile(image, `${replaceSpace}__sign.png`);
}
}
// console.log("isUrl ", isUrl);
let imgUrl;
if (!isUrl) {
imgUrl = await uploadFile(file);
} else {
imgUrl = { data: { imageUrl: image } };
imgUrl = image;
}
let initialsUrl = "";
if (Initials) {
const initialsImg = base64StringtoFile(Initials, `${replaceSpace}.png`);
const isInitialsUrl = Initials.includes("https");
if (!isInitialsUrl && Initials) {
const initialsImg = base64StringtoFile(
Initials,
`${replaceSpace}_initials.png`
);
initialsUrl = await uploadFile(initialsImg);
}
if (imgUrl.data && imgUrl.data.imageUrl) {
if (imgUrl) {
await saveEntry({
name: signName,
url: imgUrl.data.imageUrl,
initialsUrl: initialsUrl,
url: imgUrl,
initialsUrl: initialsUrl
});
}
}
@@ -191,116 +158,54 @@ const ManageSign = () => {
}
const uploadFile = async (file) => {
let parseBaseUrl = localStorage.getItem("baseUrl");
parseBaseUrl = parseBaseUrl.slice(0, -4);
const url = parseBaseUrl + `file_upload`;
const formData = new FormData();
formData.append("file", file);
const config = {
headers: {
"content-type": "multipart/form-data",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
},
onUploadProgress: function (progressEvent) {
let percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
// setpercentage(percentCompleted);
},
};
const response = await axios
.post(url, formData, config)
.then((res) => {
if (res.data.status === "Error") {
alert(res.data.message);
}
return res;
})
.catch((error) => {
console.log(error);
setIsLoader(false);
alert(`${error.message}`);
});
return response;
try {
const parseFile = new Parse.File(file.name, file);
const response = await parseFile.save();
return response?.url();
} catch (err) {
console.log("sign upload err", err);
setIsLoader(false);
alert(`${err.message}`);
}
};
const saveEntry = async (obj) => {
const signCls = `${appName}_Signature`;
const User = Parse.User.current().id;
const userId = { __type: "Pointer", className: "_User", objectId: User };
if (id) {
const User = JSON.parse(
localStorage.getItem(
"Parse/" + localStorage.getItem("parseAppId") + "/currentUser"
)
);
const url =
localStorage.getItem("baseUrl") +
`classes/${localStorage.getItem("_appName")}_Signature/${id}`;
const body = {
Initials: obj.initialsUrl ? obj.initialsUrl.data.imageUrl : "",
ImageURL: obj.url,
SignatureName: obj.name,
UserId: {
__type: "Pointer",
className: "_User",
objectId: User.objectId,
},
};
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
// "X-Parse-Session-Token": localStorage.getItem("accesstoken"),
};
const res = await axios
.put(url, body, { headers: headers })
.then((res) => {
// handleReset();
setIsLoader(false);
setIsSuccess(true);
return res;
})
.catch((error) => {
console.log(error);
setIsLoader(false);
alert(`${error.message}`);
});
return res;
try {
const updateSign = new Parse.Object(signCls);
updateSign.id = id;
updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : "");
updateSign.set("ImageURL", obj.url);
updateSign.set("SignatureName", obj.name);
updateSign.set("UserId", userId);
const res = await updateSign.save();
setIsLoader(false);
setIsSuccess(true);
return res;
} catch (err) {
console.log(err);
setIsLoader(false);
alert(`${err.message}`);
}
} else {
const User = JSON.parse(
localStorage.getItem(
"Parse/" + localStorage.getItem("parseAppId") + "/currentUser"
)
);
const url =
localStorage.getItem("baseUrl") +
`classes/${localStorage.getItem("_appName")}_Signature`;
const body = {
Initials: obj.initialsUrl ? obj.initialsUrl.data.imageUrl : "",
ImageURL: obj.url,
SignatureName: obj.name,
UserId: {
__type: "Pointer",
className: "_User",
objectId: User.objectId,
},
};
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
// "X-Parse-Session-Token": localStorage.getItem("accesstoken"),
};
const res = await axios
.post(url, body, { headers: headers })
.then((res) => {
// handleReset();
setIsLoader(false);
setIsSuccess(true);
return res;
})
.catch((error) => {
console.log(error);
setIsLoader(false);
alert(`${error.message}`);
});
return res;
try {
const updateSign = new Parse.Object(signCls);
updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : "");
updateSign.set("ImageURL", obj.url);
updateSign.set("SignatureName", obj.name);
updateSign.set("UserId", userId);
const res = await updateSign.save();
setIsLoader(false);
setIsSuccess(true);
return res;
} catch (err) {
console.log(err);
setIsLoader(false);
alert(`${err.message}`);
}
}
};
const handleSignatureBtn = () => {
@@ -319,10 +224,26 @@ const ManageSign = () => {
return (
<div
style={{
backgroundColor: "white",
maxHeight: "500px",
overflow: "auto",
overflow: "auto"
}}
>
{isLoader && (
<div className="absolute bg-black bg-opacity-75 inset-0 z-50 flex justify-center items-center">
<div style={{ height: "300px" }}>
<div
style={{
marginLeft: "45%",
marginTop: "150px",
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
</div>
)}
{isSuccess && (
<div
className="alert alert-success successBox"
@@ -332,12 +253,11 @@ const ManageSign = () => {
Signature saved successfully!
</div>
)}
<div
className="mainDiv"
style={{
width: "100%",
paddingRight: "10px",
paddingRight: "10px"
}}
>
<div style={{ margin: 20 }}>
@@ -346,7 +266,7 @@ const ManageSign = () => {
fontWeight: "700",
fontSize: 15,
color: "#000",
paddingBottom: 8,
paddingBottom: 8
}}
>
Manage Signature
@@ -357,10 +277,10 @@ const ManageSign = () => {
style={{
fontSize: 12,
position: "relative",
paddingBottom: 5,
paddingBottom: 5
}}
>
Signer's Name
Signer&apos;s Name
{nameWarning && (
<div
className="warning nameWarning"
@@ -386,7 +306,7 @@ const ManageSign = () => {
height: 35,
padding: "6px 12px",
marginBottom: 10,
fontSize: 12,
fontSize: 12
}}
required
onFocus={() => setNameWarning(false)}
@@ -397,7 +317,7 @@ const ManageSign = () => {
htmlFor="imgoverview"
style={{
fontSize: 12,
paddingBottom: 5,
paddingBottom: 5
}}
>
Signature/Image
@@ -412,7 +332,7 @@ const ManageSign = () => {
flexDirection: "row",
justifyContent: "space-between",
width: "50%",
paddingLeft: 10,
paddingLeft: 10
}}
>
<div
@@ -422,7 +342,7 @@ const ManageSign = () => {
justifyContent: "space-around",
alignItems: "center",
gap: 10,
marginBottom: 10,
marginBottom: 10
}}
>
<>
@@ -456,9 +376,7 @@ const ManageSign = () => {
<div
style={{
position: "relative",
border: "2px solid #888",
marginBottom: 6,
border: "2px solid #888"
}}
className="signatureCanvas"
>
@@ -468,7 +386,7 @@ const ManageSign = () => {
style={{
width: "100%",
height: "100%",
objectFit: "contain",
objectFit: "contain"
}}
/>
</div>
@@ -479,7 +397,7 @@ const ManageSign = () => {
canvasProps={{
width: "456px",
height: "180px",
className: "signatureCanvas",
className: "signatureCanvas"
}}
backgroundColor="rgb(255, 255, 255)"
onEnd={() =>
@@ -492,10 +410,9 @@ const ManageSign = () => {
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
// width: 460,
justifyContent: "space-between"
}}
className="penContainer"
className="penContainerDefault"
>
<div>
{!image && (
@@ -504,19 +421,18 @@ const ManageSign = () => {
>
{allColor.map((data, key) => {
return (
<img
alt="black img"
<i
style={{
border: "none",
margin: "5px",
color: data,
borderBottom:
key === 0 && penColor === "blue"
? "2px solid blue"
: key === 1 && penColor === "red"
? "2px solid red"
: key === 2 && penColor === "black"
? "2px solid black"
: "2px solid white",
? "2px solid red"
: key === 2 && penColor === "black"
? "2px solid black"
: "2px solid white"
}}
onClick={() => {
if (key === 0) {
@@ -528,10 +444,10 @@ const ManageSign = () => {
}
}}
key={key}
src={data}
className="fa solid fa-pen-nib"
width={20}
height={20}
/>
></i>
);
})}
</div>
@@ -540,7 +456,7 @@ const ManageSign = () => {
<div>
<div
type="button"
className="clearbtn"
className="clearbtn cursor-pointer"
onClick={() => handleClear()}
>
Clear
@@ -565,23 +481,16 @@ const ManageSign = () => {
</div>
<div style={{ position: "relative" }}>
<div style={{ margin: "6px 5px 18px" }}>
<span
// onClick={() => handleSignatureBtn()}
className="signature"
>
Initials
</span>
<span className="signature">Initials</span>
</div>
<div>
{isInitials ? (
<div
style={{
position: "relative",
border: "2px solid #888",
marginBottom: 6,
border: "2px solid #888"
}}
className="signatureCanvas"
className="intialSignature"
>
<img
alt="preview image"
@@ -589,7 +498,7 @@ const ManageSign = () => {
style={{
width: "100%",
height: "100%",
objectFit: "contain",
objectFit: "contain"
}}
/>
</div>
@@ -598,9 +507,7 @@ const ManageSign = () => {
ref={initailsRef}
penColor={initialPen}
canvasProps={{
width: "456px",
height: "180px",
className: "signatureCanvas",
className: "intialSignature"
}}
backgroundColor="rgb(255, 255, 255)"
onEnd={() =>
@@ -613,29 +520,27 @@ const ManageSign = () => {
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
// width: 460,
justifyContent: "space-between"
}}
className="penContainer"
className="penContainerInitial"
>
<div>
{!isInitials && (
<div style={{ display: "flex", flexDirection: "row" }}>
{allColor.map((data, key) => {
return (
<img
alt="pen"
<i
style={{
border: "none",
margin: "5px",
color: data,
borderBottom:
key === 0 && initialPen === "blue"
? "2px solid blue"
: key === 1 && initialPen === "red"
? "2px solid red"
: key === 2 && initialPen === "black"
? "2px solid black"
: "2px solid white",
? "2px solid red"
: key === 2 && initialPen === "black"
? "2px solid black"
: "2px solid white"
}}
onClick={() => {
if (key === 0) {
@@ -647,10 +552,10 @@ const ManageSign = () => {
}
}}
key={key}
src={data}
className="fa solid fa-pen-nib"
width={20}
height={20}
/>
></i>
);
})}
</div>
@@ -659,7 +564,7 @@ const ManageSign = () => {
<div>
<div
type="button"
className="clearbtn"
className="clearbtn cursor-pointer"
onClick={() => handleClearInitials()}
>
Clear
@@ -687,11 +592,6 @@ const ManageSign = () => {
</button>
</div>
</div>
{isLoader && (
<div className="loaderContainer">
<div className="loader"></div>
</div>
)}
</div>
</div>
);
@@ -1,15 +1,15 @@
import React, { useEffect, useState, useRef } from "react";
import "./LegaDrive.css";
import loader from "../../assests/loader2.gif";
import PdfFileComponent from "./FolderDrive/legaDriveComponent";
import { themeColor, iconColor } from "../../utils/ThemeColor/backColor";
import { getDrive } from "../../utils/Utils";
import "../styles/opensigndrive.css";
import loader from "../assets/images/loader2.gif";
import DriveBody from "../components/opensigndrive/DriveBody";
import { themeColor, iconColor } from "../constant/const";
import { getDrive } from "../constant/Utils";
import { useNavigate } from "react-router-dom";
import Title from "../component/Title";
import Title from "../components/Title";
import Parse from "parse";
import ModalUi from "../../premitives/ModalUi";
import ModalUi from "../primitives/ModalUi";
function PdfFile() {
function Opensigndrive() {
const navigate = useNavigate();
const scrollRef = useRef(null);
const [isList, setIsList] = useState(false);
@@ -45,6 +45,7 @@ function PdfFile() {
} else {
getPdfDocumentList();
}
// eslint-disable-next-line
}, [docId]);
//function for get all pdf document list
@@ -300,9 +301,9 @@ function PdfFile() {
// Cleanup the event listener when the component unmounts
document.removeEventListener("click", closeMenuOnOutsideClick);
};
}, [isShowSort || isNewFol]);
}, [isShowSort, isNewFol]);
const handleFolderTab = (folderData, isMove) => {
const handleFolderTab = (folderData) => {
return folderData.map((data, id) => {
return (
<React.Fragment key={id}>
@@ -336,7 +337,7 @@ function PdfFile() {
setError("");
};
return (
<div className="folderComponent ">
<div style={{ backgroundColor: "white" }} className="folderComponent">
<Title title={"OpenSign™ Drive"} drive={true} />
<div>
<ModalUi
@@ -444,9 +445,7 @@ function PdfFile() {
></div>
<div style={{ display: "flex", flexDirection: "row" }}>
<button
style={{
background: themeColor()
}}
style={{ background: themeColor }}
type="submit"
className="finishBtn"
>
@@ -524,7 +523,7 @@ function PdfFile() {
<i
className="fa fa-plus-square"
aria-hidden="true"
style={{ fontSize: "25px", color: `${iconColor()}` }}
style={{ fontSize: "25px", color: `${iconColor}` }}
></i>
</div>
<div
@@ -588,13 +587,13 @@ function PdfFile() {
style={{
marginRight: "5px",
fontSize: "14px",
color: `${iconColor()}`
color: `${iconColor}`
}}
></i>
<span
style={{
fontSize: "15px",
color: `${iconColor()}`
color: `${iconColor}`
}}
>
{selectedSort}
@@ -705,7 +704,7 @@ function PdfFile() {
<i
onClick={() => setIsList(!isList)}
className="fa fa-th-large"
style={{ fontSize: "24px", color: `${iconColor()}` }}
style={{ fontSize: "24px", color: `${iconColor}` }}
aria-hidden="true"
></i>
</div>
@@ -714,7 +713,7 @@ function PdfFile() {
<i
className="fa fa-list"
aria-hidden="true"
style={{ fontSize: "23px", color: `${iconColor()}` }}
style={{ fontSize: "23px", color: `${iconColor}` }}
></i>
</div>
)}
@@ -735,7 +734,7 @@ function PdfFile() {
<span style={{ fontWeight: "bold" }}>No Data Found!</span>
</div>
) : (
<PdfFileComponent
<DriveBody
pdfData={pdfData}
setFolderName={setFolderName}
setIsLoading={setIsLoading}
@@ -755,4 +754,4 @@ function PdfFile() {
);
}
export default PdfFile;
export default Opensigndrive;
@@ -1,14 +1,15 @@
import React, { useState, useRef, useEffect } from "react";
import { themeColor } from "../utils/ThemeColor/backColor";
import { themeColor } from "../constant/const";
import { PDFDocument } from "pdf-lib";
import "../css/signature.css";
import "../styles/signature.css";
import axios from "axios";
import loader from "../assests/loader2.gif";
import loader from "../assets/images/loader2.gif";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { useParams } from "react-router-dom";
import SignPad from "./component/signPad";
import RenderAllPdfPage from "./component/renderAllPdfPage";
import SignPad from "../components/pdf/SignPad";
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
import Tour from "reactour";
import {
contractDocument,
multiSignEmbed,
@@ -19,16 +20,15 @@ import {
onSaveSign,
onSaveImage,
addDefaultSignatureImg
} from "../utils/Utils";
import Loader from "./component/loader";
import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata";
import Header from "./component/header";
import RenderPdf from "./component/renderPdf";
import CustomModal from "./component/CustomModal";
import Title from "./component/Title";
import DefaultSignature from "./component/defaultSignature";
import ModalUi from "../premitives/ModalUi";
} from "../constant/Utils";
import Loader from "../primitives/LoaderWithMsg";
import HandleError from "../primitives/HandleError";
import Header from "../components/pdf/PdfHeader";
import RenderPdf from "../components/pdf/RenderPdf";
import PdfDeclineModal from "../primitives/PdfDeclineModal";
import Title from "../components/Title";
import DefaultSignature from "../components/pdf/DefaultSignature";
import ModalUi from "../primitives/ModalUi";
function PdfRequestFiles() {
const { docId } = useParams();
@@ -57,12 +57,12 @@ function PdfRequestFiles() {
const [pdfNewWidth, setPdfNewWidth] = useState();
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
const [signerPos, setSignerPos] = useState([]);
const [noData, setNoData] = useState(false);
const [signerObjectId, setSignerObjectId] = useState();
const [isUiLoading, setIsUiLoading] = useState(false);
const [isDecline, setIsDecline] = useState({ isDeclined: false });
const [currentSigner, setCurrentSigner] = useState(false);
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
const [defaultSignAlert, setDefaultSignAlert] = useState({
isShow: false,
alertMessage: ""
@@ -71,6 +71,8 @@ function PdfRequestFiles() {
isCertificate: false,
isModal: false
});
const [myInitial, setMyInitial] = useState("");
const [isInitial, setIsInitial] = useState(false);
const [pdfLoadFail, setPdfLoadFail] = useState({
status: false,
type: "load"
@@ -79,6 +81,9 @@ function PdfRequestFiles() {
const [isExpired, setIsExpired] = useState(false);
const [alreadySign, setAlreadySign] = useState(false);
const [containerWH, setContainerWH] = useState({});
const [validateAlert, setValidateAlert] = useState(false);
const [widgetsTour, setWidgetsTour] = useState(false);
const [minRequiredCount, setminRequiredCount] = useState();
const [sendInOrder, setSendInOrder] = useState(false);
const divRef = useRef(null);
const isMobile = window.innerWidth < 767;
@@ -105,6 +110,7 @@ function PdfRequestFiles() {
if (documentId) {
getDocumentDetails();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if (divRef.current) {
@@ -115,10 +121,12 @@ function PdfRequestFiles() {
height: divRef.current.offsetHeight
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [divRef.current]);
//function for get document details for perticular signer with signer'object id
const getDocumentDetails = async () => {
let currUserId;
//getting document details
const documentData = await contractDocument(documentId);
if (documentData && documentData.length > 0) {
@@ -135,9 +143,7 @@ function PdfRequestFiles() {
(data) => data.UserId.objectId === jsonSender.objectId
);
const currUserId = getCurrentSigner[0]
? getCurrentSigner[0].objectId
: "";
currUserId = getCurrentSigner[0] ? getCurrentSigner[0].objectId : "";
setSignerObjectId(currUserId);
if (documentData[0].SignedUrl) {
setPdfUrl(documentData[0].SignedUrl);
@@ -287,7 +293,7 @@ function PdfRequestFiles() {
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else {
setNoData(true);
setHandleError("No Data Found!");
const loadObj = {
isLoad: false
};
@@ -315,7 +321,9 @@ function PdfRequestFiles() {
if (res[0] && res.length > 0) {
setDefaultSignImg(res[0].ImageURL);
setMyInitial(res[0]?.Initials);
}
const loadObj = {
isLoad: false
};
@@ -325,6 +333,7 @@ function PdfRequestFiles() {
const loadObj = {
isLoad: false
};
console.log("Err ", err);
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
});
@@ -356,30 +365,135 @@ function PdfRequestFiles() {
return true;
}
};
//function for embed signature or image url in pdf
async function embedImages() {
async function embedWidgetsData() {
const validateSigning = checkSendInOrder();
if (validateSigning) {
const checkUser = signerPos.filter(
(data) => data.signerObjId === signerObjectId
);
if (checkUser && checkUser.length > 0) {
let checkSignUrl = [];
const checkSign = checkUser[0].placeHolder.filter(
(data, ind) => data.pos
);
for (let i = 0; i < checkSign.length; i++) {
const posData = checkSign[i].pos.filter((pos) => !pos.SignUrl);
if (posData && posData.length > 0) {
checkSignUrl.push(posData);
let checkboxExist,
requiredRadio,
showAlert = false,
widgetKey,
radioExist,
requiredCheckbox;
for (let i = 0; i < checkUser[0].placeHolder.length; i++) {
for (let j = 0; j < checkUser[0].placeHolder[i].pos.length; j++) {
checkboxExist =
checkUser[0].placeHolder[i].pos[j].type === "checkbox";
radioExist = checkUser[0].placeHolder[i].pos[j].type === "radio";
if (checkboxExist) {
requiredCheckbox = checkUser[0].placeHolder[i].pos.filter(
(position) =>
!position.options?.isReadOnly && position.type === "checkbox"
);
if (requiredCheckbox && requiredCheckbox.length > 0) {
for (let i = 0; i < requiredCheckbox.length; i++) {
const minCount =
requiredCheckbox[i].options?.validation?.minRequiredCount;
const parseMin = minCount && parseInt(minCount);
const maxCount =
requiredCheckbox[i].options?.validation?.maxRequiredCount;
const parseMax = maxCount && parseInt(maxCount);
const response =
requiredCheckbox[i].options?.response?.length;
const defaultValue =
requiredCheckbox[i].options?.defaultValue?.length;
if (parseMin === 0 && parseMax === 0) {
if (!showAlert) {
showAlert = false;
setminRequiredCount(null);
}
} else if (parseMin === 0 && parseMax > 0) {
if (!showAlert) {
showAlert = false;
setminRequiredCount(null);
}
} else if (!response) {
if (!defaultValue) {
if (!showAlert) {
showAlert = true;
widgetKey = requiredCheckbox[i].key;
setminRequiredCount(parseMin);
}
}
} else if (parseMin > 0 && parseMin > response) {
if (!showAlert) {
showAlert = true;
widgetKey = requiredCheckbox[i].key;
setminRequiredCount(parseMin);
}
}
}
}
} else if (radioExist) {
requiredRadio = checkUser[0].placeHolder[i].pos.filter(
(position) =>
!position.options?.isReadOnly && position.type === "radio"
);
if (requiredRadio && requiredRadio?.length > 0) {
let checkSigned;
for (let i = 0; i < requiredRadio?.length; i++) {
checkSigned = requiredRadio[i]?.options.response;
if (!checkSigned) {
let checkDefaultSigned =
requiredRadio[i]?.options.defaultValue;
if (!checkDefaultSigned) {
if (!showAlert) {
showAlert = true;
widgetKey = requiredRadio[i].key;
setminRequiredCount(null);
}
}
}
}
}
} else {
const requiredWidgets = checkUser[0].placeHolder[i].pos.filter(
(position) =>
position.options?.status === "required" &&
position.type !== "radio" &&
position.type !== "checkbox"
);
if (requiredWidgets && requiredWidgets?.length > 0) {
let checkSigned;
for (let i = 0; i < requiredWidgets?.length; i++) {
checkSigned = requiredWidgets[i]?.options?.response;
if (!checkSigned) {
const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl;
let checkDefaultSigned =
requiredWidgets[i]?.options?.defaultValue;
if (!checkSignUrl) {
if (!checkDefaultSigned) {
if (!showAlert) {
showAlert = true;
widgetKey = requiredWidgets[i].key;
setminRequiredCount(null);
}
}
}
}
}
}
}
}
}
if (checkSignUrl && checkSignUrl.length > 0) {
setIsAlert({
isShow: true,
alertMessage: "Please complete your signature!"
});
if (checkboxExist && requiredCheckbox && showAlert) {
setUnSignedWidgetId(widgetKey);
setWidgetsTour(true);
} else if (radioExist && showAlert) {
setUnSignedWidgetId(widgetKey);
setWidgetsTour(true);
} else if (showAlert) {
setUnSignedWidgetId(widgetKey);
setWidgetsTour(true);
} else {
setIsUiLoading(true);
const pngUrl = checkUser[0].placeHolder;
@@ -390,97 +504,14 @@ function PdfRequestFiles() {
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
ignoreEncryption: true
});
// let pdfBase64;
//checking if signature is only one then send image url in jpeg formate to server
// if (pngUrl.length === 1 && pngUrl[0].pos.length === 1) {
// if (isDocId) {
// try {
// pdfBase64 = await getBase64FromUrl(pdfUrl);
// } catch (err) {
// console.log(err);
// }
// } else {
// //embed document's object id to all pages in pdf document
// try {
// await embedDocId(pdfDoc, documentId, allPages);
// } catch (err) {
// console.log(err);
// }
// try {
// pdfBase64 = await pdfDoc.saveAsBase64({
// useObjectStreams: false
// });
// } catch (err) {
// console.log(err);
// }
// }
// for (let pngData of pngUrl) {
// const imgUrlList = pngData.pos;
// const pageNo = pngData.pageNumber;
// imgUrlList.map(async (data) => {
// //cheking signUrl is defau;t signature url of custom url
// let ImgUrl = data.SignUrl;
// const checkUrl = urlValidator(ImgUrl);
// //if default signature url then convert it in base 64
// if (checkUrl) {
// ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
// }
// //function for called convert png signatre to jpeg in base 64
// convertPNGtoJPEG(ImgUrl)
// .then((jpegBase64Data) => {
// const removeBase64Fromjpeg = "data:image/jpeg;base64,";
// const newImgUrl = jpegBase64Data.replace(
// removeBase64Fromjpeg,
// ""
// );
// //function for call to embed signature in pdf and get digital signature pdf
// signPdfFun(
// newImgUrl,
// documentId,
// signerObjectId,
// pdfOriginalWidth,
// pngUrl,
// containerWH,
// setIsAlert,
// data,
// pdfBase64,
// pageNo
// )
// .then((res) => {
// if (res && res.status === "success") {
// setPdfUrl(res.data);
// setIsSigned(true);
// setSignedSigners([]);
// setUnSignedSigners([]);
// getDocumentDetails();
// } else {
// setIsAlert({
// isShow: true,
// alertMessage: "something went wrong"
// });
// }
// })
// .catch((err) => {
// setIsAlert({
// isShow: true,
// alertMessage: "something went wrong"
// });
// });
// })
// .catch((error) => {
// console.error("Error:", error);
// });
// });
// }
// }
// //else if signature is more than one then embed all sign with the use of pdf-lib
// else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) {
const flag = false;
const extUserPtr = pdfDetails[0].ExtUserPtr;
const HeaderDocId = extUserPtr?.HeaderDocId;
//embed document's object id to all pages in pdf document
if (!isDocId) {
await embedDocId(pdfDoc, documentId, allPages);
if (!HeaderDocId) {
if (!isDocId) {
await embedDocId(pdfDoc, documentId, allPages);
}
}
//embed multi signature in pdf
const pdfBytes = await multiSignEmbed(
@@ -490,15 +521,13 @@ function PdfRequestFiles() {
flag,
containerWH
);
//function for call to embed signature in pdf and get digital signature pdf
try {
const res = await signPdfFun(
pdfBytes,
documentId,
signerObjectId,
pdfOriginalWidth,
pngUrl,
containerWH,
setIsAlert
);
if (res && res.status === "success") {
@@ -514,7 +543,6 @@ function PdfRequestFiles() {
const newIndex = index + 1;
const user = pdfDetails?.[0].Signers[newIndex];
if (user) {
let sendMail;
// console.log("pdfDetails", pdfDetails);
const expireDate = pdfDetails?.[0].ExpiryDate.iso;
const newDate = new Date(expireDate);
@@ -543,16 +571,14 @@ function PdfRequestFiles() {
const serverParams = `${newServer}&${localStorage.getItem(
"parseAppId"
)}&${localStorage.getItem("_appName")}`;
const hostUrl =
window.location.origin + "/loadmf/signmicroapp";
const hostUrl = window.location.origin;
let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${user.Email}/${objectId}/${serverParams}`;
const openSignUrl =
"https://www.opensignlabs.com/contact-us";
const orgName = pdfDetails[0]?.ExtUserPtr.Company
? pdfDetails[0].ExtUserPtr.Company
: "";
const themeBGcolor = themeColor();
const themeBGcolor = themeColor;
let params = {
recipient: user.Email,
subject: `${pdfDetails?.[0].ExtUserPtr.Name} has requested you to sign ${pdfDetails?.[0].Name}`,
@@ -581,7 +607,7 @@ function PdfRequestFiles() {
openSignUrl +
" target=_blank>here</a>.</p> </div></div></body> </html>"
};
sendMail = await axios.post(url, params, {
await axios.post(url, params, {
headers: headers
});
} catch (error) {
@@ -602,9 +628,7 @@ function PdfRequestFiles() {
});
}
}
setIsSignPad(false);
// }
} else {
setIsAlert({
isShow: true,
@@ -619,6 +643,21 @@ function PdfRequestFiles() {
});
}
}
//function for update TourStatus
const closeTour = async () => {
setWidgetsTour(false);
};
const tourConfig = [
{
selector: '[data-tut="IsSigned"]',
content: minRequiredCount
? `Please confirm that you have selected at least ${minRequiredCount} checkboxes.`
: "Ensure this field is accurately filled and meets all requirements.",
position: "top",
style: { fontSize: "13px" }
}
];
//function for get pdf page details
const pageDetails = async (pdf) => {
@@ -690,7 +729,11 @@ function PdfRequestFiles() {
//function for save button to save signature or image url
const saveSign = (isDefaultSign, width, height) => {
const isTypeText = width && height ? true : false;
const signatureImg = isDefaultSign ? defaultSignImg : signature;
const signatureImg = isDefaultSign
? isDefaultSign === "initials"
? myInitial
: defaultSignImg
: signature;
let imgWH = { width: width ? width : "", height: height ? height : "" };
setIsSignPad(false);
setIsImageSelect(false);
@@ -729,7 +772,7 @@ function PdfRequestFiles() {
isTypeText
);
const updateSignerData = currentSigner.map((obj, ind) => {
const updateSignerData = currentSigner.map((obj) => {
if (obj.signerObjId === signerObjectId) {
return { ...obj, placeHolder: getUpdatePosition };
}
@@ -851,8 +894,6 @@ function PdfRequestFiles() {
<Loader isLoading={isLoading} />
) : handleError ? (
<HandleError handleError={handleError} />
) : noData ? (
<Nodata />
) : (
<div>
{isUiLoading && (
@@ -865,7 +906,7 @@ function PdfRequestFiles() {
justifyContent: "center",
flexDirection: "column",
alignItems: "center",
zIndex: "20",
zIndex: "999",
backgroundColor: "#e6f2f2",
opacity: 0.8
}}
@@ -920,40 +961,45 @@ function PdfRequestFiles() {
</button>
</div>
</ModalUi>
<Tour
showNumber={false}
showNavigation={false}
showNavigationNumber={false}
onRequestClose={closeTour}
steps={tourConfig}
isOpen={widgetsTour}
rounded={5}
closeWithMask={false}
/>
{/* this modal is used to show decline alert */}
<CustomModal
<PdfDeclineModal
containerWH={containerWH}
show={isDecline.isDeclined}
headMsg="Document Declined"
bodyMssg={
isDecline.currnt === "Sure" ? (
<p className="pTagBody">
Are you sure want to decline this document ?
</p>
) : isDecline.currnt === "YouDeclined" ? (
<p className="pTagBody">You have declined this document!</p>
) : (
isDecline.currnt === "another" && (
<p className="pTagBody">
You cannot sign this document as it has been declined by
one or more person(s).
</p>
)
)
isDecline.currnt === "Sure"
? "Are you sure want to decline this document ?"
: isDecline.currnt === "YouDeclined"
? "You have declined this document!"
: isDecline.currnt === "another" &&
"You cannot sign this document as it has been declined by one or more person(s)."
}
footerMessage={isDecline.currnt === "Sure"}
declineDoc={declineDoc}
setIsDecline={setIsDecline}
/>
{/* this modal is used for show expired alert */}
<CustomModal
<PdfDeclineModal
containerWH={containerWH}
show={isExpired}
headMsg="Document Expired!"
bodyMssg="This Document is no longer available."
/>
<ModalUi
headerColor={defaultSignImg ? themeColor() : "#dc3545"}
headerColor={defaultSignImg ? themeColor : "#dc3545"}
isOpen={defaultSignAlert.isShow}
title={"Auto sign"}
handleClose={() => {
@@ -980,7 +1026,7 @@ function PdfRequestFiles() {
<button
onClick={() => addDefaultSignature()}
style={{
background: themeColor()
background: themeColor
}}
type="button"
className="finishBtn"
@@ -1079,6 +1125,10 @@ function PdfRequestFiles() {
onSaveImage={saveImage}
onSaveSign={saveSign}
defaultSign={defaultSignImg}
myInitial={myInitial}
isInitial={isInitial}
setIsInitial={setIsInitial}
setIsStamp={setIsStamp}
/>
{/* pdf header which contain funish back button */}
<Header
@@ -1090,7 +1140,7 @@ function PdfRequestFiles() {
signerPos={signerPos}
isSigned={isSigned}
isCompleted={isCompleted}
embedImages={embedImages}
embedWidgetsData={embedWidgetsData}
isShowHeader={true}
setIsDecline={setIsDecline}
decline={true}
@@ -1120,6 +1170,9 @@ function PdfRequestFiles() {
pdfLoadFail={pdfLoadFail}
setSignerPos={setSignerPos}
containerWH={containerWH}
setIsInitial={setIsInitial}
setValidateAlert={setValidateAlert}
unSignedWidgetId={unSignedWidgetId}
/>
)}
</div>
@@ -1132,9 +1185,7 @@ function PdfRequestFiles() {
{signedSigners.length > 0 && (
<>
<div
style={{
background: themeColor()
}}
style={{ background: themeColor }}
className="signedStyle"
>
Signed by
@@ -1197,7 +1248,7 @@ function PdfRequestFiles() {
<>
<div
style={{
background: themeColor(),
background: themeColor,
color: "white",
padding: "5px",
fontFamily: "sans-serif",
@@ -1262,7 +1313,6 @@ function PdfRequestFiles() {
)}
{defaultSignImg && !alreadySign && (
<DefaultSignature
themeColor={themeColor}
defaultSignImg={defaultSignImg}
setDefaultSignImg={setDefaultSignImg}
userObjectId={signerObjectId}
@@ -1277,6 +1327,38 @@ function PdfRequestFiles() {
</div>
</div>
)}
<ModalUi
headerColor={"#dc3545"}
isOpen={validateAlert}
title={"Validation alert"}
handleClose={() => {
setValidateAlert(false);
}}
>
<div style={{ height: "100%", padding: 20 }}>
<p>
The input does not meet the criteria set by the regular expression.
</p>
<div
style={{
height: "1px",
backgroundColor: "#9f9f9f",
width: "100%",
marginTop: "15px",
marginBottom: "15px"
}}
></div>
<button
onClick={() => setValidateAlert(false)}
type="button"
className="finishBtn cancelBtn"
>
Close
</button>
</div>
</ModalUi>
</DndProvider>
);
}
@@ -7,15 +7,11 @@ import { connect } from "react-redux";
import Title from "../components/Title";
import { useNavigate, useLocation } from "react-router-dom";
const appId = localStorage.getItem("AppID12");
const server = localStorage.getItem("BaseUrl12");
Parse.serverURL = server;
Parse.initialize(appId);
const PgSignUp = (props) => {
const navigate = useNavigate();
const location = useLocation();
const [parseBaseUrl] = useState(localStorage.getItem("BaseUrl12"));
const [parseAppId] = useState(localStorage.getItem("AppID12"));
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
const [formData, setFormData] = useState({
password: "",
confirmPassword: ""
@@ -29,11 +25,7 @@ const PgSignUp = (props) => {
// below useEffect is used to fetch App data and save to redux state
useEffect(() => {
// Parse.User.logOut()
props.fetchAppInfo(
localStorage.getItem("domain"),
localStorage.getItem("BaseUrl12"),
localStorage.getItem("AppID12")
);
props.fetchAppInfo();
handleSignedUpUser();
// eslint-disable-next-line
}, []);
@@ -224,8 +216,8 @@ const PgSignUp = (props) => {
};
const handleNavigation = async (sessionToken) => {
const baseUrl = localStorage.getItem("BaseUrl12");
const parseAppId = localStorage.getItem("AppID12");
const baseUrl = localStorage.getItem("baseUrl");
const parseAppId = localStorage.getItem("parseAppId");
const res = await axios.get(baseUrl + "users/me", {
headers: {
"X-Parse-Session-Token": sessionToken,
@@ -299,8 +291,6 @@ const PgSignUp = (props) => {
"extended_class",
element.extended_class
);
localStorage.setItem("userpointer", element.userpointer);
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
@@ -407,11 +397,11 @@ const PgSignUp = (props) => {
localStorage.setItem("pageType", element.pageType);
setIsLoader(false);
const redirectUrl =
location?.state?.from ||
`/${element.pageType}/${element.pageId}`;
location?.state?.from ||
`/${element.pageType}/${element.pageId}`;
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
}
},
(error) => {
@@ -53,18 +53,16 @@ const Report = () => {
setHeading(json.heading);
setReportName(json.reportName);
setForm(json.form);
Parse.serverURL = localStorage.getItem("BaseUrl12");
Parse.initialize(localStorage.getItem("AppID12"));
const currentUser = Parse.User.current().id;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
sessiontoken: localStorage.getItem("accesstoken")
};
try {
const params = { reportId: id, skip: skipUserRecord, limit: limit };
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
const url = `${localStorage.getItem("baseUrl")}/functions/getReport`;
const res = await axios.post(url, params, {
headers: headers,
signal: abortController.signal // is used to cancel fetch query
@@ -7,6 +7,7 @@ import { fetchAppInfo, showTenantName } from "../redux/actions";
import { useNavigate, NavLink } from "react-router-dom";
import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
import Alert from "../primitives/Alert";
const Signup = (props) => {
const { width } = useWindowSize();
@@ -15,14 +16,12 @@ const Signup = (props) => {
const [phone, setPhone] = useState("");
const [password, setPassword] = useState("");
const [email, setEmail] = useState("");
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
const [company, setCompany] = useState("");
const [jobTitle, setJobTitle] = useState("");
const [state, setState] = useState({
loading: false,
toastColor: "#5cb85c",
toastDescription: ""
alertType: "success",
alertMsg: ""
});
const [showPassword, setShowPassword] = useState(false);
const [lengthValid, setLengthValid] = useState(false);
@@ -36,8 +35,8 @@ const Signup = (props) => {
if (Parse.User.current()) {
await Parse.User.logOut();
}
let baseUrl = localStorage.getItem("BaseUrl12");
let appid = localStorage.getItem("AppID12");
let baseUrl = localStorage.getItem("baseUrl");
let appid = localStorage.getItem("parseAppId");
let applogo = localStorage.getItem("appLogo");
let domain = localStorage.getItem("domain");
let appversion = localStorage.getItem("appVersion");
@@ -51,8 +50,8 @@ const Signup = (props) => {
localStorage.clear();
localStorage.setItem("BaseUrl12", baseUrl);
localStorage.setItem("AppID12", appid);
localStorage.setItem("baseUrl", baseUrl);
localStorage.setItem("parseAppId", appid);
localStorage.setItem("appLogo", applogo);
localStorage.setItem("domain", domain);
localStorage.setItem("appversion", appversion);
@@ -80,8 +79,6 @@ const Signup = (props) => {
};
localStorage.setItem("userDetails", JSON.stringify(userDetails));
try {
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
event.preventDefault();
var user = new Parse.User();
user.set("name", name);
@@ -129,12 +126,8 @@ const Signup = (props) => {
alert("User already exists with this username!");
setState({ loading: false });
} else {
let baseUrl = localStorage.getItem("BaseUrl12");
let parseAppId = localStorage.getItem("AppID12");
// console.log("state.email ", email);
try {
Parse.serverURL = baseUrl;
Parse.initialize(parseAppId);
await Parse.User.requestPasswordReset(email).then(
async function (res1) {
if (res1.data === undefined) {
@@ -161,8 +154,8 @@ const Signup = (props) => {
};
const handleNavigation = async (sessionToken) => {
const baseUrl = localStorage.getItem("BaseUrl12");
const parseAppId = localStorage.getItem("AppID12");
const baseUrl = localStorage.getItem("baseUrl");
const parseAppId = localStorage.getItem("parseAppId");
const res = await axios.get(baseUrl + "users/me", {
headers: {
"X-Parse-Session-Token": sessionToken,
@@ -236,8 +229,6 @@ const Signup = (props) => {
"extended_class",
element.extended_class
);
localStorage.setItem("userpointer", element.userpointer);
await Parse.Cloud.run("getUserDetails", {
email: email
}).then(
@@ -358,19 +349,18 @@ const Signup = (props) => {
}
},
(error) => {
/* alert(
"You dont have access to this application."
); */
setState({
loading: false,
toastColor: "#d9534f",
toastDescription:
"You dont have access to this application."
alertType: "danger",
alertMsg:
"You dont have access to this application!"
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
localStorage.setItem("accesstoken", null);
console.error("Error while fetching Follow", error);
@@ -381,25 +371,29 @@ const Signup = (props) => {
} else {
setState({
loading: false,
toastColor: "#d9534f",
toastDescription: "User Role Not Found."
alertType: "danger",
alertMsg: "User Role Not Found!"
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
}
} else {
setState({
loading: false,
toastColor: "#d9534f",
toastDescription: "User Role Not Found."
alertType: "danger",
alertMsg: "User Role Not Found!"
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
}
})
@@ -407,13 +401,16 @@ const Signup = (props) => {
console.log("err", err);
setState({
loading: false,
toastColor: "#d9534f",
toastDescription: `Does not have permissions to access this application.`
alertType: "danger",
alertMsg:
"Does not have permissions to access this application!"
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
});
}
@@ -421,24 +418,22 @@ const Signup = (props) => {
// alert(`${error.message}`);
setState({
loading: false,
toastColor: "#d9534f",
toastDescription: `${error.message}`
alertType: "danger",
alertMsg: `${error.message}`
});
const x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
setState({
loading: false,
alertType: "danger",
alertMsg: ""
});
}, 2000);
console.log(error);
}
}
};
useEffect(() => {
props.fetchAppInfo(
localStorage.getItem("domain"),
localStorage.getItem("BaseUrl12"),
localStorage.getItem("AppID12")
);
props.fetchAppInfo();
// eslint-disable-next-line
}, []);
@@ -644,10 +639,7 @@ const Signup = (props) => {
)}
</div>
</div>
<div id="snackbar" style={{ backgroundColor: state.toastColor }}>
{state.toastDescription}
</div>
<Alert type={state.alertType}>{state.alertMsg}</Alert>
</div>
) : (
<div
File diff suppressed because it is too large Load Diff
@@ -1,39 +1,38 @@
import React, { useEffect, useState, useRef } from "react";
import RenderAllPdfPage from "./component/renderAllPdfPage";
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
import { useParams, useNavigate } from "react-router-dom";
import axios from "axios";
import "../css/./signature.css";
import sign from "../assests/sign3.png";
import stamp from "../assests/stamp2.png";
import { themeColor } from "../utils/ThemeColor/backColor";
import "../styles/signature.css";
import { themeColor } from "../constant/const";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { useDrag, useDrop } from "react-dnd";
import FieldsComponent from "./component/fieldsComponent";
import WidgetComponent from "../components/pdf/WidgetComponent";
import Tour from "reactour";
import Loader from "./component/loader";
import HandleError from "./component/HandleError";
import Nodata from "./component/Nodata";
import SignerListPlace from "./component/signerListPlace";
import Header from "./component/header";
import Loader from "../primitives/LoaderWithMsg";
import HandleError from "../primitives/HandleError";
import SignerListPlace from "../components/pdf/SignerListPlace";
import Header from "../components/pdf/PdfHeader";
import WidgetNameModal from "../components/pdf/WidgetNameModal";
import {
pdfNewWidthFun,
contractUsers,
getHostUrl,
randomId,
addZIndex,
createDocument
} from "../utils/Utils";
import RenderPdf from "./component/renderPdf";
import "../css/AddUser.css";
import Title from "./component/Title";
import LinkUserModal from "./component/LinkUserModal";
import EditTemplate from "./component/EditTemplate";
import ModalUi from "../premitives/ModalUi";
import AddRoleModal from "./component/AddRoleModal";
import PlaceholderCopy from "./component/PlaceholderCopy";
import ModalComponent from "./component/modalComponent";
import TourContentWithBtn from "../premitives/TourContentWithBtn";
createDocument,
defaultWidthHeight,
addWidgetOptions
} from "../constant/Utils";
import RenderPdf from "../components/pdf/RenderPdf";
import "../styles/AddUser.css";
import Title from "../components/Title";
import LinkUserModal from "../primitives/LinkUserModal";
import EditTemplate from "../components/pdf/EditTemplate";
import ModalUi from "../primitives/ModalUi";
import AddRoleModal from "../components/pdf/AddRoleModal";
import PlaceholderCopy from "../components/pdf/PlaceholderCopy";
import TourContentWithBtn from "../primitives/TourContentWithBtn";
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
const TemplatePlaceholder = () => {
const navigate = useNavigate();
const { templateId } = useParams();
@@ -62,7 +61,6 @@ const TemplatePlaceholder = () => {
const [checkTourStatus, setCheckTourStatus] = useState(false);
const [tourStatus, setTourStatus] = useState([]);
const [signerUserId, setSignerUserId] = useState();
const [noData, setNoData] = useState(false);
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
const [contractName, setContractName] = useState("");
const [containerWH, setContainerWH] = useState();
@@ -74,6 +72,11 @@ const TemplatePlaceholder = () => {
const [isResize, setIsResize] = useState(false);
const [isSigners, setIsSigners] = useState(false);
const [zIndex, setZIndex] = useState(1);
const [showDropdown, setShowDropdown] = useState(false);
const [widgetType, setWidgetType] = useState("");
const [isRadio, setIsRadio] = useState(false);
const [selectWidgetId, setSelectWidgetId] = useState("");
const [isNameModal, setIsNameModal] = useState(false);
const [pdfLoadFail, setPdfLoadFail] = useState({
status: false,
type: "load"
@@ -93,7 +96,7 @@ const TemplatePlaceholder = () => {
"#ffffcc"
];
const isMobile = window.innerWidth < 767;
const [{ isOver }, drop] = useDrop({
const [, drop] = useDrop({
accept: "BOX",
drop: (item, monitor) => addPositionOfSignature(item, monitor),
collect: (monitor) => ({
@@ -105,7 +108,7 @@ const TemplatePlaceholder = () => {
item: {
type: "BOX",
id: 1,
text: "drag me"
text: "signature"
},
collect: (monitor) => ({
isDragSign: !!monitor.isDragging()
@@ -117,37 +120,12 @@ const TemplatePlaceholder = () => {
item: {
type: "BOX",
id: 2,
text: "drag me"
text: "stamp"
},
collect: (monitor) => ({
isDragStamp: !!monitor.isDragging()
})
});
const [{ isDragSignatureSS }, dragSignatureSS] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 3,
text: "drag me"
},
collect: (monitor) => ({
isDragSignatureSS: !!monitor.isDragging()
})
});
const [{ isDragStampSS }, dragStampSS] = useDrag({
type: "BOX",
item: {
type: "BOX",
id: 4,
text: "drag me"
},
collect: (monitor) => ({
isDragStampSS: !!monitor.isDragging()
})
});
const [uniqueId, setUniqueId] = useState("");
const [isModalRole, setIsModalRole] = useState(false);
const [roleName, setRoleName] = useState("");
@@ -159,6 +137,9 @@ const TemplatePlaceholder = () => {
const [IsReceipent, setIsReceipent] = useState(true);
const [isDontShow, setIsDontShow] = useState(false);
const [isDragging, setIsDragging] = useState(false);
const [currWidgetsDetails, setCurrWidgetsDetails] = useState([]);
const [isCheckbox, setIsCheckbox] = useState(false);
const [widgetName, setWidgetName] = useState(false);
const senderUser =
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
@@ -170,7 +151,7 @@ const TemplatePlaceholder = () => {
useEffect(() => {
fetchTemplate();
// eslint-disable-next-line
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
@@ -182,6 +163,7 @@ const TemplatePlaceholder = () => {
height: divRef.current.offsetHeight
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [divRef.current]);
// `fetchTemplate` function in used to get Template from server and setPlaceholder ,setSigner if present
@@ -277,8 +259,7 @@ const TemplatePlaceholder = () => {
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else {
setNoData(true);
setHandleError("No Data Found!");
const loadObj = {
isLoad: false
};
@@ -317,8 +298,7 @@ const TemplatePlaceholder = () => {
setHandleError("Error: Something went wrong!");
setIsLoading(loadObj);
} else if (res.length === 0) {
setNoData(true);
setHandleError("No Data Found!");
const loadObj = {
isLoad: false
};
@@ -328,6 +308,9 @@ const TemplatePlaceholder = () => {
//function for setting position after drop signature button over pdf
const addPositionOfSignature = (item, monitor) => {
if (item && item.text) {
setWidgetName(item.text);
}
getSignerPos(item, monitor);
};
@@ -345,26 +328,29 @@ const TemplatePlaceholder = () => {
// (data) => data.signerObjId === signerObjId
// );
let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
const dragTypeValue = item?.text ? item.text : monitor.type;
let dropData = [];
let placeHolder;
if (item === "onclick") {
const dropObj = {
xPosition: window.innerWidth / 2 - 100,
//onclick put placeholder center on pdf
xPosition: window.innerWidth / 2 - 150,
yPosition: window.innerHeight / 2 - 60,
isStamp: monitor,
isStamp:
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
key: key,
isDrag: false,
scale: scale,
isMobile: isMobile,
yBottom: window.innerHeight / 2 - 60,
zIndex: posZIndex
zIndex: posZIndex,
type: dragTypeValue,
options: addWidgetOptions(dragTypeValue)
};
dropData.push(dropObj);
placeHolder = {
pageNumber: pageNumber,
pos: dropData
};
} else if (item.type === "BOX") {
} else {
const offset = monitor.getClientOffset();
//adding and updating drop position in array when user drop signature button in div
const containerRect = document
@@ -372,20 +358,17 @@ const TemplatePlaceholder = () => {
.getBoundingClientRect();
const x = offset.x - containerRect.left;
const y = offset.y - containerRect.top;
const ybottom = containerRect.bottom - offset.y;
const dropObj = {
xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x,
yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y,
isStamp: isDragStamp || isDragStampSS ? true : false,
isStamp:
(dragTypeValue === "stamp" || dragTypeValue === "image") && true,
key: key,
isDrag: false,
firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos,
firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos,
yBottom: ybottom,
scale: scale,
isMobile: isMobile,
zIndex: posZIndex
zIndex: posZIndex,
type: item.text,
options: addWidgetOptions(dragTypeValue)
};
dropData.push(dropObj);
@@ -454,12 +437,28 @@ const TemplatePlaceholder = () => {
}
setSignerPos((prev) => [...prev, placeHolderPos]);
}
if (dragTypeValue === "dropdown") {
setShowDropdown(true);
} else if (dragTypeValue === "checkbox") {
setIsCheckbox(true);
} else if (dragTypeValue === "radio") {
setIsRadio(true);
} else if (dragTypeValue !== "label" && dragTypeValue !== "signature") {
setIsNameModal(true);
}
setCurrWidgetsDetails({});
setWidgetType(dragTypeValue);
setSignKey(key);
setSelectWidgetId(key);
setIsMailSend(false);
} else {
setIsReceipent(false);
}
}
};
//function for get pdf page details
const pageDetails = async (pdf) => {
const load = {
@@ -507,7 +506,7 @@ const TemplatePlaceholder = () => {
const getXYdata = getPageNumer[0].pos;
const getPosData = getXYdata;
const addSignPos = getPosData.map((url, ind) => {
const addSignPos = getPosData.map((url) => {
if (url.key === keyValue) {
return {
...url,
@@ -520,13 +519,13 @@ const TemplatePlaceholder = () => {
return url;
});
const newUpdateSignPos = getPlaceHolder.map((obj, ind) => {
const newUpdateSignPos = getPlaceHolder.map((obj) => {
if (obj.pageNumber === pageNumber) {
return { ...obj, pos: addSignPos };
}
return obj;
});
const newUpdateSigner = updateSignPos.map((obj, ind) => {
const newUpdateSigner = updateSignPos.map((obj) => {
if (obj.Id === signId) {
return { ...obj, placeHolder: newUpdateSignPos };
}
@@ -562,19 +561,19 @@ const TemplatePlaceholder = () => {
if (getPageNumer.length > 0) {
const getXYdata = getPageNumer[0].pos.filter(
(data, ind) => data.key !== key
(data) => data.key !== key
);
if (getXYdata.length > 0) {
updateData.push(getXYdata);
const newUpdatePos = getPlaceHolder.map((obj, ind) => {
const newUpdatePos = getPlaceHolder.map((obj) => {
if (obj.pageNumber === pageNumber) {
return { ...obj, pos: updateData[0] };
}
return obj;
});
const newUpdateSigner = signerPos.map((obj, ind) => {
const newUpdateSigner = signerPos.map((obj) => {
if (obj.Id === Id) {
return { ...obj, placeHolder: newUpdatePos };
}
@@ -589,7 +588,7 @@ const TemplatePlaceholder = () => {
);
if (getRemainPage && getRemainPage.length > 0) {
const newUpdatePos = filterSignerPos.map((obj, ind) => {
const newUpdatePos = filterSignerPos.map((obj) => {
if (obj.Id === Id) {
return { ...obj, placeHolder: getRemainPage };
}
@@ -629,7 +628,7 @@ const TemplatePlaceholder = () => {
};
//function for capture position of x and y on hover signature button last position
const handleMouseLeave = (e) => {
const handleMouseLeave = () => {
setSignBtnPosition([xySignature]);
};
@@ -664,7 +663,6 @@ const TemplatePlaceholder = () => {
try {
const data = {
Placeholders: signerPos,
SignedUrl: pdfDetails[0].URL,
Signers: signers,
Name: pdfDetails[0]?.Name || "",
Note: pdfDetails[0]?.Note || "",
@@ -686,7 +684,7 @@ const TemplatePlaceholder = () => {
}
}
)
.then((result) => {
.then(() => {
setIsCreateDocModal(true);
setIsMailSend(true);
const loadObj = {
@@ -727,7 +725,7 @@ const TemplatePlaceholder = () => {
selector: '[data-tut="reactourFirst"]',
content: () => (
<TourContentWithBtn
message={`Select a role from this list to add a place-holder where he is supposed to sign.The placeholder will appear in the same colour as the recipient name once you drop it on the document.`}
message={`Once roles are added, select a role from list to add a place-holder where he is supposed to sign. The placeholder will appear in the same colour as the role name once you drop it on the document.`}
isChecked={handleDontShow}
/>
),
@@ -739,7 +737,7 @@ const TemplatePlaceholder = () => {
selector: '[data-tut="reactourSecond"]',
content: () => (
<TourContentWithBtn
message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`}
message={`Drag a widget placeholder onto the PDF to choose your desired signing location.`}
isChecked={handleDontShow}
/>
),
@@ -761,7 +759,7 @@ const TemplatePlaceholder = () => {
selector: '[data-tut="reactourFour"]',
content: () => (
<TourContentWithBtn
message={`Clicking "Save" button will save the template and will ask you for creating new document.`}
message={`Clicking "Save" button will save the template and will ask you if you want to create a new document using this template.`}
isChecked={handleDontShow}
/>
),
@@ -805,7 +803,7 @@ const TemplatePlaceholder = () => {
}
}
)
.then((Listdata) => {
.then(() => {
// const json = Listdata.data;
// const res = json.results;
})
@@ -819,11 +817,10 @@ const TemplatePlaceholder = () => {
const handleCreateDocModal = async () => {
setIsCreateDocModal(false);
setIsCreateDoc(true);
const hostUrl = getHostUrl();
// handle create document
const res = await createDocument(pdfDetails, signerPos, signersdata);
if (res.status === "success") {
navigate(`${hostUrl}placeHolderSign/${res.id}`, {
navigate(`/placeHolderSign/${res.id}`, {
state: { title: "Use Template" }
});
setIsCreateDoc(false);
@@ -964,6 +961,208 @@ const TemplatePlaceholder = () => {
setIsModalRole(false);
};
const handleSaveWidgetsOptions = (
dropdownName,
dropdownOptions,
minCount,
maxCount,
isReadOnly,
addOption,
deleteOption,
status,
defaultValue
) => {
const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
if (filterSignerPos.length > 0) {
const getPlaceHolder = filterSignerPos[0].placeHolder;
const getPageNumer = getPlaceHolder.filter(
(data) => data.pageNumber === pageNumber
);
if (getPageNumer.length > 0) {
const getXYdata = getPageNumer[0].pos;
const getPosData = getXYdata;
const addSignPos = getPosData.map((position) => {
if (position.key === signKey) {
if (widgetType === "radio") {
if (addOption) {
return {
...position,
Height: position.Height
? position.Height + 15
: defaultWidthHeight(widgetType).height + 15
};
} else if (deleteOption) {
return {
...position,
Height: position.Height
? position.Height - 15
: defaultWidthHeight(widgetType).height - 15
};
} else {
return {
...position,
options: {
...position.options,
name: dropdownName,
values: dropdownOptions,
status: status,
defaultValue: defaultValue
}
};
}
} else if (widgetType === "checkbox") {
if (addOption) {
return {
...position,
Height: position.Height
? position.Height + 15
: defaultWidthHeight(widgetType).height + 15
};
} else if (deleteOption) {
return {
...position,
Height: position.Height
? position.Height - 15
: defaultWidthHeight(widgetType).height - 15
};
} else {
return {
...position,
options: {
...position.options,
name: dropdownName,
values: dropdownOptions,
validation: {
minRequiredCount: minCount,
maxRequiredCount: maxCount
},
isReadOnly: isReadOnly,
defaultValue: defaultValue
}
};
}
} else {
return {
...position,
options: {
...position.options,
name: dropdownName,
status: status,
values: dropdownOptions,
defaultValue: defaultValue
}
};
}
}
return position;
});
const newUpdateSignPos = getPlaceHolder.map((obj) => {
if (obj.pageNumber === pageNumber) {
return { ...obj, pos: addSignPos };
}
return obj;
});
const newUpdateSigner = signerPos.map((obj) => {
if (obj.Id === uniqueId) {
return { ...obj, placeHolder: newUpdateSignPos };
}
return obj;
});
setSignerPos(newUpdateSigner);
if (!addOption && !deleteOption) {
handleNameModal();
}
}
}
};
const handleWidgetdefaultdata = (defaultdata) => {
const options = ["email", "number", "text"];
let inputype;
if (defaultdata.textvalidate) {
inputype = options.includes(defaultdata.textvalidate)
? defaultdata.textvalidate
: "regex";
} else {
inputype = "text";
}
const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
if (filterSignerPos.length > 0) {
const getPlaceHolder = filterSignerPos[0].placeHolder;
const getPageNumer = getPlaceHolder.filter(
(data) => data.pageNumber === pageNumber
);
if (getPageNumer.length > 0) {
const getXYdata = getPageNumer[0].pos;
const getPosData = getXYdata;
const addSignPos = getPosData.map((position) => {
if (position.key === signKey) {
if (position.type === "text") {
return {
...position,
options: {
...position.options,
name: defaultdata?.name || "text",
status: defaultdata?.status || "required",
hint: defaultdata?.hint || "",
defaultValue: defaultdata?.defaultValue || "",
validation: {
type: inputype,
pattern:
inputype === "regex" ? defaultdata.textvalidate : ""
}
}
};
} else {
return {
...position,
options: {
...position.options,
name: defaultdata.name,
status: defaultdata.status,
defaultValue: defaultdata.defaultValue
}
};
}
}
return position;
});
const newUpdateSignPos = getPlaceHolder.map((obj) => {
if (obj.pageNumber === pageNumber) {
return { ...obj, pos: addSignPos };
}
return obj;
});
const newUpdateSigner = signerPos.map((obj) => {
if (obj.Id === uniqueId) {
return { ...obj, placeHolder: newUpdateSignPos };
}
return obj;
});
setSignerPos(newUpdateSigner);
}
}
setCurrWidgetsDetails({});
handleNameModal();
};
const handleNameModal = () => {
setIsNameModal(false);
setCurrWidgetsDetails({});
setShowDropdown(false);
setIsRadio(false);
setIsCheckbox(false);
};
return (
<div>
<Title title={"Template"} />
@@ -972,8 +1171,6 @@ const TemplatePlaceholder = () => {
<Loader isLoading={isLoading} />
) : handleError ? (
<HandleError handleError={handleError} />
) : noData ? (
<Nodata />
) : (
<div className="signatureContainer" ref={divRef}>
{/* this component used for UI interaction and show their functionality */}
@@ -1055,7 +1252,7 @@ const TemplatePlaceholder = () => {
handleCreateDocModal();
}}
style={{
background: themeColor(),
background: themeColor,
color: "white"
}}
type="button"
@@ -1077,10 +1274,65 @@ const TemplatePlaceholder = () => {
</div>
</ModalUi>
{isCreateDoc && <Loader isLoading={isLoading} />}
<ModalComponent
isShow={isShowEmail}
type={"signersAlert"}
setIsShowEmail={setIsShowEmail}
<ModalUi
headerColor={"#dc3545"}
isOpen={isShowEmail}
title={"signers alert"}
handleClose={() => {
setIsShowEmail(false);
}}
>
<div style={{ height: "100%", padding: 20 }}>
<p>Please select signer for add placeholder!</p>
<div
style={{
height: "1px",
backgroundColor: "#9f9f9f",
width: "100%",
marginTop: "15px",
marginBottom: "15px"
}}
></div>
<button
onClick={() => {
setIsShowEmail(false);
}}
type="button"
className="finishBtn cancelBtn"
>
Ok
</button>
</div>
</ModalUi>
<DropdownWidgetOption
type="radio"
title="Radio group"
showDropdown={isRadio}
setShowDropdown={setIsRadio}
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
currWidgetsDetails={currWidgetsDetails}
setCurrWidgetsDetails={setCurrWidgetsDetails}
handleClose={handleNameModal}
/>
<DropdownWidgetOption
type="checkbox"
title="Checkbox"
showDropdown={isCheckbox}
setShowDropdown={setIsCheckbox}
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
currWidgetsDetails={currWidgetsDetails}
setCurrWidgetsDetails={setCurrWidgetsDetails}
handleClose={handleNameModal}
/>
<DropdownWidgetOption
type="dropdown"
title="Dropdown options"
showDropdown={showDropdown}
setShowDropdown={setShowDropdown}
handleSaveWidgetsOptions={handleSaveWidgetsOptions}
currWidgetsDetails={currWidgetsDetails}
setCurrWidgetsDetails={setCurrWidgetsDetails}
handleClose={handleNameModal}
/>
<PlaceholderCopy
isPageCopy={isPageCopy}
@@ -1139,6 +1391,14 @@ const TemplatePlaceholder = () => {
setSignKey={setSignKey}
setSignerObjId={setSignerObjId}
isDragging={isDragging}
setShowDropdown={setShowDropdown}
setCurrWidgetsDetails={setCurrWidgetsDetails}
setWidgetType={setWidgetType}
setIsRadio={setIsRadio}
setSelectWidgetId={setSelectWidgetId}
selectWidgetId={selectWidgetId}
setIsCheckbox={setIsCheckbox}
handleNameModal={setIsNameModal}
/>
)}
</div>
@@ -1146,25 +1406,19 @@ const TemplatePlaceholder = () => {
{/* signature button */}
{isMobile ? (
<div>
<FieldsComponent
<WidgetComponent
dataTut="reactourFirst"
dataTut2="reactourSecond"
pdfUrl={isMailSend}
sign={sign}
stamp={stamp}
dragSignature={dragSignature}
signRef={signRef}
handleDivClick={handleDivClick}
handleMouseLeave={handleMouseLeave}
isDragSign={isDragSign}
themeColor={themeColor}
dragStamp={dragStamp}
dragRef={dragRef}
isDragStamp={isDragStamp}
isSignYourself={true}
isDragSignatureSS={isDragSignatureSS}
dragSignatureSS={dragSignatureSS}
dragStampSS={dragStampSS}
isSignYourself={false}
addPositionOfSignature={addPositionOfSignature}
signerPos={signerPos}
signersdata={signersdata}
@@ -1184,44 +1438,50 @@ const TemplatePlaceholder = () => {
handleRoleChange={handleRoleChange}
handleOnBlur={handleOnBlur}
title={"Roles"}
initial={true}
isTemplateFlow={true}
/>
</div>
) : (
<div>
<div className="signerComponent">
<SignerListPlace
signerPos={signerPos}
signersdata={signersdata}
isSelectListId={isSelectListId}
setSignerObjId={setSignerObjId}
setRoleName={setRoleName}
setIsSelectId={setIsSelectId}
setContractName={setContractName}
handleAddSigner={handleAddSigner}
setUniqueId={setUniqueId}
handleDeleteUser={handleDeleteUser}
handleRoleChange={handleRoleChange}
handleOnBlur={handleOnBlur}
title={"Roles"}
/>
<div data-tut="reactourSecond">
<FieldsComponent
pdfUrl={isMailSend}
sign={sign}
stamp={stamp}
dragSignature={dragSignature}
signRef={signRef}
handleDivClick={handleDivClick}
handleMouseLeave={handleMouseLeave}
isDragSign={isDragSign}
themeColor={themeColor}
dragStamp={dragStamp}
dragRef={dragRef}
isDragStamp={isDragStamp}
isSignYourself={false}
addPositionOfSignature={addPositionOfSignature}
<div
style={{ maxHeight: window.innerHeight - 70 + "px" }}
className="autoSignScroll"
>
<SignerListPlace
signerPos={signerPos}
signersdata={signersdata}
isSelectListId={isSelectListId}
setSignerObjId={setSignerObjId}
setRoleName={setRoleName}
setIsSelectId={setIsSelectId}
setContractName={setContractName}
handleAddSigner={handleAddSigner}
setUniqueId={setUniqueId}
handleDeleteUser={handleDeleteUser}
handleRoleChange={handleRoleChange}
handleOnBlur={handleOnBlur}
title={"Roles"}
/>
<div data-tut="reactourSecond">
<WidgetComponent
pdfUrl={isMailSend}
dragSignature={dragSignature}
signRef={signRef}
handleDivClick={handleDivClick}
handleMouseLeave={handleMouseLeave}
isDragSign={isDragSign}
dragStamp={dragStamp}
dragRef={dragRef}
isDragStamp={isDragStamp}
isSignYourself={false}
addPositionOfSignature={addPositionOfSignature}
title={"Roles"}
initial={true}
isTemplateFlow={true}
/>
</div>
</div>
</div>
</div>
@@ -1257,6 +1517,13 @@ const TemplatePlaceholder = () => {
onSuccess={handleEditTemplateForm}
/>
</ModalUi>
<WidgetNameModal
widgetName={widgetName}
defaultdata={currWidgetsDetails}
isOpen={isNameModal}
handleClose={handleNameModal}
handleData={handleWidgetdefaultdata}
/>
</div>
);
};
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import { Navigate, useNavigate } from "react-router-dom";
import Parse from "parse";
import { SaveFileSize } from "../constant/saveFileSize";
@@ -6,6 +6,7 @@ import dp from "../assets/images/dp.png";
import Title from "../components/Title";
import sanitizeFileName from "../primitives/sanitizeFileName";
import axios from "axios";
function UserProfile() {
const navigate = useNavigate();
let UserProfile = JSON.parse(localStorage.getItem("UserInformation"));
@@ -17,9 +18,16 @@ function UserProfile() {
const [Image, setImage] = useState(localStorage.getItem("profileImg"));
const [isLoader, setIsLoader] = useState(false);
const [percentage, setpercentage] = useState(0);
const [isDisableDocId, setIsDisableDocId] = useState(false);
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
useEffect(() => {
const extClass = localStorage.getItem("Extand_Class");
const jsonSender = JSON.parse(extClass);
const HeaderDocId = jsonSender[0]?.HeaderDocId;
if (HeaderDocId) {
setIsDisableDocId(HeaderDocId);
}
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
setIsLoader(true);
@@ -33,6 +41,7 @@ function UserProfile() {
object.set("name", name);
object.set("ProfilePic", Image);
object.set("phone", phn);
object.save().then(
async (response) => {
if (response) {
@@ -66,8 +75,12 @@ function UserProfile() {
const extClass = localStorage.getItem("extended_class");
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
const ExtUserId = extData[0].objectId;
// console.log("UserId ", ExtUserId);
const body = { Phone: obj.Phone, Name: obj.Name };
const body = {
Phone: obj.Phone,
Name: obj.Name,
HeaderDocId: isDisableDocId
};
await axios.put(
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
body,
@@ -137,6 +150,10 @@ function UserProfile() {
return <Navigate to={_redirect} />;
}
const handleDisableDocId = () => {
setIsDisableDocId((prevChecked) => !prevChecked);
};
return (
<React.Fragment>
<Title title={"Profile"} />
@@ -241,6 +258,22 @@ function UserProfile() {
: "Not verified"}
</span>
</li>
<li className="flex justify-between items-center border-y-[1px] border-gray-300 py-2 break-all">
<span className="font-semibold">Disable DocumentId :</span>{" "}
<span>
<label className="relative inline-flex items-center cursor-pointer mb-0">
<input
disabled={editmode ? false : true}
checked={isDisableDocId}
onChange={handleDisableDocId}
type="checkbox"
value=""
className="sr-only peer"
/>
<div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
</label>
</span>
</li>
</ul>
<div className="flex justify-center pt-2 pb-3 md:pt-3 md:pb-4">
{editmode ? (
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react";
import Parse from "parse";
import axios from "axios";
import "../css/AddUser.css";
import "../styles/AddUser.css";
const AddUser = (props) => {
const [name, setName] = useState("");
const [phone, setPhone] = useState("");
@@ -11,9 +11,6 @@ const AddUser = (props) => {
const [isUserExist, setIsUserExist] = useState(false);
const parseBaseUrl = localStorage.getItem("baseUrl");
const parseAppId = localStorage.getItem("parseAppId");
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
useEffect(() => {
checkUserExist();
}, []);
@@ -50,8 +47,6 @@ const AddUser = (props) => {
e.preventDefault();
e.stopPropagation();
setIsLoader(true);
Parse.serverURL = parseBaseUrl;
Parse.initialize(parseAppId);
try {
const contactQuery = new Parse.Object("contracts_Contactbook");
contactQuery.set("Name", name);
@@ -158,10 +153,10 @@ const AddUser = (props) => {
const res = await contactQuery.save();
const parseData = JSON.parse(JSON.stringify(res));
if(props.details){
if (props.details) {
props.details(parseData);
}
if (props.closePopup) {
props.closePopup();
}
+1 -1
View File
@@ -18,7 +18,7 @@ const Alert = ({ children, type }) => {
<>
{children && (
<div
className={`z-40 fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm ${textcolor} rounded py-[.75rem] px-[1.25rem] `}
className={`z-40 fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm ${textcolor} rounded py-[.75rem] px-[1.25rem] z-50`}
>
{children}
</div>
@@ -2,10 +2,10 @@ import React, { useState, useEffect, useMemo } from "react";
import pad from "../assets/images/pad.svg";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import "../styles/report.css";
import ModalUi from "./ModalUi";
import AppendFormInForm from "../components/AppendFormInForm";
import AddSigner from "../components/AddSigner";
import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const";
import Alert from "./Alert";
const ReportTable = ({
ReportName,
List,
@@ -67,7 +67,7 @@ const ReportTable = ({
const handlemicroapp = async (item, url, btnLabel) => {
if (ReportName === "Templates") {
if (btnLabel === "Edit") {
navigate(`/asmf/${url}/${item.objectId}`);
navigate(`/${url}/${item.objectId}`);
} else {
setActLoader({ [`${item.objectId}_${btnLabel}`]: true });
try {
@@ -149,7 +149,8 @@ const ReportTable = ({
if (res.data && res.data.objectId) {
setActLoader({});
setIsAlert(true);
navigate(`/asmf/${url}/${res.data.objectId}`, {
setTimeout(() => setIsAlert(false), 1500);
navigate(`/${url}/${res.data.objectId}`, {
state: { title: "Use Template" }
});
}
@@ -157,6 +158,7 @@ const ReportTable = ({
console.log("Err", err);
setIsAlert(true);
setIsErr(true);
setTimeout(() => setIsAlert(false), 1500);
setActLoader({});
}
} else {
@@ -166,18 +168,20 @@ const ReportTable = ({
} else {
setIsAlert(true);
setIsErr(true);
setTimeout(() => setIsAlert(false), 1500);
setActLoader({});
}
} catch (err) {
console.log("err", err);
setIsAlert(true);
setIsErr(true);
setTimeout(() => setIsAlert(false), 1500);
setActLoader({});
}
}
} else {
localStorage.removeItem("rowlevel");
navigate("/rpmf/" + url);
navigate(`/${url}`);
localStorage.setItem("rowlevel", JSON.stringify(item));
}
@@ -211,13 +215,15 @@ const ReportTable = ({
setIsDeleteModal({});
setActLoader({ [item.objectId]: true });
try {
const url =
process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/";
const serverUrl = process.env.REACT_APP_SERVERURL
? process.env.REACT_APP_SERVERURL
: window.location.origin + "/api/app";
const url = serverUrl + "/classes/contracts_Contactbook/";
const body = { IsDeleted: true };
const res = await axios.put(url + item.objectId, body, {
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
});
@@ -225,6 +231,7 @@ const ReportTable = ({
if (res.data && res.data.updatedAt) {
setActLoader({});
setIsAlert(true);
setTimeout(() => setIsAlert(false), 1500);
const upldatedList = List.filter((x) => x.objectId !== item.objectId);
setList(upldatedList);
}
@@ -232,6 +239,7 @@ const ReportTable = ({
console.log("err", err);
setIsAlert(true);
setIsErr(true);
setTimeout(() => setIsAlert(false), 1500);
setActLoader({});
}
};
@@ -240,17 +248,12 @@ const ReportTable = ({
return (
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
{isAlert && (
<div
className={`alert alert-${isErr ? "danger" : "success"} alertBox`}
role="alert"
onAnimationEnd={() => setIsAlert(false)}
>
<Alert type={isErr ? "danger" : "success"}>
{isErr
? "Something went wrong, Please try again later!"
: "Record deleted successfully!"}
</div>
</Alert>
)}
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
<div className="font-light">{ReportName}</div>
{ReportName === "Templates" && (
@@ -495,7 +498,7 @@ const ReportTable = ({
isOpen={isContactform}
handleClose={handleContactFormModal}
>
<AppendFormInForm
<AddSigner
handleUserData={handleUserData}
closePopup={handleContactFormModal}
/>
@@ -7,7 +7,7 @@ function HandleError({ handleError }) {
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
height: "100vh"
}}
>
<span style={{ fontSize: "20px", color: "gray" }}>{handleError}</span>
@@ -0,0 +1,47 @@
import React from "react";
import SelectSigners from "../components/shared/fields/SelectSigners";
import AddUser from "./AddUser";
import ModalUi from "./ModalUi";
const LinkUserModal = (props) => {
return (
<ModalUi
title={"Add/Choose Signer"}
isOpen={props.isAddUser[props.uniqueId]}
handleClose={props.closePopup}
>
<SelectSigners
details={props.handleAddUser}
closePopup={props.closePopup}
/>
<div
style={{
display: "flex",
alignItems: "center",
gap: 5,
margin: "0 30%",
color: "#808080"
}}
>
<span
style={{
height: 1,
width: "100%",
backgroundColor: "#ccc"
}}
></span>
<span>or</span>
<span
style={{
height: 1,
width: "100%",
backgroundColor: "#ccc"
}}
></span>
</div>
<AddUser details={props.handleAddUser} closePopup={props.closePopup} />
</ModalUi>
);
};
export default LinkUserModal;
@@ -0,0 +1,27 @@
import React from "react";
import loader from "../assets/images/loader2.gif";
function Loader({ isLoading }) {
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
flexDirection: "column"
}}
>
<img
alt="no img"
src={loader}
style={{ width: "80px", height: "80px" }}
/>
<span style={{ fontSize: "13px", color: "gray" }}>
{isLoading.message}
</span>
</div>
);
}
export default Loader;
+10 -2
View File
@@ -1,4 +1,5 @@
import React from "react";
const ModalUi = ({
children,
title,
@@ -6,13 +7,20 @@ const ModalUi = ({
headColor,
handleClose,
showHeader = true,
showClose = true
showClose = true,
styleClass
}) => {
return (
<>
{isOpen && (
<div className="fixed z-[999] top-0 left-0 w-[100%] h-[100%] bg-black bg-opacity-[75%]">
<div className="fixed z-[1000] top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-sm bg-white rounded shadow-md max-h-90 min-w-[90%] md:min-w-[500px] overflow-y-auto hide-scrollbar">
<div
className={
styleClass
? styleClass
: "fixed z-[1000] top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-sm bg-white rounded shadow-md max-h-90 min-w-[90%] md:min-w-[500px] overflow-y-auto hide-scrollbar"
}
>
{showHeader && (
<div
className="flex justify-between rounded-t items-center py-[15px] px-[20px] text-white"
@@ -0,0 +1,59 @@
import React from "react";
import "../styles/signature.css";
import { rejectBtn } from "../constant/const";
function CustomModal({
show,
headMsg,
bodyMssg,
footerMessage,
declineDoc,
setIsDecline,
containerWH
}) {
const isMobile = window.innerWidth < 767;
return (
show && (
<div
className="bg-black bg-opacity-[75%] absolute z-[999] flex flex-col items-center justify-center"
style={{
width: containerWH && containerWH.width,
height: isMobile ? "100%" : containerWH && containerWH.height
}}
>
<div className="bg-white rounded outline-none md:w-[40%] w-[80%]">
<div className="bg-[#de4337] text-white p-[10px] rounded-t">
{headMsg && headMsg}
</div>
<div className="p-[15px]">
<p className="text-[15px]">{bodyMssg && bodyMssg}</p>
</div>
{footerMessage && (
<>
<div className="h-[1px] bg-[#9f9f9f] w-full"></div>
<div className="m-[15px] ">
<button
className={`${rejectBtn} text-white mr-2`}
style={{ background: "#de4337" }}
type="button"
onClick={() => declineDoc()}
>
Yes
</button>
<button
type="button"
className={rejectBtn}
onClick={() => setIsDecline({ isDeclined: false })}
>
Close
</button>
</div>
</>
)}
</div>
</div>
)
);
}
export default CustomModal;
@@ -12,14 +12,22 @@ export default function TourContentWithBtn({ message, isChecked }) {
return (
<div>
<p>{message}</p>
<label style={{ textAlign: "center", display: "flex", "justifyContent":'center' }}>
<label
style={{
textAlign: "center",
display: "flex",
justifyContent: "center"
}}
>
<input
type="checkbox"
style={{ marginRight: 3 }}
checked={isCheck}
onChange={handleCheck}
/>{" "}
<span style={{color:"#787878", fontSize: 12}}>Don't show this again</span>
<span style={{ color: "#787878", fontSize: 12 }}>
Don&apos;t show this again
</span>
</label>
</div>
);

Some files were not shown because too many files have changed in this diff Show More