mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-04 16:58:05 +02:00
Compare commits
250
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acd1c589d7 | ||
|
|
de62052453 | ||
|
|
de120dae39 | ||
|
|
08d1e9a360 | ||
|
|
74a9d08550 | ||
|
|
6fc86e026b | ||
|
|
72da56a916 | ||
|
|
4ba7ffbb1a | ||
|
|
0d9a0b8bb1 | ||
|
|
084aa69702 | ||
|
|
597635800f | ||
|
|
8da2c7fad4 | ||
|
|
2b0276ead9 | ||
|
|
45a96ece54 | ||
|
|
729d19dfd3 | ||
|
|
29aa123669 | ||
|
|
f69caf016a | ||
|
|
48e0e0ee15 | ||
|
|
a71278f95c | ||
|
|
f7bb11ede1 | ||
|
|
6a365f7734 | ||
|
|
e4d946e519 | ||
|
|
149a16f150 | ||
|
|
d8ff3d9faa | ||
|
|
fe34001e42 | ||
|
|
fcdd7e2758 | ||
|
|
025c30b685 | ||
|
|
e742e85f0e | ||
|
|
476a99feae | ||
|
|
29464585b8 | ||
|
|
cdd078699b | ||
|
|
9ef1e22fda | ||
|
|
655401e04b | ||
|
|
b550c07ca8 | ||
|
|
fd72094b8a | ||
|
|
4d7348abc2 | ||
|
|
ec68479e98 | ||
|
|
ac05942e58 | ||
|
|
b387b6b402 | ||
|
|
e13baeb2fc | ||
|
|
52eb8e4a68 | ||
|
|
71189783a8 | ||
|
|
aec9396524 | ||
|
|
d74390b974 | ||
|
|
998fe013c8 | ||
|
|
06d4c9aeaf | ||
|
|
bc77a9b0a1 | ||
|
|
07c0390401 | ||
|
|
c50d753d74 | ||
|
|
65eef5739d | ||
|
|
01eed3664b | ||
|
|
685e09d406 | ||
|
|
7bacca1f78 | ||
|
|
3764ab5c30 | ||
|
|
2f7a1d67b6 | ||
|
|
8726efb0aa | ||
|
|
e073e83ad6 | ||
|
|
69140d2139 | ||
|
|
aeed48c0ef | ||
|
|
1f9504b9cc | ||
|
|
5518d6932e | ||
|
|
f14e301b6c | ||
|
|
901ddf35bb | ||
|
|
9aa3166528 | ||
|
|
a90e679228 | ||
|
|
90b5e3c860 | ||
|
|
74f6612271 | ||
|
|
2862a97c4e | ||
|
|
5c3f967128 | ||
|
|
6fde71e947 | ||
|
|
2900464272 | ||
|
|
10bac3c11f | ||
|
|
302f38d472 | ||
|
|
8ecdbc43a3 | ||
|
|
6721b334cf | ||
|
|
454f557d14 | ||
|
|
635693b394 | ||
|
|
0be1816046 | ||
|
|
feb162e03e | ||
|
|
c8801846fa | ||
|
|
a793fc3722 | ||
|
|
ffdabe4a00 | ||
|
|
5536c99052 | ||
|
|
ba1c3145f3 | ||
|
|
0fbe6aeb6c | ||
|
|
4898c4a851 | ||
|
|
85aa6b2947 | ||
|
|
3b02d2bcdb | ||
|
|
ed01f4a7a0 | ||
|
|
1f395cf25f | ||
|
|
cf98e73d13 | ||
|
|
10112ac20d | ||
|
|
9a0183274f | ||
|
|
6b2e16c21d | ||
|
|
3c51baf1c9 | ||
|
|
3f4be1c4f3 | ||
|
|
62b36f58f7 | ||
|
|
ba3591c7bc | ||
|
|
1ec11b8733 | ||
|
|
ab89d3b71f | ||
|
|
1811173648 | ||
|
|
b218e96107 | ||
|
|
64a0be8776 | ||
|
|
414e2d819c | ||
|
|
0769101f28 | ||
|
|
5dc86119d3 | ||
|
|
4999dc2b18 | ||
|
|
962d36c088 | ||
|
|
d071986aac | ||
|
|
afb4de9d0c | ||
|
|
bc5c8cac33 | ||
|
|
be93e6a214 | ||
|
|
37748057e3 | ||
|
|
eb3bb77692 | ||
|
|
df0ce3f086 | ||
|
|
0a99b5181e | ||
|
|
8a5d3a0368 | ||
|
|
c00406e401 | ||
|
|
aeead23c86 | ||
|
|
83fe88911f | ||
|
|
527bca32d2 | ||
|
|
9bf4940c2e | ||
|
|
a653df6935 | ||
|
|
dfc6da388c | ||
|
|
3e2c822bbc | ||
|
|
1a20841a94 | ||
|
|
c6be81923b | ||
|
|
6b47f6a27b | ||
|
|
33b0111ed0 | ||
|
|
48fd9e52b3 | ||
|
|
d85074b127 | ||
|
|
5ada9a411b | ||
|
|
6f50de1ef1 | ||
|
|
612150cf4b | ||
|
|
634db83e8e | ||
|
|
b32c8068ef | ||
|
|
ae464274b0 | ||
|
|
c5ceba8d57 | ||
|
|
903d626c27 | ||
|
|
e5b4fb123f | ||
|
|
116893c1b4 | ||
|
|
592254a9a3 | ||
|
|
f52c6e24fe | ||
|
|
70ae1e24fc | ||
|
|
c491595fc8 | ||
|
|
6875135ede | ||
|
|
662049d878 | ||
|
|
1764d7f9ba | ||
|
|
07933b56b1 | ||
|
|
f6ba4db62d | ||
|
|
5bd36f91d9 | ||
|
|
c199c3019e | ||
|
|
facbc8e76e | ||
|
|
c3c6f6bab3 | ||
|
|
f5e216fedc | ||
|
|
c40a923388 | ||
|
|
a86f4fd9b7 | ||
|
|
59f6d022cf | ||
|
|
b7beeee260 | ||
|
|
31c861cbe4 | ||
|
|
6a9408b7b4 | ||
|
|
a9fd264a01 | ||
|
|
6c77bbfe75 | ||
|
|
890c3d2b1f | ||
|
|
3ede441f54 | ||
|
|
2433ad5957 | ||
|
|
fffd907d63 | ||
|
|
51edc339cd | ||
|
|
bf307abe9a | ||
|
|
08a97707b7 | ||
|
|
d99fecd46e | ||
|
|
6c59c0ec9a | ||
|
|
32c75d1fc3 | ||
|
|
7f0f81c334 | ||
|
|
a882f07f57 | ||
|
|
74b81a5363 | ||
|
|
9b75764717 | ||
|
|
c1468112b0 | ||
|
|
950b74789c | ||
|
|
7e4f12e41a | ||
|
|
d75c1d7c0c | ||
|
|
7eacbedf59 | ||
|
|
2e5947279f | ||
|
|
ef5ac7d626 | ||
|
|
658c37cc4d | ||
|
|
ffc8e4b23e | ||
|
|
3fb96fc792 | ||
|
|
71016ba5e0 | ||
|
|
cd1a6fdaf6 | ||
|
|
c2afeed448 | ||
|
|
37fd7bbeda | ||
|
|
71fbde0099 | ||
|
|
ca6cb60d78 | ||
|
|
df1c0ea66c | ||
|
|
46279efc2c | ||
|
|
aca2848406 | ||
|
|
eaec3cf607 | ||
|
|
ad25d73f26 | ||
|
|
481b9ac1e0 | ||
|
|
4cd3791feb | ||
|
|
7de8699437 | ||
|
|
4c162676b1 | ||
|
|
ca390bdfa6 | ||
|
|
22d064fd38 | ||
|
|
444c9bbfdf | ||
|
|
b289686d42 | ||
|
|
eeb878b340 | ||
|
|
7894d69cc9 | ||
|
|
b992d7db24 | ||
|
|
50b72f4d85 | ||
|
|
44639f66b0 | ||
|
|
ae740efced | ||
|
|
66c020d903 | ||
|
|
562a7d6fc8 | ||
|
|
090c17c2c0 | ||
|
|
70637d6143 | ||
|
|
f38e8705de | ||
|
|
ba06ff72a0 | ||
|
|
82312a1e0d | ||
|
|
1a8cf11a3e | ||
|
|
3deacbabc3 | ||
|
|
c28805add9 | ||
|
|
80fb320ae4 | ||
|
|
76c9c1fa53 | ||
|
|
f38d83dbe0 | ||
|
|
ee9411729d | ||
|
|
f6f7c6cecd | ||
|
|
a45fc0dd60 | ||
|
|
348f7810b9 | ||
|
|
45bec128a9 | ||
|
|
4da307315c | ||
|
|
c87aa415a9 | ||
|
|
b1786ec16a | ||
|
|
6ad35e979e | ||
|
|
9d996d5cb7 | ||
|
|
008e3e8783 | ||
|
|
8458906b0b | ||
|
|
6933aa309b | ||
|
|
067ea68d3b | ||
|
|
e4e8a0b721 | ||
|
|
dc392adc1d | ||
|
|
741efff1fa | ||
|
|
38b7311e66 | ||
|
|
e0ccf049a6 | ||
|
|
1e58b35db5 | ||
|
|
498bd18630 | ||
|
|
b530ef882a | ||
|
|
850d14064a | ||
|
|
273ada837b | ||
|
|
280b812e5b |
+1
-1
@@ -40,7 +40,7 @@ DO_SECRET_ACCESS_KEY=
|
|||||||
# Digital ocean spaces region or AWS s3 region
|
# Digital ocean spaces region or AWS s3 region
|
||||||
DO_REGION=us-west
|
DO_REGION=us-west
|
||||||
# local storage
|
# local storage
|
||||||
USE_LOCAL=TRUE
|
USE_LOCAL=true
|
||||||
|
|
||||||
# Email mailgun or set SMTP_ENABLE true to use SMTP config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
# Email mailgun or set SMTP_ENABLE true to use SMTP config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
||||||
MAILGUN_API_KEY=
|
MAILGUN_API_KEY=
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'staging'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ We would like to thank all our contributors and users for their support and feed
|
|||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/VikramNagwal"><img src="https://avatars.githubusercontent.com/u/123088024?v=4?s=100" width="100px;" alt="Vikram"/><br /><sub><b>Vikram</b></sub></a><br /><a href="#code-VikramNagwal" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/VikramNagwal"><img src="https://avatars.githubusercontent.com/u/123088024?v=4?s=100" width="100px;" alt="Vikram"/><br /><sub><b>Vikram</b></sub></a><br /><a href="#code-VikramNagwal" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ugoconsonni"><img src="https://avatars.githubusercontent.com/u/13661702?v=4?s=100" width="100px;" alt="ugoconsonni"/><br /><sub><b>ugoconsonni</b></sub></a><br /><a href="#code-ugoconsonni" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ugoconsonni"><img src="https://avatars.githubusercontent.com/u/13661702?v=4?s=100" width="100px;" alt="ugoconsonni"/><br /><sub><b>ugoconsonni</b></sub></a><br /><a href="#code-ugoconsonni" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/daniel-mutwiri"><img src="https://avatars.githubusercontent.com/u/8936960?v=4?s=100" width="100px;" alt="Daniel Mutwiri"/><br /><sub><b>Daniel Mutwiri</b></sub></a><br /><a href="#code-daniel-mutwiri" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/daniel-mutwiri"><img src="https://avatars.githubusercontent.com/u/8936960?v=4?s=100" width="100px;" alt="Daniel Mutwiri"/><br /><sub><b>Daniel Mutwiri</b></sub></a><br /><a href="#code-daniel-mutwiri" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zathiel"><img src="https://avatars.githubusercontent.com/u/26553418?v=4?s=100" width="100px;" alt="Zathiel"/><br /><sub><b>Zathiel</b></sub></a><br /><a href="#code-Zathiel" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zathiel"><img src="https://avatars.githubusercontent.com/u/26553418?v=4?s=100" width="100px;" alt="Zathiel"/><br /><sub><b>Zathiel</b></sub></a><br /><a href="#code-Zathiel" title="Code">💻</a><a href="#security-Zathiel" title="Security">🛡️</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Generated
+4049
-3499
File diff suppressed because it is too large
Load Diff
+21
-16
@@ -4,21 +4,23 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^0.8.2",
|
"@formkit/auto-animate": "^0.8.2",
|
||||||
"@radix-ui/themes": "^2.0.3",
|
"@radix-ui/themes": "^3.0.5",
|
||||||
"@react-pdf/renderer": "^3.4.4",
|
"@react-pdf/renderer": "^3.4.4",
|
||||||
"@reduxjs/toolkit": "^2.2.1",
|
"@reduxjs/toolkit": "^2.2.5",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.7.2",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"parse": "^4.3.1",
|
"nth-check": "^2.1.1",
|
||||||
|
"parse": "^5.1.0",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"radix-ui": "^1.0.1",
|
"radix-ui": "^1.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.10.2",
|
"react-bootstrap": "^2.10.2",
|
||||||
|
"react-confetti": "^6.1.0",
|
||||||
"react-cookie": "^7.1.4",
|
"react-cookie": "^7.1.4",
|
||||||
"react-datepicker": "^6.4.0",
|
"react-datepicker": "^6.9.0",
|
||||||
"react-dnd": "^16.0.1",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dnd-multi-backend": "^8.0.3",
|
"react-dnd-multi-backend": "^8.0.3",
|
||||||
@@ -27,25 +29,24 @@
|
|||||||
"react-gtm-module": "^2.0.11",
|
"react-gtm-module": "^2.0.11",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-konva": "^18.2.10",
|
"react-konva": "^18.2.10",
|
||||||
"react-modal": "^3.16.1",
|
"react-pdf": "^9.0.0",
|
||||||
"react-pdf": "^7.7.3",
|
|
||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-redux": "^9.1.0",
|
"react-redux": "^9.1.2",
|
||||||
"react-rnd": "^10.4.10",
|
"react-rnd": "^10.4.11",
|
||||||
"react-router-dom": "^6.22.3",
|
"react-router-dom": "^6.22.3",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-scrollbars-custom": "^4.1.1",
|
"react-scrollbars-custom": "^4.1.1",
|
||||||
"react-select": "^5.8.0",
|
"react-select": "^5.8.0",
|
||||||
"react-signature-canvas": "^1.0.6",
|
"react-signature-canvas": "^1.0.6",
|
||||||
"react-tooltip": "^5.26.3",
|
"react-tooltip": "^5.26.4",
|
||||||
"react-web-share": "^2.0.2",
|
"react-web-share": "^2.0.2",
|
||||||
"reactour": "^1.19.3",
|
"reactour": "^1.19.4",
|
||||||
"redux": "^5.0.1",
|
"redux": "^5.0.1",
|
||||||
"redux-thunk": "^3.1.0",
|
"redux-thunk": "^3.1.0",
|
||||||
"regex-parser": "^2.3.0",
|
"regex-parser": "^2.3.0",
|
||||||
"serve": "^14.2.1",
|
"serve": "^14.2.3",
|
||||||
"styled-components": "^4.4.1",
|
"styled-components": "^4.4.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^4.0.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "serve -s build",
|
"start": "serve -s build",
|
||||||
@@ -83,16 +84,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/runtime-corejs2": "^7.24.5",
|
"@babel/runtime-corejs2": "^7.24.7",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"commitizen": "^4.3.0",
|
"commitizen": "^4.3.0",
|
||||||
|
"daisyui": "^4.12.2",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.34.1",
|
"eslint-plugin-react": "^7.34.1",
|
||||||
"lint-staged": "^15.2.2",
|
"lint-staged": "^15.2.5",
|
||||||
"postcss": "^8.4.38",
|
"postcss": "^8.4.38",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"pretty-quick": "^3.3.1",
|
"pretty-quick": "^3.3.1",
|
||||||
"tailwindcss": "^3.4.1"
|
"tailwindcss": "^3.4.4"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"nth-check": "$nth-check"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" data-theme="opensigncss">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -50,4 +50,4 @@
|
|||||||
-->
|
-->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Binary file not shown.
+10
-19
@@ -16,6 +16,8 @@ import PlaceHolderSign from "./pages/PlaceHolderSign";
|
|||||||
import PdfRequestFiles from "./pages/PdfRequestFiles";
|
import PdfRequestFiles from "./pages/PdfRequestFiles";
|
||||||
import LazyPage from "./primitives/LazyPage";
|
import LazyPage from "./primitives/LazyPage";
|
||||||
import { isEnableSubscription } from "./constant/const";
|
import { isEnableSubscription } from "./constant/const";
|
||||||
|
import SSOVerify from "./pages/SSOVerify";
|
||||||
|
import Loader from "./primitives/Loader";
|
||||||
const DebugPdf = lazy(() => import("./pages/DebugPdf"));
|
const DebugPdf = lazy(() => import("./pages/DebugPdf"));
|
||||||
const ForgetPassword = lazy(() => import("./pages/ForgetPassword"));
|
const ForgetPassword = lazy(() => import("./pages/ForgetPassword"));
|
||||||
const GuestLogin = lazy(() => import("./pages/GuestLogin"));
|
const GuestLogin = lazy(() => import("./pages/GuestLogin"));
|
||||||
@@ -28,25 +30,13 @@ const Opensigndrive = lazy(() => import("./pages/Opensigndrive"));
|
|||||||
const ManageSign = lazy(() => import("./pages/Managesign"));
|
const ManageSign = lazy(() => import("./pages/Managesign"));
|
||||||
const GenerateToken = lazy(() => import("./pages/GenerateToken"));
|
const GenerateToken = lazy(() => import("./pages/GenerateToken"));
|
||||||
const Webhook = lazy(() => import("./pages/Webhook"));
|
const Webhook = lazy(() => import("./pages/Webhook"));
|
||||||
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
|
|
||||||
|
|
||||||
const Loader = () => {
|
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`;
|
||||||
|
|
||||||
|
const AppLoader = () => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="flex justify-center items-center h-[100vh]">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -75,9 +65,9 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-[#eef1f5]">
|
<div className="bg-base-200">
|
||||||
{isloading ? (
|
{isloading ? (
|
||||||
<Loader />
|
<AppLoader />
|
||||||
) : (
|
) : (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
@@ -181,6 +171,7 @@ function App() {
|
|||||||
element={<PdfRequestFiles />}
|
element={<PdfRequestFiles />}
|
||||||
/>
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/sso" element={<SSOVerify />} />
|
||||||
<Route path="*" element={<PageNotFound />} />
|
<Route path="*" element={<PageNotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 316 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 61 KiB |
@@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const AddSigner = (props) => {
|
const AddSigner = (props) => {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
@@ -23,7 +23,7 @@ const AddSigner = (props) => {
|
|||||||
);
|
);
|
||||||
if (savedUserDetails && addYourself) {
|
if (savedUserDetails && addYourself) {
|
||||||
setName(savedUserDetails.name);
|
setName(savedUserDetails.name);
|
||||||
setPhone(savedUserDetails.phone);
|
setPhone(savedUserDetails?.phone || "");
|
||||||
setEmail(savedUserDetails.email);
|
setEmail(savedUserDetails.email);
|
||||||
}
|
}
|
||||||
}, [addYourself]);
|
}, [addYourself]);
|
||||||
@@ -50,145 +50,161 @@ const AddSigner = (props) => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setIsLoader(true);
|
setIsLoader(true);
|
||||||
if (localStorage.getItem("TenantId")) {
|
if (localStorage.getItem("TenantId")) {
|
||||||
try {
|
|
||||||
const contactQuery = new Parse.Object("contracts_Contactbook");
|
|
||||||
contactQuery.set("Name", name);
|
|
||||||
contactQuery.set("Phone", phone);
|
|
||||||
contactQuery.set("Email", email);
|
|
||||||
contactQuery.set("UserRole", "contracts_Guest");
|
|
||||||
|
|
||||||
contactQuery.set("TenantId", {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: "partners_Tenant",
|
|
||||||
objectId: localStorage.getItem("TenantId")
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const _users = Parse.Object.extend("User");
|
const user = Parse.User.current();
|
||||||
const _user = new _users();
|
const query = new Parse.Query("contracts_Contactbook");
|
||||||
_user.set("name", name);
|
query.equalTo("CreatedBy", user);
|
||||||
_user.set("username", email);
|
query.notEqualTo("IsDeleted", true);
|
||||||
_user.set("email", email);
|
query.equalTo("Email", email);
|
||||||
_user.set("phone", phone);
|
const res = await query.first();
|
||||||
_user.set("password", phone);
|
// console.log(res);
|
||||||
|
if (!res) {
|
||||||
const user = await _user.save();
|
const contactQuery = new Parse.Object("contracts_Contactbook");
|
||||||
if (user) {
|
contactQuery.set("Name", name);
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
if (phone) {
|
||||||
const headers = {
|
contactQuery.set("Phone", phone);
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_Guest",
|
|
||||||
userId: user.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
contactQuery.set(
|
|
||||||
"CreatedBy",
|
|
||||||
Parse.User.createWithoutData(currentUser.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
contactQuery.set("UserId", user);
|
|
||||||
const acl = new Parse.ACL();
|
|
||||||
acl.setPublicReadAccess(true);
|
|
||||||
acl.setPublicWriteAccess(true);
|
|
||||||
acl.setReadAccess(currentUser.id, true);
|
|
||||||
acl.setWriteAccess(currentUser.id, true);
|
|
||||||
|
|
||||||
contactQuery.setACL(acl);
|
|
||||||
|
|
||||||
const res = await contactQuery.save();
|
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
|
||||||
if (props.details) {
|
|
||||||
props.details({
|
|
||||||
value: parseData[props.valueKey],
|
|
||||||
label: parseData[props.displayKey]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (props.closePopup) {
|
|
||||||
props.closePopup();
|
|
||||||
}
|
|
||||||
if (props.handleUserData) {
|
|
||||||
props.handleUserData(parseData);
|
|
||||||
}
|
}
|
||||||
|
contactQuery.set("Email", email);
|
||||||
|
contactQuery.set("UserRole", "contracts_Guest");
|
||||||
|
|
||||||
|
contactQuery.set("TenantId", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "partners_Tenant",
|
||||||
|
objectId: localStorage.getItem("TenantId")
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const _users = Parse.Object.extend("User");
|
||||||
|
const _user = new _users();
|
||||||
|
_user.set("name", name);
|
||||||
|
_user.set("username", email);
|
||||||
|
_user.set("email", email);
|
||||||
|
_user.set("password", email);
|
||||||
|
if (phone) {
|
||||||
|
_user.set("phone", phone);
|
||||||
|
}
|
||||||
|
const user = await _user.save();
|
||||||
|
if (user) {
|
||||||
|
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: localStorage.getItem("_appName"),
|
||||||
|
roleName: "contracts_Guest",
|
||||||
|
userId: user.id
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
contactQuery.set(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
contactQuery.set("UserId", user);
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
acl.setPublicWriteAccess(true);
|
||||||
|
acl.setReadAccess(currentUser.id, true);
|
||||||
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
|
||||||
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
if (props.details) {
|
||||||
|
props.details({
|
||||||
|
value: parseData[props.valueKey],
|
||||||
|
label: parseData[props.displayKey]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoader(false);
|
||||||
|
// Reset the form fields
|
||||||
|
setAddYourself(false);
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
if (err.code === 202) {
|
||||||
|
const params = { email: email };
|
||||||
|
const userRes = await Parse.Cloud.run("getUserId", params);
|
||||||
|
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: localStorage.getItem("_appName"),
|
||||||
|
roleName: "contracts_Guest",
|
||||||
|
userId: userRes.id
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
contactQuery.set(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
contactQuery.set("UserId", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: userRes.id
|
||||||
|
});
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
acl.setPublicWriteAccess(true);
|
||||||
|
acl.setReadAccess(currentUser.id, true);
|
||||||
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
if (props.details) {
|
||||||
|
props.details({
|
||||||
|
value: parseData[props.valueKey],
|
||||||
|
label: parseData[props.displayKey]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
// Reset the form fields
|
||||||
|
setAddYourself(false);
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("Contact already exist!");
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
// Reset the form fields
|
|
||||||
setAddYourself(false);
|
|
||||||
setName("");
|
|
||||||
setPhone("");
|
|
||||||
setEmail("");
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err ", err);
|
console.log("err in fetch contact", err);
|
||||||
if (err.code === 202) {
|
setIsLoader(false);
|
||||||
const params = { email: email };
|
alert("something went wrong, please try again later");
|
||||||
const userRes = await Parse.Cloud.run("getUserId", params);
|
|
||||||
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
const body = {
|
|
||||||
appName: localStorage.getItem("_appName"),
|
|
||||||
roleName: "contracts_Guest",
|
|
||||||
userId: userRes.id
|
|
||||||
};
|
|
||||||
await axios.post(roleurl, body, { headers: headers });
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
contactQuery.set(
|
|
||||||
"CreatedBy",
|
|
||||||
Parse.User.createWithoutData(currentUser.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
contactQuery.set("UserId", {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: "_User",
|
|
||||||
objectId: userRes.id
|
|
||||||
});
|
|
||||||
const acl = new Parse.ACL();
|
|
||||||
acl.setPublicReadAccess(true);
|
|
||||||
acl.setPublicWriteAccess(true);
|
|
||||||
acl.setReadAccess(currentUser.id, true);
|
|
||||||
acl.setWriteAccess(currentUser.id, true);
|
|
||||||
|
|
||||||
contactQuery.setACL(acl);
|
|
||||||
const res = await contactQuery.save();
|
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
|
||||||
if (props.details) {
|
|
||||||
props.details({
|
|
||||||
value: parseData[props.valueKey],
|
|
||||||
label: parseData[props.displayKey]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (props.closePopup) {
|
|
||||||
props.closePopup();
|
|
||||||
}
|
|
||||||
if (props.handleUserData) {
|
|
||||||
props.handleUserData(parseData);
|
|
||||||
}
|
|
||||||
setIsLoader(false);
|
|
||||||
// Reset the form fields
|
|
||||||
setAddYourself(false);
|
|
||||||
setName("");
|
|
||||||
setPhone("");
|
|
||||||
setEmail("");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} else {
|
||||||
// console.log("err", err);
|
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert("something went wrong!");
|
alert("something went wrong, please try again later");
|
||||||
}
|
|
||||||
}else{
|
|
||||||
alert('something went wrong, please try again later')
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -211,38 +227,29 @@ const AddSigner = (props) => {
|
|||||||
<div className="h-full p-[20px]">
|
<div className="h-full p-[20px]">
|
||||||
{isLoader && (
|
{isLoader && (
|
||||||
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30">
|
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30">
|
||||||
<div
|
<Loader />
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="w-full mx-auto p-2">
|
<div className="w-full mx-auto p-2 text-base-content">
|
||||||
{isUserExist && (
|
{isUserExist && (
|
||||||
<div className="mb-3">
|
<div className="mb-3 flex items-center">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="addYourself"
|
id="addYourself"
|
||||||
checked={addYourself}
|
checked={addYourself}
|
||||||
onChange={handleAddYourselfChange}
|
onChange={handleAddYourselfChange}
|
||||||
className="form-checkbox"
|
className="op-checkbox op-checkbox-sm"
|
||||||
/>
|
/>
|
||||||
<label htmlFor="addYourself" className="ml-2 text-gray-700">
|
<label htmlFor="addYourself" className="ml-2 mb-0">
|
||||||
Add Yourself
|
Add Yourself
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label htmlFor="name" className="block text-xs font-semibold">
|
||||||
htmlFor="name"
|
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
|
||||||
>
|
|
||||||
Name
|
Name
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -251,59 +258,45 @@ const AddSigner = (props) => {
|
|||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
required
|
required
|
||||||
disabled={addYourself}
|
disabled={addYourself}
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label htmlFor="email" className="block text-xs font-semibold">
|
||||||
htmlFor="email"
|
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
|
||||||
>
|
|
||||||
Email
|
Email
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
id="email"
|
id="email"
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value?.toLowerCase())}
|
||||||
required
|
required
|
||||||
disabled={addYourself}
|
disabled={addYourself}
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label htmlFor="phone" className="block text-xs font-semibold">
|
||||||
htmlFor="phone"
|
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
|
||||||
>
|
|
||||||
Phone
|
Phone
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="phone"
|
id="phone"
|
||||||
value={phone}
|
value={phone}
|
||||||
onChange={(e) => setPhone(e.target.value)}
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
required
|
|
||||||
disabled={addYourself}
|
disabled={addYourself}
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mt-4 flex gap-x-2 justify-start">
|
||||||
<div className="mt-4 flex justify-start">
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
style={{ backgroundColor: modalSubmitBtnColor }}
|
|
||||||
className="mr-2 px-[20px] py-1.5 text-white rounded shadow-md text-center focus:outline-none "
|
|
||||||
>
|
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleReset()}
|
onClick={() => handleReset()}
|
||||||
style={{ backgroundColor: modalCancelBtnColor }}
|
className="op-btn op-btn-secondary"
|
||||||
className="px-4 py-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import Parse from "parse";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Title from "./Title";
|
import Title from "./Title";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const AddUser = (props) => {
|
const AddUser = (props) => {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
@@ -62,8 +63,10 @@ const AddUser = (props) => {
|
|||||||
_user.set("name", name);
|
_user.set("name", name);
|
||||||
_user.set("username", email);
|
_user.set("username", email);
|
||||||
_user.set("email", email);
|
_user.set("email", email);
|
||||||
_user.set("phone", phone);
|
_user.set("password", email);
|
||||||
_user.set("password", phone);
|
if (phone) {
|
||||||
|
_user.set("phone", phone);
|
||||||
|
}
|
||||||
|
|
||||||
const user = await _user.save();
|
const user = await _user.save();
|
||||||
if (user) {
|
if (user) {
|
||||||
@@ -193,13 +196,7 @@ const AddUser = (props) => {
|
|||||||
{isUserExist && <Alert type="danger">User already exists!</Alert>}
|
{isUserExist && <Alert type="danger">User already exists!</Alert>}
|
||||||
{isLoader && (
|
{isLoader && (
|
||||||
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30 z-50">
|
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30 z-50">
|
||||||
<div
|
<Loader />
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="w-full mx-auto">
|
<div className="w-full mx-auto">
|
||||||
@@ -211,7 +208,7 @@ const AddUser = (props) => {
|
|||||||
className="block text-xs text-gray-700 font-semibold"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
>
|
>
|
||||||
Name
|
Name
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -219,7 +216,7 @@ const AddUser = (props) => {
|
|||||||
value={name}
|
value={name}
|
||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
required
|
required
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
@@ -228,7 +225,7 @@ const AddUser = (props) => {
|
|||||||
className="block text-xs text-gray-700 font-semibold"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
>
|
>
|
||||||
Email
|
Email
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
@@ -236,7 +233,7 @@ const AddUser = (props) => {
|
|||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
required
|
required
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
@@ -245,7 +242,7 @@ const AddUser = (props) => {
|
|||||||
className="block text-xs text-gray-700 font-semibold"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
>
|
>
|
||||||
Phone
|
Phone
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -253,7 +250,7 @@ const AddUser = (props) => {
|
|||||||
value={phone}
|
value={phone}
|
||||||
onChange={(e) => setPhone(e.target.value)}
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
required
|
required
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import SuggestionInput from "./shared/fields/SuggestionInput";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
|
const BulkSendUi = (props) => {
|
||||||
|
const [forms, setForms] = useState([]);
|
||||||
|
const [formId, setFormId] = useState(2);
|
||||||
|
const formRef = useRef(null);
|
||||||
|
const [scrollOnNextUpdate, setScrollOnNextUpdate] = useState(false);
|
||||||
|
const [isSubmit, setIsSubmit] = useState(false);
|
||||||
|
const [allowedForm, setAllowedForm] = useState(0);
|
||||||
|
const [isSignatureExist, setIsSignatureExist] = useState();
|
||||||
|
const allowedSigners = 50;
|
||||||
|
useEffect(() => {
|
||||||
|
signatureExist();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//function to check atleast one signature field exist
|
||||||
|
const signatureExist = () => {
|
||||||
|
const getPlaceholder = props.item?.Placeholders;
|
||||||
|
const checkIsSignatureExistt = getPlaceholder?.every((placeholderObj) =>
|
||||||
|
placeholderObj?.placeHolder?.some((holder) =>
|
||||||
|
holder?.pos?.some((posItem) => posItem?.type === "signature")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
setIsSignatureExist(checkIsSignatureExistt);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
if (scrollOnNextUpdate && formRef.current) {
|
||||||
|
formRef.current.scrollIntoView({
|
||||||
|
behavior: "smooth",
|
||||||
|
block: "end",
|
||||||
|
inline: "nearest"
|
||||||
|
});
|
||||||
|
setScrollOnNextUpdate(false);
|
||||||
|
}
|
||||||
|
}, [forms, scrollOnNextUpdate]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(() => {
|
||||||
|
if (props?.Placeholders?.length > 0) {
|
||||||
|
let users = [];
|
||||||
|
props?.Placeholders?.forEach((element) => {
|
||||||
|
if (!element.signerObjId) {
|
||||||
|
users = [
|
||||||
|
...users,
|
||||||
|
{
|
||||||
|
fieldId: element.Id,
|
||||||
|
email: "",
|
||||||
|
label: element.Role,
|
||||||
|
signer: {}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setForms((prevForms) => [...prevForms, { Id: 1, fields: users }]);
|
||||||
|
const totalForms = Math.floor(allowedSigners / users?.length);
|
||||||
|
setAllowedForm(totalForms);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
const handleInputChange = (index, signer, fieldIndex) => {
|
||||||
|
const newForms = [...forms];
|
||||||
|
newForms[index].fields[fieldIndex].email = signer?.Email
|
||||||
|
? signer?.Email
|
||||||
|
: signer || "";
|
||||||
|
newForms[index].fields[fieldIndex].signer = signer?.objectId ? signer : "";
|
||||||
|
setForms(newForms);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddForm = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// Check if the quick send limit has been reached
|
||||||
|
if (forms?.length < allowedForm) {
|
||||||
|
if (props?.Placeholders.length > 0) {
|
||||||
|
let newForm = [];
|
||||||
|
props?.Placeholders?.forEach((element) => {
|
||||||
|
if (!element.signerObjId) {
|
||||||
|
newForm = [
|
||||||
|
...newForm,
|
||||||
|
{
|
||||||
|
fieldId: element.Id,
|
||||||
|
email: "",
|
||||||
|
label: element.Role,
|
||||||
|
signer: {}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setForms([...forms, { Id: formId, fields: newForm }]);
|
||||||
|
}
|
||||||
|
setFormId(formId + 1);
|
||||||
|
setScrollOnNextUpdate(true);
|
||||||
|
} else {
|
||||||
|
// If the limit has been reached, throw an error with the appropriate message
|
||||||
|
alert("Quick send reached limit.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemoveForm = (index) => {
|
||||||
|
const updatedForms = forms.filter((_, i) => i !== index);
|
||||||
|
setForms(updatedForms);
|
||||||
|
};
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsSubmit(true);
|
||||||
|
|
||||||
|
// Create a copy of Placeholders array from props.item
|
||||||
|
let Placeholders = [...props.item.Placeholders];
|
||||||
|
// Initialize an empty array to store updated documents
|
||||||
|
let Documents = [];
|
||||||
|
|
||||||
|
// Loop through each form
|
||||||
|
forms.forEach((form) => {
|
||||||
|
// Map through the copied Placeholders array to update email values
|
||||||
|
const updatedPlaceholders = Placeholders.map((placeholder) => {
|
||||||
|
// Find the field in the current form that matches the placeholder Id
|
||||||
|
const field = form.fields.find(
|
||||||
|
(element) => parseInt(element.fieldId) === placeholder.Id
|
||||||
|
);
|
||||||
|
// If a matching field is found, update the email value in the placeholder
|
||||||
|
const signer = field?.signer?.objectId ? field.signer : {};
|
||||||
|
if (field) {
|
||||||
|
return {
|
||||||
|
...placeholder,
|
||||||
|
email: field.email,
|
||||||
|
signerObjId: field?.signer?.objectId || "",
|
||||||
|
signerPtr: signer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// If no matching field is found, keep the placeholder as is
|
||||||
|
return placeholder;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Push a new document object with updated Placeholders into the Documents array
|
||||||
|
Documents.push({ ...props.item, Placeholders: updatedPlaceholders });
|
||||||
|
});
|
||||||
|
// console.log("Documents ", Documents);
|
||||||
|
await batchQuery(Documents);
|
||||||
|
};
|
||||||
|
|
||||||
|
const batchQuery = async (Documents) => {
|
||||||
|
const serverUrl = localStorage.getItem("baseUrl");
|
||||||
|
const functionsUrl = `${serverUrl}functions/batchdocuments`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const params = {
|
||||||
|
Documents: JSON.stringify(Documents)
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(functionsUrl, params, { headers: headers });
|
||||||
|
// console.log("res ", res);
|
||||||
|
if (res.data && res.data.result) {
|
||||||
|
props.handleClose("success", Documents?.length);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err ", err);
|
||||||
|
props.handleClose("error", 0);
|
||||||
|
} finally {
|
||||||
|
setIsSubmit(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isSubmit && (
|
||||||
|
<div className="absolute z-[999] h-full w-full flex justify-center items-center bg-black bg-opacity-30">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{props.Placeholders?.length > 0 ? (
|
||||||
|
isSignatureExist ? (
|
||||||
|
<>
|
||||||
|
{props.Placeholders?.some((x) => !x.signerObjId) ? (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div className="min-h-max max-h-[250px] overflow-y-auto">
|
||||||
|
{forms?.map((form, index) => (
|
||||||
|
<div
|
||||||
|
key={form.Id}
|
||||||
|
className="p-3 op-card border-[1px] border-gray-400 mt-3 mx-4 mb-4 bg-base-200 text-base-content grid grid-cols-1 md:grid-cols-2 gap-2 relative"
|
||||||
|
>
|
||||||
|
{form?.fields?.map((field, fieldIndex) => (
|
||||||
|
<div className="flex flex-col" key={field.fieldId}>
|
||||||
|
<label>{field.label}</label>
|
||||||
|
<SuggestionInput
|
||||||
|
required
|
||||||
|
type="email"
|
||||||
|
value={field.value}
|
||||||
|
index={fieldIndex}
|
||||||
|
onChange={(signer) =>
|
||||||
|
handleInputChange(index, signer, fieldIndex)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{forms?.length > 1 && (
|
||||||
|
<button
|
||||||
|
onClick={() => handleRemoveForm(index)}
|
||||||
|
className="absolute right-3 top-1 text-[red] border-[1px] border-[red] rounded-lg w-[1.7rem] h-[1.7rem]"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<div ref={formRef}></div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col mx-4 mb-4 gap-3">
|
||||||
|
<button
|
||||||
|
onClick={handleAddForm}
|
||||||
|
className="op-btn op-btn-primary focus:outline-none"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-plus"></i> <span>Add new</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="op-btn op-btn-secondary focus:outline-none"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-paper-plane"></i>{" "}
|
||||||
|
<span>Send</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
) : (
|
||||||
|
<div className="text-black p-3 bg-white w-full text-sm md:text-base flex justify-center items-center">
|
||||||
|
All roles in this document are currently linked to contacts. To
|
||||||
|
'quick send' copies of this template to multiple
|
||||||
|
signers, please ensure that at least one role is not linked to
|
||||||
|
any contact.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="text-black p-3 bg-white w-full text-sm md:text-base flex justify-center items-center">
|
||||||
|
Please ensure there's at least one signature widget added for
|
||||||
|
all recipients.
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<div className="text-black p-3 bg-white w-full text-sm md:text-base flex justify-center items-center">
|
||||||
|
Please add at least one role to this template in order to 'quick
|
||||||
|
send' copies of it to multiple signers.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BulkSendUi;
|
||||||
@@ -45,12 +45,16 @@ const Footer = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="bg-[#222c3c] text-[#98a6ba] text-center text-[13px] py-3">
|
<footer className="op-footer op-footer-center py-3 bg-base-300 text-base-content text-center text-[13px]">
|
||||||
All Rights Reserved © {new Date().getFullYear()}
|
<aside>
|
||||||
<span onClick={openUrl} className="hover:underline cursor-pointer">
|
<p>
|
||||||
{appName} ( version: {version ? version : `${Package.version} `})
|
All Rights Reserved © {new Date().getFullYear()}
|
||||||
</span>
|
<span onClick={openUrl} className="hover:underline cursor-pointer">
|
||||||
</div>
|
{appName} ( version: {version ? version : `${Package.version} `})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</aside>
|
||||||
|
</footer>
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
showButton ? "block" : "hidden"
|
showButton ? "block" : "hidden"
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const FullScreenButton = () => {
|
|||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<button
|
<button
|
||||||
onClick={toggleFullScreen}
|
onClick={toggleFullScreen}
|
||||||
className="text-black p-2 text-sm focus:outline-none"
|
className="text-base-content p-2 text-sm focus:outline-none"
|
||||||
>
|
>
|
||||||
{isFullScreen ? (
|
{isFullScreen ? (
|
||||||
<i className="fa-solid fa-compress"></i>
|
<i className="fa-solid fa-compress"></i>
|
||||||
|
|||||||
@@ -44,7 +44,13 @@ const Header = ({ showSidebar }) => {
|
|||||||
|
|
||||||
const closeDropdown = () => {
|
const closeDropdown = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
Parse.User.logOut();
|
if (Parse?.User?.current()) {
|
||||||
|
try {
|
||||||
|
Parse.User.logOut();
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
let appdata = localStorage.getItem("userSettings");
|
let appdata = localStorage.getItem("userSettings");
|
||||||
let applogo = localStorage.getItem("appLogo");
|
let applogo = localStorage.getItem("appLogo");
|
||||||
let appName = localStorage.getItem("appName");
|
let appName = localStorage.getItem("appName");
|
||||||
@@ -87,14 +93,16 @@ const Header = ({ showSidebar }) => {
|
|||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row justify-between items-center gap-x-3 md:gap-x-4 bg-white md:px-4 px-2 shadow h-[50px] md:w-full ">
|
<div className="op-navbar bg-base-100 shadow">
|
||||||
<button
|
<div className="flex-none">
|
||||||
className="cursor-pointer focus:outline-none"
|
<button
|
||||||
onClick={showSidebar}
|
className="op-btn op-btn-square op-btn-ghost focus:outline-none"
|
||||||
>
|
onClick={showSidebar}
|
||||||
<i className={`fa-solid fa-bars text-xl `}></i>
|
>
|
||||||
</button>
|
<i className="fa-solid fa-bars text-xl text-base-content"></i>
|
||||||
<div className="flex-1">
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1 ml-2">
|
||||||
<div className="h-[25px] md:h-[40px] w-auto overflow-hidden">
|
<div className="h-[25px] md:h-[40px] w-auto overflow-hidden">
|
||||||
<img
|
<img
|
||||||
className="object-contain h-full w-auto"
|
className="object-contain h-full w-auto"
|
||||||
@@ -103,10 +111,7 @@ const Header = ({ showSidebar }) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div id="profile-menu" className="flex-none gap-2">
|
||||||
id="profile-menu"
|
|
||||||
className="flex justify-between items-center gap-x-3"
|
|
||||||
>
|
|
||||||
{!isSubscribe && (
|
{!isSubscribe && (
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
@@ -118,7 +123,7 @@ const Header = ({ showSidebar }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isPro && (
|
{isPro && (
|
||||||
<div className="w-[35px] h-[35px] rounded-full ring-[1px] ring-offset-2 ring-[#002862] text-[#002862] overflow-hidden font-semibold flex items-center justify-center">
|
<div className="w-[35px] h-[35px] bg-white rounded-full ring-[1px] ring-offset-2 ring-[#002862] text-[#002862] overflow-hidden font-semibold flex items-center justify-center">
|
||||||
PRO
|
PRO
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -138,60 +143,66 @@ const Header = ({ showSidebar }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{width >= 768 && (
|
{width >= 768 && (
|
||||||
<div onClick={toggleDropdown} className="cursor-pointer text-sm">
|
<div
|
||||||
|
onClick={toggleDropdown}
|
||||||
|
className="cursor-pointer text-base-content text-sm"
|
||||||
|
>
|
||||||
{username && username}
|
{username && username}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="relative">
|
<div className="op-dropdown op-dropdown-end" id="profile-menu">
|
||||||
<div className="cursor-pointer">
|
<div tabIndex={0} role="button" className="op-btn op-btn-ghost">
|
||||||
<i onClick={toggleDropdown} className="fa-solid fa-angle-down"></i>
|
<i
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
onClick={toggleDropdown}
|
||||||
|
className="fa-solid fa-angle-down text-base-content"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<ul
|
||||||
className={`dropdown absolute text-sm text-gray-700 font-light right-0 mt-4 p-1 w-48 bg-white border rounded-lg shadow-lg z-10 ${
|
tabIndex={0}
|
||||||
isOpen ? "block" : "hidden"
|
className="mt-3 z-[1] p-2 shadow op-menu op-menu-sm op-dropdown-content text-base-content bg-base-100 rounded-box w-52"
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<ul>
|
<li onClick={() => openInNewTab("https://docs.opensignlabs.com")}>
|
||||||
<li
|
<span>
|
||||||
className="hover:bg-gray-100 rounded-t-lg py-1 px-2 cursor-pointer font-normal"
|
|
||||||
onClick={() => openInNewTab("https://docs.opensignlabs.com")}
|
|
||||||
>
|
|
||||||
<i className="fa-solid fa-book"></i> Docs
|
<i className="fa-solid fa-book"></i> Docs
|
||||||
</li>
|
</span>
|
||||||
<li
|
</li>
|
||||||
className="hover:bg-gray-100 py-1 px-2 cursor-pointer font-normal"
|
<li
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
navigate("/profile");
|
navigate("/profile");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<span>
|
||||||
<i className="fa-regular fa-user"></i> Profile
|
<i className="fa-regular fa-user"></i> Profile
|
||||||
</li>
|
</span>
|
||||||
<li
|
</li>
|
||||||
className="hover:bg-gray-100 py-1 px-2 cursor-pointer font-normal"
|
<li
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
navigate("/changepassword");
|
navigate("/changepassword");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<span>
|
||||||
<i className="fa-solid fa-lock"></i> Change Password
|
<i className="fa-solid fa-lock"></i> Change Password
|
||||||
</li>
|
</span>
|
||||||
<li
|
</li>
|
||||||
className="hover:bg-gray-100 py-1 px-2 cursor-pointer font-normal"
|
<li
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open("https://console.opensignlabs.com/");
|
window.open("https://console.opensignlabs.com/");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<span>
|
||||||
<i className="fa-regular fa-id-card"></i> Console
|
<i className="fa-regular fa-id-card"></i> Console
|
||||||
</li>
|
</span>
|
||||||
<li
|
</li>
|
||||||
className="hover:bg-gray-100 rounded-b-lg py-1 px-2 cursor-pointer font-normal"
|
<li onClick={closeDropdown}>
|
||||||
onClick={closeDropdown}
|
<span>
|
||||||
>
|
|
||||||
<i className="fa-solid fa-arrow-right-from-bracket"></i> Log Out
|
<i className="fa-solid fa-arrow-right-from-bracket"></i> Log Out
|
||||||
</li>
|
</span>
|
||||||
</ul>
|
</li>
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
// import FacebookLogin from "react-facebook-login";
|
// import FacebookLogin from "react-facebook-login";
|
||||||
|
|
||||||
const LoginFacebook = ({
|
const LoginFacebook = ({
|
||||||
@@ -49,7 +50,7 @@ const LoginFacebook = ({
|
|||||||
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
||||||
// console.log("extRes ", extRes);
|
// console.log("extRes ", extRes);
|
||||||
if (extRes) {
|
if (extRes) {
|
||||||
const params = { ...details, Phone: extRes.get("Phone") };
|
const params = { ...details, Phone: extRes?.get("Phone") || "" };
|
||||||
const payload = await Parse.Cloud.run("facebooksign", params);
|
const payload = await Parse.Cloud.run("facebooksign", params);
|
||||||
// console.log("payload ", payload);
|
// console.log("payload ", payload);
|
||||||
if (payload && payload.sessiontoken) {
|
if (payload && payload.sessiontoken) {
|
||||||
@@ -59,7 +60,7 @@ const LoginFacebook = ({
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: details.Name,
|
name: details.Name,
|
||||||
email: details.Email,
|
email: details.Email,
|
||||||
phone: extRes.get("Phone"),
|
phone: extRes?.get("Phone") || "",
|
||||||
company: extRes.get("Company")
|
company: extRes.get("Company")
|
||||||
};
|
};
|
||||||
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||||
@@ -75,7 +76,7 @@ const LoginFacebook = ({
|
|||||||
const handleSubmitbtn = async () => {
|
const handleSubmitbtn = async () => {
|
||||||
if (userDetails.Phone && userDetails.Company) {
|
if (userDetails.Phone && userDetails.Company) {
|
||||||
setThirdpartyLoader(true);
|
setThirdpartyLoader(true);
|
||||||
const params = { ...fBDetails, Phone: userDetails.Phone };
|
const params = { ...fBDetails, Phone: userDetails?.Phone || "" };
|
||||||
const payload = await Parse.Cloud.run("facebooksign", params);
|
const payload = await Parse.Cloud.run("facebooksign", params);
|
||||||
// console.log("payload ", payload);
|
// console.log("payload ", payload);
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ const LoginFacebook = ({
|
|||||||
name: userDetails.Name,
|
name: userDetails.Name,
|
||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
// "passsword":userDetails.Phone,
|
// "passsword":userDetails.Phone,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails?.Phone || "",
|
||||||
role: "contracts_User",
|
role: "contracts_User",
|
||||||
company: userDetails.Company
|
company: userDetails.Company
|
||||||
}
|
}
|
||||||
@@ -96,7 +97,7 @@ const LoginFacebook = ({
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: userDetails.Name,
|
name: userDetails.Name,
|
||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails?.Phone || "",
|
||||||
company: userDetails.Company
|
company: userDetails.Company
|
||||||
};
|
};
|
||||||
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||||
@@ -112,29 +113,10 @@ const LoginFacebook = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div style={{ position: "relative" }}>
|
<div className="relative">
|
||||||
{thirdpartyLoader && (
|
{thirdpartyLoader && (
|
||||||
<div
|
<div className="fixed flex justify-center items-center inset-0 bg-black bg-opacity-25 z-20 ">
|
||||||
style={{
|
<Loader />
|
||||||
position: "fixed",
|
|
||||||
width: "100vw",
|
|
||||||
height: "100vh",
|
|
||||||
backgroundColor: "rgba(0,0,0,0.2)",
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
zIndex: 2
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "fixed",
|
|
||||||
fontSize: "50px",
|
|
||||||
color: "#3ac9d6",
|
|
||||||
top: "50%",
|
|
||||||
left: "45%"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* <FacebookLogin
|
{/* <FacebookLogin
|
||||||
@@ -146,11 +128,10 @@ const LoginFacebook = ({
|
|||||||
/> */}
|
/> */}
|
||||||
{isModal && (
|
{isModal && (
|
||||||
<div
|
<div
|
||||||
className="modal fade show"
|
className="modal fade show block z-[1]"
|
||||||
id="exampleModal"
|
id="exampleModal"
|
||||||
tabIndex="-1"
|
tabIndex="-1"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
style={{ display: "block", zIndex: 1 }}
|
|
||||||
>
|
>
|
||||||
<div className="modal-dialog" role="document">
|
<div className="modal-dialog" role="document">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
@@ -163,13 +144,8 @@ const LoginFacebook = ({
|
|||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
<form>
|
<form>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label
|
<label htmlFor="Phone" className="col-form-label">
|
||||||
htmlFor="Phone"
|
Phone <span className="text-[red] text-[13px]">*</span>
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="col-form-label"
|
|
||||||
>
|
|
||||||
Phone{" "}
|
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="tel"
|
type="tel"
|
||||||
@@ -186,13 +162,8 @@ const LoginFacebook = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label
|
<label htmlFor="Company" className="col-form-label">
|
||||||
htmlFor="Company"
|
Company <span className="text-[red] text-[13px]">*</span>
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="col-form-label"
|
|
||||||
>
|
|
||||||
Company{" "}
|
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -212,16 +183,14 @@ const LoginFacebook = ({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleSubmitbtn()}
|
onClick={() => handleSubmitbtn()}
|
||||||
className="btn btn-info"
|
className="btn btn-info mr-[10px]"
|
||||||
style={{ marginRight: 10 }}
|
|
||||||
>
|
>
|
||||||
Sign up
|
Sign up
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-secondary"
|
className="btn btn-secondary w-[90px]"
|
||||||
onClick={() => setIsModal(false)}
|
onClick={() => setIsModal(false)}
|
||||||
style={{ width: 90 }}
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Parse from "parse";
|
|||||||
import { jwtDecode } from "jwt-decode";
|
import { jwtDecode } from "jwt-decode";
|
||||||
import { useScript } from "../hook/useScript";
|
import { useScript } from "../hook/useScript";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* `GoogleSignInBtn`as it's name indicates it render google sign in button
|
* `GoogleSignInBtn`as it's name indicates it render google sign in button
|
||||||
@@ -110,7 +110,7 @@ const GoogleSignInBtn = ({
|
|||||||
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
||||||
// console.log("extRes ", extRes);
|
// console.log("extRes ", extRes);
|
||||||
if (extRes) {
|
if (extRes) {
|
||||||
const params = { ...details, Phone: extRes.get("Phone") };
|
const params = { ...details, Phone: extRes?.get("Phone") || "" };
|
||||||
const payload = await Parse.Cloud.run("googlesign", params);
|
const payload = await Parse.Cloud.run("googlesign", params);
|
||||||
// console.log("payload ", payload);
|
// console.log("payload ", payload);
|
||||||
if (payload && payload.sessiontoken) {
|
if (payload && payload.sessiontoken) {
|
||||||
@@ -121,7 +121,7 @@ const GoogleSignInBtn = ({
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: details.Name,
|
name: details.Name,
|
||||||
email: details.Gmail,
|
email: details.Gmail,
|
||||||
phone: extRes.get("Phone"),
|
phone: extRes?.get("Phone") || "",
|
||||||
company: extRes.get("Company")
|
company: extRes.get("Company")
|
||||||
};
|
};
|
||||||
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||||
@@ -139,7 +139,7 @@ const GoogleSignInBtn = ({
|
|||||||
setThirdpartyLoader(true);
|
setThirdpartyLoader(true);
|
||||||
// e.preventDefault()
|
// e.preventDefault()
|
||||||
// console.log("handelSubmit", userDetails);
|
// console.log("handelSubmit", userDetails);
|
||||||
const params = { ...googleDetails, Phone: userDetails.Phone };
|
const params = { ...googleDetails, Phone: userDetails?.Phone };
|
||||||
const payload = await Parse.Cloud.run("googlesign", params);
|
const payload = await Parse.Cloud.run("googlesign", params);
|
||||||
|
|
||||||
// console.log("payload ", payload);
|
// console.log("payload ", payload);
|
||||||
@@ -149,7 +149,7 @@ const GoogleSignInBtn = ({
|
|||||||
name: userDetails.Name,
|
name: userDetails.Name,
|
||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
// "passsword":userDetails.Phone,
|
// "passsword":userDetails.Phone,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails?.Phone || "",
|
||||||
role: "contracts_User",
|
role: "contracts_User",
|
||||||
company: userDetails.Company,
|
company: userDetails.Company,
|
||||||
jobTitle: userDetails.Destination
|
jobTitle: userDetails.Destination
|
||||||
@@ -161,7 +161,7 @@ const GoogleSignInBtn = ({
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: userDetails.Name,
|
name: userDetails.Name,
|
||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails?.Phone || "",
|
||||||
company: userDetails.Company
|
company: userDetails.Company
|
||||||
// jobTitle: userDetails.JobTitle
|
// jobTitle: userDetails.JobTitle
|
||||||
};
|
};
|
||||||
@@ -207,45 +207,22 @@ const GoogleSignInBtn = ({
|
|||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div style={{ position: "relative" }}>
|
<div className="relative">
|
||||||
{thirdpartyLoader && (
|
{thirdpartyLoader && (
|
||||||
<div
|
<div className="fixed flex justify-center items-center inset-0 bg-black bg-opacity-25 z-20 ">
|
||||||
style={{
|
<Loader />
|
||||||
position: "fixed",
|
|
||||||
width: "100vw",
|
|
||||||
height: "100vh",
|
|
||||||
backgroundColor: "rgba(0,0,0,0.2)",
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
zIndex: 2
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "fixed",
|
|
||||||
fontSize: "50px",
|
|
||||||
color: "#3ac9d6",
|
|
||||||
top: "50%",
|
|
||||||
left: "45%"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div ref={googleBtn} className="text-sm"></div>
|
<div ref={googleBtn} className="text-sm"></div>
|
||||||
<ModalUi showClose={false} isOpen={isModal} title="Sign up form">
|
<ModalUi showClose={false} isOpen={isModal} title="Sign up form">
|
||||||
<form className="px-4 py-3">
|
<form className="px-4 py-3 text-base-content">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label htmlFor="Phone" className="block text-xs font-semibold">
|
||||||
htmlFor="Phone"
|
Phone <span className="text-[13px] text-[red]">*</span>
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
|
||||||
>
|
|
||||||
Phone <span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="tel"
|
type="tel"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
id="Phone"
|
id="Phone"
|
||||||
value={userDetails.Phone}
|
value={userDetails.Phone}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -258,16 +235,12 @@ const GoogleSignInBtn = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label htmlFor="Company" className="block text-xs font-semibold">
|
||||||
htmlFor="Company"
|
Company <span className="text-[13px] text-[red]">*</span>
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
|
||||||
>
|
|
||||||
Company <span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
id="Company"
|
id="Company"
|
||||||
value={userDetails.Company}
|
value={userDetails.Company}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -280,16 +253,12 @@ const GoogleSignInBtn = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label htmlFor="JobTitle" className="block text-xs font-semibold">
|
||||||
htmlFor="JobTitle"
|
Job Title <span className="text-[13px] text-[red]">*</span>
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
|
||||||
>
|
|
||||||
Job Title <span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
id="JobTitle"
|
id="JobTitle"
|
||||||
value={userDetails.Destination}
|
value={userDetails.Destination}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -301,20 +270,18 @@ const GoogleSignInBtn = ({
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="flex flex-row gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="px-3 py-1.5 text-white rounded shadow-md text-center focus:outline-none "
|
className="op-btn op-btn-primary"
|
||||||
onClick={() => handleSubmitbtn()}
|
onClick={() => handleSubmitbtn()}
|
||||||
style={{ marginRight: 10, backgroundColor: modalSubmitBtnColor }}
|
|
||||||
>
|
>
|
||||||
Sign up
|
Sign up
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="p-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
className="op-btn op-btn-ghost"
|
||||||
onClick={handleCloseModal}
|
onClick={handleCloseModal}
|
||||||
style={{ width: 90, backgroundColor: modalCancelBtnColor }}
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -4,27 +4,11 @@ import { Stage, Layer, Rect } from "react-konva";
|
|||||||
const RenderDebugPdf = (props) => {
|
const RenderDebugPdf = (props) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div className="sticky top-0 p-[10px] z-10 bg-white border-[1px] border-[gray] my-[5px]">
|
||||||
style={{
|
|
||||||
position: "sticky",
|
|
||||||
top: 0,
|
|
||||||
padding: 10,
|
|
||||||
zIndex: 1,
|
|
||||||
backgroundColor: "white",
|
|
||||||
border: "1px solid grey",
|
|
||||||
margin: "5px 0"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{`Co-ordinates: X - ${props.hoverCoordinates.x}, Y - ${props.hoverCoordinates.y}`}
|
{`Co-ordinates: X - ${props.hoverCoordinates.x}, Y - ${props.hoverCoordinates.y}`}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
className="relative flex-1 cursor-crosshair border-[1px] border-[gray] overflow-auto"
|
||||||
flex: 1,
|
|
||||||
position: "relative",
|
|
||||||
border: "1px solid grey",
|
|
||||||
overflow: "auto",
|
|
||||||
cursor: "crosshair"
|
|
||||||
}}
|
|
||||||
onMouseMove={props.handleMouseMoveDiv}
|
onMouseMove={props.handleMouseMoveDiv}
|
||||||
>
|
>
|
||||||
<Document
|
<Document
|
||||||
@@ -57,7 +41,7 @@ const RenderDebugPdf = (props) => {
|
|||||||
onMouseUp={props.handleMouseUp}
|
onMouseUp={props.handleMouseUp}
|
||||||
width={props.pdfDimension.width}
|
width={props.pdfDimension.width}
|
||||||
height={props.pdfDimension.height}
|
height={props.pdfDimension.height}
|
||||||
style={{ position: "absolute", top: 0, left: 0 }}
|
className="absolute top-0 right-0"
|
||||||
>
|
>
|
||||||
<Layer>
|
<Layer>
|
||||||
{props.annotations
|
{props.annotations
|
||||||
|
|||||||
@@ -26,18 +26,18 @@ const DashboardButton = (props) => {
|
|||||||
props.Data && props.Data.Redirect_type
|
props.Data && props.Data.Redirect_type
|
||||||
? "cursor-pointer"
|
? "cursor-pointer"
|
||||||
: "cursor-default"
|
: "cursor-default"
|
||||||
} w-full px-3 py-2 flex text-white rounded-md shadow overflow-hidden`}
|
} w-full shadow-md px-3 py-2 op-card bg-base-100`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-start gap-5">
|
<div className="flex flex-row items-center">
|
||||||
<span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
|
<span className="rounded-full bg-base-content bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
|
||||||
<i
|
<i
|
||||||
className={`${
|
className={`${
|
||||||
props.Icon ? props.Icon : "fa fa-solid fa-info"
|
props.Icon ? props.Icon : "fa fa-solid fa-info"
|
||||||
} text-[25px] lg:text-[30px]`}
|
} text-[25px] lg:text-[30px]`}
|
||||||
></i>
|
></i>
|
||||||
</span>
|
</span>
|
||||||
<div className="">
|
<div className="op-card-title text-lg ml-3 text-base-content">
|
||||||
<div className="text-base lg:text-lg text-black"> {props.Label}</div>
|
{props.Label}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -336,25 +336,29 @@ const DashboardCard = (props) => {
|
|||||||
props.Data && props.Data.Redirect_type
|
props.Data && props.Data.Redirect_type
|
||||||
? "cursor-pointer"
|
? "cursor-pointer"
|
||||||
: "cursor-default"
|
: "cursor-default"
|
||||||
} w-full h-[140px] px-3 pt-4 pb-10 text-white rounded-md shadow overflow-hidden relative`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-start gap-5">
|
<div className="flex items-center justify-start gap-5 text-white">
|
||||||
<span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
|
<span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
|
||||||
<i
|
<i
|
||||||
className={`${
|
className={`${
|
||||||
props.Icon ? props.Icon : "fa fa-solid fa-info"
|
props.Icon ? props.Icon : "fa fa-solid fa-info"
|
||||||
} text-[25px] lg:text-[30px]`}
|
} text-[25px] lg:text-[30px]`}
|
||||||
></i>
|
></i>
|
||||||
</span>
|
</span>
|
||||||
<div className="">
|
<div className="font-medium">
|
||||||
<div className="text-base lg:text-lg"> {props.Label}</div>
|
<div className="text-base lg:text-lg"> {props.Label}</div>
|
||||||
<div className="text-2xl font-light">
|
<div className="text-2xl font-light">
|
||||||
{loading ? <div className="loader-01"></div> : setFormat(response)}
|
{loading ? <div className="loader-01"></div> : setFormat(response)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs absolute top-2 right-1">
|
<div className="text-xs absolute top-3 right-2">
|
||||||
<Tooltip id={props.Label} iconColor={"white"} message={props?.Data?.tourMessage} />
|
<Tooltip
|
||||||
|
id={props.Label}
|
||||||
|
iconColor={"white"}
|
||||||
|
message={props?.Data?.tourMessage}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import Parse from "parse";
|
|||||||
import ReportTable from "../../primitives/GetReportDisplay";
|
import ReportTable from "../../primitives/GetReportDisplay";
|
||||||
import reportJson from "../../json/ReportJson";
|
import reportJson from "../../json/ReportJson";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import Loader from "../../primitives/Loader";
|
||||||
function DashboardReport(props) {
|
function DashboardReport(props) {
|
||||||
// console.log("props ", props)
|
// console.log("props ", props)
|
||||||
const [List, setList] = useState([]);
|
const [List, setList] = useState([]);
|
||||||
@@ -121,21 +122,8 @@ function DashboardReport(props) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="h-[250px] flex justify-center items-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -18,51 +18,26 @@ const buttonList = [
|
|||||||
];
|
];
|
||||||
const GetDashboard = (props) => {
|
const GetDashboard = (props) => {
|
||||||
const Button = ({ label, redirectId, redirectType, icon }) => (
|
const Button = ({ label, redirectId, redirectType, icon }) => (
|
||||||
<div className={"bg-white rounded-md shadow w-full"}>
|
<DashboardButton
|
||||||
<Suspense
|
Icon={icon}
|
||||||
fallback={
|
Label={label}
|
||||||
<div style={{ height: "300px" }}>
|
Data={{ Redirect_type: redirectType, Redirect_id: redirectId }}
|
||||||
<div
|
/>
|
||||||
style={{
|
|
||||||
marginLeft: "45%",
|
|
||||||
marginTop: "150px",
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<DashboardButton
|
|
||||||
Icon={icon}
|
|
||||||
Label={label}
|
|
||||||
Data={{ Redirect_type: redirectType, Redirect_id: redirectId }}
|
|
||||||
/>
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
const renderSwitchWithTour = (col) => {
|
const renderSwitchWithTour = (col) => {
|
||||||
switch (col.widget.type) {
|
switch (col.widget.type) {
|
||||||
case "Card":
|
case "Card":
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={"bg-[#2ed8b6] rounded-md shadow mb-3 md:mb-0"}
|
className={`${
|
||||||
|
col?.widget?.bgColor ? col.widget.bgColor : "bg-[#2ed8b6]"
|
||||||
|
} op-card w-full h-[140px] px-3 pt-4 mb-3 shadow-md"`}
|
||||||
data-tut={col.widget.data.tourSection}
|
data-tut={col.widget.data.tourSection}
|
||||||
style={{ background: col.widget.bgColor }}
|
|
||||||
>
|
>
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<div style={{ height: "300px" }}>
|
<div className="h-[150px] w-full flex justify-center items-center">
|
||||||
<div
|
loading...
|
||||||
style={{
|
|
||||||
marginLeft: "45%",
|
|
||||||
marginTop: "150px",
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -72,7 +47,6 @@ const GetDashboard = (props) => {
|
|||||||
Format={col.widget.format && col.widget.format}
|
Format={col.widget.format && col.widget.format}
|
||||||
Data={col.widget.data}
|
Data={col.widget.data}
|
||||||
FilterData={col.widget.filter}
|
FilterData={col.widget.filter}
|
||||||
DefaultQuery={props.DefaultQuery}
|
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
@@ -89,7 +63,7 @@ const GetDashboard = (props) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return null;
|
return <></>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const renderSwitch = (col) => {
|
const renderSwitch = (col) => {
|
||||||
@@ -97,8 +71,9 @@ const GetDashboard = (props) => {
|
|||||||
case "Card":
|
case "Card":
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={"bg-[#2ed8b6] rounded-md shadow mb-3 md:mb-0"}
|
className={`${
|
||||||
style={{ background: col.widget.bgColor }}
|
col?.widget?.bgColor ? col.widget.bgColor : "bg-[#2ed8b6]"
|
||||||
|
} op-card w-full h-[140px] px-3 pt-4 mb-3 shadow-md"`}
|
||||||
>
|
>
|
||||||
<Suspense fallback={<div>please wait</div>}>
|
<Suspense fallback={<div>please wait</div>}>
|
||||||
<DashboardCard
|
<DashboardCard
|
||||||
@@ -107,7 +82,6 @@ const GetDashboard = (props) => {
|
|||||||
Format={col.widget.format && col.widget.format}
|
Format={col.widget.format && col.widget.format}
|
||||||
Data={col.widget.data}
|
Data={col.widget.data}
|
||||||
FilterData={col.widget.filter}
|
FilterData={col.widget.filter}
|
||||||
DefaultQuery={props.DefaultQuery}
|
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,7 +96,7 @@ const GetDashboard = (props) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return null;
|
return <></>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@@ -130,7 +104,7 @@ const GetDashboard = (props) => {
|
|||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<div
|
<div
|
||||||
data-tut={"tourbutton"}
|
data-tut={"tourbutton"}
|
||||||
className="flex flex-col md:flex-row gap-6 md:gap-8"
|
className="flex flex-col md:flex-row gap-4"
|
||||||
>
|
>
|
||||||
{buttonList.map((btn) => (
|
{buttonList.map((btn) => (
|
||||||
<Button
|
<Button
|
||||||
@@ -143,21 +117,19 @@ const GetDashboard = (props) => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{props.dashboard.map((val, key) => (
|
<div className="grid grid-cols-12 w-full gap-x-4">
|
||||||
<div key={"a" + key} className="row">
|
{props?.dashboard?.columns?.map((col, i) =>
|
||||||
{val.columns.map((col, i) =>
|
col.widget.data && col.widget.data.tourSection ? (
|
||||||
col.widget.data && col.widget.data.tourSection ? (
|
<div key={i} className={col?.colsize}>
|
||||||
<div key={i} className={props.classnameArray[key][i]}>
|
{renderSwitchWithTour(col)}
|
||||||
{renderSwitchWithTour(col)}
|
</div>
|
||||||
</div>
|
) : (
|
||||||
) : (
|
<div key={i} className={col?.colsize}>
|
||||||
<div key={i} className={props.classnameArray[key][i]}>
|
{renderSwitch(col)}
|
||||||
{renderSwitch(col)}
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import Table from "react-bootstrap/Table";
|
import Table from "react-bootstrap/Table";
|
||||||
import * as HoverCard from "@radix-ui/react-hover-card";
|
import * as HoverCard from "@radix-ui/react-hover-card";
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
import FolderModal from "../shared/fields/FolderModal";
|
import FolderModal from "../shared/fields/FolderModal";
|
||||||
|
|
||||||
function DriveBody(props) {
|
function DriveBody(props) {
|
||||||
@@ -313,32 +312,21 @@ function DriveBody(props) {
|
|||||||
|
|
||||||
const signersName = () => {
|
const signersName = () => {
|
||||||
const getSignersName = signerExist.map((data) => data.Name);
|
const getSignersName = signerExist.map((data) => data.Name);
|
||||||
const signerName = getSignersName.join(",");
|
const signerName = getSignersName.join(", ");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span className="statusSpan w-[90%] break-words">{signerName}</span>
|
||||||
className="statusSpan"
|
|
||||||
style={{ width: "90%", wordWrap: "break-word" }}
|
|
||||||
>
|
|
||||||
{signerName}{" "}
|
|
||||||
</span>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
return listType === "table" ? (
|
return listType === "table" ? (
|
||||||
data.Type === "Folder" ? (
|
data.Type === "Folder" ? (
|
||||||
<tr onClick={() => handleOnclikFolder(data)}>
|
<tr onClick={() => handleOnclikFolder(data)}>
|
||||||
<td
|
<td className="cursor-pointer flex items-center">
|
||||||
style={{ cursor: "pointer", display: "flex", alignItems: "center" }}
|
|
||||||
>
|
|
||||||
<i
|
<i
|
||||||
className="fa fa-folder"
|
className="fa fa-folder mr-[8px] text-[26px] text-[#f0ad26]"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{ color: "#f0ad26", marginRight: "8px", fontSize: "26px" }}
|
|
||||||
></i>
|
></i>
|
||||||
|
<span className="text-[12px] font-medium">{data.Name}</span>
|
||||||
<span style={{ fontSize: "12px", fontWeight: "500" }}>
|
|
||||||
{data.Name}
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td>_</td>
|
<td>_</td>
|
||||||
<td>Folder</td>
|
<td>Folder</td>
|
||||||
@@ -347,17 +335,9 @@ function DriveBody(props) {
|
|||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
<tr onClick={() => checkPdfStatus(data)}>
|
<tr onClick={() => checkPdfStatus(data)}>
|
||||||
<td
|
<td className="cursor-pointer flex items-center">
|
||||||
style={{ cursor: "pointer", display: "flex", alignItems: "center" }}
|
<i className="fa fa-file-pdf mr-[8px] text-[26px] text-[#ed4d0e]"></i>
|
||||||
>
|
<span className="text-[12px] font-medium">{data.Name}</span>
|
||||||
<i
|
|
||||||
className="fa fa-file-pdf"
|
|
||||||
style={{ color: "#ed4d0e", marginRight: "8px", fontSize: "26px" }}
|
|
||||||
></i>
|
|
||||||
|
|
||||||
<span style={{ fontSize: "12px", fontWeight: "500" }}>
|
|
||||||
{data.Name}
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td>{createddate}</td>
|
<td>{createddate}</td>
|
||||||
<td>Pdf</td>
|
<td>Pdf</td>
|
||||||
@@ -368,31 +348,22 @@ function DriveBody(props) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleMenuItemClick("Download", data);
|
handleMenuItemClick("Download", data);
|
||||||
}}
|
}}
|
||||||
className="fa fa-download"
|
className="fa fa-download mr-[8px] text-[#ed280e]"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{ color: "#ed280e", marginRight: "8px" }}
|
|
||||||
></i>
|
></i>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)
|
)
|
||||||
) : listType === "list" && data.Type === "Folder" ? (
|
) : listType === "list" && data.Type === "Folder" ? (
|
||||||
<div key={ind} className="folderBox">
|
<div key={ind} className="icon-container">
|
||||||
<ContextMenu.Root>
|
<ContextMenu.Root>
|
||||||
<ContextMenu.Trigger className="ContextMenuTrigger">
|
<ContextMenu.Trigger className="ContextMenuTrigger">
|
||||||
<div
|
<div data-tut={props.dataTutSeventh}>
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
cursor: "pointer"
|
|
||||||
}}
|
|
||||||
data-tut={props.dataTutSeventh}
|
|
||||||
>
|
|
||||||
<img
|
<img
|
||||||
alt="no img"
|
alt="folder"
|
||||||
onClick={() => handleOnclikFolder(data)}
|
onClick={() => handleOnclikFolder(data)}
|
||||||
src={folder}
|
src={folder}
|
||||||
width={100}
|
className="w-full h-full"
|
||||||
height={103}
|
|
||||||
/>
|
/>
|
||||||
{rename === data.objectId ? (
|
{rename === data.objectId ? (
|
||||||
<input
|
<input
|
||||||
@@ -411,12 +382,7 @@ function DriveBody(props) {
|
|||||||
defaultValue={renameValue}
|
defaultValue={renameValue}
|
||||||
// value={renameValue}
|
// value={renameValue}
|
||||||
onChange={(e) => setRenameValue(e.target.value)}
|
onChange={(e) => setRenameValue(e.target.value)}
|
||||||
style={{
|
className="w-[100px] border-[1.5px] border-black rounded-sm text-[10px]"
|
||||||
width: "100px",
|
|
||||||
border: "1.5px solid black",
|
|
||||||
borderRadius: "2px",
|
|
||||||
fontSize: "10px"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<span className="foldName">{data.Name}</span>
|
<span className="foldName">{data.Name}</span>
|
||||||
@@ -434,8 +400,8 @@ function DriveBody(props) {
|
|||||||
onClick={() => handleMenuItemClick("Rename", data)}
|
onClick={() => handleMenuItemClick("Rename", data)}
|
||||||
className="ContextMenuItem"
|
className="ContextMenuItem"
|
||||||
>
|
>
|
||||||
<i className="fa-solid fa-font"></i>
|
<i className="fa-solid fa-font mr-[8px]"></i>
|
||||||
<span style={{ marginLeft: "8px" }}>Rename</span>
|
<span>Rename</span>
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Content>
|
</ContextMenu.Content>
|
||||||
</ContextMenu.Portal>
|
</ContextMenu.Portal>
|
||||||
@@ -450,7 +416,7 @@ function DriveBody(props) {
|
|||||||
<ContextMenu.Trigger className="ContextMenuTrigger">
|
<ContextMenu.Trigger className="ContextMenuTrigger">
|
||||||
<img
|
<img
|
||||||
alt="PDF"
|
alt="PDF"
|
||||||
className="pdf-icon"
|
className="w-full h-full"
|
||||||
src={pdfLogo}
|
src={pdfLogo}
|
||||||
onClick={() => checkPdfStatus(data)}
|
onClick={() => checkPdfStatus(data)}
|
||||||
data-tut={props.dataTutSixth}
|
data-tut={props.dataTutSixth}
|
||||||
@@ -472,12 +438,7 @@ function DriveBody(props) {
|
|||||||
defaultValue={renameValue}
|
defaultValue={renameValue}
|
||||||
// value={renameValue}
|
// value={renameValue}
|
||||||
onChange={(e) => setRenameValue(e.target.value)}
|
onChange={(e) => setRenameValue(e.target.value)}
|
||||||
style={{
|
className="w-[100px] border-[1.5px] border-black rounded-sm text-[10px]"
|
||||||
width: "100px",
|
|
||||||
border: "1.5px solid black",
|
|
||||||
borderRadius: "2px",
|
|
||||||
fontSize: "10px"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<span className="fileName">{data.Name}</span>
|
<span className="fileName">{data.Name}</span>
|
||||||
@@ -522,7 +483,7 @@ function DriveBody(props) {
|
|||||||
className="ContextMenuItem"
|
className="ContextMenuItem"
|
||||||
>
|
>
|
||||||
<i className={menu.icon}></i>
|
<i className={menu.icon}></i>
|
||||||
<span style={{ marginLeft: "8px" }}>{menu.type}</span>
|
<span className="ml-[8px]">{menu.type}</span>
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -533,21 +494,21 @@ function DriveBody(props) {
|
|||||||
</HoverCard.Trigger>
|
</HoverCard.Trigger>
|
||||||
<HoverCard.Portal>
|
<HoverCard.Portal>
|
||||||
<HoverCard.Content className="HoverCardContent" sideOffset={5}>
|
<HoverCard.Content className="HoverCardContent" sideOffset={5}>
|
||||||
<strong style={{ fontSize: "13px" }}>Title: </strong>
|
<strong className="text-[13px]">Title: </strong>
|
||||||
<span className="statusSpan" style={{ marginBottom: "0px" }}>
|
<span className="statusSpan" style={{ marginBottom: "0px" }}>
|
||||||
{" "}
|
{" "}
|
||||||
{data.Name}
|
{data.Name}
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<strong style={{ fontSize: "13px" }}>Status: </strong>
|
<strong className="text-[13px]">Status: </strong>
|
||||||
<span className="statusSpan"> {status}</span>
|
<span className="statusSpan"> {status}</span>
|
||||||
<br />
|
<br />
|
||||||
<strong style={{ fontSize: "13px" }}>Created Date: </strong>
|
<strong className="text-[13px]">Created Date: </strong>
|
||||||
<span className="statusSpan">{createddate}</span>
|
<span className="statusSpan">{createddate}</span>
|
||||||
<br />
|
<br />
|
||||||
{signerExist && (
|
{signerExist && (
|
||||||
<>
|
<>
|
||||||
<strong style={{ fontSize: "13px" }}>Signers: </strong>
|
<strong className="text-[13px]">Signers: </strong>
|
||||||
{/* <span className="statusSpan">kjefjjnejkfnkbjs bbfjkdsbjbfjkbjk kscbjkbjkb</span> */}
|
{/* <span className="statusSpan">kjefjjnejkfnkbjs bbfjkdsbjbfjkbjk kscbjkbjkb</span> */}
|
||||||
{signersName()}
|
{signersName()}
|
||||||
</>
|
</>
|
||||||
@@ -587,13 +548,9 @@ function DriveBody(props) {
|
|||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="pdfContainer">
|
<div className="flex flex-row flex-wrap items-center mt-1 pb-[20px] mx-[5px]">
|
||||||
{props.pdfData.map((data, ind) => {
|
{props.pdfData.map((data, ind) => {
|
||||||
return (
|
return <div key={ind}>{handleFolderData(data, ind, "list")}</div>;
|
||||||
<div className="box" key={ind}>
|
|
||||||
{handleFolderData(data, ind, "list")}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -609,44 +566,23 @@ function DriveBody(props) {
|
|||||||
)}
|
)}
|
||||||
<ModalUi
|
<ModalUi
|
||||||
isOpen={isDeleteDoc}
|
isOpen={isDeleteDoc}
|
||||||
headerColor={themeColor}
|
|
||||||
title={"Delete Document"}
|
title={"Delete Document"}
|
||||||
handleClose={() => {
|
handleClose={() => setIsDeleteDoc(false)}
|
||||||
setIsDeleteDoc(false);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-full p-[20px] text-base-content">
|
||||||
<p>Are you sure you want to delete this document?</p>
|
<p>Are you sure you want to delete this document?</p>
|
||||||
|
<div className="h-[1px] w-full bg-[#9f9f9f] my-[15px]"></div>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => handleDeleteDocument(selectDoc)}
|
||||||
handleDeleteDocument(selectDoc);
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn"
|
className="op-btn op-btn-primary mr-2"
|
||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => setIsDeleteDoc(false)}
|
||||||
setIsDeleteDoc(false);
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-neutral"
|
||||||
>
|
>
|
||||||
No
|
No
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -8,11 +8,8 @@ const AddRoleModal = (props) => {
|
|||||||
isOpen={props.isModalRole}
|
isOpen={props.isModalRole}
|
||||||
handleClose={props.handleCloseRoleModal}
|
handleClose={props.handleCloseRoleModal}
|
||||||
>
|
>
|
||||||
<div className="addusercontainer">
|
<div className="h-full py-[10px] px-[20px]">
|
||||||
<form
|
<form className="flex flex-col" onSubmit={props.handleAddRole}>
|
||||||
style={{ display: "flex", flexDirection: "column" }}
|
|
||||||
onSubmit={props.handleAddRole}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
value={props.roleName}
|
value={props.roleName}
|
||||||
onChange={(e) => props.setRoleName(e.target.value)}
|
onChange={(e) => props.setRoleName(e.target.value)}
|
||||||
@@ -21,39 +18,20 @@ const AddRoleModal = (props) => {
|
|||||||
? "User " + (props.signersdata.length + 1)
|
? "User " + (props.signersdata.length + 1)
|
||||||
: "User 1"
|
: "User 1"
|
||||||
}
|
}
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs mt-1"
|
||||||
/>
|
/>
|
||||||
<p
|
<p className="text-[gray] text-[11px] mt-[5px] mb-[10px] ml-[10px]">
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
fontSize: 11,
|
|
||||||
margin: "10px 0 10px 5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
e.g: Customer, Hr, Director, Manager, Student, etc...
|
e.g: Customer, Hr, Director, Manager, Student, etc...
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div className="h-[1px] w-full bg-[#9f9f9f] mb-[10px]"></div>
|
||||||
style={{
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
style={{
|
|
||||||
background: "#00a2b7"
|
|
||||||
}}
|
|
||||||
className="finishBtn"
|
|
||||||
>
|
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={props.handleCloseRoleModal}
|
onClick={props.handleCloseRoleModal}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-ghost ml-2"
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
function DefaultSignature({ defaultSignImg, xyPostion, setDefaultSignAlert }) {
|
function DefaultSignature({ defaultSignImg, xyPostion, setDefaultSignAlert }) {
|
||||||
const confirmToaddDefaultSign = () => {
|
const confirmToaddDefaultSign = () => {
|
||||||
if (xyPostion.length > 0) {
|
if (xyPostion.length > 0) {
|
||||||
@@ -17,55 +16,26 @@ function DefaultSignature({ defaultSignImg, xyPostion, setDefaultSignAlert }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div data-tut="reactourThird">
|
||||||
<div
|
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white",
|
|
||||||
padding: "5px",
|
|
||||||
fontFamily: "sans-serif",
|
|
||||||
marginTop: "5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Signature
|
Signature
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="flex flex-col items-center mt-[10px] font-semibold">
|
||||||
style={{
|
<p className="text-base-content">Your Signature</p>
|
||||||
display: "flex",
|
<div className="op-card shadow-md h-[111px] w-[90%] p-2">
|
||||||
flexDirection: "column",
|
<img
|
||||||
alignItems: "center",
|
alt="signature"
|
||||||
marginTop: "10px",
|
className="w-full h-full object-contain"
|
||||||
fontWeight: "600"
|
src={defaultSignImg}
|
||||||
}}
|
/>
|
||||||
>
|
</div>
|
||||||
<>
|
<button
|
||||||
<p>Your Signature</p>
|
type="button"
|
||||||
<div className="defaultSignBox">
|
className="op-btn op-btn-primary op-btn-sm mt-[10px]"
|
||||||
<img
|
onClick={() => confirmToaddDefaultSign()}
|
||||||
alt="default img"
|
>
|
||||||
style={{
|
Auto Sign All
|
||||||
width: "100%",
|
</button>
|
||||||
height: "100%",
|
|
||||||
objectFit: "contain"
|
|
||||||
}}
|
|
||||||
src={defaultSignImg}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white",
|
|
||||||
marginTop: "20px",
|
|
||||||
cursor: "pointer",
|
|
||||||
marginBottom: "10px"
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="finishBtn finishnHover"
|
|
||||||
onClick={() => confirmToaddDefaultSign()}
|
|
||||||
>
|
|
||||||
Auto Sign All
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Loader from "../../primitives/LoaderWithMsg";
|
import LoaderWithMsg from "../../primitives/LoaderWithMsg";
|
||||||
import { contractDocument } from "../../constant/Utils";
|
import { contractDocument } from "../../constant/Utils";
|
||||||
import HandleError from "../../primitives/HandleError";
|
import HandleError from "../../primitives/HandleError";
|
||||||
function DraftDocument() {
|
function DraftDocument() {
|
||||||
@@ -86,7 +86,7 @@ function DraftDocument() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{isLoading.isLoader ? (
|
{isLoading.isLoader ? (
|
||||||
<Loader isLoading={isLoading} />
|
<LoaderWithMsg isLoading={isLoading} />
|
||||||
) : (
|
) : (
|
||||||
<HandleError handleError={isLoading.message} />
|
<HandleError handleError={isLoading.message} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { isEnableSubscription, themeColor } from "../../constant/const";
|
import { isEnableSubscription } from "../../constant/const";
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import { radioButtonWidget } from "../../constant/Utils";
|
import { radioButtonWidget } from "../../constant/Utils";
|
||||||
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
||||||
@@ -147,7 +147,7 @@ function DropdownWidgetOption(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalUi isOpen={props.showDropdown} title={props.title} showClose={false}>
|
<ModalUi isOpen={props.showDropdown} title={props.title} showClose={false}>
|
||||||
<div className="h-full p-[15px]">
|
<div className="h-full p-[15px] text-base-content">
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -155,38 +155,25 @@ function DropdownWidgetOption(props) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<label style={{ fontSize: "13px", fontWeight: "600" }}>
|
<label className="text-[13px] font-semibold">
|
||||||
Name<span style={{ color: "red", fontSize: 13 }}> *</span>
|
Name<span className="text-[red] text-[13px]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
required
|
required
|
||||||
defaultValue={dropdownName}
|
defaultValue={dropdownName}
|
||||||
value={dropdownName}
|
value={dropdownName}
|
||||||
onChange={(e) => setDropdownName(e.target.value)}
|
onChange={(e) => setDropdownName(e.target.value)}
|
||||||
className="drodown-input"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<label
|
<label className="text-[13px] font-semibold mt-[5px]">
|
||||||
style={{ fontSize: "13px", fontWeight: "600", marginTop: "5px" }}
|
|
||||||
>
|
|
||||||
Options
|
Options
|
||||||
</label>
|
</label>
|
||||||
|
<div className="flex flex-col">
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{dropdownOptionList.map((option, index) => (
|
{dropdownOptionList.map((option, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
style={{
|
className="flex flex-row mb-[5px] items-center"
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
marginBottom: "5px",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{props.type === "checkbox" && !props.isSignYourself && (
|
{props.type === "checkbox" && !props.isSignYourself && (
|
||||||
<input
|
<input
|
||||||
@@ -206,51 +193,34 @@ function DropdownWidgetOption(props) {
|
|||||||
setDefaultCheckbox(removeOption);
|
setDefaultCheckbox(removeOption);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{
|
className="op-checkbox focus:outline-none hover:border-base-content mr-[5px]"
|
||||||
width: "23px",
|
|
||||||
height: "19px",
|
|
||||||
marginRight: "5px"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<input
|
<input
|
||||||
required
|
required
|
||||||
className="drodown-input"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
type="text"
|
type="text"
|
||||||
value={option}
|
value={option}
|
||||||
onChange={(e) => handleInputChange(index, e.target.value)}
|
onChange={(e) => handleInputChange(index, e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<i
|
<i
|
||||||
className="fa-solid fa-rectangle-xmark"
|
className="fa-solid fa-rectangle-xmark text-[25px] ml-[10px] text-error"
|
||||||
onClick={() => handleDeleteInput(index)}
|
onClick={() => handleDeleteInput(index)}
|
||||||
style={{
|
|
||||||
color: "red",
|
|
||||||
fontSize: "25px",
|
|
||||||
marginLeft: "10px"
|
|
||||||
}}
|
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
<i
|
<i
|
||||||
onClick={handleAddInput}
|
onClick={handleAddInput}
|
||||||
style={{
|
className="fa-solid fa-square-plus text-[25px] ml-[10px] text-primary"
|
||||||
cursor: "pointer",
|
|
||||||
color: themeColor,
|
|
||||||
fontSize: "25px",
|
|
||||||
marginLeft: "10px"
|
|
||||||
}}
|
|
||||||
className="fa-solid fa-square-plus"
|
|
||||||
></i>
|
></i>
|
||||||
<div>
|
<div>
|
||||||
{props.type === "checkbox" && !props.isSignYourself && (
|
{props.type === "checkbox" && !props.isSignYourself && (
|
||||||
<>
|
<>
|
||||||
<label
|
<label
|
||||||
style={{
|
className={`${
|
||||||
fontSize: "13px",
|
!props.isSubscribe ? "text-[gray]" : ""
|
||||||
fontWeight: "600",
|
} text-[13px] font-semibold`}
|
||||||
color: !props.isSubscribe && "gray"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Minimun check
|
Minimun check
|
||||||
</label>
|
</label>
|
||||||
@@ -263,18 +233,16 @@ function DropdownWidgetOption(props) {
|
|||||||
const count = handleSetMinMax(e);
|
const count = handleSetMinMax(e);
|
||||||
setMinCount(count);
|
setMinCount(count);
|
||||||
}}
|
}}
|
||||||
className={
|
className={`${
|
||||||
props.isSubscribe || !isEnableSubscription
|
props.isSubscribe || !isEnableSubscription
|
||||||
? "drodown-input"
|
? ""
|
||||||
: "disabled drodown-input"
|
: "pointer-events-none bg-opacity-50"
|
||||||
}
|
} op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs`}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
style={{
|
className={`${
|
||||||
fontSize: "13px",
|
!props.isSubscribe ? "text-[gray]" : ""
|
||||||
fontWeight: "600",
|
} text-[13px] font-semibold`}
|
||||||
color: !props.isSubscribe && "gray"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Maximum check
|
Maximum check
|
||||||
</label>
|
</label>
|
||||||
@@ -286,11 +254,11 @@ function DropdownWidgetOption(props) {
|
|||||||
const count = handleSetMinMax(e);
|
const count = handleSetMinMax(e);
|
||||||
setMaxCount(count);
|
setMaxCount(count);
|
||||||
}}
|
}}
|
||||||
className={
|
className={`${
|
||||||
props.isSubscribe || !isEnableSubscription
|
props.isSubscribe || !isEnableSubscription
|
||||||
? "drodown-input"
|
? ""
|
||||||
: "disabled drodown-input"
|
: "pointer-events-none bg-opacity-50"
|
||||||
}
|
} op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs`}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -298,32 +266,22 @@ function DropdownWidgetOption(props) {
|
|||||||
</div>
|
</div>
|
||||||
{["dropdown", radioButtonWidget].includes(props.type) && (
|
{["dropdown", radioButtonWidget].includes(props.type) && (
|
||||||
<>
|
<>
|
||||||
<label
|
<label className="text-[13px] font-semibold mt-[5px]">
|
||||||
style={{
|
|
||||||
fontSize: "13px",
|
|
||||||
fontWeight: "600",
|
|
||||||
marginTop: "5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Default value
|
Default value
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
onChange={(e) => setDefaultValue(e.target.value)}
|
onChange={(e) => setDefaultValue(e.target.value)}
|
||||||
className="drodown-input"
|
className="op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
name="defaultvalue"
|
name="defaultvalue"
|
||||||
value={defaultValue}
|
value={defaultValue}
|
||||||
placeholder="select default value"
|
placeholder="select default value"
|
||||||
>
|
>
|
||||||
<option value="" disabled hidden style={{ fontSize: "13px" }}>
|
<option value="" disabled hidden className="text-[13px]">
|
||||||
Select...
|
Select...
|
||||||
</option>
|
</option>
|
||||||
{dropdownOptionList.map((data, ind) => {
|
{dropdownOptionList.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<option
|
<option className="text-[13px]" key={ind} value={data}>
|
||||||
style={{ fontSize: "13px" }}
|
|
||||||
key={ind}
|
|
||||||
value={data}
|
|
||||||
>
|
|
||||||
{data}
|
{data}
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
@@ -333,35 +291,21 @@ function DropdownWidgetOption(props) {
|
|||||||
)}
|
)}
|
||||||
{props.type !== "checkbox" && props.type !== radioButtonWidget && (
|
{props.type !== "checkbox" && props.type !== radioButtonWidget && (
|
||||||
<>
|
<>
|
||||||
<div
|
<div className="flex flex-row gap-[10px] mt-[0.5rem]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
gap: 10,
|
|
||||||
marginTop: "0.5rem"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{statusArr.map((data, ind) => {
|
{statusArr.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={ind}
|
key={ind}
|
||||||
style={{
|
className="flex flex-row gap-[5px] items-center"
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
gap: 5,
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
style={{ accentColor: "red" }}
|
className="op-radio op-radio-xs my-1"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="status"
|
name="status"
|
||||||
onChange={() => setStatus(data.toLowerCase())}
|
onChange={() => setStatus(data.toLowerCase())}
|
||||||
checked={status.toLowerCase() === data.toLowerCase()}
|
checked={status.toLowerCase() === data.toLowerCase()}
|
||||||
/>
|
/>
|
||||||
<div style={{ fontSize: "13px", fontWeight: "500" }}>
|
<div className="text-[13px] font-500">{data}</div>
|
||||||
{data}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -369,33 +313,31 @@ function DropdownWidgetOption(props) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{["checkbox", radioButtonWidget].includes(props.type) && (
|
{["checkbox", radioButtonWidget].includes(props.type) && (
|
||||||
<div className="flex flex-row gap-5 mt-2 items-center text-center">
|
<div className="flex flex-row gap-5 my-2 items-center text-center">
|
||||||
{!props.isSignYourself && (
|
{!props.isSignYourself && (
|
||||||
<div>
|
<div className="flex items-center">
|
||||||
<input
|
<input
|
||||||
id="isreadonly"
|
id="isreadonly"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={isReadOnly}
|
checked={isReadOnly}
|
||||||
onChange={(e) => {
|
className="op-checkbox op-checkbox-sm"
|
||||||
setIsReadOnly(e.target.checked);
|
onChange={(e) => setIsReadOnly(e.target.checked)}
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<label className="ml-1" htmlFor="isreadonly">
|
<label className="ml-1 mb-0" htmlFor="isreadonly">
|
||||||
Is read only
|
Is read only
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div className="flex items-center">
|
||||||
<input
|
<input
|
||||||
id="ishidelabel"
|
id="ishidelabel"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={isHideLabel}
|
checked={isHideLabel}
|
||||||
onChange={(e) => {
|
className="op-checkbox op-checkbox-sm"
|
||||||
setIsHideLabel(e.target.checked);
|
onChange={(e) => setIsHideLabel(e.target.checked)}
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<label className="ml-1" htmlFor="ishidelabel">
|
<label className="ml-1 mb-0" htmlFor="ishidelabel">
|
||||||
Hide labels
|
Hide labels
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -421,19 +363,15 @@ function DropdownWidgetOption(props) {
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
disabled={dropdownOptionList.length === 0 && true}
|
disabled={dropdownOptionList.length === 0 && true}
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
type="submit"
|
type="submit"
|
||||||
className={"finishBtn"}
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
{props.currWidgetsDetails?.options?.values?.length > 0 && (
|
{props.currWidgetsDetails?.options?.values?.length > 0 && (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-ghost ml-1"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.handleClose && props.handleClose();
|
props.handleClose && props.handleClose();
|
||||||
resetState();
|
resetState();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import "../../styles/AddUser.css";
|
import { checkIsSubscribed, getFileName } from "../../constant/Utils";
|
||||||
import { getFileName } from "../../constant/Utils";
|
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
||||||
|
import Upgrade from "../../primitives/Upgrade";
|
||||||
|
import { isEnableSubscription } from "../../constant/const";
|
||||||
// import SelectFolder from "../../premitives/SelectFolder";
|
// import SelectFolder from "../../premitives/SelectFolder";
|
||||||
|
|
||||||
const EditTemplate = ({ template, onSuccess }) => {
|
const EditTemplate = ({ template, onSuccess }) => {
|
||||||
@@ -9,9 +11,21 @@ const EditTemplate = ({ template, onSuccess }) => {
|
|||||||
Name: template?.Name || "",
|
Name: template?.Name || "",
|
||||||
Note: template?.Note || "",
|
Note: template?.Note || "",
|
||||||
Description: template?.Description || "",
|
Description: template?.Description || "",
|
||||||
SendinOrder: template?.SendinOrder ? `${template?.SendinOrder}` : "false"
|
SendinOrder: template?.SendinOrder ? `${template?.SendinOrder}` : "false",
|
||||||
|
AutomaticReminders: template?.AutomaticReminders || false,
|
||||||
|
RemindOnceInEvery: template?.RemindOnceInEvery || 5
|
||||||
});
|
});
|
||||||
|
const [isSubscribe, setIsSubscribe] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
fetchSubscription();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
const fetchSubscription = async () => {
|
||||||
|
if (isEnableSubscription) {
|
||||||
|
const getIsSubscribe = await checkIsSubscribed();
|
||||||
|
setIsSubscribe(getIsSubscribe);
|
||||||
|
}
|
||||||
|
};
|
||||||
const handleStrInput = (e) => {
|
const handleStrInput = (e) => {
|
||||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
};
|
};
|
||||||
@@ -25,34 +39,40 @@ const EditTemplate = ({ template, onSuccess }) => {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const isChecked = formData.SendinOrder === "true" ? true : false;
|
const isChecked = formData.SendinOrder === "true" ? true : false;
|
||||||
const data = { ...formData, SendinOrder: isChecked };
|
const AutoReminder = formData?.AutomaticReminders || false;
|
||||||
|
|
||||||
|
let reminderDate = {};
|
||||||
|
if (AutoReminder) {
|
||||||
|
const RemindOnceInEvery = parseInt(formData?.RemindOnceInEvery);
|
||||||
|
const ReminderDate = new Date(template?.createdAt);
|
||||||
|
ReminderDate.setDate(ReminderDate.getDate() + RemindOnceInEvery);
|
||||||
|
reminderDate = { NextReminderDate: ReminderDate };
|
||||||
|
}
|
||||||
|
const data = { ...formData, SendinOrder: isChecked, ...reminderDate };
|
||||||
onSuccess(data);
|
onSuccess(data);
|
||||||
};
|
};
|
||||||
|
const handleAutoReminder = () => {
|
||||||
|
setFormData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
AutomaticReminders: !formData.AutomaticReminders
|
||||||
|
}));
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="addusercontainer">
|
<div className="max-h-[300px] md:max-h-[400px] overflow-y-scroll p-[10px]">
|
||||||
<div className="form-wrapper">
|
<div className="text-base-content">
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="name" style={{ fontSize: 13 }}>
|
<label htmlFor="name" className="text-[13px]">
|
||||||
File
|
File
|
||||||
</label>
|
</label>
|
||||||
<div
|
<div className="op-input op-input-bordered op-input-sm focus:outline-none py-2 font-semibold w-full text-xs">
|
||||||
style={{
|
|
||||||
padding: "0.5rem 0.75rem",
|
|
||||||
border: "1px solid #d1d5db",
|
|
||||||
borderRadius: "0.375rem",
|
|
||||||
fontSize: "0.75rem",
|
|
||||||
fontWeight: "700"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{getFileName(template.URL)}
|
{getFileName(template.URL)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<label htmlFor="name" style={{ fontSize: 13 }}>
|
<label htmlFor="name" className="text-[13px]">
|
||||||
Name
|
Name
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[13px] text-[red]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -60,11 +80,11 @@ const EditTemplate = ({ template, onSuccess }) => {
|
|||||||
value={formData.Name}
|
value={formData.Name}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
required
|
required
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<label htmlFor="Note" style={{ fontSize: 13 }}>
|
<label htmlFor="Note" className="text-[13px]">
|
||||||
Note
|
Note
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -73,11 +93,11 @@ const EditTemplate = ({ template, onSuccess }) => {
|
|||||||
id="Note"
|
id="Note"
|
||||||
value={formData.Note}
|
value={formData.Note}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<label htmlFor="Description" style={{ fontSize: 13 }}>
|
<label htmlFor="Description" className="text-[13px]">
|
||||||
Description
|
Description
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -86,51 +106,85 @@ const EditTemplate = ({ template, onSuccess }) => {
|
|||||||
id="Description"
|
id="Description"
|
||||||
value={formData.Description}
|
value={formData.Description}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<label style={{ fontSize: 13 }}>Send In Order</label>
|
<label className="text-[13px]">Send In Order</label>
|
||||||
<div
|
<div className="flex items-center gap-[8px] ml-[8px] mb-[5px]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 8,
|
|
||||||
marginLeft: 8,
|
|
||||||
marginBottom: 5
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
value={"true"}
|
value={"true"}
|
||||||
|
className="op-radio op-radio-xs"
|
||||||
name="SendinOrder"
|
name="SendinOrder"
|
||||||
checked={formData.SendinOrder === "true"}
|
checked={formData.SendinOrder === "true"}
|
||||||
onChange={handleStrInput}
|
onChange={handleStrInput}
|
||||||
/>
|
/>
|
||||||
<div style={{ fontSize: 12 }}>Yes</div>
|
<div className="text-[12px]">Yes</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="flex items-center gap-[8px] ml-[8px] mb-[5px]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 8,
|
|
||||||
marginLeft: 8,
|
|
||||||
marginBottom: 5
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
value={"false"}
|
value={"false"}
|
||||||
name="SendinOrder"
|
name="SendinOrder"
|
||||||
|
className="op-radio op-radio-xs"
|
||||||
checked={formData.SendinOrder === "false"}
|
checked={formData.SendinOrder === "false"}
|
||||||
onChange={handleStrInput}
|
onChange={handleStrInput}
|
||||||
/>
|
/>
|
||||||
<div style={{ fontSize: 12 }}>No</div>
|
<div className="text-[12px]">No</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <SelectFolder onSuccess={handleFolder} folderCls={"contracts_Template"} /> */}
|
<div className="text-xs mt-2">
|
||||||
<div className="buttoncontainer">
|
{!isEnableSubscription && (
|
||||||
<button type="submit" className="submitbutton">
|
<PremiumAlertHeader
|
||||||
|
message={
|
||||||
|
"Disable Auto reminder is free in beta, this feature will incur a fee later."
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
isSubscribe || !isEnableSubscription
|
||||||
|
? "font-semibold"
|
||||||
|
: "font-semibold text-gray-300"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Auto reminder{" "}
|
||||||
|
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
||||||
|
</span>
|
||||||
|
<label
|
||||||
|
className={`${
|
||||||
|
isSubscribe || !isEnableSubscription
|
||||||
|
? "cursor-pointer "
|
||||||
|
: "pointer-events-none opacity-50"
|
||||||
|
} relative block items-center mb-0`}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked={formData.AutomaticReminders}
|
||||||
|
onChange={handleAutoReminder}
|
||||||
|
type="checkbox"
|
||||||
|
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white mt-2"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{isSubscribe && formData?.AutomaticReminders === true && (
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">
|
||||||
|
Remind once in every (Days)
|
||||||
|
<span className="text-red-500 text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={formData.RemindOnceInEvery}
|
||||||
|
name="RemindOnceInEvery"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
onChange={handleStrInput}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="mt-[1rem] flex justify-start">
|
||||||
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,52 +1,42 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Tooltip from "../../primitives/Tooltip";
|
import Tooltip from "../../primitives/Tooltip";
|
||||||
|
|
||||||
import ReactQuill from "react-quill";
|
import ReactQuill from "react-quill";
|
||||||
import "react-quill/dist/quill.snow.css";
|
import "react-quill/dist/quill.snow.css";
|
||||||
import EditorToolbar, { module1, formats } from "./EditorToolbar";
|
import EditorToolbar, { module1, formats } from "./EditorToolbar";
|
||||||
|
|
||||||
export function EmailBody(props) {
|
export function EmailBody(props) {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<form className="flex flex-col text-base-content text-lg font-normal">
|
||||||
<div className={`flex justify-center py-1 p-2`}>
|
<div className="m-2 md:m-10 p-3 md:p-10 shadow-md hover:shadow-lg border-[1px] border-indigo-800 rounded-md">
|
||||||
<div className=" flex flex-col">
|
<label className="text-sm ml-2">
|
||||||
<form>
|
Subject <Tooltip message={"email subject"} />
|
||||||
<div className="text-lg font-normal text-black">
|
</label>
|
||||||
<div className=" m-2 md:m-10 p-3 md:p-10 shadow-md hover:shadow-lg border-[1px] border-indigo-800 rounded-md">
|
<input
|
||||||
<label className="text-sm ml-2">
|
required
|
||||||
Subject <Tooltip message={"email subject"} />
|
value={props.requestSubject}
|
||||||
</label>
|
onChange={(e) => props.setRequestSubject(e.target.value)}
|
||||||
<input
|
placeholder='${senderName} has requested you to sign "${documentName}"'
|
||||||
required
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={props.requestSubject}
|
/>
|
||||||
onChange={(e) => props.setRequestSubject(e.target.value)}
|
<label className="text-sm ml-2 mt-3">
|
||||||
placeholder='${senderName} has requested you to sign "${documentName}"'
|
Body <Tooltip message={"email body"} />
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
</label>
|
||||||
/>
|
<div className="px-3 py-2 w-full focus:outline-none text-xs">
|
||||||
<label className="text-sm ml-2 mt-3">
|
<EditorToolbar containerId="toolbar1" />
|
||||||
Body <Tooltip message={"email body"} />
|
<ReactQuill
|
||||||
</label>
|
theme="snow"
|
||||||
|
value={props.requestBody}
|
||||||
<div className="px-3 py-2 w-full focus:outline-none text-xs">
|
// value={typedText}
|
||||||
<EditorToolbar containerId="toolbar1" />
|
placeholder="add body of email "
|
||||||
<ReactQuill
|
// readOnly={loading}
|
||||||
theme="snow"
|
// onChangeSelection={handleTextSelection} // Listen for text selection
|
||||||
value={props.requestBody}
|
ref={props.editorRef}
|
||||||
// value={typedText}
|
modules={module1}
|
||||||
placeholder="add body of email "
|
formats={formats}
|
||||||
// readOnly={loading}
|
onChange={props.handleOnchangeRequest}
|
||||||
// onChangeSelection={handleTextSelection} // Listen for text selection
|
/>
|
||||||
ref={props.editorRef}
|
|
||||||
modules={module1}
|
|
||||||
formats={formats}
|
|
||||||
onChange={props.handleOnchangeRequest}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ import axios from "axios";
|
|||||||
import { getBase64FromUrl } from "../../constant/Utils";
|
import { getBase64FromUrl } from "../../constant/Utils";
|
||||||
import { themeColor } from "../../constant/const";
|
import { themeColor } from "../../constant/const";
|
||||||
import printModule from "print-js";
|
import printModule from "print-js";
|
||||||
import loader from "../../assets/images/loader2.gif";
|
import Loader from "../../primitives/Loader";
|
||||||
|
|
||||||
function EmailComponent({
|
function EmailComponent({
|
||||||
isEmail,
|
isEmail,
|
||||||
pdfUrl,
|
pdfUrl,
|
||||||
isCeleb,
|
|
||||||
setIsEmail,
|
setIsEmail,
|
||||||
setSuccessEmail,
|
setSuccessEmail,
|
||||||
pdfName,
|
pdfName,
|
||||||
@@ -22,6 +21,7 @@ function EmailComponent({
|
|||||||
const [emailList, setEmailList] = useState([]);
|
const [emailList, setEmailList] = useState([]);
|
||||||
const [emailValue, setEmailValue] = useState();
|
const [emailValue, setEmailValue] = useState();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [isEmailCelebration, setIsEmailCelebration] = useState(false);
|
||||||
//function for send email
|
//function for send email
|
||||||
const sendEmail = async () => {
|
const sendEmail = async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
@@ -62,6 +62,10 @@ function EmailComponent({
|
|||||||
" target=_blank>here</a> </p></div></div></body></html>"
|
" target=_blank>here</a> </p></div></div></body></html>"
|
||||||
};
|
};
|
||||||
sendMail = await axios.post(url, params, { headers: headers });
|
sendMail = await axios.post(url, params, { headers: headers });
|
||||||
|
setIsEmailCelebration(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsEmailCelebration(false);
|
||||||
|
}, 3000);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error", error);
|
console.log("error", error);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -169,148 +173,59 @@ function EmailComponent({
|
|||||||
<div className="modaloverlay">
|
<div className="modaloverlay">
|
||||||
<div className="modalcontainer">
|
<div className="modalcontainer">
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
<div
|
<div className="absolute w-full h-full flex flex-col justify-center items-center z-[20] bg-[#e6f2f2] bg-opacity-80">
|
||||||
style={{
|
<Loader />
|
||||||
position: "absolute",
|
<span className="text-[12px] font-bold">
|
||||||
height: "100%",
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center",
|
|
||||||
zIndex: "20",
|
|
||||||
backgroundColor: "#e6f2f2",
|
|
||||||
opacity: 0.8
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="no img"
|
|
||||||
src={loader}
|
|
||||||
style={{ width: "70px", height: "70px" }}
|
|
||||||
/>
|
|
||||||
<span style={{ fontSize: "12px", fontWeight: "bold" }}>
|
|
||||||
This might take some time
|
This might take some time
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div style={{ background: "#32a3ac" }} className="modalheader">
|
<div style={{ background: "#32a3ac" }} className="modalheader">
|
||||||
<span style={{ color: "white" }}>Successfully signed!</span>
|
<span className="text-white">Successfully signed!</span>
|
||||||
|
<div className="flex flex-row">
|
||||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
|
||||||
<div></div>
|
<div></div>
|
||||||
{!isAndroid && (
|
{!isAndroid && (
|
||||||
<button
|
<button
|
||||||
onClick={handleToPrint}
|
onClick={handleToPrint}
|
||||||
style={{
|
className="op-btn op-btn-neutral op-btn-sm text-[15px]"
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
className="btn btn-primary btn-sm"
|
|
||||||
>
|
>
|
||||||
<i
|
<i className="fa fa-print" aria-hidden="true"></i>
|
||||||
className="fa fa-print"
|
|
||||||
style={{
|
|
||||||
fontSize: "15px",
|
|
||||||
marginRight: "3px",
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
Print
|
Print
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="btn btn-danger btn-sm"
|
className="op-btn op-btn-primary op-btn-sm text-[15px] ml-2"
|
||||||
onClick={() => handleDownloadPdf()}
|
onClick={() => handleDownloadPdf()}
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center",
|
|
||||||
marginLeft: "10px"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<i
|
<i className="fa fa-download" aria-hidden="true"></i>
|
||||||
className="fa fa-download"
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
fontSize: "15px",
|
|
||||||
marginRight: "3px"
|
|
||||||
}}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
Download
|
Download
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-full p-[20px]">
|
||||||
{isCeleb && (
|
{isEmailCelebration && (
|
||||||
<div
|
<div className="absolute w-[100%] flex justify-center items-center">
|
||||||
style={{
|
<img alt="celeb" width={300} height={250} src={celebration} />
|
||||||
position: "absolute",
|
|
||||||
marginLeft: "50px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="print img"
|
|
||||||
width={300}
|
|
||||||
height={250}
|
|
||||||
// style={styles.gifCeleb}
|
|
||||||
src={celebration}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<p
|
<p className="font-medium text-[15px] mb-[5px] text-base-content align-baseline">
|
||||||
style={{
|
|
||||||
fontFamily: "system-ui",
|
|
||||||
verticalAlign: "baseline",
|
|
||||||
fontWeight: "500",
|
|
||||||
color: "#403f3e",
|
|
||||||
fontSize: "15px",
|
|
||||||
marginBottom: "5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Recipients added here will get a copy of the signed document.
|
Recipients added here will get a copy of the signed document.
|
||||||
</p>
|
</p>
|
||||||
{emailList.length > 0 ? (
|
{emailList.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
<div className="addEmail">
|
<div className="addEmail">
|
||||||
<div
|
<div className="flex flex-row flex-wrap">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
|
|
||||||
flexWrap: "wrap"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{emailList.map((data, ind) => {
|
{emailList.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="emailChip"
|
className="flex flex-row items-center bg-[#47a3ad] m-[4px] rounded-md py-[5px] px-[10px]"
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
key={ind}
|
key={ind}
|
||||||
>
|
>
|
||||||
<span
|
<span className="text-white text-[13px]">
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
fontSize: "13px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{data}
|
{data}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
style={{
|
className="text-white text-[13px] font-semibold ml-[7px] cursor-pointer"
|
||||||
color: "white",
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: 600,
|
|
||||||
marginLeft: 7,
|
|
||||||
cursor: "pointer"
|
|
||||||
}}
|
|
||||||
onClick={() => removeChip(ind)}
|
onClick={() => removeChip(ind)}
|
||||||
>
|
>
|
||||||
<i className="fa-solid fa-xmark"></i>
|
<i className="fa-solid fa-xmark"></i>
|
||||||
@@ -323,7 +238,7 @@ function EmailComponent({
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={emailValue}
|
value={emailValue}
|
||||||
className="addEmailInput"
|
className="p-[10px] pb-[20px] rounded w-full text-[15px] bg-white outline-none"
|
||||||
onChange={handleEmailValue}
|
onChange={handleEmailValue}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
@@ -341,7 +256,7 @@ function EmailComponent({
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={emailValue}
|
value={emailValue}
|
||||||
className="emailInput"
|
className="p-[10px] pb-[20px] rounded w-full text-[15px] outline-none bg-white border-2 border-[#47a3ad]"
|
||||||
onChange={handleEmailValue}
|
onChange={handleEmailValue}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
placeholder="Add the email addresses"
|
placeholder="Add the email addresses"
|
||||||
@@ -354,67 +269,36 @@ function EmailComponent({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<span
|
<button
|
||||||
style={{
|
className={`${
|
||||||
cursor: emailValue && "pointer"
|
emailValue ? "cursor-pointer" : "cursor-default"
|
||||||
}}
|
} op-btn op-btn-primary op-btn-sm m-2 shadow-md`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (emailValue) {
|
if (emailValue) {
|
||||||
handleEnterPress("add");
|
handleEnterPress("add");
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i
|
<i className="fa fa-plus" aria-hidden="true"></i>
|
||||||
style={{
|
</button>
|
||||||
backgroundColor: themeColor,
|
|
||||||
padding: "5px 7px",
|
|
||||||
marginTop: "10px",
|
|
||||||
color: "white",
|
|
||||||
borderRadius: "2px"
|
|
||||||
}}
|
|
||||||
className="fa fa-plus"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div
|
<div className="bg-[#e3e2e1] mt-[10px] p-[5px] rounded">
|
||||||
style={{
|
<span className="font-bold">Note: </span>
|
||||||
background: "#e3e2e1",
|
<span className="text-[15px]">
|
||||||
marginTop: "10px",
|
|
||||||
padding: "5px",
|
|
||||||
borderRadius: "3px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontWeight: "700" }}>Note:</span>
|
|
||||||
<span style={{ fontSize: "15px" }}>
|
|
||||||
{" "}
|
|
||||||
You can only send to ten recipients at a time.
|
You can only send to ten recipients at a time.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
<button
|
||||||
disabled={emailList.length === 0 && true}
|
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className={emailList.length === 0 ? "defaultBtn" : "finishBtn"}
|
className="op-btn op-btn-primary"
|
||||||
onClick={() => sendEmail()}
|
onClick={() => emailList.length > 0 && sendEmail()}
|
||||||
>
|
>
|
||||||
Send
|
Send
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-ghost ml-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsEmail(false);
|
setIsEmail(false);
|
||||||
setEmailValue("");
|
setEmailValue("");
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PrevNext from "./PrevNext";
|
import PrevNext from "./PrevNext";
|
||||||
import printModule from "print-js";
|
import {
|
||||||
import { getBase64FromUrl } from "../../constant/Utils";
|
handleDownloadCertificate,
|
||||||
import { saveAs } from "file-saver";
|
handleDownloadPdf,
|
||||||
|
handleToPrint
|
||||||
|
} from "../../constant/Utils";
|
||||||
import "../../styles/signature.css";
|
import "../../styles/signature.css";
|
||||||
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
import axios from "axios";
|
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import { appInfo } from "../../constant/appinfo";
|
import Loader from "../../primitives/Loader";
|
||||||
|
|
||||||
function Header({
|
function Header({
|
||||||
isPdfRequestFiles,
|
isPdfRequestFiles,
|
||||||
@@ -40,16 +40,9 @@ function Header({
|
|||||||
signerPos && signerPos?.filter((data) => data.Role !== "prefill");
|
signerPos && signerPos?.filter((data) => data.Role !== "prefill");
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [isCertificate, setIsCertificate] = useState(false);
|
const [isDownloading, setIsDownloading] = useState("");
|
||||||
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||||
//for go to previous page
|
|
||||||
function previousPage() {
|
|
||||||
changePage(-1);
|
|
||||||
}
|
|
||||||
//for go to next page
|
|
||||||
function nextPage() {
|
|
||||||
changePage(1);
|
|
||||||
}
|
|
||||||
//function for show decline alert
|
//function for show decline alert
|
||||||
const handleDeclinePdfAlert = async () => {
|
const handleDeclinePdfAlert = async () => {
|
||||||
const currentDecline = {
|
const currentDecline = {
|
||||||
@@ -59,123 +52,6 @@ function Header({
|
|||||||
setIsDecline(currentDecline);
|
setIsDecline(currentDecline);
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for print digital sign pdf
|
|
||||||
const handleToPrint = async (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
|
||||||
const axiosRes = await axios.post(
|
|
||||||
`${appInfo.baseUrl}/functions/getsignedurl`,
|
|
||||||
{ url: pdfUrl },
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"content-type": "Application/json",
|
|
||||||
"X-Parse-Application-Id": appInfo.appId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const url = axiosRes.data.result;
|
|
||||||
const pdf = await getBase64FromUrl(url);
|
|
||||||
const isAndroidDevice = navigator.userAgent.match(/Android/i);
|
|
||||||
const isAppleDevice =
|
|
||||||
(/iPad|iPhone|iPod/.test(navigator.platform) ||
|
|
||||||
(navigator.platform === "MacIntel" &&
|
|
||||||
navigator.maxTouchPoints > 1)) &&
|
|
||||||
!window.MSStream;
|
|
||||||
if (isAndroidDevice || isAppleDevice) {
|
|
||||||
const byteArray = Uint8Array.from(
|
|
||||||
atob(pdf)
|
|
||||||
.split("")
|
|
||||||
.map((char) => char.charCodeAt(0))
|
|
||||||
);
|
|
||||||
const blob = new Blob([byteArray], { type: "application/pdf" });
|
|
||||||
const blobUrl = URL.createObjectURL(blob);
|
|
||||||
window.open(blobUrl, "_blank");
|
|
||||||
} else {
|
|
||||||
printModule({ printable: pdf, type: "pdf", base64: true });
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log("err in getsignedurl", err);
|
|
||||||
alert("something went wrong, please try again later.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//handle download signed pdf
|
|
||||||
const handleDownloadPdf = async () => {
|
|
||||||
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
|
|
||||||
try {
|
|
||||||
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
|
||||||
const axiosRes = await axios.post(
|
|
||||||
`${appInfo.baseUrl}/functions/getsignedurl`,
|
|
||||||
{ url: pdfUrl },
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"content-type": "Application/json",
|
|
||||||
"X-Parse-Application-Id": appInfo.appId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const url = axiosRes.data.result;
|
|
||||||
saveAs(url, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
|
||||||
} catch (err) {
|
|
||||||
console.log("err in getsignedurl", err);
|
|
||||||
alert("something went wrong, please try again later.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const sanitizeFileName = (pdfName) => {
|
|
||||||
// Replace spaces with underscore
|
|
||||||
return pdfName.replace(/ /g, "_");
|
|
||||||
};
|
|
||||||
|
|
||||||
//handle download signed pdf
|
|
||||||
const handleDownloadCertificate = async () => {
|
|
||||||
if (pdfDetails?.length > 0 && pdfDetails[0]?.CertificateUrl) {
|
|
||||||
try {
|
|
||||||
await fetch(pdfDetails[0] && pdfDetails[0]?.CertificateUrl);
|
|
||||||
const certificateUrl = pdfDetails[0] && pdfDetails[0]?.CertificateUrl;
|
|
||||||
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
|
|
||||||
} catch (err) {
|
|
||||||
console.log("err in download in certificate", err);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setIsCertificate(true);
|
|
||||||
try {
|
|
||||||
const data = {
|
|
||||||
docId: pdfDetails[0]?.objectId
|
|
||||||
};
|
|
||||||
const docDetails = await axios.post(
|
|
||||||
`${localStorage.getItem("baseUrl")}functions/getDocument`,
|
|
||||||
data,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
||||||
sessionToken: localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (docDetails.data && docDetails.data.result) {
|
|
||||||
const doc = docDetails.data.result;
|
|
||||||
if (doc?.CertificateUrl) {
|
|
||||||
await fetch(doc?.CertificateUrl);
|
|
||||||
const certificateUrl = doc?.CertificateUrl;
|
|
||||||
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
|
|
||||||
setIsCertificate(false);
|
|
||||||
} else {
|
|
||||||
setIsCertificate(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log("err in download in certificate", err);
|
|
||||||
alert("something went wrong, please try again later.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: "5px 0px 5px 0px" }} className="mobileHead">
|
<div style={{ padding: "5px 0px 5px 0px" }} className="mobileHead">
|
||||||
{isMobile && isShowHeader ? (
|
{isMobile && isShowHeader ? (
|
||||||
@@ -188,56 +64,22 @@ function Header({
|
|||||||
: window.innerWidth - 30 + "px"
|
: window.innerWidth - 30 + "px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="preBtn2">
|
<div className="flex justify-between items-center py-[5px] px-[10px] ">
|
||||||
<div onClick={() => navigate(-1)}>
|
<div onClick={() => navigate(-1)}>
|
||||||
<i
|
<i
|
||||||
className="fa fa-arrow-left"
|
className="fa fa-arrow-left text-base-content"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{ color: themeColor, cursor: "pointer" }}
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<i
|
|
||||||
onClick={() => {
|
|
||||||
if (pageNumber > 1) {
|
|
||||||
previousPage();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="fa fa-backward"
|
|
||||||
style={{ color: "gray", cursor: "pointer" }}
|
|
||||||
></i>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: "13px",
|
|
||||||
fontWeight: "600",
|
|
||||||
marginLeft: "10px",
|
|
||||||
marginRight: "10px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
|
|
||||||
</span>
|
|
||||||
<i
|
|
||||||
onClick={() => {
|
|
||||||
if (pageNumber < allPages) {
|
|
||||||
nextPage();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="fa fa-forward"
|
|
||||||
style={{ color: "gray", cursor: "pointer" }}
|
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
|
<PrevNext
|
||||||
|
pageNumber={pageNumber}
|
||||||
|
allPages={allPages}
|
||||||
|
changePage={changePage}
|
||||||
|
/>
|
||||||
{pdfUrl && alreadySign ? (
|
{pdfUrl && alreadySign ? (
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger asChild>
|
<DropdownMenu.Trigger asChild>
|
||||||
<div
|
<div className="op-link op-link-primary no-underline text-[16px] font-semibold pr-[3px] pl-[5px]">
|
||||||
style={{
|
|
||||||
color: themeColor,
|
|
||||||
border: "none",
|
|
||||||
fontWeight: "650",
|
|
||||||
fontSize: "16px",
|
|
||||||
padding: "0px 3px 0px 5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i className="fa fa-ellipsis-v" aria-hidden="true"></i>
|
<i className="fa fa-ellipsis-v" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenu.Trigger>
|
</DropdownMenu.Trigger>
|
||||||
@@ -248,18 +90,14 @@ function Header({
|
|||||||
>
|
>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
className="DropdownMenuItem"
|
className="DropdownMenuItem"
|
||||||
onClick={() => handleDownloadPdf()}
|
onClick={() =>
|
||||||
|
handleDownloadPdf(pdfDetails, pdfUrl, setIsDownloading)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div className="flex flex-row">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
<i
|
||||||
className="fa fa-arrow-down"
|
className="fa fa-arrow-down mr-[2px]"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{ marginRight: "2px" }}
|
|
||||||
></i>
|
></i>
|
||||||
Download
|
Download
|
||||||
</div>
|
</div>
|
||||||
@@ -267,17 +105,16 @@ function Header({
|
|||||||
{isCompleted && (
|
{isCompleted && (
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
className="DropdownMenuItem"
|
className="DropdownMenuItem"
|
||||||
onClick={() => handleDownloadCertificate()}
|
onClick={() =>
|
||||||
|
handleDownloadCertificate(
|
||||||
|
pdfDetails,
|
||||||
|
setIsDownloading
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div className="border-none bg-[#fff]">
|
||||||
style={{
|
|
||||||
border: "none",
|
|
||||||
backgroundColor: "#fff"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
<i
|
||||||
className="fa-solid fa-award"
|
className="fa-solid fa-award mr-[2px]"
|
||||||
style={{ marginRight: "2px" }}
|
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
Certificate
|
Certificate
|
||||||
@@ -289,15 +126,9 @@ function Header({
|
|||||||
className="DropdownMenuItem"
|
className="DropdownMenuItem"
|
||||||
onClick={() => setIsEmail(true)}
|
onClick={() => setIsEmail(true)}
|
||||||
>
|
>
|
||||||
<div
|
<div className="flex flex-row">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
<i
|
||||||
className="fa fa-envelope"
|
className="fa fa-envelope mr-[2px]"
|
||||||
style={{ marginRight: "2px" }}
|
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
Mail
|
Mail
|
||||||
@@ -306,18 +137,14 @@ function Header({
|
|||||||
)}
|
)}
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
className="DropdownMenuItem"
|
className="DropdownMenuItem"
|
||||||
onClick={handleToPrint}
|
onClick={(e) =>
|
||||||
|
handleToPrint(e, pdfUrl, setIsDownloading)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div className="flex flex-row">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
<i
|
||||||
className="fa fa-print"
|
className="fa fa-print mr-[2px]"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{ marginRight: "2px" }}
|
|
||||||
></i>
|
></i>
|
||||||
Print
|
Print
|
||||||
</div>
|
</div>
|
||||||
@@ -326,24 +153,16 @@ function Header({
|
|||||||
</DropdownMenu.Portal>
|
</DropdownMenu.Portal>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ display: "flex", justifyContent: "space-around" }}>
|
<div className="flex justify-around items-center">
|
||||||
{/* current signer is checking user send request and check status of pdf sign than if current
|
{/* current signer is checking user send request and check status of pdf sign than if current
|
||||||
user exist than show finish button else no
|
user exist than show finish button else no
|
||||||
*/}
|
*/}
|
||||||
{currentSigner && (
|
{currentSigner && (
|
||||||
<>
|
<div className="flex items-center" data-tut="reactourFifth">
|
||||||
{decline && (
|
{decline && (
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => handleDeclinePdfAlert()}
|
||||||
handleDeclinePdfAlert();
|
className="text-[red] border-none font-[650] text-[14px] mr-2"
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
color: "red",
|
|
||||||
border: "none",
|
|
||||||
fontWeight: "650",
|
|
||||||
fontSize: "16px",
|
|
||||||
marginRight: "10px"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Decline
|
Decline
|
||||||
</div>
|
</div>
|
||||||
@@ -355,12 +174,9 @@ function Header({
|
|||||||
alertSendEmail();
|
alertSendEmail();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{
|
className={`${
|
||||||
color: isMailSend ? "gray" : themeColor,
|
isMailSend ? "" : "op-link-primary"
|
||||||
border: "none",
|
} op-link no-underline font-[650] text-[14px]`}
|
||||||
fontWeight: "650",
|
|
||||||
fontSize: "16px"
|
|
||||||
}}
|
|
||||||
data-tut={dataTut4}
|
data-tut={dataTut4}
|
||||||
>
|
>
|
||||||
{completeBtnTitle ? completeBtnTitle : "Send"}
|
{completeBtnTitle ? completeBtnTitle : "Send"}
|
||||||
@@ -375,17 +191,45 @@ function Header({
|
|||||||
embedWidgetsData();
|
embedWidgetsData();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{
|
className="border-none font-[650] text-[14px] op-link op-link-primary no-underline"
|
||||||
color: themeColor,
|
|
||||||
border: "none",
|
|
||||||
fontWeight: "650",
|
|
||||||
fontSize: "16px"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Finish
|
Finish
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
<DropdownMenu.Root>
|
||||||
|
<DropdownMenu.Trigger asChild>
|
||||||
|
<div className="font-[650] text-[18px] px-2 ml-[4px] op-link op-link-info no-underline">
|
||||||
|
<i
|
||||||
|
className="fa fa-ellipsis-v"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
</DropdownMenu.Trigger>
|
||||||
|
<DropdownMenu.Portal>
|
||||||
|
<DropdownMenu.Content
|
||||||
|
className="bg-white shadow-md rounded px-2 py-1"
|
||||||
|
sideOffset={5}
|
||||||
|
>
|
||||||
|
<DropdownMenu.Item
|
||||||
|
className="flex flex-row justify-center items-center text-[13px] focus:outline-none cursor-pointer"
|
||||||
|
onClick={() =>
|
||||||
|
handleDownloadPdf(
|
||||||
|
pdfDetails,
|
||||||
|
pdfUrl,
|
||||||
|
setIsDownloading
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-arrow-down mr-[5px]"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span className="font-[500]">Download</span>
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
</DropdownMenu.Content>
|
||||||
|
</DropdownMenu.Portal>
|
||||||
|
</DropdownMenu.Root>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -406,12 +250,12 @@ function Header({
|
|||||||
signersdata.length !== filterPrefill.length && (
|
signersdata.length !== filterPrefill.length && (
|
||||||
<div>
|
<div>
|
||||||
{filterPrefill.length === 0 ? (
|
{filterPrefill.length === 0 ? (
|
||||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
<span className="text-[13px] text-[#f5405e]">
|
||||||
Add {signersdata.length - filterPrefill.length}{" "}
|
Add {signersdata.length - filterPrefill.length}{" "}
|
||||||
recipients signature
|
recipients signature
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span style={{ fontSize: "13px", color: "#f5405e" }}>
|
<span className="text-[13px] text-[#f5405e]">
|
||||||
Add {signersdata.length - filterPrefill.length} more
|
Add {signersdata.length - filterPrefill.length} more
|
||||||
recipients signature
|
recipients signature
|
||||||
</span>
|
</span>
|
||||||
@@ -431,158 +275,175 @@ function Header({
|
|||||||
<button
|
<button
|
||||||
onClick={() => navigate(-1)}
|
onClick={() => navigate(-1)}
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[18px] text-black font-[500] text-sm mr-[5px] bg-white"
|
className="op-btn op-btn-ghost op-btn-sm mr-[5px]"
|
||||||
>
|
>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
disabled={isMailSend && true}
|
disabled={isMailSend && true}
|
||||||
data-tut="reactourFour"
|
data-tut="reactourFour"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[18px] font-[500] text-sm mr-[5px]"
|
className="op-btn op-btn-primary op-btn-sm mr-[5px]"
|
||||||
style={{
|
onClick={() => alertSendEmail()}
|
||||||
background: isMailSend ? "rgb(203, 203, 203)" : "#188ae2",
|
|
||||||
color: isMailSend ? "rgb(77, 75, 75)" : "white"
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
alertSendEmail();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{completeBtnTitle
|
{completeBtnTitle
|
||||||
? completeBtnTitle
|
? completeBtnTitle
|
||||||
: isMailSend
|
: isMailSend
|
||||||
? "Sent"
|
? "Sent"
|
||||||
: "Send"}
|
: "Send"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : isPdfRequestFiles ? (
|
) : isPdfRequestFiles ? (
|
||||||
alreadySign ? (
|
alreadySign ? (
|
||||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
<div className="flex flex-row">
|
||||||
{isCompleted && (
|
{isCompleted && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleDownloadCertificate()}
|
onClick={() =>
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#08bc66]"
|
handleDownloadCertificate(pdfDetails, setIsDownloading)
|
||||||
|
}
|
||||||
|
className="op-btn op-btn-secondary op-btn-sm mr-[5px] shadow"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className="fa-solid fa-award py-[3px]"
|
className="fa-solid fa-award py-[3px]"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
<span className="hidden lg:block ml-1">Certificate</span>
|
<span className="hidden lg:block">Certificate</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={handleToPrint}
|
onClick={(e) => handleToPrint(e, pdfUrl, setIsDownloading)}
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#188ae2]"
|
className="op-btn op-btn-neutral op-btn-sm mr-[5px] shadow"
|
||||||
>
|
>
|
||||||
<i className="fa fa-print py-[3px]" aria-hidden="true"></i>
|
<i className="fa fa-print py-[3px]" aria-hidden="true"></i>
|
||||||
<span className="hidden lg:block ml-1">Print</span>
|
<span className="hidden lg:block">Print</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#f14343]"
|
className="op-btn op-btn-primary op-btn-sm mr-[5px] shadow"
|
||||||
onClick={() => handleDownloadPdf()}
|
onClick={() =>
|
||||||
|
handleDownloadPdf(pdfDetails, pdfUrl, setIsDownloading)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<i className="fa fa-download py-[3px]" aria-hidden="true"></i>
|
<i className="fa fa-download py-[3px]" aria-hidden="true"></i>
|
||||||
<span className="hidden lg:block ml-1">Download</span>
|
<span className="hidden lg:block">Download</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex">
|
<div className="flex" data-tut="reactourFifth">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate(-1)}
|
onClick={() => navigate(-1)}
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[18px] text-black font-[500] text-sm mr-[5px] bg-white"
|
className="op-btn op-btn-ghost op-btn-sm mr-[5px]"
|
||||||
>
|
>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
{currentSigner && (
|
{currentSigner && (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
style={{ background: "#de4337" }}
|
className="op-btn op-btn-secondary op-btn-sm mr-[5px] shadow"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[18px] text-white font-[500] text-[13px] mr-[5px] bg-[#f14343]"
|
onClick={() => handleDeclinePdfAlert()}
|
||||||
onClick={() => {
|
|
||||||
handleDeclinePdfAlert();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Decline
|
Decline
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
style={{
|
|
||||||
background: "#188ae2"
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[18px] text-white font-[500] text-[13px] mr-[5px] bg-[#188ae2]"
|
className="op-btn op-btn-primary op-btn-sm mr-[5px] shadow"
|
||||||
onClick={() => {
|
onClick={() => embedWidgetsData()}
|
||||||
embedWidgetsData();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Finish
|
Finish
|
||||||
</button>
|
</button>
|
||||||
|
<div className="op-dropdown op-dropdown-end">
|
||||||
|
<div
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
className="op-btn op-btn-info op-btn-sm shadow"
|
||||||
|
>
|
||||||
|
<i className="fa fa-ellipsis-v" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
<ul
|
||||||
|
tabIndex={0}
|
||||||
|
className="op-dropdown-content z-[1] op-menu op-menu-sm p-1 shadow bg-base-100 rounded-box mt-1"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
onClick={() =>
|
||||||
|
handleDownloadPdf(
|
||||||
|
pdfDetails,
|
||||||
|
pdfUrl,
|
||||||
|
setIsDownloading
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className="font-semibold text-[12px]">
|
||||||
|
<i
|
||||||
|
className="fa fa-arrow-down"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>{" "}
|
||||||
|
Download
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
) : isCompleted ? (
|
) : isCompleted ? (
|
||||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
<div className="flex flex-row">
|
||||||
{isCompleted && (
|
{isCompleted && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleDownloadCertificate()}
|
onClick={() =>
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#08bc66]"
|
handleDownloadCertificate(pdfDetails, setIsDownloading)
|
||||||
|
}
|
||||||
|
className="op-btn op-btn-secondary op-btn-sm font-medium text-[13px] mr-[5px] shadow"
|
||||||
>
|
>
|
||||||
<i
|
<i className="fa-solid fa-award" aria-hidden="true"></i>
|
||||||
className="fa-solid fa-award py-[3px]"
|
<span className="hidden lg:block">Certificate</span>
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
<span className="hidden lg:block ml-1">Certificate</span>
|
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={handleToPrint}
|
onClick={(e) => handleToPrint(e, pdfUrl, setIsDownloading)}
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#188ae2]"
|
className="op-btn op-btn-neutral op-btn-sm font-medium text-[13px] mr-[5px] shadow"
|
||||||
>
|
>
|
||||||
<i className="fa fa-print py-[3px]" aria-hidden="true"></i>
|
<i className="fa fa-print" aria-hidden="true"></i>
|
||||||
<span className="hidden lg:block ml-1">Print</span>
|
<span className="hidden lg:block">Print</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#f14343]"
|
className="op-btn op-btn-primary op-btn-sm font-medium text-[13px] mr-[5px] shadow"
|
||||||
onClick={() => handleDownloadPdf()}
|
onClick={() =>
|
||||||
|
handleDownloadPdf(pdfDetails, pdfUrl, setIsDownloading)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<i className="fa fa-download py-[3px]" aria-hidden="true"></i>
|
<i className="fa fa-download" aria-hidden="true"></i>
|
||||||
<span className="hidden lg:block ml-1">Download</span>
|
<span className="hidden lg:block">Download</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[11px] text-white font-[500] text-[13px] mr-[5px] bg-[#3ba7e5]"
|
className="op-btn op-btn-info op-btn-sm font-medium text-[13px] mr-[5px] shadow"
|
||||||
onClick={() => setIsEmail(true)}
|
onClick={() => setIsEmail(true)}
|
||||||
>
|
>
|
||||||
<i className="fa fa-envelope py-[3px]" aria-hidden="true"></i>
|
<i className="fa fa-envelope" aria-hidden="true"></i>
|
||||||
<span className="hidden lg:block ml-1">Mail</span>
|
<span className="hidden lg:block">Mail</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => navigate(-1)}
|
||||||
navigate(-1);
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[18px] text-black font-[500] text-sm mr-[5px] bg-white"
|
className="op-btn op-btn-ghost op-btn-sm mr-[5px]"
|
||||||
>
|
>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
style={{
|
|
||||||
background: "#188ae2"
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center shadow rounded-[3px] py-[3px] px-[18px] text-white font-[500] text-[13px] mr-[5px] bg-[#188ae2]"
|
className="op-btn op-btn-primary op-btn-sm mr-[5px]"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!pdfUrl) {
|
if (!pdfUrl) {
|
||||||
embedWidgetsData();
|
embedWidgetsData();
|
||||||
@@ -595,12 +456,22 @@ function Header({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{isDownloading === "pdf" && (
|
||||||
|
<div className="fixed z-[200] inset-0 flex justify-center items-center bg-black bg-opacity-30">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<ModalUi
|
<ModalUi
|
||||||
isOpen={isCertificate}
|
isOpen={isDownloading === "certificate"}
|
||||||
title={"Generating certificate"}
|
title={
|
||||||
handleClose={() => setIsCertificate(false)}
|
isDownloading === "certificate"
|
||||||
|
? "Generating certificate"
|
||||||
|
: "PDF Download"
|
||||||
|
}
|
||||||
|
handleClose={() => setIsDownloading("")}
|
||||||
>
|
>
|
||||||
<div className="p-3 md:p-5 text-[13px] md:text-base text-center">
|
<div className="p-3 md:p-5 text-[13px] md:text-base text-center text-base-content">
|
||||||
|
{isDownloading === "certificate"}{" "}
|
||||||
<p>
|
<p>
|
||||||
Your completion certificate is being generated. Please wait
|
Your completion certificate is being generated. Please wait
|
||||||
momentarily.
|
momentarily.
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import { randomId, textWidget } from "../../constant/Utils";
|
import { randomId, textWidget } from "../../constant/Utils";
|
||||||
|
|
||||||
@@ -195,13 +194,13 @@ function PlaceholderCopy(props) {
|
|||||||
props.setIsPageCopy(false);
|
props.setIsPageCopy(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-full p-[20px] text-base-content">
|
||||||
{copyType.map((data, key) => {
|
{copyType.map((data, key) => {
|
||||||
return (
|
return (
|
||||||
<div key={key} style={{ display: "flex", flexDirection: "column" }}>
|
<div key={key} className="flex flex-col">
|
||||||
<label key={key} style={{ fontSize: "16px", fontWeight: "500" }}>
|
<label className="text-[16px] font-medium">
|
||||||
<input
|
<input
|
||||||
style={{ accentColor: "red", marginRight: "10px" }}
|
className="mr-[8px] op-radio op-radio-xs"
|
||||||
type="radio"
|
type="radio"
|
||||||
value={data}
|
value={data}
|
||||||
onChange={() => setSelectCopyType(data)}
|
onChange={() => setSelectCopyType(data)}
|
||||||
@@ -214,33 +213,22 @@ function PlaceholderCopy(props) {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<div
|
<div className="flex bg-[#9f9f9f] w-full my-[15px]"></div>
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleApplyCopy();
|
handleApplyCopy();
|
||||||
handleUniqueId();
|
handleUniqueId();
|
||||||
}}
|
}}
|
||||||
style={{ background: themeColor }}
|
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!selectCopyType}
|
disabled={!selectCopyType}
|
||||||
className="finishBtn"
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
Apply
|
Apply
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-ghost"
|
||||||
onClick={() => {
|
onClick={() => handleUniqueId()}
|
||||||
handleUniqueId();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -352,12 +352,9 @@ function PlaceholderType(props) {
|
|||||||
return (
|
return (
|
||||||
<div key={ind} className="flex items-center text-center gap-0.5">
|
<div key={ind} className="flex items-center text-center gap-0.5">
|
||||||
<input
|
<input
|
||||||
style={{
|
className={`${
|
||||||
// width: props.pos.Width,
|
ind === 0 ? "mt-0" : "mt-[5px]"
|
||||||
display: "flex",
|
} flex justify-center op-checkbox op-checkbox-xs rounded-[0.350rem]`}
|
||||||
justifyContent: "center",
|
|
||||||
marginTop: ind === 0 ? 0 : "5px"
|
|
||||||
}}
|
|
||||||
onBlur={handleInputBlur}
|
onBlur={handleInputBlur}
|
||||||
disabled={
|
disabled={
|
||||||
props.isNeedSign &&
|
props.isNeedSign &&
|
||||||
@@ -425,7 +422,7 @@ function PlaceholderType(props) {
|
|||||||
? "labelTextArea labelWidthMobile"
|
? "labelTextArea labelWidthMobile"
|
||||||
: "labelTextArea labelWidthDesktop"
|
: "labelTextArea labelWidthDesktop"
|
||||||
}
|
}
|
||||||
style={{ whiteSpace: "pre-wrap" }}
|
style={{ whiteSpace: "pre-wrap", color: "initial" }}
|
||||||
cols="50"
|
cols="50"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -443,7 +440,7 @@ function PlaceholderType(props) {
|
|||||||
<select
|
<select
|
||||||
className="inputPlaceholder"
|
className="inputPlaceholder"
|
||||||
id="myDropdown"
|
id="myDropdown"
|
||||||
style={{ fontSize: "12px" }}
|
style={{ fontSize: "12px", color: "initial" }}
|
||||||
value={selectOption}
|
value={selectOption}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setSelectOption(e.target.value);
|
setSelectOption(e.target.value);
|
||||||
@@ -528,7 +525,7 @@ function PlaceholderType(props) {
|
|||||||
? "labelTextArea labelWidthMobile"
|
? "labelTextArea labelWidthMobile"
|
||||||
: "labelTextArea labelWidthDesktop"
|
: "labelTextArea labelWidthDesktop"
|
||||||
}
|
}
|
||||||
style={{ whiteSpace: "pre-wrap" }}
|
style={{ whiteSpace: "pre-wrap", color: "initial" }}
|
||||||
cols="50"
|
cols="50"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -567,7 +564,7 @@ function PlaceholderType(props) {
|
|||||||
? "labelTextArea labelWidthMobile"
|
? "labelTextArea labelWidthMobile"
|
||||||
: "labelTextArea labelWidthDesktop"
|
: "labelTextArea labelWidthDesktop"
|
||||||
}
|
}
|
||||||
style={{ whiteSpace: "pre-wrap" }}
|
style={{ whiteSpace: "pre-wrap", color: "initial" }}
|
||||||
cols="50"
|
cols="50"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -606,7 +603,7 @@ function PlaceholderType(props) {
|
|||||||
? "labelTextArea labelWidthMobile"
|
? "labelTextArea labelWidthMobile"
|
||||||
: "labelTextArea labelWidthDesktop"
|
: "labelTextArea labelWidthDesktop"
|
||||||
}
|
}
|
||||||
style={{ whiteSpace: "pre-wrap" }}
|
style={{ whiteSpace: "pre-wrap", color: "initial" }}
|
||||||
cols="50"
|
cols="50"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -728,7 +725,7 @@ function PlaceholderType(props) {
|
|||||||
? "labelTextArea labelWidthMobile"
|
? "labelTextArea labelWidthMobile"
|
||||||
: "labelTextArea labelWidthDesktop"
|
: "labelTextArea labelWidthDesktop"
|
||||||
}
|
}
|
||||||
style={{ whiteSpace: "pre-wrap" }}
|
style={{ whiteSpace: "pre-wrap", color: "initial" }}
|
||||||
cols="50"
|
cols="50"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -748,12 +745,11 @@ function PlaceholderType(props) {
|
|||||||
return (
|
return (
|
||||||
<div key={ind} className="flex items-center text-center gap-0.5">
|
<div key={ind} className="flex items-center text-center gap-0.5">
|
||||||
<input
|
<input
|
||||||
style={{
|
className={`${ind === 0 ? "mt-0" : "mt-[5px]"} ${
|
||||||
width: props.pos.Width,
|
props?.pos?.Width
|
||||||
display: "flex",
|
? `w-[${props?.pos?.Width}px] h-[${props?.pos?.Width}px]`
|
||||||
justifyContent: "center",
|
: "w-[15px] h-[15px]"
|
||||||
marginTop: ind === 0 ? 0 : "5px"
|
} flex justify-center op-radio`}
|
||||||
}}
|
|
||||||
type="radio"
|
type="radio"
|
||||||
disabled={
|
disabled={
|
||||||
props.isNeedSign &&
|
props.isNeedSign &&
|
||||||
@@ -800,7 +796,11 @@ function PlaceholderType(props) {
|
|||||||
? "labelTextArea labelWidthMobile"
|
? "labelTextArea labelWidthMobile"
|
||||||
: "labelTextArea labelWidthDesktop"
|
: "labelTextArea labelWidthDesktop"
|
||||||
}
|
}
|
||||||
style={{ whiteSpace: "pre-wrap", overflow: "hidden" }}
|
style={{
|
||||||
|
whiteSpace: "pre-wrap",
|
||||||
|
overflow: "hidden",
|
||||||
|
color: "initial"
|
||||||
|
}}
|
||||||
cols="50"
|
cols="50"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
|
|
||||||
function PrevNext({ pageNumber, allPages, changePage }) {
|
function PrevNext({ pageNumber, allPages, changePage }) {
|
||||||
//for go to previous page
|
//for go to previous page
|
||||||
@@ -12,40 +11,30 @@ function PrevNext({ pageNumber, allPages, changePage }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="flex items-center">
|
||||||
<div className="preBtn1">
|
<button
|
||||||
<button
|
className="op-btn op-btn-secondary op-btn-xs md:op-btn-sm font-semibold text-xs"
|
||||||
className="py-[3px] px-[10px] text-xs bg-[#d3edeb] font-[600] mr-[5px]"
|
disabled={pageNumber <= 1}
|
||||||
disabled={pageNumber <= 1}
|
onClick={previousPage}
|
||||||
onClick={previousPage}
|
>
|
||||||
>
|
<span className="block lg:hidden">
|
||||||
<span className="block lg:hidden">
|
<i className="fa fa-backward" aria-hidden="true"></i>
|
||||||
<i
|
|
||||||
className="fa fa-backward"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ color: themeColor, cursor: "pointer" }}
|
|
||||||
></i>
|
|
||||||
</span>
|
|
||||||
<span className="lg:block hidden">Prev</span>
|
|
||||||
</button>
|
|
||||||
<span className="text-xs font-[500]">
|
|
||||||
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
|
|
||||||
</span>
|
</span>
|
||||||
<button
|
<span className="lg:block hidden">Prev</span>
|
||||||
className="py-[3px] px-[10px] text-xs bg-[#d3edeb] font-[600] ml-[5px]"
|
</button>
|
||||||
disabled={pageNumber >= allPages}
|
<span className="text-xs text-base-content font-medium mx-2">
|
||||||
onClick={nextPage}
|
{pageNumber || (allPages ? 1 : "--")} of {allPages || "--"}
|
||||||
>
|
</span>
|
||||||
<span className="block lg:hidden">
|
<button
|
||||||
<i
|
className="op-btn op-btn-secondary op-btn-xs md:op-btn-sm font-semibold text-xs"
|
||||||
className="fa fa-forward"
|
disabled={pageNumber >= allPages}
|
||||||
aria-hidden="true"
|
onClick={nextPage}
|
||||||
style={{ color: themeColor, cursor: "pointer" }}
|
>
|
||||||
></i>
|
<span className="block lg:hidden">
|
||||||
</span>
|
<i className="fa fa-forward" aria-hidden="true"></i>
|
||||||
<span className="lg:block hidden">Next</span>
|
</span>
|
||||||
</button>
|
<span className="lg:block hidden">Next</span>
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,37 +7,15 @@ import {
|
|||||||
isMobile,
|
isMobile,
|
||||||
nameColor
|
nameColor
|
||||||
} from "../../constant/Utils";
|
} from "../../constant/Utils";
|
||||||
|
const cursor =
|
||||||
|
"cursor-[url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAASElEQVR4nGNgwAMkJSUbpKSkOvCpIaT5PxSTbogUQjMYMwxeIIXmVFIxA8UGDDyQGg0DnIDi6JKUlCxHMqCeZAOghjSAMD5FAKfeaURdUFxCAAAAAElFTkSuQmCC'),_pointer]";
|
||||||
const RecipientList = (props) => {
|
const RecipientList = (props) => {
|
||||||
const [animationParent] = useAutoAnimate();
|
const [animationParent] = useAutoAnimate();
|
||||||
const [isHover, setIsHover] = useState();
|
const [isHover, setIsHover] = useState();
|
||||||
const [isEdit, setIsEdit] = useState(false);
|
const [isEdit, setIsEdit] = useState(false);
|
||||||
//function for onhover signer name change background color
|
//function for onhover signer name change background color
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
const onHoverStyle = (ind, blockColor) => {
|
|
||||||
const style = {
|
|
||||||
background: blockColor ? blockColor : color[ind % color.length],
|
|
||||||
padding: "10px",
|
|
||||||
marginTop: "2px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
borderBottom: "1px solid #e3e1e1",
|
|
||||||
alignItems: "center"
|
|
||||||
};
|
|
||||||
return style;
|
|
||||||
};
|
|
||||||
//function for onhover signer name remove background color
|
|
||||||
const nonHoverStyle = () => {
|
|
||||||
const style = {
|
|
||||||
padding: "10px",
|
|
||||||
marginTop: "2px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
borderBottom: "1px solid #e3e1e1",
|
|
||||||
alignItems: "center"
|
|
||||||
};
|
|
||||||
return style;
|
|
||||||
};
|
|
||||||
const isWidgetExist = (Id) => {
|
const isWidgetExist = (Id) => {
|
||||||
return props.signerPos.some((x) => x.Id === Id);
|
return props.signerPos.some((x) => x.Id === Id);
|
||||||
};
|
};
|
||||||
@@ -116,18 +94,21 @@ const RecipientList = (props) => {
|
|||||||
data-tut="reactourFirst"
|
data-tut="reactourFirst"
|
||||||
onMouseEnter={() => setIsHover(ind)}
|
onMouseEnter={() => setIsHover(ind)}
|
||||||
onMouseLeave={() => setIsHover(null)}
|
onMouseLeave={() => setIsHover(null)}
|
||||||
className={
|
className={`${
|
||||||
props.sendInOrder
|
props.sendInOrder
|
||||||
? props.isMailSend
|
? props.isMailSend
|
||||||
? "disabled"
|
? "pointer-events-none bg-opacity-80"
|
||||||
: "dragCursor"
|
: `text-[12px] font-bold ${cursor}`
|
||||||
: props.isMailSend && "disabled"
|
: props.isMailSend && "pointer-events-none bg-opacity-80"
|
||||||
}
|
} flex flex-row rounded-xl px-2 py-[10px] mt-1 mx-1 items-center last:mb-0.5`}
|
||||||
style={
|
style={{
|
||||||
(!isMobile && isHover === ind) || props.isSelectListId === ind
|
background:
|
||||||
? onHoverStyle(ind, obj?.blockColor)
|
(!isMobile && isHover === ind) || props.isSelectListId === ind
|
||||||
: nonHoverStyle(ind)
|
? obj?.blockColor
|
||||||
}
|
? obj?.blockColor
|
||||||
|
: color[ind % color.length]
|
||||||
|
: "transparent"
|
||||||
|
}}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
props.setSignerObjId(obj?.objectId || "");
|
props.setSignerObjId(obj?.objectId || "");
|
||||||
@@ -141,38 +122,16 @@ const RecipientList = (props) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div className="flex flex-row items-center w-full">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center",
|
|
||||||
width: "100%"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
|
className="flex w-[30px] h-[30px] rounded-full items-center justify-center mr-2"
|
||||||
style={{
|
style={{
|
||||||
background: obj?.blockColor
|
background: obj?.blockColor
|
||||||
? darkenColor(obj?.blockColor, 0.4)
|
? darkenColor(obj?.blockColor, 0.4)
|
||||||
: nameColor[ind % nameColor.length],
|
: nameColor[ind % nameColor.length]
|
||||||
width: 30,
|
|
||||||
height: 30,
|
|
||||||
display: "flex",
|
|
||||||
borderRadius: 30 / 2,
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
marginRight: "12px"
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span className="text-white uppercase font-bold text-center text-[12px]">
|
||||||
className={props.sendInOrder && "dragCursor"}
|
|
||||||
style={{
|
|
||||||
fontSize: "12px",
|
|
||||||
textAlign: "center",
|
|
||||||
fontWeight: "bold",
|
|
||||||
color: "white",
|
|
||||||
textTransform: "uppercase"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{isWidgetExist(obj.Id) ? (
|
{isWidgetExist(obj.Id) ? (
|
||||||
<i className="fa-solid fa-check"></i>
|
<i className="fa-solid fa-check"></i>
|
||||||
) : (
|
) : (
|
||||||
@@ -185,67 +144,72 @@ const RecipientList = (props) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
className={`${
|
||||||
display: "flex",
|
obj?.Name ? "flex-col" : "flex-row"
|
||||||
flexDirection: obj.Name ? "column" : "row",
|
} flex items-center`}
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{obj.Name ? (
|
{obj.Name ? (
|
||||||
<span className={"userName"}>{obj.Name}</span>
|
<span
|
||||||
|
className={`${
|
||||||
|
(!isMobile && isHover === ind) ||
|
||||||
|
props.isSelectListId === ind
|
||||||
|
? "text-[#424242]"
|
||||||
|
: "text-base-content"
|
||||||
|
} text-[12px] font-bold w-[100px] whitespace-nowrap overflow-hidden text-ellipsis`}
|
||||||
|
>
|
||||||
|
{obj.Name}
|
||||||
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<span
|
||||||
<span
|
className={`${
|
||||||
className="userName"
|
(!isMobile && isHover === ind) ||
|
||||||
style={{ cursor: "pointer" }}
|
props.isSelectListId === ind
|
||||||
onClick={() => {
|
? "text-[#424242]"
|
||||||
setIsEdit({ [obj.Id]: true });
|
: "text-base-content"
|
||||||
props.setRoleName(obj.Role);
|
} text-[12px] font-bold w-[100px] whitespace-nowrap overflow-hidden text-ellipsis cursor-pointer`}
|
||||||
}}
|
onClick={() => {
|
||||||
>
|
setIsEdit({ [obj.Id]: true });
|
||||||
{isEdit?.[obj.Id] && props.handleRoleChange ? (
|
props.setRoleName(obj.Role);
|
||||||
<input
|
}}
|
||||||
ref={inputRef}
|
>
|
||||||
style={{
|
{isEdit?.[obj.Id] && props.handleRoleChange ? (
|
||||||
backgroundColor: "transparent",
|
<input
|
||||||
width: "inherit",
|
ref={inputRef}
|
||||||
padding: "3px"
|
className="bg-transparent p-[3px"
|
||||||
}}
|
value={obj.Role}
|
||||||
value={obj.Role}
|
onChange={(e) => props.handleRoleChange(e, obj.Id)}
|
||||||
onChange={(e) => props.handleRoleChange(e, obj.Id)}
|
onBlur={() => {
|
||||||
onBlur={() => {
|
setIsEdit({});
|
||||||
setIsEdit({});
|
props.handleOnBlur(obj.Role, obj.Id);
|
||||||
props.handleOnBlur(obj.Role, obj.Id);
|
}}
|
||||||
}}
|
onKeyDown={(e) => {
|
||||||
onKeyDown={(e) => {
|
if (e.key === "Enter") {
|
||||||
if (e.key === "Enter") {
|
e.preventDefault();
|
||||||
e.preventDefault();
|
inputRef.current.blur();
|
||||||
inputRef.current.blur();
|
}
|
||||||
}
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
) : (
|
||||||
) : (
|
<span className="p-[3px]">{obj.Role}</span>
|
||||||
<span style={{ padding: "3px" }}>{obj.Role}</span>
|
)}
|
||||||
)}
|
</span>
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
{obj.Name && (
|
{obj.Name && (
|
||||||
<span className={"useEmail"}>
|
<span
|
||||||
|
className={` ${
|
||||||
|
(!isMobile && isHover === ind) ||
|
||||||
|
props.isSelectListId === ind
|
||||||
|
? "text-[#424242]"
|
||||||
|
: "text-base-content"
|
||||||
|
} text-[10px] font-medium w-[100px] whitespace-nowrap overflow-hidden text-ellipsis`}
|
||||||
|
>
|
||||||
{obj?.Role || obj?.Email}
|
{obj?.Role || obj?.Email}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{isMobile && props.sendInOrder && (
|
{isMobile && props.sendInOrder && (
|
||||||
<div
|
<div className="flex flex-row items-center gap-[5px]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 5
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (ind !== 0) {
|
if (ind !== 0) {
|
||||||
@@ -253,7 +217,7 @@ const RecipientList = (props) => {
|
|||||||
handleChangeSequence(e, ind, "up");
|
handleChangeSequence(e, ind, "up");
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{ color: ind === 0 ? "gray" : "black" }}
|
className={ind === 0 ? "text-[gray]" : "text-black"}
|
||||||
>
|
>
|
||||||
▲
|
▲
|
||||||
</div>
|
</div>
|
||||||
@@ -264,10 +228,11 @@ const RecipientList = (props) => {
|
|||||||
handleChangeSequence(e, ind, null, "down");
|
handleChangeSequence(e, ind, null, "down");
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{
|
className={
|
||||||
color:
|
ind === props.signersdata.length - 1
|
||||||
ind === props.signersdata.length - 1 ? "gray" : "black"
|
? "text-[gray]"
|
||||||
}}
|
: "text-black"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
▼
|
▼
|
||||||
</div>
|
</div>
|
||||||
@@ -279,7 +244,12 @@ const RecipientList = (props) => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
props.handleDeleteUser(obj.Id);
|
props.handleDeleteUser(obj.Id);
|
||||||
}}
|
}}
|
||||||
style={{ cursor: "pointer", marginLeft: "5px" }}
|
className={`${
|
||||||
|
(!isMobile && isHover === ind) ||
|
||||||
|
props.isSelectListId === ind
|
||||||
|
? "text-[#424242]"
|
||||||
|
: "text-base-content"
|
||||||
|
} cursor-pointer ml-[5px]`}
|
||||||
>
|
>
|
||||||
<i className="fa-regular fa-trash-can"></i>
|
<i className="fa-regular fa-trash-can"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import RSC from "react-scrollbars-custom";
|
import RSC from "react-scrollbars-custom";
|
||||||
import { Document, Page } from "react-pdf";
|
import { Document, Page } from "react-pdf";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
|
|
||||||
function RenderAllPdfPage({
|
function RenderAllPdfPage({
|
||||||
signPdfUrl,
|
signPdfUrl,
|
||||||
@@ -40,15 +39,7 @@ function RenderAllPdfPage({
|
|||||||
const ispageNumber = signPageNumber.includes(index + 1);
|
const ispageNumber = signPageNumber.includes(index + 1);
|
||||||
return (
|
return (
|
||||||
ispageNumber && (
|
ispageNumber && (
|
||||||
<div
|
<div className="absolute z-20 top-[1px] -right-[13px] -translate-x-1/2 -translate-y-1/2">
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
zIndex: 2,
|
|
||||||
top: -12,
|
|
||||||
right: -7,
|
|
||||||
transform: "translate(50% -50%)"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
<i
|
||||||
style={{ color: bookmarkColor || "red" }}
|
style={{ color: bookmarkColor || "red" }}
|
||||||
className="fa-solid fa-bookmark"
|
className="fa-solid fa-bookmark"
|
||||||
@@ -58,24 +49,10 @@ function RenderAllPdfPage({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="showPages">
|
<div>
|
||||||
<div
|
<div className=" hidden md:flex flex-row bg-base-100 h-full">
|
||||||
style={{
|
<div className="w-[140px]">
|
||||||
display: "flex",
|
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
|
||||||
flexDirection: "row",
|
|
||||||
boxShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px",
|
|
||||||
backgroundColor: "white",
|
|
||||||
height: "100%"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ width: "140px" }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
background: themeColor
|
|
||||||
// color:"white"
|
|
||||||
}}
|
|
||||||
className="signedStyle"
|
|
||||||
>
|
|
||||||
Pages
|
Pages
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -95,21 +72,11 @@ function RenderAllPdfPage({
|
|||||||
{Array.from(new Array(allPages), (el, index) => (
|
{Array.from(new Array(allPages), (el, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
style={{
|
className={`${
|
||||||
width: "100px",
|
pageNumber - 1 === index
|
||||||
border:
|
? "border-[red]"
|
||||||
pageNumber - 1 === index
|
: "border-[#878787]"
|
||||||
? "2px solid red"
|
} border-2 w-[100px] m-[10px] flex justify-center items-center relative`}
|
||||||
: "2px solid #878787",
|
|
||||||
// padding: "5px",
|
|
||||||
margin: "10px",
|
|
||||||
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPageNumber(index + 1);
|
setPageNumber(index + 1);
|
||||||
if (setSignBtnPosition) {
|
if (setSignBtnPosition) {
|
||||||
@@ -119,13 +86,7 @@ function RenderAllPdfPage({
|
|||||||
>
|
>
|
||||||
{signerPos && addSignatureBookmark(index)}
|
{signerPos && addSignatureBookmark(index)}
|
||||||
|
|
||||||
<div
|
<div className="relative z-[1] overflow-hidden">
|
||||||
style={{
|
|
||||||
position: "relative",
|
|
||||||
zIndex: 1,
|
|
||||||
overflow: "hidden"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Page
|
<Page
|
||||||
key={`page_${index + 1}`}
|
key={`page_${index + 1}`}
|
||||||
pageNumber={index + 1}
|
pageNumber={index + 1}
|
||||||
|
|||||||
@@ -204,34 +204,32 @@ function RenderPdf({
|
|||||||
};
|
};
|
||||||
//function for render placeholder block over pdf document
|
//function for render placeholder block over pdf document
|
||||||
const checkSignedSignes = (data) => {
|
const checkSignedSignes = (data) => {
|
||||||
const checkSign = signedSigners.filter(
|
let checkSign = [];
|
||||||
(sign) => sign.objectId === data.signerObjId
|
//condition to handle quick send flow and using normal request sign flow
|
||||||
|
checkSign = signedSigners.filter(
|
||||||
|
(sign) => sign?.Id === data?.Id || sign?.objectId === data?.signerObjId
|
||||||
);
|
);
|
||||||
if (data.signerObjId === signerObjectId) {
|
if (data.signerObjId === signerObjectId) {
|
||||||
setCurrentSigner(true);
|
setCurrentSigner(true);
|
||||||
}
|
}
|
||||||
const handleAllUserName = (Id, Role, type) => {
|
const handleAllUserName = (Id, Role, type) => {
|
||||||
return pdfDetails[0].Signers.map((signerData, key) => {
|
return (
|
||||||
return (
|
<React.Fragment>
|
||||||
signerData.objectId === data.signerObjId && (
|
<div className="text-black text-[8px] font-medium">
|
||||||
<React.Fragment key={key}>
|
{
|
||||||
{signerData?.Name && (
|
pdfDetails[0].Signers?.find(
|
||||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
(signer) => signer.objectId === data.signerObjId
|
||||||
{signerData.Name}
|
)?.Name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
{type && (
|
{type && <div className="text-[11px] font-bold">{type}</div>}
|
||||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
{Role && (
|
||||||
)}
|
<div className="text-black text-[8px] font-medium">
|
||||||
{Role && (
|
{`(${Role})`}
|
||||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
</div>
|
||||||
{`(${Role})`}
|
)}
|
||||||
</div>
|
</React.Fragment>
|
||||||
)}
|
);
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -290,14 +288,12 @@ function RenderPdf({
|
|||||||
if (checkSign?.Name) {
|
if (checkSign?.Name) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
<div className="text-black text-[8px] font-medium">
|
||||||
{checkSign?.Name}
|
{checkSign?.Name}
|
||||||
</div>
|
</div>
|
||||||
{type && (
|
{type && <div className="text-[11px] font-bold">{type}</div>}
|
||||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
|
||||||
)}
|
|
||||||
{Role && (
|
{Role && (
|
||||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
<div className="text-black text-[8px] font-medium">
|
||||||
{`(${Role})`}
|
{`(${Role})`}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -306,24 +302,16 @@ function RenderPdf({
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{type && (
|
{type && <div className="text-[11px] font-bold">{type}</div>}
|
||||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
<div className="text-black text-[8px] font-medium">{Role}</div>
|
||||||
)}
|
|
||||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
|
||||||
{Role}
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{type && (
|
{type && <div className="text-[11px] font-bold">{type}</div>}
|
||||||
<div style={{ fontWeight: "700", fontSize: 11 }}>{type}</div>
|
<div className="text-black text-[8px] font-medium">{Role}</div>
|
||||||
)}
|
|
||||||
<div style={{ color: "black", fontSize: 8, fontWeight: "500" }}>
|
|
||||||
{Role}
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -334,6 +322,7 @@ function RenderPdf({
|
|||||||
{successEmail && <Alert type={"success"}>Email sent successfully!</Alert>}
|
{successEmail && <Alert type={"success"}>Email sent successfully!</Alert>}
|
||||||
{isMobile && scale ? (
|
{isMobile && scale ? (
|
||||||
<div
|
<div
|
||||||
|
data-tut="reactourForth"
|
||||||
style={{
|
style={{
|
||||||
border: "0.1px solid #ebe8e8",
|
border: "0.1px solid #ebe8e8",
|
||||||
marginTop: isGuestSigner && "30px"
|
marginTop: isGuestSigner && "30px"
|
||||||
@@ -461,17 +450,9 @@ function RenderPdf({
|
|||||||
}))}
|
}))}
|
||||||
|
|
||||||
{/* this component for render pdf document is in middle of the component */}
|
{/* this component for render pdf document is in middle of the component */}
|
||||||
<div
|
<div className="flex items-center justify-center">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Document
|
<Document
|
||||||
onLoadError={() => {
|
onLoadError={() => setPdfLoadFail(true)}
|
||||||
setPdfLoadFail(true);
|
|
||||||
}}
|
|
||||||
loading={"Loading Document.."}
|
loading={"Loading Document.."}
|
||||||
onLoadSuccess={pageDetails}
|
onLoadSuccess={pageDetails}
|
||||||
// ref={pdfRef}'
|
// ref={pdfRef}'
|
||||||
@@ -517,10 +498,8 @@ function RenderPdf({
|
|||||||
noScrollX={pdfNewWidth < pdfOriginalWidth ? false : true}
|
noScrollX={pdfNewWidth < pdfOriginalWidth ? false : true}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
data-tut="reactourForth"
|
||||||
border: "0.1px solid #ebe8e8",
|
style={{ border: "0.1px solid #ebe8e8", width: pdfOriginalWidth }}
|
||||||
width: pdfOriginalWidth
|
|
||||||
}}
|
|
||||||
ref={drop}
|
ref={drop}
|
||||||
id="container"
|
id="container"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React, { useRef, useState, useEffect } from "react";
|
import React, { useRef, useState, useEffect } from "react";
|
||||||
import SignatureCanvas from "react-signature-canvas";
|
import SignatureCanvas from "react-signature-canvas";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
|
|
||||||
function SignPad({
|
function SignPad({
|
||||||
isSignPad,
|
isSignPad,
|
||||||
@@ -78,21 +77,16 @@ function SignPad({
|
|||||||
//save button component
|
//save button component
|
||||||
const SaveBtn = () => {
|
const SaveBtn = () => {
|
||||||
return (
|
return (
|
||||||
<div style={{ marginTop: "2px" }}>
|
<div>
|
||||||
{(isTab === "draw" || isTab === "uploadImage") && (
|
{(isTab === "draw" || isTab === "uploadImage") && (
|
||||||
<button
|
<button
|
||||||
style={{
|
|
||||||
color: "black",
|
|
||||||
border: "1px solid #ccc"
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn saveBtn"
|
className="op-btn op-btn-ghost mr-1 mt-[2px]"
|
||||||
onClick={() => handleClear()}
|
onClick={() => handleClear()}
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCurrWidgetsDetails({});
|
setCurrWidgetsDetails({});
|
||||||
@@ -127,19 +121,12 @@ function SignPad({
|
|||||||
setSignValue("");
|
setSignValue("");
|
||||||
setIsStamp(false);
|
setIsStamp(false);
|
||||||
}}
|
}}
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
disabled={
|
|
||||||
isSignImg || image || isDefaultSign || textWidth ? false : true
|
|
||||||
}
|
|
||||||
type="button"
|
type="button"
|
||||||
className={
|
className={`${
|
||||||
isSignImg || image || isDefaultSign || textWidth
|
isSignImg || image || isDefaultSign || textWidth
|
||||||
? "finishBtn saveBtn"
|
? ""
|
||||||
: "disabledFinish saveBtn"
|
: "pointer-events-none"
|
||||||
}
|
} op-btn op-btn-primary shadow-lg`}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
@@ -214,8 +201,8 @@ function SignPad({
|
|||||||
const fontfamily = fontStyle
|
const fontfamily = fontStyle
|
||||||
? fontStyle
|
? fontStyle
|
||||||
: fontSelect
|
: fontSelect
|
||||||
? fontSelect
|
? fontSelect
|
||||||
: "Fasthand";
|
: "Fasthand";
|
||||||
|
|
||||||
//creating span for getting text content width
|
//creating span for getting text content width
|
||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
@@ -256,7 +243,7 @@ function SignPad({
|
|||||||
|
|
||||||
const PenColorComponent = (props) => {
|
const PenColorComponent = (props) => {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
<div className="flex flex-row items-start">
|
||||||
{allColor.map((data, key) => {
|
{allColor.map((data, key) => {
|
||||||
return (
|
return (
|
||||||
<i
|
<i
|
||||||
@@ -267,10 +254,10 @@ function SignPad({
|
|||||||
key === 0 && penColor === "blue"
|
key === 0 && penColor === "blue"
|
||||||
? "2px solid blue"
|
? "2px solid blue"
|
||||||
: key === 1 && penColor === "red"
|
: key === 1 && penColor === "red"
|
||||||
? "2px solid red"
|
? "2px solid red"
|
||||||
: key === 2 && penColor === "black"
|
: key === 2 && penColor === "black"
|
||||||
? "2px solid black"
|
? "2px solid black"
|
||||||
: "2px solid white"
|
: "2px solid white"
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props?.convertToImg &&
|
props?.convertToImg &&
|
||||||
@@ -296,33 +283,14 @@ function SignPad({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{isSignPad && (
|
{isSignPad && (
|
||||||
<div className="modaloverlay">
|
<div className="op-modal op-modal-open">
|
||||||
<div className="modalcontainer">
|
<div className="op-modal-box px-[13px] pt-2 pb-0">
|
||||||
<div
|
<div className="flex justify-between text-base-content items-center">
|
||||||
className="modalheader"
|
<div className="text-[1.2rem]">
|
||||||
style={{ padding: "0 13px", marginTop: "5px" }}
|
<div className="flex flex-row justify-between mt-[3px]">
|
||||||
>
|
<div className="flex flex-row justify-between gap-[5px] md:gap-[8px] text-[11px] md:text-base">
|
||||||
<div className="modaltitle">
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
background: "white",
|
|
||||||
marginTop: "3px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-around",
|
|
||||||
alignItems: "end",
|
|
||||||
gap: 10
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{isStamp ? (
|
{isStamp ? (
|
||||||
<span style={{ color: themeColor }} className="signTab">
|
<span className="op-link-primary op-link">
|
||||||
{widgetType === "image"
|
{widgetType === "image"
|
||||||
? "Upload image"
|
? "Upload image"
|
||||||
: "Upload stamp image"}
|
: "Upload stamp image"}
|
||||||
@@ -337,23 +305,14 @@ function SignPad({
|
|||||||
setIsTab("draw");
|
setIsTab("draw");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
className={`${
|
||||||
color: isTab === "draw" ? themeColor : "#515252",
|
isTab === "draw"
|
||||||
marginLeft: "2px"
|
? "op-link-primary"
|
||||||
}}
|
: "no-underline"
|
||||||
className="signTab"
|
} op-link underline-offset-8 ml-[2px]`}
|
||||||
>
|
>
|
||||||
Draw
|
Draw
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border:
|
|
||||||
isTab === "draw"
|
|
||||||
? "1.5px solid #108783"
|
|
||||||
: "1.5px solid #ffffff"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
@@ -363,22 +322,14 @@ function SignPad({
|
|||||||
setIsTab("uploadImage");
|
setIsTab("uploadImage");
|
||||||
setSignatureType("");
|
setSignatureType("");
|
||||||
}}
|
}}
|
||||||
style={{
|
className={`${
|
||||||
color:
|
isTab === "uploadImage"
|
||||||
isTab === "uploadImage" ? themeColor : "#515252"
|
? "op-link-primary"
|
||||||
}}
|
: "no-underline"
|
||||||
className="signTab"
|
} op-link underline-offset-8 ml-[2px]`}
|
||||||
>
|
>
|
||||||
Upload Image
|
Upload Image
|
||||||
</span>
|
</span>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border:
|
|
||||||
isTab === "uploadImage"
|
|
||||||
? "1.5px solid #108783"
|
|
||||||
: "1.5px solid #ffffff"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
@@ -389,23 +340,14 @@ function SignPad({
|
|||||||
setSignatureType("");
|
setSignatureType("");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
className={`${
|
||||||
color: isTab === "type" ? themeColor : "#515252",
|
isTab === "type"
|
||||||
marginLeft: "2px"
|
? "op-link-primary"
|
||||||
}}
|
: "no-underline"
|
||||||
className="signTab"
|
} op-link underline-offset-8 ml-[2px]`}
|
||||||
>
|
>
|
||||||
Type
|
Type
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border:
|
|
||||||
isTab === "type"
|
|
||||||
? "1.5px solid #108783"
|
|
||||||
: "1.5px solid #ffffff"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
{!isInitial && defaultSign ? (
|
{!isInitial && defaultSign ? (
|
||||||
<div>
|
<div>
|
||||||
@@ -417,24 +359,14 @@ function SignPad({
|
|||||||
setSignatureType("");
|
setSignatureType("");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
className={`${
|
||||||
color:
|
isTab === "mysignature"
|
||||||
isTab === "mysignature"
|
? "op-link-primary"
|
||||||
? themeColor
|
: "no-underline"
|
||||||
: "#515252"
|
} op-link underline-offset-8 ml-[2px]`}
|
||||||
}}
|
|
||||||
className="signTab"
|
|
||||||
>
|
>
|
||||||
My Signature
|
My Signature
|
||||||
</span>
|
</span>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border:
|
|
||||||
isTab === "mysignature"
|
|
||||||
? "1.5px solid #108783"
|
|
||||||
: "1.5px solid #ffffff"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
isInitial &&
|
isInitial &&
|
||||||
@@ -448,24 +380,14 @@ function SignPad({
|
|||||||
setSignatureType("");
|
setSignatureType("");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
className={`${
|
||||||
color:
|
isTab === "mysignature"
|
||||||
isTab === "mysignature"
|
? "op-link-primary"
|
||||||
? themeColor
|
: "no-underline"
|
||||||
: "#515252"
|
} op-link underline-offset-8 ml-[2px]`}
|
||||||
}}
|
|
||||||
className="signTab"
|
|
||||||
>
|
>
|
||||||
My Initials
|
My Initials
|
||||||
</span>
|
</span>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border:
|
|
||||||
isTab === "mysignature"
|
|
||||||
? "1.5px solid #108783"
|
|
||||||
: "1.5px solid #ffffff"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
@@ -475,8 +397,7 @@ function SignPad({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="closebtn"
|
className="text-[1.5rem] cursor-pointer"
|
||||||
style={{ color: "black" }}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPenColor("blue");
|
setPenColor("blue");
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
@@ -493,10 +414,10 @@ function SignPad({
|
|||||||
×
|
×
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="p-[20px] h-full">
|
||||||
{isDefaultSign ? (
|
{isDefaultSign ? (
|
||||||
<>
|
<>
|
||||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
<div className="flex justify-center">
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: "1.3px solid #007bff",
|
border: "1.3px solid #007bff",
|
||||||
@@ -514,24 +435,19 @@ function SignPad({
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="stamp img"
|
alt="stamp img"
|
||||||
style={{
|
className="w-full h-full object-contain bg-white"
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
background: "rgb(255, 255, 255)",
|
|
||||||
objectFit: "contain"
|
|
||||||
}}
|
|
||||||
draggable="false"
|
draggable="false"
|
||||||
src={isInitial ? myInitial : defaultSign}
|
src={isInitial ? myInitial : defaultSign}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
<div className="flex justify-end">
|
||||||
<SaveBtn />
|
<SaveBtn />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : isImageSelect || isStamp ? (
|
) : isImageSelect || isStamp ? (
|
||||||
!image ? (
|
!image ? (
|
||||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
<div className="flex justify-center">
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: "1.3px solid #007bff",
|
border: "1.3px solid #007bff",
|
||||||
@@ -562,7 +478,7 @@ function SignPad({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
<div className="flex justify-center">
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: "1.3px solid #007bff",
|
border: "1.3px solid #007bff",
|
||||||
@@ -581,39 +497,26 @@ function SignPad({
|
|||||||
ref={imageRef}
|
ref={imageRef}
|
||||||
src={image.src}
|
src={image.src}
|
||||||
draggable="false"
|
draggable="false"
|
||||||
style={{
|
className=" object-contain h-full w-full"
|
||||||
objectFit: "contain",
|
|
||||||
height: "100%",
|
|
||||||
width: "100%"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="flex justify-end">
|
||||||
style={{ display: "flex", justifyContent: "flex-end" }}
|
|
||||||
>
|
|
||||||
<SaveBtn />
|
<SaveBtn />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
) : isTab === "type" ? (
|
) : isTab === "type" ? (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div className="flex justify-between items-center">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="signatureText">
|
<span className="signatureText">
|
||||||
{isInitial ? "Initials" : "Signature"}:
|
{isInitial ? "Initials" : "Signature"}:
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
maxLength={isInitial ? 3 : 30}
|
maxLength={isInitial ? 3 : 30}
|
||||||
style={{ fontFamily: fontSelect, color: penColor }}
|
style={{ fontFamily: fontSelect, color: penColor }}
|
||||||
type="text"
|
type="text"
|
||||||
className="signatureInput"
|
className="ml-1 op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-[20px]"
|
||||||
placeholder="Your signature"
|
placeholder="Your signature"
|
||||||
value={signValue}
|
value={signValue}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
@@ -622,7 +525,6 @@ function SignPad({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="fontOptionContainer">
|
<div className="fontOptionContainer">
|
||||||
{fontOptions.map((font, ind) => {
|
{fontOptions.map((font, ind) => {
|
||||||
return (
|
return (
|
||||||
@@ -653,21 +555,14 @@ function SignPad({
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div className="flex flex-row justify-between mt-[10px]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
marginTop: "10px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PenColorComponent convertToImg={convertToImg} />
|
<PenColorComponent convertToImg={convertToImg} />
|
||||||
<SaveBtn />
|
<SaveBtn />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
<div className="flex justify-center">
|
||||||
<SignatureCanvas
|
<SignatureCanvas
|
||||||
ref={canvasRef}
|
ref={canvasRef}
|
||||||
penColor={penColor}
|
penColor={penColor}
|
||||||
@@ -687,14 +582,7 @@ function SignPad({
|
|||||||
dotSize={1}
|
dotSize={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="flex flex-row justify-between mt-[10px]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
marginTop: "10px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PenColorComponent />
|
<PenColorComponent />
|
||||||
<SaveBtn />
|
<SaveBtn />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
import "../../styles/signature.css";
|
import "../../styles/signature.css";
|
||||||
function Signedby({ pdfDetails }) {
|
function Signedby({ pdfDetails }) {
|
||||||
const getFirstLetter = (name) => {
|
const getFirstLetter = (name) => {
|
||||||
@@ -8,50 +7,18 @@ function Signedby({ pdfDetails }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="signerComponent">
|
<div className="hidden md:block w-[180px] h-full bg-base-100">
|
||||||
<div
|
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
className="signedStyle"
|
|
||||||
>
|
|
||||||
Signed By
|
Signed By
|
||||||
</div>
|
</div>
|
||||||
<div style={{ marginTop: "2px", background: "white" }}>
|
<div className="mt-[2px] bg-base-100">
|
||||||
<div
|
<div className="bg-[#93a3db] rounded-xl mx-1 flex flex-row items-center py-[10px]">
|
||||||
style={{
|
<div className="bg-[#576081] flex w-[30px] h-[30px] rounded-full justify-center items-center mx-1">
|
||||||
display: "flex",
|
<span className="text-[12px] text-center font-bold text-white uppercase">
|
||||||
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)}
|
{getFirstLetter(pdfDetails.ExtUserPtr.Name)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
<div className="flex flex-col">
|
||||||
<span className="userName">{pdfDetails.ExtUserPtr.Name}</span>
|
<span className="userName">{pdfDetails.ExtUserPtr.Name}</span>
|
||||||
<span className="useEmail">{pdfDetails.ExtUserPtr.Email}</span>
|
<span className="useEmail">{pdfDetails.ExtUserPtr.Email}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,37 +1,22 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
import RecipientList from "./RecipientList";
|
import RecipientList from "./RecipientList";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
|
|
||||||
function SignerListPlace(props) {
|
function SignerListPlace(props) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
|
||||||
style={{
|
<span>
|
||||||
background: themeColor,
|
|
||||||
padding: "5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="signedStyle">
|
|
||||||
{props.title ? props.title : "Recipients"}
|
{props.title ? props.title : "Recipients"}
|
||||||
<span className="absolute text-xs z-[30] mt-1 ml-0.5">
|
<span className="text-xs mt-1 ml-0.5">
|
||||||
{props?.title === "Roles" && (
|
{props?.title === "Roles" && (
|
||||||
<>
|
<>
|
||||||
<a data-tooltip-id="my-tooltip">
|
<a data-tooltip-id="my-tooltip">
|
||||||
<sup>
|
<sup>
|
||||||
<i
|
<i className="fa-solid fa-question rounded-full border-[1.5px] border-base-content text-[11px] py-[1px] px-[3px]"></i>
|
||||||
className="fa-solid fa-question rounded-full"
|
|
||||||
style={{
|
|
||||||
borderColor: "white",
|
|
||||||
color: "white",
|
|
||||||
fontSize: 11,
|
|
||||||
borderWidth: 1.5,
|
|
||||||
padding: "1px 3px"
|
|
||||||
}}
|
|
||||||
></i>
|
|
||||||
</sup>
|
</sup>
|
||||||
</a>
|
</a>
|
||||||
<Tooltip id="my-tooltip">
|
<Tooltip id="my-tooltip" className="z-[100]">
|
||||||
<div className="max-w-[450px]">
|
<div className="max-w-[450px]">
|
||||||
<p className="font-bold">What are template roles?</p>
|
<p className="font-bold">What are template roles?</p>
|
||||||
<p>
|
<p>
|
||||||
@@ -68,36 +53,32 @@ function SignerListPlace(props) {
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="signerList">
|
<div className="overflow-auto hide-scrollbar max-h-[180px]">
|
||||||
<RecipientList {...props} />
|
<RecipientList {...props} />
|
||||||
</div>
|
</div>
|
||||||
{props.handleAddSigner ? (
|
<div className="mx-1">
|
||||||
<div
|
{props.handleAddSigner ? (
|
||||||
data-tut="reactourAddbtn"
|
<div
|
||||||
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"
|
role="button"
|
||||||
onClick={() => props.handleAddSigner()}
|
data-tut="reactourAddbtn"
|
||||||
style={{
|
className="op-btn op-btn-accent op-btn-outline w-full mt-[14px]"
|
||||||
opacity: props.isMailSend && "0.5",
|
disabled={props?.isMailSend ? true : false}
|
||||||
pointerEvents: props.isMailSend && "none"
|
onClick={() => props.handleAddSigner()}
|
||||||
}}
|
>
|
||||||
>
|
<i className="fa-solid fa-plus"></i> Add role
|
||||||
<i className="fa-solid fa-plus"></i>
|
</div>
|
||||||
<span style={{ marginLeft: 2 }}>Add role</span>
|
) : (
|
||||||
</div>
|
<div
|
||||||
) : (
|
role="button"
|
||||||
<div
|
data-tut="reactourAddbtn"
|
||||||
data-tut="reactourAddbtn"
|
className="op-btn op-btn-accent op-btn-outline w-full mt-[14px]"
|
||||||
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"
|
disabled={props?.isMailSend ? true : false}
|
||||||
onClick={() => props.setIsAddSigner(true)}
|
onClick={() => props.setIsAddSigner(true)}
|
||||||
style={{
|
>
|
||||||
opacity: props.isMailSend && "0.5",
|
<i className="fa-solid fa-plus"></i> Add recipients
|
||||||
pointerEvents: props.isMailSend && "none"
|
</div>
|
||||||
}}
|
)}
|
||||||
>
|
</div>
|
||||||
<i className="fa-solid fa-plus"></i>
|
|
||||||
<span style={{ marginLeft: 2 }}>Add recipients</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { rejectBtn, submitBtn, themeColor } from "../../constant/const";
|
import Loader from "../../primitives/Loader";
|
||||||
|
|
||||||
function VerifyEmail(props) {
|
function VerifyEmail(props) {
|
||||||
return (
|
return (
|
||||||
<div className="bg-black bg-opacity-[75%] absolute z-[999] flex flex-col items-center justify-center w-full h-full rounded">
|
<dialog className="op-modal op-modal-open absolute z-[1999]">
|
||||||
<div className="bg-white rounded outline-none md:w-[40%] w-[80%]">
|
<div className="md:w-[40%] w-[80%] op-modal-box p-0 overflow-y-auto hide-scrollbar text-sm">
|
||||||
<div
|
<h3 className="font-bold text-lg pt-[15px] px-[20px] text-base-content">
|
||||||
style={{ backgroundColor: themeColor }}
|
|
||||||
className=" text-white p-[10px] rounded-t"
|
|
||||||
>
|
|
||||||
OTP verification
|
OTP verification
|
||||||
</div>
|
</h3>
|
||||||
{props.isVerifyModal ? (
|
{props.isVerifyModal ? (
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
@@ -18,25 +15,24 @@ function VerifyEmail(props) {
|
|||||||
props.handleVerifyEmail(e);
|
props.handleVerifyEmail(e);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="px-6 py-3">
|
<div className="px-6 py-3 text-base-content">
|
||||||
<label className="mb-2">Enter OTP</label>
|
<label className="mb-2">Enter OTP</label>
|
||||||
<input
|
<input
|
||||||
required
|
required
|
||||||
type="tel"
|
type="tel"
|
||||||
pattern="[0-9]{4}"
|
pattern="[0-9]{4}"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="w-full op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
placeholder="Enter OTP received over email"
|
placeholder="Enter OTP received over email"
|
||||||
value={props.otp}
|
value={props.otp}
|
||||||
onChange={(e) => props.setOtp(e.target.value)}
|
onChange={(e) => props.setOtp(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
|
||||||
<div className="px-6 my-3">
|
<div className="px-6 my-3">
|
||||||
<button type="submit" className={submitBtn}>
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
Verify
|
Verify
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`${rejectBtn} ml-2`}
|
className="op-btn op-btn-secondary ml-2"
|
||||||
onClick={(e) => props.handleResend(e)}
|
onClick={(e) => props.handleResend(e)}
|
||||||
>
|
>
|
||||||
Resend
|
Resend
|
||||||
@@ -44,29 +40,15 @@ function VerifyEmail(props) {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
) : props.otpLoader ? (
|
) : props.otpLoader ? (
|
||||||
<div
|
<div className="h-[150px] flex items-center justify-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "150px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="px-6 py-3">
|
<div className="px-6 py-3 text-base-content">
|
||||||
<p className="mb-2">Please verify your email !</p>
|
<p className="mb-2 text-sm">Please verify your email !</p>
|
||||||
<hr />
|
|
||||||
<div className="px-0 mt-3">
|
<div className="px-0 mt-3">
|
||||||
<button
|
<button
|
||||||
className={submitBtn}
|
className="op-btn op-btn-primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.handleVerifyBtn();
|
props.handleVerifyBtn();
|
||||||
@@ -78,7 +60,7 @@ function VerifyEmail(props) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import {
|
|||||||
textWidget,
|
textWidget,
|
||||||
widgets
|
widgets
|
||||||
} from "../../constant/Utils";
|
} from "../../constant/Utils";
|
||||||
import { themeColor } from "../../constant/const";
|
|
||||||
function WidgetComponent({
|
function WidgetComponent({
|
||||||
dragSignature,
|
dragSignature,
|
||||||
signRef,
|
signRef,
|
||||||
@@ -256,117 +255,82 @@ function WidgetComponent({
|
|||||||
className="stickyfooter"
|
className="stickyfooter"
|
||||||
style={{ width: window.innerWidth + "px" }}
|
style={{ width: window.innerWidth + "px" }}
|
||||||
>
|
>
|
||||||
{isSigners && (
|
<div className="mx-1">
|
||||||
<div
|
{isSigners && (
|
||||||
data-tut={dataTut}
|
<div
|
||||||
style={{
|
data-tut={dataTut}
|
||||||
background: blockColor
|
className="py-[10px] flex justify-center items-center op-card"
|
||||||
? blockColor
|
|
||||||
: isSelectListId
|
|
||||||
? color[isSelectListId % color.length]
|
|
||||||
: color[0],
|
|
||||||
padding: "10px 20px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
onClick={() => handleModal()}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
style={{
|
||||||
fontSize: "13px",
|
background: blockColor
|
||||||
fontWeight: "700",
|
? blockColor
|
||||||
textAlign: "center"
|
: isSelectListId
|
||||||
|
? color[isSelectListId % color.length]
|
||||||
|
: color[0]
|
||||||
}}
|
}}
|
||||||
|
onClick={() => handleModal()}
|
||||||
>
|
>
|
||||||
{title ? title : "Recipient"}
|
<span className="text-[13px] font-bold flex items-center">
|
||||||
</span>
|
{title ? title : "Recipient"}
|
||||||
<span
|
{signersdata[isSelectListId]?.Role && (
|
||||||
style={{
|
<div>
|
||||||
fontSize: "13px",
|
{signersdata[isSelectListId]?.Name ? (
|
||||||
fontWeight: "700",
|
<>
|
||||||
display: "flex",
|
:{" "}
|
||||||
alignItems: "center"
|
{signersdata[isSelectListId]?.Name?.length > 12
|
||||||
}}
|
? `${signersdata[isSelectListId].Name.slice(
|
||||||
>
|
0,
|
||||||
{signersdata[isSelectListId]?.Role && (
|
12
|
||||||
<div>
|
)}...`
|
||||||
{signersdata[isSelectListId]?.Name ? (
|
: signersdata[isSelectListId]?.Name}
|
||||||
<>
|
</>
|
||||||
:{" "}
|
) : (
|
||||||
{signersdata[isSelectListId]?.Name?.length > 12
|
<>
|
||||||
? `${signersdata[isSelectListId].Name.slice(
|
:{" "}
|
||||||
0,
|
{signersdata[isSelectListId]?.Role?.length > 12
|
||||||
12
|
? `${signersdata[isSelectListId].Role.slice(
|
||||||
)}...`
|
0,
|
||||||
: signersdata[isSelectListId]?.Name}
|
12
|
||||||
</>
|
)}...`
|
||||||
) : (
|
: signersdata[isSelectListId]?.Role}
|
||||||
<>
|
</>
|
||||||
:{" "}
|
)}
|
||||||
{signersdata[isSelectListId]?.Role?.length > 12
|
</div>
|
||||||
? `${signersdata[isSelectListId].Role.slice(
|
)}
|
||||||
0,
|
<div className="ml-[6px] text-[16px]">
|
||||||
12
|
<i className="fa-solid fa-angle-down"></i>
|
||||||
)}...`
|
|
||||||
: signersdata[isSelectListId]?.Role}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
</span>
|
||||||
<div style={{ marginLeft: 6, fontSize: 16 }}>
|
</div>
|
||||||
<i className="fa-solid fa-angle-down"></i>
|
)}
|
||||||
</div>
|
</div>
|
||||||
</span>
|
<div className="mx-1">
|
||||||
</div>
|
{handleAddSigner ? (
|
||||||
)}
|
|
||||||
{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>
|
|
||||||
) : (
|
|
||||||
setIsAddSigner && (
|
|
||||||
<div
|
<div
|
||||||
data-tut="reactourAddbtn"
|
data-tut="reactourAddbtn"
|
||||||
style={{
|
className="op-btn op-btn-accent w-full my-[2px]"
|
||||||
margin: "5px 0 5px 0",
|
onClick={() => handleAddSigner()}
|
||||||
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={() => setIsAddSigner(true)}
|
|
||||||
>
|
>
|
||||||
<i className="fa-solid fa-plus"></i>
|
<i className="fa-solid fa-plus"></i>
|
||||||
<span style={{ marginLeft: 2 }}>Add recipients</span>
|
<span>Add role</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
) : (
|
||||||
)}
|
setIsAddSigner && (
|
||||||
|
<div
|
||||||
|
data-tut="reactourAddbtn"
|
||||||
|
className="op-btn op-btn-accent w-full my-[2px]"
|
||||||
|
onClick={() => setIsAddSigner(true)}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-plus"></i>
|
||||||
|
<span>Add recipients</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
ref={scrollContainerRef}
|
ref={scrollContainerRef}
|
||||||
style={{
|
className="bg-base-100 border-[2px] border-t-primary"
|
||||||
background: "white",
|
|
||||||
borderTop: `2px solid ${themeColor}`
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div
|
<div className="flex whitespace-nowrap overflow-x-scroll pt-[10px] pb-[5px] pr-[5px]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
overflowX: "scroll",
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
padding: "10px 5px 10px 1px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<WidgetList
|
<WidgetList
|
||||||
updateWidgets={updateWidgets}
|
updateWidgets={updateWidgets}
|
||||||
handleDivClick={handleDivClick}
|
handleDivClick={handleDivClick}
|
||||||
@@ -383,20 +347,14 @@ function WidgetComponent({
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
data-tut={dataTut}
|
data-tut={dataTut}
|
||||||
className={
|
className={`${
|
||||||
isMailSend ? "disabled signerComponent " : "signerComponent"
|
isMailSend ? "bg-opacity-50 pointer-events-none" : ""
|
||||||
}
|
} hidden md:block w-[180px] h-full bg-base-100`}
|
||||||
>
|
>
|
||||||
<div
|
<div className="mx-2 pr-2 pt-2 pb-1 text-[15px] text-base-content font-semibold border-b-[1px] border-base-300">
|
||||||
style={{
|
<span>Fields</span>
|
||||||
background: themeColor,
|
|
||||||
padding: "5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="signedStyle">Fields</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col items-center my-3">
|
||||||
<div className="signLayoutContainer1">
|
|
||||||
<WidgetList
|
<WidgetList
|
||||||
updateWidgets={updateWidgets}
|
updateWidgets={updateWidgets}
|
||||||
handleDivClick={handleDivClick}
|
handleDivClick={handleDivClick}
|
||||||
@@ -413,7 +371,7 @@ function WidgetComponent({
|
|||||||
handleClose={handleModal}
|
handleClose={handleModal}
|
||||||
>
|
>
|
||||||
{signersdata.length > 0 ? (
|
{signersdata.length > 0 ? (
|
||||||
<div style={{ maxHeight: "600px", overflow: "auto" }}>
|
<div className="max-h-[600px] overflow-auto pb-1">
|
||||||
<RecipientList
|
<RecipientList
|
||||||
signerPos={signerPos}
|
signerPos={signerPos}
|
||||||
signersdata={signersdata}
|
signersdata={signersdata}
|
||||||
@@ -433,14 +391,7 @@ function WidgetComponent({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div className=" p-[20px] text-[15px] font-medium text-center">
|
||||||
style={{
|
|
||||||
padding: 20,
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: "500",
|
|
||||||
textAlign: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Please add a {title ? title : "recipients"}
|
Please add a {title ? title : "recipients"}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { getWidgetType } from "../../constant/Utils";
|
|||||||
function WidgetList(props) {
|
function WidgetList(props) {
|
||||||
return props.updateWidgets.map((item, ind) => {
|
return props.updateWidgets.map((item, ind) => {
|
||||||
return (
|
return (
|
||||||
<div key={ind} style={{ marginBottom: "5px" }}>
|
<div key={ind} className="mb-[5px]">
|
||||||
<div
|
<div
|
||||||
className="widgets"
|
className="select-none"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.addPositionOfSignature &&
|
props.addPositionOfSignature &&
|
||||||
props.addPositionOfSignature("onclick", item);
|
props.addPositionOfSignature("onclick", item);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { textInputWidget } from "../../constant/Utils";
|
|||||||
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
import PremiumAlertHeader from "../../primitives/PremiumAlertHeader";
|
||||||
import Upgrade from "../../primitives/Upgrade";
|
import Upgrade from "../../primitives/Upgrade";
|
||||||
import { isEnableSubscription } from "../../constant/const";
|
import { isEnableSubscription } from "../../constant/const";
|
||||||
|
import Tooltip from "../../primitives/Tooltip";
|
||||||
|
|
||||||
const WidgetNameModal = (props) => {
|
const WidgetNameModal = (props) => {
|
||||||
const [formdata, setFormdata] = useState({
|
const [formdata, setFormdata] = useState({
|
||||||
@@ -121,15 +122,15 @@ const WidgetNameModal = (props) => {
|
|||||||
props.widgetName === textInputWidget
|
props.widgetName === textInputWidget
|
||||||
? "pt-0"
|
? "pt-0"
|
||||||
: ""
|
: ""
|
||||||
} p-[20px]`}
|
} p-[20px] text-base-content`}
|
||||||
>
|
>
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem] text-[13px]">
|
||||||
<label htmlFor="name" style={{ fontSize: 13 }}>
|
<label htmlFor="name">
|
||||||
Name
|
Name
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[red]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
name="name"
|
name="name"
|
||||||
value={formdata.name}
|
value={formdata.name}
|
||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
@@ -139,39 +140,41 @@ const WidgetNameModal = (props) => {
|
|||||||
{(props.defaultdata?.type === textInputWidget ||
|
{(props.defaultdata?.type === textInputWidget ||
|
||||||
props.widgetName === textInputWidget) && (
|
props.widgetName === textInputWidget) && (
|
||||||
<>
|
<>
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem]">
|
||||||
<label
|
<div className="flex items-center gap-1">
|
||||||
htmlFor="textvalidate"
|
<label
|
||||||
className={
|
htmlFor="textvalidate"
|
||||||
!props.isSubscribe && isEnableSubscription && "disabled"
|
className={`${
|
||||||
}
|
!props.isSubscribe && isEnableSubscription
|
||||||
style={{ fontSize: 13 }}
|
? "bg-opacity-50 pointer-events-none"
|
||||||
>
|
: ""
|
||||||
Validation
|
} text-[13px]`}
|
||||||
</label>
|
>
|
||||||
{!props.isSubscribe && isEnableSubscription && <Upgrade />}
|
Validation
|
||||||
|
</label>
|
||||||
|
<Tooltip
|
||||||
|
url={"https://www.w3schools.com/jsref/jsref_obj_regexp.asp"}
|
||||||
|
/>
|
||||||
|
{!props.isSubscribe && isEnableSubscription && <Upgrade />}
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
className={
|
className={`${
|
||||||
!props.isSubscribe && isEnableSubscription && "disabled"
|
!props.isSubscribe && isEnableSubscription
|
||||||
}
|
? "bg-opacity-50 pointer-events-none"
|
||||||
style={{
|
: ""
|
||||||
display: "flex",
|
} flex flex-row gap-[10px] mb-[0.5rem]`}
|
||||||
flexDirection: "row",
|
|
||||||
gap: 10,
|
|
||||||
marginBottom: "0.5rem"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div style={{ width: "100%", position: "relative" }}>
|
<div className="w-full relative group">
|
||||||
<input
|
<input
|
||||||
className="relative z-20 w-[87%] md:w-[92%] p-2.5 border-[1px] border-[#d1d5db] rounded-l-md outline-none text-xs"
|
className="z-20 relative op-input op-input-bordered rounded-r-none op-input-sm focus:outline-none group-hover:border-base-content w-[87%] md:w-[92%] text-xs"
|
||||||
name="textvalidate"
|
name="textvalidate"
|
||||||
placeholder="Enter custom expression"
|
placeholder="Enter custom regular expression"
|
||||||
value={formdata.textvalidate}
|
value={formdata.textvalidate}
|
||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
// onBlur={() => handleBlurRegex()}
|
// onBlur={() => handleBlurRegex()}
|
||||||
/>
|
/>
|
||||||
<select
|
<select
|
||||||
className="validationlist addUserInput"
|
className="validationlist op-input op-input-bordered op-input-sm focus:outline-none group-hover:border-base-content w-full text-xs"
|
||||||
name="textvalidate"
|
name="textvalidate"
|
||||||
value={formdata.textvalidate}
|
value={formdata.textvalidate}
|
||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
@@ -179,17 +182,13 @@ const WidgetNameModal = (props) => {
|
|||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
disabled={formdata?.textvalidate}
|
disabled={formdata?.textvalidate}
|
||||||
style={{ fontSize: "13px" }}
|
className="text-[13px]"
|
||||||
>
|
>
|
||||||
Select...
|
Select...
|
||||||
</option>
|
</option>
|
||||||
{inputOpt.map((data, ind) => {
|
{inputOpt.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<option
|
<option className="text-[13px]" key={ind} value={data}>
|
||||||
style={{ fontSize: "13px" }}
|
|
||||||
key={ind}
|
|
||||||
value={data}
|
|
||||||
>
|
|
||||||
{data}
|
{data}
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
@@ -199,12 +198,12 @@ const WidgetNameModal = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem]">
|
||||||
<label htmlFor="name" style={{ fontSize: 13 }}>
|
<label htmlFor="name" className="text-[13px]">
|
||||||
Default value
|
Default value
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
name="defaultValue"
|
name="defaultValue"
|
||||||
value={formdata.defaultValue}
|
value={formdata.defaultValue}
|
||||||
onChange={(e) => handledefaultChange(e)}
|
onChange={(e) => handledefaultChange(e)}
|
||||||
@@ -222,37 +221,22 @@ const WidgetNameModal = (props) => {
|
|||||||
style={{ fontSize: 12 }}
|
style={{ fontSize: 12 }}
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className="fas fa-exclamation-circle"
|
className="fas fa-exclamation-circle text-[15px]"
|
||||||
style={{ color: "#fab005", fontSize: 15 }}
|
style={{ color: "#fab005" }}
|
||||||
></i>{" "}
|
></i>
|
||||||
invalid default value
|
invalid default value
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem]">
|
||||||
<div
|
<div className="flex flex-row gap-[10px] mb-[0.5rem]">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
gap: 10,
|
|
||||||
marginBottom: "0.5rem"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{statusArr.map((data, ind) => {
|
{statusArr.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={ind} className="flex flex-row gap-[5px] items-center">
|
||||||
key={ind}
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
gap: 5,
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
style={{ accentColor: "red", marginRight: "10px" }}
|
className="mr-[2px] op-radio op-radio-xs"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="status"
|
name="status"
|
||||||
onChange={() =>
|
onChange={() =>
|
||||||
@@ -262,9 +246,7 @@ const WidgetNameModal = (props) => {
|
|||||||
formdata.status.toLowerCase() === data.toLowerCase()
|
formdata.status.toLowerCase() === data.toLowerCase()
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div style={{ fontSize: "13px", fontWeight: "500" }}>
|
<div className="text-[13px] font-medium">{data}</div>
|
||||||
{data}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -272,35 +254,20 @@ const WidgetNameModal = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
{(props.defaultdata?.type === textInputWidget ||
|
{(props.defaultdata?.type === textInputWidget ||
|
||||||
props?.widgetName === textInputWidget) && (
|
props?.widgetName === textInputWidget) && (
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem]">
|
||||||
<label htmlFor="hint" style={{ fontSize: 13 }}>
|
<label htmlFor="hint" className="text-[13px]">
|
||||||
Hint
|
Hint
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
name="hint"
|
name="hint"
|
||||||
value={formdata.hint}
|
value={formdata.hint}
|
||||||
onChange={(e) => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div
|
<div className="h-[1px] w-full mb-[16px] bg-[#b7b3b3]"></div>
|
||||||
style={{
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
height: 1,
|
|
||||||
backgroundColor: "#b7b3b3",
|
|
||||||
width: "100%",
|
|
||||||
marginBottom: "16px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
padding: "5px 20px",
|
|
||||||
backgroundColor: "#32a3ac"
|
|
||||||
}}
|
|
||||||
type="submit"
|
|
||||||
className="finishBtn"
|
|
||||||
>
|
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import Alert from "../../../primitives/Alert";
|
import Alert from "../../../primitives/Alert";
|
||||||
|
import Loader from "../../../primitives/Loader";
|
||||||
|
|
||||||
const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||||
const folderPtr = {
|
const folderPtr = {
|
||||||
@@ -25,9 +26,11 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
|||||||
if (parentFolderId) {
|
if (parentFolderId) {
|
||||||
FolderQuery.equalTo("Folder", folderPtr);
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
FolderQuery.equalTo("Type", "Folder");
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
FolderQuery.notEqualTo("IsArchive", true);
|
||||||
} else {
|
} else {
|
||||||
FolderQuery.doesNotExist("Folder");
|
FolderQuery.doesNotExist("Folder");
|
||||||
FolderQuery.equalTo("Type", "Folder");
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
FolderQuery.notEqualTo("IsArchive", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await FolderQuery.find();
|
const res = await FolderQuery.find();
|
||||||
@@ -49,6 +52,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
|||||||
const exsitQuery = new Parse.Query(folderCls);
|
const exsitQuery = new Parse.Query(folderCls);
|
||||||
exsitQuery.equalTo("Name", name);
|
exsitQuery.equalTo("Name", name);
|
||||||
exsitQuery.equalTo("Type", "Folder");
|
exsitQuery.equalTo("Type", "Folder");
|
||||||
|
exsitQuery.notEqualTo("IsArchive", true);
|
||||||
if (parentFolderId) {
|
if (parentFolderId) {
|
||||||
exsitQuery.equalTo("Folder", folderPtr);
|
exsitQuery.equalTo("Folder", folderPtr);
|
||||||
}
|
}
|
||||||
@@ -110,11 +114,8 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
|||||||
{isAlert && <Alert type={alert.type}>{alert.message}</Alert>}
|
{isAlert && <Alert type={alert.type}>{alert.message}</Alert>}
|
||||||
<div id="createFolder" className="relative">
|
<div id="createFolder" className="relative">
|
||||||
{isLoader && (
|
{isLoader && (
|
||||||
<div className="absolute h-full w-full flex justify-center items-center ">
|
<div className="absolute h-full w-full flex justify-center items-center">
|
||||||
<div
|
<Loader />
|
||||||
style={{ fontSize: "45px", color: "#3dd3e0" }}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<h1 className="text-base font-semibold">Create Folder</h1>
|
<h1 className="text-base font-semibold">Create Folder</h1>
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ const FolderModal = (props) => {
|
|||||||
if (folderPtr) {
|
if (folderPtr) {
|
||||||
FolderQuery.equalTo("Folder", folderPtr);
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
FolderQuery.equalTo("Type", "Folder");
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
FolderQuery.notEqualTo("IsArchive", true);
|
||||||
} else {
|
} else {
|
||||||
FolderQuery.doesNotExist("Folder");
|
FolderQuery.doesNotExist("Folder");
|
||||||
FolderQuery.equalTo("Type", "Folder");
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
FolderQuery.notEqualTo("IsArchive", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await FolderQuery.find();
|
const res = await FolderQuery.find();
|
||||||
|
|||||||
@@ -45,9 +45,11 @@ const SelectFolder = ({ required, onSuccess, folderCls, isReset }) => {
|
|||||||
if (folderPtr) {
|
if (folderPtr) {
|
||||||
FolderQuery.equalTo("Folder", folderPtr);
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
FolderQuery.equalTo("Type", "Folder");
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
FolderQuery.notEqualTo("IsArchive", true);
|
||||||
} else {
|
} else {
|
||||||
FolderQuery.doesNotExist("Folder");
|
FolderQuery.doesNotExist("Folder");
|
||||||
FolderQuery.equalTo("Type", "Folder");
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
FolderQuery.notEqualTo("IsArchive", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await FolderQuery.find();
|
const res = await FolderQuery.find();
|
||||||
@@ -172,7 +174,7 @@ const SelectFolder = ({ required, onSuccess, folderCls, isReset }) => {
|
|||||||
<div className="relative max-w-sm">
|
<div className="relative max-w-sm">
|
||||||
<div
|
<div
|
||||||
onClick={() => SetIsOpen(true)}
|
onClick={() => SetIsOpen(true)}
|
||||||
className=" cursor-pointer rounded px-[20px] py-[20px] bg-white border border-gray-200 shadow flex max-w-sm gap-8 items-center"
|
className=" cursor-pointer rounded px-[20px] py-[20px] bg-base-100 border-[1px] border-base-200 shadow flex max-w-sm gap-8 items-center"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<i
|
<i
|
||||||
|
|||||||
@@ -3,16 +3,6 @@ import Parse from "parse";
|
|||||||
import "../../../styles/AddUser.css";
|
import "../../../styles/AddUser.css";
|
||||||
import AsyncSelect from "react-select/async";
|
import AsyncSelect from "react-select/async";
|
||||||
|
|
||||||
const customStyles = {
|
|
||||||
control: (provided) => ({
|
|
||||||
...provided,
|
|
||||||
fontSize: "13px" // Font size for the control
|
|
||||||
}),
|
|
||||||
option: (provided) => ({
|
|
||||||
...provided,
|
|
||||||
fontSize: "13px" // Font size for the options
|
|
||||||
})
|
|
||||||
};
|
|
||||||
const SelectSigners = (props) => {
|
const SelectSigners = (props) => {
|
||||||
const [userList, setUserList] = useState([]);
|
const [userList, setUserList] = useState([]);
|
||||||
const [selected, setSelected] = useState();
|
const [selected, setSelected] = useState();
|
||||||
@@ -79,32 +69,44 @@ const SelectSigners = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="addusercontainer">
|
<div className="h-full px-[20px] py-[10px] text-base-content">
|
||||||
<div className="form-wrapper">
|
<div className="w-full mx-auto p-[8px]">
|
||||||
<div className="form-section" style={{ marginBottom: 0 }}>
|
<div className="mb-0">
|
||||||
<label style={{ fontSize: 14, fontWeight: "700" }}>Choose User</label>
|
<label className="text-[14px] font-bold">Choose from contacts</label>
|
||||||
<AsyncSelect
|
<AsyncSelect
|
||||||
cacheOptions
|
cacheOptions
|
||||||
defaultOptions
|
defaultOptions
|
||||||
value={selected}
|
value={selected}
|
||||||
loadingMessage={() => "Loading..."}
|
loadingMessage={() => "Loading..."}
|
||||||
noOptionsMessage={() => "User not Found"}
|
noOptionsMessage={() => "Contact not found"}
|
||||||
loadOptions={loadOptions}
|
loadOptions={loadOptions}
|
||||||
onChange={handleOptions}
|
onChange={handleOptions}
|
||||||
styles={customStyles}
|
unstyled
|
||||||
|
classNames={{
|
||||||
|
control: () =>
|
||||||
|
"op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full h-full text-[11px]",
|
||||||
|
valueContainer: () =>
|
||||||
|
"flex flex-row gap-x-[2px] gap-y-[2px] md:gap-y-0 w-full my-[2px]",
|
||||||
|
multiValue: () => "op-badge op-badge-primary h-full text-[11px]",
|
||||||
|
multiValueLabel: () => "mb-[2px]",
|
||||||
|
menu: () =>
|
||||||
|
"mt-1 shadow-md rounded-lg bg-base-200 text-base-content",
|
||||||
|
menuList: () => "shadow-md rounded-lg overflow-hidden",
|
||||||
|
option: () =>
|
||||||
|
"bg-base-200 text-base-content rounded-lg m-1 hover:bg-base-300 p-2",
|
||||||
|
noOptionsMessage: () => "p-2 bg-base-200 rounded-lg m-1 p-2"
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{isError ? (
|
<p
|
||||||
<p style={{ color: "red", fontSize: "12px", margin: "5px" }}>
|
className={`${
|
||||||
Please select signer
|
isError ? "text-[red]" : "text-transparent"
|
||||||
</p>
|
} text-[11px] ml-[6px] my-[2px]`}
|
||||||
) : (
|
>
|
||||||
<p style={{ color: "transparent", fontSize: "12px", margin: "5px" }}>
|
Please select signer
|
||||||
.
|
</p>
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<div>
|
<div>
|
||||||
<button className="submitbutton" onClick={() => handleAdd()}>
|
<button className="op-btn op-btn-primary" onClick={() => handleAdd()}>
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,15 +1,30 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Select from "react-select";
|
import Select from "react-select";
|
||||||
import AddSigner from "../../AddSigner";
|
import AddSigner from "../../AddSigner";
|
||||||
import Modal from "react-modal";
|
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import Tooltip from "../../../primitives/Tooltip";
|
import Tooltip from "../../../primitives/Tooltip";
|
||||||
|
import { createPortal } from "react-dom";
|
||||||
function arrayMove(array, from, to) {
|
function arrayMove(array, from, to) {
|
||||||
array = array.slice();
|
array = array.slice();
|
||||||
array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
|
array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AddSignerModal = ({ isOpen, children }) => {
|
||||||
|
if (!isOpen) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPortal(
|
||||||
|
<div className="op-modal op-modal-open">
|
||||||
|
<div className="op-modal-box p-0 min-w-[90%] md:min-w-[500px] max-h-90 overflow-y-auto hide-scrollbar text-sm">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
document.body
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* react-sortable-hoc is depcreated not usable from react 18.x.x
|
* react-sortable-hoc is depcreated not usable from react 18.x.x
|
||||||
* need to replace it with @dnd-kit
|
* need to replace it with @dnd-kit
|
||||||
@@ -17,7 +32,6 @@ function arrayMove(array, from, to) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const SignersInput = (props) => {
|
const SignersInput = (props) => {
|
||||||
Modal.setAppElement("body");
|
|
||||||
const [state, setState] = useState(undefined);
|
const [state, setState] = useState(undefined);
|
||||||
// const [editFormData, setEditFormData] = useState([]);
|
// const [editFormData, setEditFormData] = useState([]);
|
||||||
const [selected, setSelected] = useState([]);
|
const [selected, setSelected] = useState([]);
|
||||||
@@ -108,15 +122,17 @@ const SignersInput = (props) => {
|
|||||||
<label className="block relative">
|
<label className="block relative">
|
||||||
Signers
|
Signers
|
||||||
{props.required && <span className="text-red-500 text-[13px]">*</span>}
|
{props.required && <span className="text-red-500 text-[13px]">*</span>}
|
||||||
<span className="absolute ml-1 text-xs z-50">
|
<span className="absolute ml-1 text-xs z-30">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id={"signer-tooltip"}
|
id={"signer-tooltip"}
|
||||||
message={"Begin typing a contact's name to see suggested signers from your saved contacts or add new ones. Arrange the signing order by adding signers in the desired sequence. Use the '+' button to include signers and the 'x' to remove them. Each signer will receive an email prompt to sign the document in the order listed."}
|
message={
|
||||||
|
"Begin typing a contact's name to see suggested signers from your saved contacts or add new ones. Arrange the signing order by adding signers in the desired sequence. Use the '+' button to include signers and the 'x' to remove them. Each signer will receive an email prompt to sign the document in the order listed."
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<div style={{ display: "flex", gap: 5 }}>
|
<div className="flex gap-x-[5px]">
|
||||||
<div style={{ flexWrap: "wrap", width: "100%" }}>
|
<div className="w-full">
|
||||||
<Select
|
<Select
|
||||||
onSortEnd={onSortEnd}
|
onSortEnd={onSortEnd}
|
||||||
distance={4}
|
distance={4}
|
||||||
@@ -126,6 +142,22 @@ const SignersInput = (props) => {
|
|||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
closeMenuOnSelect={false}
|
closeMenuOnSelect={false}
|
||||||
required={props.required}
|
required={props.required}
|
||||||
|
noOptionsMessage={() => "Contact not found"}
|
||||||
|
unstyled
|
||||||
|
classNames={{
|
||||||
|
control: () =>
|
||||||
|
"op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full h-full text-[11px]",
|
||||||
|
valueContainer: () =>
|
||||||
|
"flex flex-row gap-x-[2px] gap-y-[2px] md:gap-y-0 w-full my-[2px]",
|
||||||
|
multiValue: () => "op-badge op-badge-primary h-full text-[11px]",
|
||||||
|
multiValueLabel: () => "mb-[2px]",
|
||||||
|
menu: () =>
|
||||||
|
"mt-1 shadow-md rounded-lg bg-base-200 text-base-content",
|
||||||
|
menuList: () => "shadow-md rounded-lg overflow-hidden",
|
||||||
|
option: () =>
|
||||||
|
"bg-base-200 text-base-content rounded-lg m-1 hover:bg-base-300 p-2",
|
||||||
|
noOptionsMessage: () => "p-2 bg-base-200 rounded-lg m-1 p-2"
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -133,66 +165,29 @@ const SignersInput = (props) => {
|
|||||||
setIsModel(true);
|
setIsModel(true);
|
||||||
openModal();
|
openModal();
|
||||||
}}
|
}}
|
||||||
style={{
|
className="cursor-pointer op-input op-input-bordered focus:outline-none hover:border-base-content max-h-[38px] min-w-[48px] flex justify-center items-center"
|
||||||
cursor: "pointer",
|
|
||||||
borderRadius: 4,
|
|
||||||
border: "1px solid #ccc",
|
|
||||||
minHeight: 38,
|
|
||||||
minWidth: 48,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<i className="fas fa-plus"></i>
|
<i className="fas fa-plus"></i>
|
||||||
</div>
|
</div>
|
||||||
<Modal
|
<AddSignerModal isOpen={modalIsOpen}>
|
||||||
isOpen={modalIsOpen}
|
<h3 className="text-base-content font-bold text-lg pt-[15px] px-[20px]">
|
||||||
onRequestClose={handleModalCloseClick}
|
Add Signer
|
||||||
shouldCloseOnOverlayClick={false}
|
</h3>
|
||||||
id="modal1"
|
<button
|
||||||
contentLabel="Modal"
|
onClick={handleModalCloseClick}
|
||||||
style={{
|
className="op-btn op-btn-sm op-btn-circle op-btn-ghost text-base-content absolute right-2 top-2"
|
||||||
content: {
|
>
|
||||||
top: "50%",
|
✕
|
||||||
left: "50%",
|
</button>
|
||||||
right: "auto",
|
{isModal && (
|
||||||
bottom: "auto",
|
<AddSigner
|
||||||
transform: "translate(-50%, -50%)",
|
valueKey={"objectId"}
|
||||||
border: "1px transparent",
|
displayKey={"Name"}
|
||||||
padding: 0
|
details={handleNewDetails}
|
||||||
},
|
closePopup={handleModalCloseClick}
|
||||||
overlay: {
|
/>
|
||||||
width: "100%",
|
)}
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
</AddSignerModal>
|
||||||
zIndex: 50
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="min-w-full md:min-w-[500px]">
|
|
||||||
<div
|
|
||||||
className="flex justify-between rounded-t items-center py-[10px] px-[20px] text-white"
|
|
||||||
style={{ background: "#32a3ac" }}
|
|
||||||
>
|
|
||||||
<div className="text-[1.2rem] font-normal">Add Signer</div>
|
|
||||||
<button
|
|
||||||
onClick={handleModalCloseClick}
|
|
||||||
className="text-[1.5rem] cursor-pointer focus:outline-none"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{isModal && (
|
|
||||||
<AddSigner
|
|
||||||
valueKey={"objectId"}
|
|
||||||
displayKey={"Name"}
|
|
||||||
details={handleNewDetails}
|
|
||||||
closePopup={handleModalCloseClick}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
|
import { findContact } from "../../../constant/Utils";
|
||||||
|
const SuggestionInput = (props) => {
|
||||||
|
const [inputValue, setInputValue] = useState(props?.value || "");
|
||||||
|
const [suggestions, setSuggestions] = useState([]);
|
||||||
|
const [showSuggestions, setShowSuggestions] = useState(false);
|
||||||
|
const ref = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener("mousedown", Clickout);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", Clickout);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const Clickout = (event) => {
|
||||||
|
if (ref.current && !ref.current.contains(event.target)) {
|
||||||
|
setShowSuggestions(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// create debounce to avoid unnecessay api calls
|
||||||
|
useEffect(() => {
|
||||||
|
let timer;
|
||||||
|
if (inputValue) {
|
||||||
|
if (timer) clearTimeout(timer);
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
(async () => {
|
||||||
|
const res = await findContact(inputValue);
|
||||||
|
if (res?.length > 0) {
|
||||||
|
setSuggestions(res);
|
||||||
|
setShowSuggestions(true);
|
||||||
|
} else {
|
||||||
|
setSuggestions(res);
|
||||||
|
setShowSuggestions(false);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [inputValue]);
|
||||||
|
|
||||||
|
const handleInputChange = async (e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
setInputValue(value?.toLowerCase());
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.trim() === "") {
|
||||||
|
setSuggestions([]);
|
||||||
|
setShowSuggestions(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSuggestionClick = (suggestion) => {
|
||||||
|
setInputValue(suggestion.Email);
|
||||||
|
setSuggestions([]);
|
||||||
|
setShowSuggestions(false);
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(suggestion);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center relative text-base-content">
|
||||||
|
<input
|
||||||
|
type={props?.type || "text"}
|
||||||
|
value={inputValue}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
placeholder="Enter Email..."
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs lowercase"
|
||||||
|
required={props.required}
|
||||||
|
/>
|
||||||
|
{showSuggestions && (
|
||||||
|
<ul
|
||||||
|
ref={ref}
|
||||||
|
className="absolute z-50 left-0 top-[2.55rem] w-full max-h-[100px] overflow-auto bg-base-200 border border-gray-300 rounded shadow-md"
|
||||||
|
>
|
||||||
|
{suggestions.map((suggestion, index) => (
|
||||||
|
<li
|
||||||
|
key={index}
|
||||||
|
className="py-2 px-2 w-full text-sm cursor-pointer hover:bg-base-300"
|
||||||
|
onClick={() => handleSuggestionClick(suggestion)}
|
||||||
|
>
|
||||||
|
{suggestion.Email}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default SuggestionInput;
|
||||||
@@ -3,14 +3,18 @@ import { NavLink } from "react-router-dom";
|
|||||||
|
|
||||||
const Menu = ({ item, isOpen, closeSidebar }) => {
|
const Menu = ({ item, isOpen, closeSidebar }) => {
|
||||||
return (
|
return (
|
||||||
<li key={item.title} role="none">
|
<li key={item.title} role="none" className="my-0.5">
|
||||||
<NavLink
|
<NavLink
|
||||||
to={
|
to={
|
||||||
item.pageType
|
item.pageType
|
||||||
? `/${item.pageType}/${item.objectId}`
|
? `/${item.pageType}/${item.objectId}`
|
||||||
: `/${item.objectId}`
|
: `/${item.objectId}`
|
||||||
}
|
}
|
||||||
className="mx-auto flex items-center hover:bg-[#eef1f5] p-3 lg:p-4 cursor-pointer focus:text-[#0056b3] focus:bg-[#eef1f5]"
|
className={({ isActive }) =>
|
||||||
|
`${
|
||||||
|
isActive ? " bg-base-300 text-base-content" : ""
|
||||||
|
} flex items-center text-left p-3 lg:p-4 text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none`
|
||||||
|
}
|
||||||
onClick={closeSidebar}
|
onClick={closeSidebar}
|
||||||
tabIndex={isOpen ? 0 : -1}
|
tabIndex={isOpen ? 0 : -1}
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import dp from "../../assets/images/dp.png";
|
|||||||
|
|
||||||
const Sidebar = ({ isOpen, closeSidebar }) => {
|
const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||||
const [menuList, setmenuList] = useState([]);
|
const [menuList, setmenuList] = useState([]);
|
||||||
|
const [submenuOpen, setSubmenuOpen] = useState(false);
|
||||||
let username = localStorage.getItem("username");
|
let username = localStorage.getItem("username");
|
||||||
const image = localStorage.getItem("profileImg") || dp;
|
const image = localStorage.getItem("profileImg") || dp;
|
||||||
const tenantname = localStorage.getItem("TenantName");
|
const tenantname = localStorage.getItem("TenantName");
|
||||||
@@ -33,10 +34,18 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleSubmenu = (title) => {
|
||||||
|
setSubmenuOpen({ [title]: !submenuOpen[title] });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMenuItem = () => {
|
||||||
|
closeSidebar();
|
||||||
|
setSubmenuOpen({});
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
className={`bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 md:translate-x-0
|
className={`absolute md:relative bg-base-100 h-screen overflow-y-auto transition-all z-[100] hide-scrollbar
|
||||||
${isOpen ? "translate-x-0 block" : "-translate-x-full hidden"}`}
|
${isOpen ? "w-full md:w-[300px]" : "w-0"}`}
|
||||||
>
|
>
|
||||||
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
|
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
|
||||||
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
|
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
|
||||||
@@ -47,13 +56,20 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-[14px] font-bold">{username}</p>
|
<p className="text-[14px] font-bold text-base-content">{username}</p>
|
||||||
<p className={`text-[12px] ${tenantname ? "mt-2" : ""}`}>
|
<p
|
||||||
|
className={`text-[12px] text-base-content ${
|
||||||
|
tenantname ? "mt-2" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
{tenantname}
|
{tenantname}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav aria-label="OpenSign Sidebar Navigation">
|
<nav
|
||||||
|
className="op-menu op-menu-sm"
|
||||||
|
aria-label="OpenSign Sidebar Navigation"
|
||||||
|
>
|
||||||
<ul
|
<ul
|
||||||
className="text-sm"
|
className="text-sm"
|
||||||
role="menubar"
|
role="menubar"
|
||||||
@@ -65,19 +81,21 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
|||||||
key={item.title}
|
key={item.title}
|
||||||
item={item}
|
item={item}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
closeSidebar={closeSidebar}
|
closeSidebar={handleMenuItem}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Submenu
|
<Submenu
|
||||||
key={item.title}
|
key={item.title}
|
||||||
item={item}
|
item={item}
|
||||||
closeSidebar={closeSidebar}
|
closeSidebar={closeSidebar}
|
||||||
|
toggleSubmenu={toggleSubmenu}
|
||||||
|
submenuOpen={submenuOpen}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<footer className="mt-4 flex justify-center items-center text-[25px] text-black gap-3">
|
<footer className="mt-4 flex justify-center items-center text-[25px] text-base-content gap-3">
|
||||||
<SocialMedia />
|
<SocialMedia />
|
||||||
</footer>
|
</footer>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import React, { useState } from "react";
|
import React from "react";
|
||||||
import { NavLink } from "react-router-dom";
|
import { NavLink } from "react-router-dom";
|
||||||
|
|
||||||
const Submenu = ({ item, closeSidebar }) => {
|
const Submenu = ({ item, closeSidebar, toggleSubmenu, submenuOpen }) => {
|
||||||
const [submenuOpen, setSubmenuOpen] = useState(false);
|
|
||||||
const { title, icon, children } = item;
|
const { title, icon, children } = item;
|
||||||
|
|
||||||
const toggleSubmenu = () => {
|
|
||||||
setSubmenuOpen(!submenuOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li role="none">
|
<li role="none" className="my-0.5">
|
||||||
<button
|
<button
|
||||||
onClick={toggleSubmenu}
|
onClick={() => toggleSubmenu(item.title)}
|
||||||
className="w-full flex items-center text-left text-[#444] p-3 lg:p-4 hover:bg-[#eef1f5] focus:outline-none focus:text-[#0056b3] focus:bg-[#eef1f5]"
|
className="flex items-center text-left p-3 lg:p-4 text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none "
|
||||||
aria-expanded={submenuOpen}
|
aria-expanded={submenuOpen}
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-controls={`submenu-${title}`}
|
aria-controls={`submenu-${title}`}
|
||||||
@@ -23,23 +17,29 @@ const Submenu = ({ item, closeSidebar }) => {
|
|||||||
<span className="ml-3 lg:ml-4">{title}</span>
|
<span className="ml-3 lg:ml-4">{title}</span>
|
||||||
<i
|
<i
|
||||||
className={`${
|
className={`${
|
||||||
submenuOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
|
submenuOpen[item.title]
|
||||||
|
? "fa-solid fa-angle-down"
|
||||||
|
: "fa-solid fa-angle-right"
|
||||||
}`}
|
}`}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{submenuOpen && (
|
{submenuOpen[item.title] && (
|
||||||
<ul id={`submenu-${title}`} role="menu" aria-label={`${title} submenu`}>
|
<ul id={`submenu-${title}`} role="menu" aria-label={`${title} submenu`}>
|
||||||
{children.map((childItem) => (
|
{children.map((childItem) => (
|
||||||
<li key={childItem.title} role="none">
|
<li key={childItem.title} role="none" className="my-0.5">
|
||||||
<NavLink
|
<NavLink
|
||||||
to={
|
to={
|
||||||
childItem.pageType
|
childItem.pageType
|
||||||
? `/${childItem.pageType}/${childItem.objectId}`
|
? `/${childItem.pageType}/${childItem.objectId}`
|
||||||
: `/${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 focus:text-[#0056b3] focus:bg-[#eef1f5] cursor-pointer"
|
className={({ isActive }) =>
|
||||||
|
`${
|
||||||
|
isActive ? "bg-base-300 text-base-content" : ""
|
||||||
|
} flex items-center text-left pl-6 md:pl-8 py-2 text-sm cursor-pointer text-base-content hover:text-base-content focus:bg-base-300 hover:bg-base-300 hover:no-underline focus:outline-none`
|
||||||
|
}
|
||||||
onClick={closeSidebar}
|
onClick={closeSidebar}
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
tabIndex={submenuOpen ? 0 : -1}
|
tabIndex={submenuOpen ? 0 : -1}
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { isEnableSubscription, themeColor } from "./const";
|
import { isEnableSubscription } from "./const";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { rgb } from "pdf-lib";
|
import { rgb } from "pdf-lib";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
import { appInfo } from "./appinfo";
|
||||||
|
import { saveAs } from "file-saver";
|
||||||
|
import printModule from "print-js";
|
||||||
|
|
||||||
export const isMobile = window.innerWidth < 767;
|
export const isMobile = window.innerWidth < 767;
|
||||||
export const textInputWidget = "text input";
|
export const textInputWidget = "text input";
|
||||||
export const textWidget = "text";
|
export const textWidget = "text";
|
||||||
export const radioButtonWidget = "radio button";
|
export const radioButtonWidget = "radio button";
|
||||||
export const openInNewTab = (url) => {
|
export const openInNewTab = (url, target) => {
|
||||||
window.open(url, "_blank", "noopener,noreferrer");
|
if (target) {
|
||||||
|
window.open(url, target, "noopener,noreferrer");
|
||||||
|
} else {
|
||||||
|
window.open(url, "_blank", "noopener,noreferrer");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function fetchSubscription(
|
export async function fetchSubscription(
|
||||||
@@ -19,11 +26,12 @@ export async function fetchSubscription(
|
|||||||
isGuestSign = false
|
isGuestSign = false
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const extClass = localStorage.getItem("Extand_Class");
|
const Extand_Class = localStorage.getItem("Extand_Class");
|
||||||
|
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
||||||
|
// console.log("extClass ", extClass);
|
||||||
let extUser;
|
let extUser;
|
||||||
if (extClass) {
|
if (extClass && extClass.length > 0) {
|
||||||
const jsonSender = JSON.parse(extClass);
|
extUser = extClass[0].objectId;
|
||||||
extUser = jsonSender[0].objectId;
|
|
||||||
} else {
|
} else {
|
||||||
extUser = extUserId;
|
extUser = extUserId;
|
||||||
}
|
}
|
||||||
@@ -171,11 +179,10 @@ export const contractUsers = async (email) => {
|
|||||||
.then((Listdata) => {
|
.then((Listdata) => {
|
||||||
const json = Listdata.data;
|
const json = Listdata.data;
|
||||||
let data = [];
|
let data = [];
|
||||||
|
|
||||||
if (json && json.result) {
|
if (json && json.result) {
|
||||||
data.push(json.result);
|
data.push(json.result);
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
return data;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("Err ", err);
|
console.log("Err ", err);
|
||||||
@@ -369,43 +376,21 @@ export const addWidgetOptions = (type) => {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const getWidgetType = (item, marginLeft) => {
|
export const getWidgetType = (item) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="op-btn op-btn-primary op-btn-outline op-btn-sm focus:outline-none outline outline-[1.5px] w-fit md:w-[150px] ml-[6px] md:ml-0 p-0 overflow-hidden">
|
||||||
<div
|
<div className="w-full h-full flex md:justify-between items-center">
|
||||||
className="signatureBtn widgets"
|
<div className="flex justify-start items-center text-[13px] ml-1">
|
||||||
style={{
|
{!isMobile && <i className="fa-sharp fa-solid fa-grip-vertical"></i>}
|
||||||
boxShadow:
|
<span className="text-center text-[15px] ml-[5px] font-semibold">
|
||||||
"0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)",
|
|
||||||
marginLeft: marginLeft && `${marginLeft}px`
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="flex items-center mr-1">
|
|
||||||
{!isMobile && (
|
|
||||||
<i
|
|
||||||
className="fa-sharp fa-solid fa-grip-vertical"
|
|
||||||
style={{ color: "#908d8d", fontSize: "13px", marginLeft: 4 }}
|
|
||||||
></i>
|
|
||||||
)}
|
|
||||||
<span className=" font-[400] text-[15px] text-black ml-[5px]">
|
|
||||||
{item.type}
|
{item.type}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="text-[20px] op-btn op-btn-primary w-[40px] h-full flex justify-center items-center">
|
||||||
style={{
|
<i className={item.icon}></i>
|
||||||
backgroundColor: themeColor,
|
|
||||||
padding: "0 5px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
style={{ color: "white", fontSize: item.iconSize }}
|
|
||||||
className={item.icon}
|
|
||||||
></i>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -561,7 +546,7 @@ export const signPdfFun = async (
|
|||||||
isCustomCompletionMail = true;
|
isCustomCompletionMail = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// below for loop is used to get first signature of user to send if to signpdf
|
// below for loop is used to get first signature of user to send if to signpdf
|
||||||
// for adding it in completion certificate
|
// for adding it in completion certificate
|
||||||
let getSignature;
|
let getSignature;
|
||||||
@@ -662,6 +647,7 @@ export const createDocument = async (template, placeholders, signerData) => {
|
|||||||
Name: Doc.Name,
|
Name: Doc.Name,
|
||||||
URL: Doc.URL,
|
URL: Doc.URL,
|
||||||
SignedUrl: Doc.SignedUrl,
|
SignedUrl: Doc.SignedUrl,
|
||||||
|
SentToOthers: Doc.SentToOthers,
|
||||||
Description: Doc.Description,
|
Description: Doc.Description,
|
||||||
Note: Doc.Note,
|
Note: Doc.Note,
|
||||||
Placeholders: placeholdersArr,
|
Placeholders: placeholdersArr,
|
||||||
@@ -676,7 +662,9 @@ export const createDocument = async (template, placeholders, signerData) => {
|
|||||||
objectId: Doc.CreatedBy.objectId
|
objectId: Doc.CreatedBy.objectId
|
||||||
},
|
},
|
||||||
Signers: signers,
|
Signers: signers,
|
||||||
SendinOrder: Doc?.SendinOrder || false
|
SendinOrder: Doc?.SendinOrder || false,
|
||||||
|
AutomaticReminders: Doc?.AutomaticReminders || false,
|
||||||
|
RemindOnceInEvery: parseInt(Doc?.RemindOnceInEvery || 5)
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1349,8 +1337,8 @@ export const multiSignEmbed = async (
|
|||||||
position.type === radioButtonWidget
|
position.type === radioButtonWidget
|
||||||
? 10
|
? 10
|
||||||
: position.type === "checkbox"
|
: position.type === "checkbox"
|
||||||
? 10
|
? 10
|
||||||
: newUpdateHeight;
|
: newUpdateHeight;
|
||||||
const newHeight = ind ? (ind > 0 ? widgetHeight : 0) : widgetHeight;
|
const newHeight = ind ? (ind > 0 ? widgetHeight : 0) : widgetHeight;
|
||||||
|
|
||||||
if (signyourself) {
|
if (signyourself) {
|
||||||
@@ -2028,3 +2016,150 @@ export const handleSendOTP = async (email) => {
|
|||||||
alert(error.message);
|
alert(error.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//handle download signed pdf
|
||||||
|
export const handleDownloadPdf = async (
|
||||||
|
pdfDetails,
|
||||||
|
pdfUrl,
|
||||||
|
setIsDownloading
|
||||||
|
) => {
|
||||||
|
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
|
||||||
|
setIsDownloading("pdf");
|
||||||
|
try {
|
||||||
|
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||||
|
const axiosRes = await axios.post(
|
||||||
|
`${appInfo.baseUrl}/functions/getsignedurl`,
|
||||||
|
{ url: pdfUrl },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"content-type": "Application/json",
|
||||||
|
"X-Parse-Application-Id": appInfo.appId,
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const url = axiosRes.data.result;
|
||||||
|
saveAs(url, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||||
|
setIsDownloading("");
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in getsignedurl", err);
|
||||||
|
setIsDownloading("");
|
||||||
|
alert("something went wrong, please try again later.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sanitizeFileName = (pdfName) => {
|
||||||
|
// Replace spaces with underscore
|
||||||
|
return pdfName.replace(/ /g, "_");
|
||||||
|
};
|
||||||
|
//function for print digital sign pdf
|
||||||
|
export const handleToPrint = async (event, pdfUrl, setIsDownloading) => {
|
||||||
|
event.preventDefault();
|
||||||
|
setIsDownloading("pdf");
|
||||||
|
try {
|
||||||
|
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||||
|
const axiosRes = await axios.post(
|
||||||
|
`${appInfo.baseUrl}/functions/getsignedurl`,
|
||||||
|
{ url: pdfUrl },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"content-type": "Application/json",
|
||||||
|
"X-Parse-Application-Id": appInfo.appId,
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const url = axiosRes.data.result;
|
||||||
|
const pdf = await getBase64FromUrl(url);
|
||||||
|
const isAndroidDevice = navigator.userAgent.match(/Android/i);
|
||||||
|
const isAppleDevice =
|
||||||
|
(/iPad|iPhone|iPod/.test(navigator.platform) ||
|
||||||
|
(navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)) &&
|
||||||
|
!window.MSStream;
|
||||||
|
if (isAndroidDevice || isAppleDevice) {
|
||||||
|
const byteArray = Uint8Array.from(
|
||||||
|
atob(pdf)
|
||||||
|
.split("")
|
||||||
|
.map((char) => char.charCodeAt(0))
|
||||||
|
);
|
||||||
|
const blob = new Blob([byteArray], { type: "application/pdf" });
|
||||||
|
const blobUrl = URL.createObjectURL(blob);
|
||||||
|
window.open(blobUrl, "_blank");
|
||||||
|
setIsDownloading("");
|
||||||
|
} else {
|
||||||
|
printModule({ printable: pdf, type: "pdf", base64: true });
|
||||||
|
setIsDownloading("");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setIsDownloading("");
|
||||||
|
console.log("err in getsignedurl", err);
|
||||||
|
alert("something went wrong, please try again later.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//handle download signed pdf
|
||||||
|
export const handleDownloadCertificate = async (
|
||||||
|
pdfDetails,
|
||||||
|
setIsDownloading
|
||||||
|
) => {
|
||||||
|
if (pdfDetails?.length > 0 && pdfDetails[0]?.CertificateUrl) {
|
||||||
|
try {
|
||||||
|
await fetch(pdfDetails[0] && pdfDetails[0]?.CertificateUrl);
|
||||||
|
const certificateUrl = pdfDetails[0] && pdfDetails[0]?.CertificateUrl;
|
||||||
|
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in download in certificate", err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsDownloading("certificate");
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
docId: pdfDetails[0]?.objectId
|
||||||
|
};
|
||||||
|
const docDetails = await axios.post(
|
||||||
|
`${localStorage.getItem("baseUrl")}functions/getDocument`,
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (docDetails.data && docDetails.data.result) {
|
||||||
|
const doc = docDetails.data.result;
|
||||||
|
if (doc?.CertificateUrl) {
|
||||||
|
await fetch(doc?.CertificateUrl);
|
||||||
|
const certificateUrl = doc?.CertificateUrl;
|
||||||
|
saveAs(certificateUrl, `Certificate_signed_by_OpenSign™.pdf`);
|
||||||
|
setIsDownloading("");
|
||||||
|
} else {
|
||||||
|
setIsDownloading("certificate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in download in certificate", err);
|
||||||
|
alert("something went wrong, please try again later.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export async function findContact(value) {
|
||||||
|
try {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const contactbook = new Parse.Query("contracts_Contactbook");
|
||||||
|
contactbook.equalTo(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
contactbook.notEqualTo("IsDeleted", true);
|
||||||
|
contactbook.matches("Email", new RegExp(value, "i"));
|
||||||
|
|
||||||
|
const contactRes = await contactbook.find();
|
||||||
|
if (contactRes) {
|
||||||
|
const res = JSON.parse(JSON.stringify(contactRes));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching suggestions:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
export const contactCls = "contracts_Contactbook";
|
export const contactCls = "contracts_Contactbook";
|
||||||
export const templateCls = "contracts_Template";
|
export const templateCls = "contracts_Template";
|
||||||
export const documentCls = "contracts_Document";
|
export const documentCls = "contracts_Document";
|
||||||
export const rejectBtn =
|
|
||||||
"bg-[#ffffff] rounded-sm shadow-md text-[12px] font-semibold uppercase text-black py-1.5 px-4 focus:outline-none text-center border-[1px] border-[#b4b4b4]";
|
|
||||||
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 themeColor = "#47a3ad";
|
||||||
export const iconColor = "#686968";
|
export const iconColor = "#686968";
|
||||||
export const isEnableSubscription = process.env.REACT_APP_ENABLE_SUBSCRIPTION;
|
export const isEnableSubscription = process.env.REACT_APP_ENABLE_SUBSCRIPTION;
|
||||||
|
|||||||
@@ -2,17 +2,16 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
body{
|
body {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom CSS to hide scrollbar */
|
/* Custom CSS to hide scrollbar */
|
||||||
.hide-scrollbar::-webkit-scrollbar {
|
.hide-scrollbar::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hide-scrollbar {
|
.hide-scrollbar {
|
||||||
-ms-overflow-style: none; /* IE and Edge */
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
scrollbar-width: none; /* Firefox */
|
scrollbar-width: none; /* Firefox */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
import DragElement from "./components/pdf/DragElement";
|
import DragElement from "./components/pdf/DragElement";
|
||||||
import TagManager from "react-gtm-module";
|
import TagManager from "react-gtm-module";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
import './polyfills'
|
||||||
const appId = process.env.REACT_APP_APPID
|
const appId = process.env.REACT_APP_APPID
|
||||||
? process.env.REACT_APP_APPID
|
? process.env.REACT_APP_APPID
|
||||||
: "opensign";
|
: "opensign";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export default function reportJson(id) {
|
|||||||
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
||||||
const contactbook = ["Sr.No", "Title", "Email", "Phone"];
|
const contactbook = ["Sr.No", "Title", "Email", "Phone"];
|
||||||
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
||||||
|
const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"];
|
||||||
switch (id) {
|
switch (id) {
|
||||||
// draft documents report
|
// draft documents report
|
||||||
case "ByHuevtCFY":
|
case "ByHuevtCFY":
|
||||||
@@ -14,8 +14,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1231",
|
btnId: "1231",
|
||||||
hoverLabel: "Edit",
|
hoverLabel: "Edit",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa-solid fa-pen",
|
btnIcon: "fa-solid fa-pen",
|
||||||
redirectUrl: "draftDocument",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -23,8 +22,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "2142",
|
btnId: "2142",
|
||||||
hoverLabel: "Delete",
|
hoverLabel: "Delete",
|
||||||
btnColor: "#ff4848",
|
btnColor: "op-btn-secondary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-trash",
|
btnIcon: "fa fa-trash",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "delete"
|
action: "delete"
|
||||||
@@ -43,8 +41,7 @@ export default function reportJson(id) {
|
|||||||
btnId: "4536",
|
btnId: "4536",
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
hoverLabel: "Sign",
|
hoverLabel: "Sign",
|
||||||
btnColor: "#3ac9d6",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa-solid fa-signature",
|
btnIcon: "fa-solid fa-signature",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "pdfRequestFiles",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -62,8 +59,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "8901",
|
btnId: "8901",
|
||||||
hoverLabel: "Share",
|
hoverLabel: "Share",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa-solid fa-share",
|
btnIcon: "fa-solid fa-share",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "share"
|
action: "share"
|
||||||
@@ -71,8 +67,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1588",
|
btnId: "1588",
|
||||||
hoverLabel: "View",
|
hoverLabel: "View",
|
||||||
btnColor: "#3ac9d6",
|
btnColor: "op-btn-secondary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-eye",
|
btnIcon: "fa fa-eye",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "pdfRequestFiles",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -80,11 +75,19 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "2234",
|
btnId: "2234",
|
||||||
hoverLabel: "option",
|
hoverLabel: "option",
|
||||||
btnColor: "transparent",
|
btnColor: "",
|
||||||
textColor: "black",
|
textColor: "black",
|
||||||
btnIcon: "fa-solid fa-ellipsis-vertical fa-lg",
|
btnIcon: "fa-solid fa-ellipsis-vertical fa-lg",
|
||||||
action: "option",
|
action: "option",
|
||||||
subaction: [
|
subaction: [
|
||||||
|
{
|
||||||
|
btnId: "1630",
|
||||||
|
btnLabel: "Resend",
|
||||||
|
hoverLabel: "Resend",
|
||||||
|
btnIcon: "fa-solid fa-envelope",
|
||||||
|
redirectUrl: "",
|
||||||
|
action: "resend"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
btnId: "1688",
|
btnId: "1688",
|
||||||
btnLabel: "Revoke",
|
btnLabel: "Revoke",
|
||||||
@@ -116,8 +119,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1378",
|
btnId: "1378",
|
||||||
hoverLabel: "Edit",
|
hoverLabel: "Edit",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-eye",
|
btnIcon: "fa fa-eye",
|
||||||
redirectUrl: "draftDocument",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -125,8 +127,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1278",
|
btnId: "1278",
|
||||||
hoverLabel: "Delete",
|
hoverLabel: "Delete",
|
||||||
btnColor: "#ff4848",
|
btnColor: "op-btn-secondary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-trash",
|
btnIcon: "fa fa-trash",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "delete"
|
action: "delete"
|
||||||
@@ -144,8 +145,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1458",
|
btnId: "1458",
|
||||||
hoverLabel: "View",
|
hoverLabel: "View",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-eye",
|
btnIcon: "fa fa-eye",
|
||||||
redirectUrl: "draftDocument",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -153,8 +153,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1358",
|
btnId: "1358",
|
||||||
hoverLabel: "Delete",
|
hoverLabel: "Delete",
|
||||||
btnColor: "#ff4848",
|
btnColor: "op-btn-secondary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-trash",
|
btnIcon: "fa fa-trash",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "delete"
|
action: "delete"
|
||||||
@@ -172,8 +171,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1898",
|
btnId: "1898",
|
||||||
hoverLabel: "View",
|
hoverLabel: "View",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-eye",
|
btnIcon: "fa fa-eye",
|
||||||
redirectUrl: "draftDocument",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -181,8 +179,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1998",
|
btnId: "1998",
|
||||||
hoverLabel: "Delete",
|
hoverLabel: "Delete",
|
||||||
btnColor: "#ff4848",
|
btnColor: "op-btn-secondary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-trash",
|
btnIcon: "fa fa-trash",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "delete"
|
action: "delete"
|
||||||
@@ -200,8 +197,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1999",
|
btnId: "1999",
|
||||||
hoverLabel: "Share",
|
hoverLabel: "Share",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa-solid fa-share",
|
btnIcon: "fa-solid fa-share",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "share"
|
action: "share"
|
||||||
@@ -209,8 +205,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "1999",
|
btnId: "1999",
|
||||||
hoverLabel: "View",
|
hoverLabel: "View",
|
||||||
btnColor: "#3ac9d6",
|
btnColor: "op-btn-secondary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-eye",
|
btnIcon: "fa fa-eye",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "pdfRequestFiles",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -218,11 +213,19 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "2234",
|
btnId: "2234",
|
||||||
hoverLabel: "option",
|
hoverLabel: "option",
|
||||||
btnColor: "transparent",
|
btnColor: "",
|
||||||
textColor: "black",
|
textColor: "black",
|
||||||
btnIcon: "fa-solid fa-ellipsis-vertical fa-lg",
|
btnIcon: "fa-solid fa-ellipsis-vertical fa-lg",
|
||||||
action: "option",
|
action: "option",
|
||||||
subaction: [
|
subaction: [
|
||||||
|
{
|
||||||
|
btnId: "1631",
|
||||||
|
btnLabel: "Resend",
|
||||||
|
hoverLabel: "Resend",
|
||||||
|
btnIcon: "fa-solid fa-envelope",
|
||||||
|
redirectUrl: "",
|
||||||
|
action: "resend"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
btnId: "6788",
|
btnId: "6788",
|
||||||
btnLabel: "Revoke",
|
btnLabel: "Revoke",
|
||||||
@@ -253,8 +256,7 @@ export default function reportJson(id) {
|
|||||||
btnId: "2001",
|
btnId: "2001",
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
hoverLabel: "Sign",
|
hoverLabel: "Sign",
|
||||||
btnColor: "#3ac9d6",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa-solid fa-signature",
|
btnIcon: "fa-solid fa-signature",
|
||||||
redirectUrl: "pdfRequestFiles",
|
redirectUrl: "pdfRequestFiles",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -270,8 +272,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "2003",
|
btnId: "2003",
|
||||||
hoverLabel: "Edit",
|
hoverLabel: "Edit",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa-solid fa-pen",
|
btnIcon: "fa-solid fa-pen",
|
||||||
redirectUrl: "draftDocument",
|
redirectUrl: "draftDocument",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
@@ -279,8 +280,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "2004",
|
btnId: "2004",
|
||||||
hoverLabel: "Delete",
|
hoverLabel: "Delete",
|
||||||
btnColor: "#ff4848",
|
btnColor: "op-btn-secondary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-trash",
|
btnIcon: "fa fa-trash",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "delete"
|
action: "delete"
|
||||||
@@ -296,8 +296,7 @@ export default function reportJson(id) {
|
|||||||
{
|
{
|
||||||
btnId: "2204",
|
btnId: "2204",
|
||||||
hoverLabel: "Delete",
|
hoverLabel: "Delete",
|
||||||
btnColor: "#f55a42",
|
btnColor: "op-btn-outline op-btn-error",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa-solid fa-trash",
|
btnIcon: "fa-solid fa-trash",
|
||||||
action: "delete"
|
action: "delete"
|
||||||
}
|
}
|
||||||
@@ -310,14 +309,13 @@ export default function reportJson(id) {
|
|||||||
case "6TeaPr321t":
|
case "6TeaPr321t":
|
||||||
return {
|
return {
|
||||||
reportName: "Templates",
|
reportName: "Templates",
|
||||||
heading: head,
|
heading: templateReport,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnId: "2234",
|
btnId: "2234",
|
||||||
btnLabel: "Use",
|
btnLabel: "Use",
|
||||||
hoverLabel: "Use",
|
hoverLabel: "Use",
|
||||||
btnColor: "#4bd396",
|
btnColor: "op-btn-primary",
|
||||||
textColor: "white",
|
|
||||||
btnIcon: "fa fa-plus",
|
btnIcon: "fa fa-plus",
|
||||||
redirectUrl: "placeHolderSign",
|
redirectUrl: "placeHolderSign",
|
||||||
action: "redirect",
|
action: "redirect",
|
||||||
@@ -325,10 +323,22 @@ export default function reportJson(id) {
|
|||||||
message:
|
message:
|
||||||
"Click the 'Use' button to create a new document from an existing template. "
|
"Click the 'Use' button to create a new document from an existing template. "
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
btnId: "1631",
|
||||||
|
btnLabel: "Quick send",
|
||||||
|
hoverLabel: "Quick send",
|
||||||
|
btnColor: "op-btn-secondary",
|
||||||
|
btnIcon: "fa-solid fa-envelope",
|
||||||
|
redirectUrl: "",
|
||||||
|
action: "bulksend",
|
||||||
|
selector: "tourbulksend",
|
||||||
|
message:
|
||||||
|
"To quickly create and send multiple documents using an existing template, click the 'Quick Send' button."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
btnId: "2234",
|
btnId: "2234",
|
||||||
hoverLabel: "option",
|
hoverLabel: "option",
|
||||||
btnColor: "transparent",
|
btnColor: "",
|
||||||
textColor: "black",
|
textColor: "black",
|
||||||
btnIcon: "fa-solid fa-ellipsis-vertical fa-lg",
|
btnIcon: "fa-solid fa-ellipsis-vertical fa-lg",
|
||||||
action: "option",
|
action: "option",
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
const dashboardJson = [
|
||||||
|
{
|
||||||
|
id: "35KBoSgoAK",
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
colsize: "col-span-12 md:col-span-6 lg:col-span-6",
|
||||||
|
widget: {
|
||||||
|
type: "Card",
|
||||||
|
icon: "fas fa-signature",
|
||||||
|
bgColor: "bg-[#f0058e]",
|
||||||
|
label: "Need your Signature",
|
||||||
|
description: null,
|
||||||
|
data: {
|
||||||
|
id: "e04ee9dc-932d-6b80-0202-703fd154eb74",
|
||||||
|
queryType: "",
|
||||||
|
class: "contracts_Document",
|
||||||
|
query:
|
||||||
|
'where={"$and":[{"AuditTrail.UserPtr":{"$ne":{"__type":"Pointer","className": "contracts_Users","objectId":"#objectId#"}}},{"AuditTrail.Activity":{"$ne":"Signed"}}],"Signers":{"$in":[{"__type":"Pointer","className":"contracts_Users","objectId":"#objectId#"}]},"IsDeclined":{"$ne":true},"IsCompleted":{"$ne":true},"Type":{"$ne":"Folder"},"Placeholders":{"$ne":null},"ExpiryDate":{"#*gt":{"__type":"#Date#","iso":"#today#"}}}&count=1',
|
||||||
|
key: "count",
|
||||||
|
Redirect_type: "Report",
|
||||||
|
Redirect_id: "4Hhwbp482K",
|
||||||
|
tourSection: "tourcard1",
|
||||||
|
tourMessage:
|
||||||
|
"Clicking on this card will take you to the list of documents awaiting your review."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colsize: "col-span-12 md:col-span-6 lg:col-span-6",
|
||||||
|
widget: {
|
||||||
|
type: "Card",
|
||||||
|
icon: "fas fa-sign-out-alt",
|
||||||
|
bgColor: "bg-[#2ed8b6]",
|
||||||
|
label: "Out for signatures",
|
||||||
|
description: null,
|
||||||
|
data: {
|
||||||
|
id: "c1935cc0-28d4-3d73-b72a-8c1e3d18a17f",
|
||||||
|
queryType: "",
|
||||||
|
class: "contracts_Document",
|
||||||
|
query:
|
||||||
|
'where={"Type":{"#*ne":"Folder"},"Signers":{"#*exists":true,"#*ne":[]},"Placeholders":{"#*ne":null},"IsCompleted":{"#*ne":true},"IsDeclined":{"#*ne":true},"IsArchive":{"#*ne":true},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"#UserId.objectId#"},"ExpiryDate":{"#*gt":{"__type":"#Date#","iso":"#today#"}}}&count=1',
|
||||||
|
key: "count",
|
||||||
|
Redirect_type: "Report",
|
||||||
|
Redirect_id: "1MwEuxLEkF",
|
||||||
|
tourSection: "tourcard2",
|
||||||
|
tourMessage:
|
||||||
|
"Clicking on this card will take you to a list of documents awaiting signature."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colsize: "col-span-12 md:col-span-6 lg:col-span-6",
|
||||||
|
widget: {
|
||||||
|
type: "report",
|
||||||
|
reportId: "5Go51Q7T8r",
|
||||||
|
data: {
|
||||||
|
tourSection: "tourreport1",
|
||||||
|
tourMessage:
|
||||||
|
"This is a list of documents that are waiting for your signature."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colsize: "col-span-12 md:col-span-6 lg:col-span-6",
|
||||||
|
widget: {
|
||||||
|
type: "report",
|
||||||
|
reportId: "d9k3UfYHBc",
|
||||||
|
data: {
|
||||||
|
tourSection: "tourreport2",
|
||||||
|
tourMessage:
|
||||||
|
"This is a list of documents you've sent to other parties for signature."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colsize: "col-span-12 md:col-span-12 lg:col-span-12",
|
||||||
|
widget: {
|
||||||
|
type: "report",
|
||||||
|
reportId: "kC5mfynCi4",
|
||||||
|
data: {
|
||||||
|
tourSection: "tourreport3",
|
||||||
|
tourMessage:
|
||||||
|
"This are documents you have started but have not finalized for sending."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
export default dashboardJson;
|
||||||
@@ -52,7 +52,8 @@ const plans = [
|
|||||||
"API Access",
|
"API Access",
|
||||||
"100 API signatures included",
|
"100 API signatures included",
|
||||||
"DocumentId removal from signed docs",
|
"DocumentId removal from signed docs",
|
||||||
"Custom email templates"
|
"Custom email templates",
|
||||||
|
"Auto reminders"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { useNavigate, useLocation, Outlet } from "react-router-dom";
|
|||||||
import { isEnableSubscription } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { useCookies } from "react-cookie";
|
import { useCookies } from "react-cookie";
|
||||||
import { fetchSubscription } from "../constant/Utils";
|
import { fetchSubscription } from "../constant/Utils";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const HomeLayout = () => {
|
const HomeLayout = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -247,27 +248,14 @@ const HomeLayout = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="sticky top-0 z-50">
|
<div className="sticky top-0 z-[101]">
|
||||||
{!isLoader && <Header showSidebar={showSidebar} />}
|
{!isLoader && <Header showSidebar={showSidebar} />}
|
||||||
</div>
|
</div>
|
||||||
{isUserValid ? (
|
{isUserValid ? (
|
||||||
<>
|
<>
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="flex h-[100vh] justify-center items-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -277,7 +265,7 @@ const HomeLayout = () => {
|
|||||||
id="renderList"
|
id="renderList"
|
||||||
className="relative h-screen flex flex-col justify-between w-full overflow-y-auto"
|
className="relative h-screen flex flex-col justify-between w-full overflow-y-auto"
|
||||||
>
|
>
|
||||||
<div className="bg-[#eef1f5] p-3">{<Outlet />}</div>
|
<div className="bg-base-200 p-3">{<Outlet />}</div>
|
||||||
<div className="z-30">
|
<div className="z-30">
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
@@ -298,13 +286,10 @@ const HomeLayout = () => {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<ModalUi title={"Session Expired"} isOpen={true} showClose={false}>
|
<ModalUi showHeader={false} isOpen={true} showClose={false}>
|
||||||
<div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5">
|
<div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5">
|
||||||
<p className="text-xl font-normal">Your session has expired.</p>
|
<p className="text-xl font-medium">Your session has expired.</p>
|
||||||
<button
|
<button onClick={handleLoginBtn} className="op-btn op-btn-neutral">
|
||||||
onClick={handleLoginBtn}
|
|
||||||
className="text-base px-3 py-1.5 rounded shadow-md text-white bg-[#1ab6ce]"
|
|
||||||
>
|
|
||||||
Login
|
Login
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -49,13 +49,13 @@ function ChangePassword() {
|
|||||||
return <Navigate to="/" />;
|
return <Navigate to="/" />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="w-full bg-white shadow rounded p-2">
|
<div className="w-full bg-base-100 text-base-content shadow rounded p-2">
|
||||||
<Title title={"Change Password"} />
|
<Title title={"Change Password"} />
|
||||||
<div className="text-xl font-bold border-b-[1px] border-gray-300">
|
<div className="text-xl font-bold border-b-[1px] border-gray-300">
|
||||||
Change Password
|
Change Password
|
||||||
</div>
|
</div>
|
||||||
<div className="m-2">
|
<div className="m-2">
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit} className=" flex flex-col gap-y-2">
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="currentpassword" className="block text-xs ml-1">
|
<label htmlFor="currentpassword" className="block text-xs ml-1">
|
||||||
Current Password
|
Current Password
|
||||||
@@ -65,7 +65,7 @@ function ChangePassword() {
|
|||||||
name="currentpassword"
|
name="currentpassword"
|
||||||
value={currentpassword}
|
value={currentpassword}
|
||||||
onChange={(e) => setCurrentPassword(e.target.value)}
|
onChange={(e) => setCurrentPassword(e.target.value)}
|
||||||
className="px-3 py-2 mb-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm text-xs w-full"
|
||||||
placeholder="Current Password"
|
placeholder="Current Password"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
@@ -79,7 +79,7 @@ function ChangePassword() {
|
|||||||
name="newpassword"
|
name="newpassword"
|
||||||
value={newpassword}
|
value={newpassword}
|
||||||
onChange={(e) => setnewpassword(e.target.value)}
|
onChange={(e) => setnewpassword(e.target.value)}
|
||||||
className="px-3 py-2 mb-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm text-xs w-full"
|
||||||
placeholder="New Password"
|
placeholder="New Password"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
@@ -91,17 +91,14 @@ function ChangePassword() {
|
|||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
name="confirmpassword"
|
name="confirmpassword"
|
||||||
className="px-3 py-2 mb-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm text-xs w-full"
|
||||||
value={confirmpassword}
|
value={confirmpassword}
|
||||||
onChange={(e) => setconfirmpassword(e.target.value)}
|
onChange={(e) => setconfirmpassword(e.target.value)}
|
||||||
placeholder="Confirm Password"
|
placeholder="Confirm Password"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button type="submit" className="op-btn op-btn-primary shadow-md m-2">
|
||||||
type="submit"
|
|
||||||
className="bg-[#188ae2] m-2 px-4 py-3 rounded-sm shadow-md text-white text-xs font-semibold uppercase"
|
|
||||||
>
|
|
||||||
Change Password
|
Change Password
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Parse from "parse";
|
|
||||||
import "../styles/loader.css";
|
import "../styles/loader.css";
|
||||||
import GetDashboard from "../components/dashboard/GetDashboard";
|
import GetDashboard from "../components/dashboard/GetDashboard";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { saveTourSteps } from "../redux/reducers/TourStepsReducer";
|
import { saveTourSteps } from "../redux/reducers/TourStepsReducer";
|
||||||
|
import dashboardJson from "../json/dashboardJson";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const [dashboard, setdashboard] = useState([]);
|
const [dashboard, setdashboard] = useState({});
|
||||||
const [classnameArray, setclassnameArray] = useState([]);
|
const [loading, setloading] = useState(true);
|
||||||
const [loading, setloading] = useState(false);
|
|
||||||
const [defaultQuery, setDefaultQuery] = useState("");
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("accesstoken")) {
|
if (localStorage.getItem("accesstoken")) {
|
||||||
@@ -30,53 +29,10 @@ const Dashboard = () => {
|
|||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
const getDashboard = async (id) => {
|
const getDashboard = async (id) => {
|
||||||
setloading(true);
|
|
||||||
try {
|
try {
|
||||||
var forms = Parse.Object.extend("w_dashboard");
|
const dashboard = dashboardJson.find((x) => x.id === id);
|
||||||
var query = new Parse.Query(forms);
|
setdashboard(dashboard);
|
||||||
query.equalTo("objectId", id);
|
const dashboardTour = dashboard.columns
|
||||||
const results = await query.first();
|
|
||||||
const resultjson = results.toJSON();
|
|
||||||
let classArray = [];
|
|
||||||
let DefaultQuery = "";
|
|
||||||
resultjson.rows.forEach((x) => {
|
|
||||||
let col_lg = "",
|
|
||||||
col_md = "",
|
|
||||||
col_xs = "",
|
|
||||||
col_sm = "",
|
|
||||||
col_ = "",
|
|
||||||
obj = {};
|
|
||||||
let subItem = [];
|
|
||||||
let item = "";
|
|
||||||
x.columns.forEach((y) => {
|
|
||||||
if (y.widget.type === "customeHtml") {
|
|
||||||
DefaultQuery = y.widget.data[0].default;
|
|
||||||
}
|
|
||||||
if (Number(y["collg"]) > 0) {
|
|
||||||
col_lg = "col-lg-" + y["collg"];
|
|
||||||
}
|
|
||||||
if (Number(y["colmd"]) > 0) {
|
|
||||||
col_md = "col-md-" + y["colmd"];
|
|
||||||
}
|
|
||||||
if (Number(y["colxs"]) > 0) {
|
|
||||||
col_xs = "col-xs-" + y["colxs"];
|
|
||||||
}
|
|
||||||
if (Number(y["colsm"]) > 0) {
|
|
||||||
col_sm = "col-sm-" + y["colsm"];
|
|
||||||
}
|
|
||||||
if (Number(y["col"]) > 0) {
|
|
||||||
col_ = "col-" + y["col"];
|
|
||||||
}
|
|
||||||
item =
|
|
||||||
col_lg + " " + col_md + " " + col_xs + " " + col_sm + " " + col_;
|
|
||||||
subItem.push(item);
|
|
||||||
});
|
|
||||||
obj = subItem;
|
|
||||||
classArray.push(obj);
|
|
||||||
});
|
|
||||||
setdashboard(resultjson.rows);
|
|
||||||
// console.log("resultjson.rows ", resultjson.rows);
|
|
||||||
const arr = resultjson.rows[0].columns
|
|
||||||
.filter((col) => {
|
.filter((col) => {
|
||||||
if (col.widget.data && col.widget.data.tourSection) {
|
if (col.widget.data && col.widget.data.tourSection) {
|
||||||
return col;
|
return col;
|
||||||
@@ -90,14 +46,7 @@ const Dashboard = () => {
|
|||||||
// style: { backgroundColor: "#abd4d2" },
|
// style: { backgroundColor: "#abd4d2" },
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
dispatch(saveTourSteps(arr));
|
dispatch(saveTourSteps(dashboardTour));
|
||||||
// console.log("arr ", arr);
|
|
||||||
setclassnameArray(classArray);
|
|
||||||
if (localStorage.getItem("DashboardDefaultFilter")) {
|
|
||||||
setDefaultQuery(localStorage.getItem("DashboardDefaultFilter"));
|
|
||||||
} else {
|
|
||||||
setDefaultQuery(DefaultQuery);
|
|
||||||
}
|
|
||||||
setloading(false);
|
setloading(false);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Problem", e);
|
console.error("Problem", e);
|
||||||
@@ -105,32 +54,16 @@ const Dashboard = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let _dash = (
|
|
||||||
<GetDashboard
|
|
||||||
dashboard={dashboard}
|
|
||||||
classnameArray={classnameArray}
|
|
||||||
DefaultQuery={defaultQuery}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
if (loading) {
|
|
||||||
_dash = (
|
|
||||||
<div style={{ height: "300px", backgroundColor: "white" }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
marginLeft: "45%",
|
|
||||||
marginTop: "150px",
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Title title="Dashboard" />
|
<Title title="Dashboard" />
|
||||||
{_dash}
|
{loading ? (
|
||||||
|
<div className="h-[300px] w-full bg-white flex justify-center items-center rounded-md">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<GetDashboard dashboard={dashboard} />
|
||||||
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import { NavLink } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import login_img from "../assets/images/login_img.svg";
|
import login_img from "../assets/images/login_img.svg";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import { appInfo } from "../constant/appinfo";
|
import { appInfo } from "../constant/appinfo";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
||||||
|
import { isEnableSubscription } from "../constant/const";
|
||||||
|
import { getAppLogo } from "../constant/Utils";
|
||||||
|
|
||||||
function ForgotPassword() {
|
function ForgotPassword() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
hideNav: ""
|
hideNav: ""
|
||||||
});
|
});
|
||||||
const [sentStatus, setSentStatus] = useState("");
|
const [sentStatus, setSentStatus] = useState("");
|
||||||
|
const [image, setImage] = useState();
|
||||||
|
|
||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
const { name, value } = event.target;
|
const { name, value } = event.target;
|
||||||
setState({ ...state, [name]: value });
|
setState({ ...state, [name]: value });
|
||||||
@@ -51,15 +56,26 @@ function ForgotPassword() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(fetchAppInfo());
|
dispatch(fetchAppInfo());
|
||||||
|
saveLogo();
|
||||||
resize();
|
resize();
|
||||||
window.addEventListener("resize", resize);
|
window.addEventListener("resize", resize);
|
||||||
return () => window.removeEventListener("resize", resize);
|
return () => window.removeEventListener("resize", resize);
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, []);
|
||||||
|
const saveLogo = async () => {
|
||||||
let image = appInfo.applogo;
|
if (isEnableSubscription) {
|
||||||
|
const logo = await getAppLogo();
|
||||||
|
if (logo) {
|
||||||
|
setImage(logo);
|
||||||
|
} else {
|
||||||
|
setImage(appInfo?.applogo || undefined);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setImage(appInfo?.applogo || undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="bg-white">
|
<div>
|
||||||
<Title title="Forgot password page" />
|
<Title title="Forgot password page" />
|
||||||
{sentStatus === "success" && (
|
{sentStatus === "success" && (
|
||||||
<Alert type="success">
|
<Alert type="success">
|
||||||
@@ -69,29 +85,31 @@ function ForgotPassword() {
|
|||||||
{sentStatus === "failed" && (
|
{sentStatus === "failed" && (
|
||||||
<Alert type={"danger"}>Please setup email adapter </Alert>
|
<Alert type={"danger"}>Please setup email adapter </Alert>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div className="md:p-10 lg:p-16">
|
||||||
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
<div className="md:p-4 lg:p-10 p-4 bg-base-100 text-base-content op-card">
|
||||||
<div className="w-[250px] h-[66px] inline-block">
|
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
|
||||||
{state.hideNav ? (
|
{image && (
|
||||||
<img src={image} width="100%" alt="" />
|
<img
|
||||||
) : (
|
src={image}
|
||||||
<img src={image} width="100%" alt="" />
|
className="object-contain h-full"
|
||||||
|
alt="applogo"
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
||||||
<div className="">
|
<div>
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<h2 className="text-[30px] mt-6">Welcome Back !</h2>
|
<h2 className="text-[30px] mt-6">Welcome Back !</h2>
|
||||||
<span className="text-[12px] text-[#878787]">
|
<span className="text-[12px] text-[#878787]">
|
||||||
Reset Your Password
|
Reset Your Password
|
||||||
</span>
|
</span>
|
||||||
<div className="shadow-md rounded my-4">
|
<div className="w-full my-4 op-card bg-base-100 shadow-md outline outline-1 outline-slate-300/50">
|
||||||
<div className="px-6 py-4">
|
<div className="px-6 py-4">
|
||||||
<label className="block text-xs">Email</label>
|
<label className="block text-xs">Email</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="email"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
|
||||||
name="email"
|
name="email"
|
||||||
|
className="op-input op-input-bordered op-input-sm w-full"
|
||||||
value={state.email}
|
value={state.email}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
required
|
required
|
||||||
@@ -99,19 +117,16 @@ function ForgotPassword() {
|
|||||||
<hr className="my-2 border-none" />
|
<hr className="my-2 border-none" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between items-center px-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-center text-xs font-bold">
|
||||||
<button
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
type="submit"
|
|
||||||
className="rounded-sm bg-[#3ac9d6] text-white px-4 py-3 text-xs font-semibold shadow uppercase"
|
|
||||||
>
|
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
<NavLink
|
<button
|
||||||
to="/"
|
onClick={() => navigate("/", { replace: true })}
|
||||||
className="rounded-sm bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] px-4 py-3 text-xs font-semibold shadow uppercase"
|
className="op-btn op-btn-secondary"
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</NavLink>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+198
-126
@@ -11,12 +11,15 @@ import SignersInput from "../components/shared/fields/SignersInput";
|
|||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import PageNotFound from "./PageNotFound";
|
import PageNotFound from "./PageNotFound";
|
||||||
import { SaveFileSize } from "../constant/saveFileSize";
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
import { getFileName, toDataUrl } from "../constant/Utils";
|
import { checkIsSubscribed, getFileName, toDataUrl } from "../constant/Utils";
|
||||||
import { PDFDocument } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { isEnableSubscription, submitBtn } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
|
import Upgrade from "../primitives/Upgrade";
|
||||||
|
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
// `Form` render all type of Form on this basis of their provided in path
|
// `Form` render all type of Form on this basis of their provided in path
|
||||||
function Form() {
|
function Form() {
|
||||||
@@ -48,7 +51,9 @@ const Forms = (props) => {
|
|||||||
TimeToCompleteDays: 15,
|
TimeToCompleteDays: 15,
|
||||||
SendinOrder: "false",
|
SendinOrder: "false",
|
||||||
password: "",
|
password: "",
|
||||||
file: ""
|
file: "",
|
||||||
|
remindOnceInEvery: 5,
|
||||||
|
autoreminder: false
|
||||||
});
|
});
|
||||||
const [fileupload, setFileUpload] = useState("");
|
const [fileupload, setFileUpload] = useState("");
|
||||||
const [fileload, setfileload] = useState(false);
|
const [fileload, setfileload] = useState(false);
|
||||||
@@ -60,6 +65,7 @@ const Forms = (props) => {
|
|||||||
const [isPassword, setIsPassword] = useState(false);
|
const [isPassword, setIsPassword] = useState(false);
|
||||||
const [isDecrypting, setIsDecrypting] = useState(false);
|
const [isDecrypting, setIsDecrypting] = useState(false);
|
||||||
const [isCorrectPass, setIsCorrectPass] = useState(true);
|
const [isCorrectPass, setIsCorrectPass] = useState(true);
|
||||||
|
const [isSubscribe, setIsSubscribe] = useState(false);
|
||||||
const handleStrInput = (e) => {
|
const handleStrInput = (e) => {
|
||||||
setIsCorrectPass(true);
|
setIsCorrectPass(true);
|
||||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
@@ -70,6 +76,17 @@ const Forms = (props) => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [props.title]);
|
}, [props.title]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchSubscription();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
const fetchSubscription = async () => {
|
||||||
|
if (isEnableSubscription) {
|
||||||
|
const getIsSubscribe = await checkIsSubscribed();
|
||||||
|
setIsSubscribe(getIsSubscribe);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function getFileAsArrayBuffer(file) {
|
function getFileAsArrayBuffer(file) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
@@ -383,6 +400,8 @@ const Forms = (props) => {
|
|||||||
if (props.title !== "Sign Yourself") {
|
if (props.title !== "Sign Yourself") {
|
||||||
const isChecked = formData.SendinOrder === "false" ? false : true;
|
const isChecked = formData.SendinOrder === "false" ? false : true;
|
||||||
object.set("SendinOrder", isChecked);
|
object.set("SendinOrder", isChecked);
|
||||||
|
object.set("AutomaticReminders", formData.autoreminder);
|
||||||
|
object.set("RemindOnceInEvery", parseInt(formData.remindOnceInEvery));
|
||||||
}
|
}
|
||||||
object.set("URL", fileupload);
|
object.set("URL", fileupload);
|
||||||
object.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
object.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||||
@@ -402,7 +421,6 @@ const Forms = (props) => {
|
|||||||
className: "contracts_Users",
|
className: "contracts_Users",
|
||||||
objectId: ExtCls[0].objectId
|
objectId: ExtCls[0].objectId
|
||||||
});
|
});
|
||||||
|
|
||||||
const res = await object.save();
|
const res = await object.save();
|
||||||
if (res) {
|
if (res) {
|
||||||
setSigners([]);
|
setSigners([]);
|
||||||
@@ -457,12 +475,19 @@ const Forms = (props) => {
|
|||||||
? "Note to myself"
|
? "Note to myself"
|
||||||
: "Please review and sign this document",
|
: "Please review and sign this document",
|
||||||
TimeToCompleteDays: 15,
|
TimeToCompleteDays: 15,
|
||||||
SendinOrder: "true"
|
SendinOrder: "true",
|
||||||
|
password: "",
|
||||||
|
file: "",
|
||||||
|
remindOnceInEvery: 5,
|
||||||
|
autoreminder: false
|
||||||
});
|
});
|
||||||
setFileUpload("");
|
setFileUpload("");
|
||||||
setpercentage(0);
|
setpercentage(0);
|
||||||
setTimeout(() => setIsReset(false), 50);
|
setTimeout(() => setIsReset(false), 50);
|
||||||
};
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
navigate("/dashboard/35KBoSgoAK");
|
||||||
|
};
|
||||||
const handlePasswordSubmit = async (e) => {
|
const handlePasswordSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsPassword(false);
|
setIsPassword(false);
|
||||||
@@ -536,8 +561,11 @@ const Forms = (props) => {
|
|||||||
inputFileRef.current.value = ""; // Set file input value to empty string
|
inputFileRef.current.value = ""; // Set file input value to empty string
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleAutoReminder = () => {
|
||||||
|
setFormData((prev) => ({ ...prev, autoreminder: !formData.autoreminder }));
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="shadow-md rounded my-2 p-3 bg-[#ffffff] md:border-[1px] md:border-gray-600/50">
|
<div className="shadow-md rounded my-2 p-3 bg-base-100 text-base-content md:border-[1px] md:border-gray-600/50">
|
||||||
<Title title={props?.title} />
|
<Title title={props?.title} />
|
||||||
{isAlert && (
|
{isAlert && (
|
||||||
<Alert type={isErr ? "danger" : "success"}>
|
<Alert type={isErr ? "danger" : "success"}>
|
||||||
@@ -547,16 +575,8 @@ const Forms = (props) => {
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
{isSubmit ? (
|
{isSubmit ? (
|
||||||
<div style={{ height: "300px" }}>
|
<div className="h-[300px] flex justify-center items-center">
|
||||||
<div
|
<Loader />
|
||||||
style={{
|
|
||||||
marginLeft: "45%",
|
|
||||||
marginTop: "150px",
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -567,29 +587,30 @@ const Forms = (props) => {
|
|||||||
>
|
>
|
||||||
<form onSubmit={handlePasswordSubmit}>
|
<form onSubmit={handlePasswordSubmit}>
|
||||||
<div className="px-6 pt-3 pb-2">
|
<div className="px-6 pt-3 pb-2">
|
||||||
<label className="mb-2 text-xs">Password</label>
|
<label className="mb-2 text-xs text-base-content">
|
||||||
|
Password
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="password"
|
name="password"
|
||||||
value={formData.password}
|
value={formData.password}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="w-full op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
placeholder="Enter pdf password"
|
placeholder="Enter pdf password"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
{!isCorrectPass ? (
|
<p
|
||||||
<p className="ml-2 text-[11px] text-red-600">
|
className={`${
|
||||||
Please provide correct password
|
!isCorrectPass
|
||||||
</p>
|
? "text-red-600"
|
||||||
) : (
|
: "text-transparent pointer-events-none"
|
||||||
<p className="ml-2 text-[11px] text-transparent text-red-600">
|
} ml-2 text-[11px] `}
|
||||||
.
|
>
|
||||||
</p>
|
Please provide correct password
|
||||||
)}
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<div className="px-6 mb-3">
|
||||||
<div className="px-6 my-3">
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
<button type="submit" className={submitBtn}>
|
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -605,12 +626,12 @@ const Forms = (props) => {
|
|||||||
style={{ width: `${percentage}%` }}
|
style={{ width: `${percentage}%` }}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-black text-sm">{percentage}%</span>
|
<span className="text-base-content text-sm">{percentage}%</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isDecrypting && (
|
{isDecrypting && (
|
||||||
<div className="flex items-center gap-x-2">
|
<div className="flex items-center gap-x-2">
|
||||||
<span className="text-black text-sm">
|
<span className="text-base-content text-sm">
|
||||||
Decrypting pdf please wait...
|
Decrypting pdf please wait...
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -624,13 +645,13 @@ const Forms = (props) => {
|
|||||||
</label>
|
</label>
|
||||||
{fileupload.length > 0 ? (
|
{fileupload.length > 0 ? (
|
||||||
<div className="flex gap-2 justify-center items-center">
|
<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="flex justify-between items-center op-input op-input-bordered op-input-sm w-full text-x text-[13px]">
|
||||||
<div className="break-all">
|
<div className="break-all">
|
||||||
file selected : {getFileName(fileupload)}
|
file selected : {getFileName(fileupload)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() => setFileUpload("")}
|
onClick={() => setFileUpload("")}
|
||||||
className="cursor-pointer px-[10px] text-[20px] font-bold bg-white text-red-500"
|
className="cursor-pointer px-[10px] text-[20px] font-bold text-red-500"
|
||||||
>
|
>
|
||||||
<i className="fa-solid fa-xmark"></i>
|
<i className="fa-solid fa-xmark"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -643,10 +664,10 @@ const Forms = (props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex gap-2 justify-center items-center">
|
<div className="flex gap-2 justify-center items-center ">
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
className="bg-white px-2 py-1.5 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-file-input op-file-input-bordered op-file-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
onChange={(e) => handleFileInput(e)}
|
onChange={(e) => handleFileInput(e)}
|
||||||
ref={inputFileRef}
|
ref={inputFileRef}
|
||||||
accept={
|
accept={
|
||||||
@@ -674,7 +695,7 @@ const Forms = (props) => {
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
name="Name"
|
name="Name"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={formData.Name}
|
value={formData.Name}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
required
|
required
|
||||||
@@ -684,7 +705,7 @@ const Forms = (props) => {
|
|||||||
<label className="block">Description</label>
|
<label className="block">Description</label>
|
||||||
<input
|
<input
|
||||||
name="Description"
|
name="Description"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={formData.Description}
|
value={formData.Description}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
/>
|
/>
|
||||||
@@ -702,7 +723,7 @@ const Forms = (props) => {
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
name="Note"
|
name="Note"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={formData.Note}
|
value={formData.Note}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
required
|
required
|
||||||
@@ -724,7 +745,7 @@ const Forms = (props) => {
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
name="TimeToCompleteDays"
|
name="TimeToCompleteDays"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={formData.TimeToCompleteDays}
|
value={formData.TimeToCompleteDays}
|
||||||
onChange={(e) => handleStrInput(e)}
|
onChange={(e) => handleStrInput(e)}
|
||||||
required
|
required
|
||||||
@@ -732,105 +753,156 @@ const Forms = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{props.title !== "Sign Yourself" && (
|
{props.title !== "Sign Yourself" && (
|
||||||
<div className="text-xs mt-2">
|
<>
|
||||||
<label className="block">
|
<div className="text-xs mt-2">
|
||||||
Send In Order
|
<label className="block">
|
||||||
<a data-tooltip-id="sendInOrder-tooltip" className="ml-1">
|
Send In Order
|
||||||
<sup>
|
<a data-tooltip-id="sendInOrder-tooltip" className="ml-1">
|
||||||
<i
|
<sup>
|
||||||
className="fa-solid fa-question rounded-full"
|
<i
|
||||||
style={{
|
className="fa-solid fa-question rounded-full"
|
||||||
borderColor: "#33bbff",
|
style={{
|
||||||
color: "#33bbff",
|
borderColor: "#33bbff",
|
||||||
fontSize: 13,
|
color: "#33bbff",
|
||||||
borderWidth: 1.5,
|
fontSize: 13,
|
||||||
padding: "1.5px 4px"
|
borderWidth: 1.5,
|
||||||
}}
|
padding: "1.5px 4px"
|
||||||
></i>
|
}}
|
||||||
</sup>
|
></i>
|
||||||
</a>
|
</sup>
|
||||||
<Tooltip id="sendInOrder-tooltip" className="z-50">
|
</a>
|
||||||
<div className="max-w-[200px] md:max-w-[450px]">
|
<Tooltip id="sendInOrder-tooltip" className="z-50">
|
||||||
<p className="font-bold">Send in Order</p>
|
<div className="max-w-[200px] md:max-w-[450px]">
|
||||||
<p>
|
<p className="font-bold">Send in Order</p>
|
||||||
Choose how you want the signing requests to be sent to
|
<p>
|
||||||
the document signers:
|
Choose how you want the signing requests to be sent to
|
||||||
</p>
|
the document signers:
|
||||||
<p className="p-[5px]">
|
</p>
|
||||||
<ol className="list-disc">
|
<p className="p-[5px]">
|
||||||
<li>
|
<ol className="list-disc">
|
||||||
<span className="font-bold">Yes:</span>
|
<li>
|
||||||
<span>
|
<span className="font-bold">Yes:</span>
|
||||||
{" "}
|
<span>
|
||||||
Selecting this option will send the signing
|
Selecting this option will send the signing
|
||||||
request to the first signer initially. Once the
|
request to the first signer initially. Once the
|
||||||
first signer completes their part, the next signer
|
first signer completes their part, the next
|
||||||
in the sequence will receive the request. This
|
signer in the sequence will receive the request.
|
||||||
process continues until all signers have signed
|
This process continues until all signers have
|
||||||
the document. This method ensures that the
|
signed the document. This method ensures that
|
||||||
document is signed in a specific order.
|
the document is signed in a specific order.
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span className="font-bold">No: </span>
|
<span className="font-bold">No: </span>
|
||||||
<span>
|
<span>
|
||||||
Selecting this option will send the signing links
|
Selecting this option will send the signing
|
||||||
to all signers simultaneously. Every signer can
|
links to all signers simultaneously. Every
|
||||||
sign the document at their convenience, regardless
|
signer can sign the document at their
|
||||||
of whether other signers have completed their
|
convenience, regardless of whether other signers
|
||||||
signatures. This method is faster but does not
|
have completed their signatures. This method is
|
||||||
enforce any signing order among the participants.
|
faster but does not enforce any signing order
|
||||||
</span>
|
among the participants.
|
||||||
</li>
|
</span>
|
||||||
</ol>
|
</li>
|
||||||
</p>
|
</ol>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Select the option that best suits the needs of your
|
Select the option that best suits the needs of your
|
||||||
document processing.
|
document processing.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</label>
|
</label>
|
||||||
|
<div className="flex items-center gap-2 ml-2 mb-1">
|
||||||
<div className="flex items-center gap-2 ml-2 mb-1">
|
<input
|
||||||
<input
|
type="radio"
|
||||||
type="radio"
|
value={"true"}
|
||||||
value={"true"}
|
className="op-radio op-radio-xs"
|
||||||
name="SendinOrder"
|
name="SendinOrder"
|
||||||
checked={formData.SendinOrder === "true"}
|
checked={formData.SendinOrder === "true"}
|
||||||
className=""
|
onChange={handleStrInput}
|
||||||
onChange={handleStrInput}
|
/>
|
||||||
/>
|
<div className="text-center">Yes</div>
|
||||||
<div className="text-center">Yes</div>
|
</div>
|
||||||
|
<div className="flex items-center gap-2 ml-2 mb-1">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
value={"false"}
|
||||||
|
name="SendinOrder"
|
||||||
|
className="op-radio op-radio-xs"
|
||||||
|
checked={formData.SendinOrder === "false"}
|
||||||
|
onChange={handleStrInput}
|
||||||
|
/>
|
||||||
|
<div className="text-center">No</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 ml-2 mb-1">
|
<div className="text-xs mt-2">
|
||||||
<input
|
{!isEnableSubscription && (
|
||||||
type="radio"
|
<PremiumAlertHeader
|
||||||
value={"false"}
|
message={
|
||||||
name="SendinOrder"
|
"Disable Auto reminder is free in beta, this feature will incur a fee later."
|
||||||
checked={formData.SendinOrder === "false"}
|
}
|
||||||
onChange={handleStrInput}
|
/>
|
||||||
/>
|
)}
|
||||||
<div className="text-center">No</div>
|
<span
|
||||||
|
className={
|
||||||
|
isSubscribe || !isEnableSubscription
|
||||||
|
? "font-semibold"
|
||||||
|
: "font-semibold text-gray-300"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Auto reminder{" "}
|
||||||
|
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
||||||
|
</span>
|
||||||
|
<label
|
||||||
|
className={`${
|
||||||
|
isSubscribe || !isEnableSubscription
|
||||||
|
? "cursor-pointer "
|
||||||
|
: "pointer-events-none opacity-50"
|
||||||
|
} relative block items-center mb-0`}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white"
|
||||||
|
checked={formData.autoreminder}
|
||||||
|
onChange={handleAutoReminder}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{formData?.autoreminder === true && (
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">
|
||||||
|
Remind once in every (Days)
|
||||||
|
<span className="text-red-500 text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={formData.remindOnceInEvery}
|
||||||
|
name="remindOnceInEvery"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
onChange={handleStrInput}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center mt-3 gap-2 text-white">
|
<div className="flex items-center mt-3 gap-2">
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
isSubmit && "cursor-progress"
|
isSubmit ? "cursor-progress" : ""
|
||||||
} bg-[#1ab6ce] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 focus:outline-none`}
|
} op-btn op-btn-primary`}
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isSubmit}
|
disabled={isSubmit}
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
className="cursor-pointer bg-[#188ae2] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 text-center ml-[2px] focus:outline-none"
|
className="op-btn op-btn-ghost"
|
||||||
onClick={() => handleReset()}
|
onClick={() => handleCancel()}
|
||||||
>
|
>
|
||||||
Reset
|
Cancel
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import axios from "axios";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import { isEnableSubscription, rejectBtn, submitBtn } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { checkIsSubscribed, copytoData, openInNewTab } from "../constant/Utils";
|
import { checkIsSubscribed, copytoData, openInNewTab } from "../constant/Utils";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
||||||
import Tooltip from "../primitives/Tooltip";
|
import Tooltip from "../primitives/Tooltip";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
function GenerateToken() {
|
function GenerateToken() {
|
||||||
const navigation = useNavigate();
|
const navigation = useNavigate();
|
||||||
@@ -109,24 +110,11 @@ function GenerateToken() {
|
|||||||
{copied && <Alert type="success">Copied</Alert>}
|
{copied && <Alert type="success">Copied</Alert>}
|
||||||
{isErr && <Alert type="danger">Something went wrong!</Alert>}
|
{isErr && <Alert type="danger">Something went wrong!</Alert>}
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="flex justify-center items-center h-screen">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-white flex flex-col justify-center shadow rounded">
|
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow rounded">
|
||||||
{!isEnableSubscription && <PremiumAlertHeader />}
|
{!isEnableSubscription && <PremiumAlertHeader />}
|
||||||
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
||||||
OpenSign™ API{" "}
|
OpenSign™ API{" "}
|
||||||
@@ -144,29 +132,32 @@ function GenerateToken() {
|
|||||||
: "w-full flex flex-col p-2 text-sm opacity-20 pointer-events-none select-none"
|
: "w-full flex flex-col p-2 text-sm opacity-20 pointer-events-none select-none"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<li
|
<li className="flex flex-col md:flex-row justify-between items-center border-y-[1px] border-gray-300 break-all py-2">
|
||||||
className={`flex flex-col md:flex-row justify-between items-center border-y-[1px] border-gray-300 break-all py-2`}
|
<div className="w-full md:w-[70%] flex-col md:flex-row text-xs md:text-[15px] flex items-center gap-x-5 ">
|
||||||
>
|
|
||||||
<div className="w-[70%] flex-col md:flex-row flex items-center gap-5 ">
|
|
||||||
<span className="">Api Token:</span>{" "}
|
<span className="">Api Token:</span>{" "}
|
||||||
<span
|
<span id="token" className="md:text-end py-2 md:py-0">
|
||||||
id="token"
|
<span
|
||||||
className=" md:text-end cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => copytoclipboard(apiToken)}
|
onClick={() => copytoclipboard(apiToken)}
|
||||||
>
|
>
|
||||||
{apiToken ? apiToken : "_____"}
|
{apiToken ? apiToken : "_____"}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
className="op-btn op-btn-accent op-btn-outline op-btn-sm ml-2"
|
||||||
|
onClick={() => copytoclipboard(apiToken)}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-copy"></i>
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
|
||||||
onClick={apiToken ? handleModal : handleSubmit}
|
onClick={apiToken ? handleModal : handleSubmit}
|
||||||
className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-4 py-2 text-xs md:text-base focus:outline-none"
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
{apiToken ? "Regenerate Token" : "Generate Token"}
|
{apiToken ? "Regenerate Token" : "Generate Token"}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div className="flex items-center justify-center ">
|
<div className="flex items-center justify-center ">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -175,7 +166,7 @@ function GenerateToken() {
|
|||||||
"https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"
|
"https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="rounded hover:bg-[#15b4e9] border-[1px] my-2 border-[#15b4e9] text-[#15b4e9] hover:text-white px-11 py-2 text-xs md:text-base focus:outline-none"
|
className="op-btn op-btn-secondary my-2"
|
||||||
>
|
>
|
||||||
View Docs
|
View Docs
|
||||||
</button>
|
</button>
|
||||||
@@ -216,7 +207,7 @@ function GenerateToken() {
|
|||||||
handleClose={handleModal}
|
handleClose={handleModal}
|
||||||
>
|
>
|
||||||
<div className="m-[20px]">
|
<div className="m-[20px]">
|
||||||
<div className="text-lg font-normal text-black">
|
<div className="text-lg font-normal text-base-content">
|
||||||
Are you sure you want to regenerate token it will expire old
|
Are you sure you want to regenerate token it will expire old
|
||||||
token?
|
token?
|
||||||
</div>
|
</div>
|
||||||
@@ -224,11 +215,14 @@ function GenerateToken() {
|
|||||||
<div className="flex items-center mt-3 gap-2 text-white">
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
<button
|
<button
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
className={submitBtn + "ml-[2px]"}
|
className="op-btn op-btn-primary ml-[2px]"
|
||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
<button onClick={handleModal} className={rejectBtn}>
|
<button
|
||||||
|
onClick={handleModal}
|
||||||
|
className="op-btn op-btn-secondary"
|
||||||
|
>
|
||||||
No
|
No
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import "../styles/loginPage.css";
|
|
||||||
import loader from "../assets/images/loader2.gif";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { isEnableSubscription, themeColor } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { contractUsers, getAppLogo } from "../constant/Utils";
|
import { contractUsers, getAppLogo } from "../constant/Utils";
|
||||||
import logo from "../assets/images/logo.png";
|
import logo from "../assets/images/logo.png";
|
||||||
import { appInfo } from "../constant/appinfo";
|
import { appInfo } from "../constant/appinfo";
|
||||||
|
import Parse from "parse";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
function GuestLogin() {
|
function GuestLogin() {
|
||||||
const { id, userMail, contactBookId, base64url } = useParams();
|
const { id, userMail, contactBookId, base64url } = useParams();
|
||||||
let navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [email, setEmail] = useState(userMail);
|
const [email, setEmail] = useState(userMail);
|
||||||
const [OTP, setOTP] = useState("");
|
const [OTP, setOTP] = useState("");
|
||||||
const [EnterOTP, setEnterOtp] = useState(false);
|
const [EnterOTP, setEnterOtp] = useState(false);
|
||||||
@@ -19,9 +19,10 @@ function GuestLogin() {
|
|||||||
const [appLogo, setAppLogo] = useState("");
|
const [appLogo, setAppLogo] = useState("");
|
||||||
const [documentId, setDocumentId] = useState(id);
|
const [documentId, setDocumentId] = useState(id);
|
||||||
const [contactId, setContactId] = useState(contactBookId);
|
const [contactId, setContactId] = useState(contactBookId);
|
||||||
|
const [sendmail, setSendmail] = useState();
|
||||||
|
const [contact, setContact] = useState({ name: "", phone: "", email: "" });
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleServerUrl();
|
handleServerUrl();
|
||||||
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -52,53 +53,51 @@ function GuestLogin() {
|
|||||||
//split url in array from '/'
|
//split url in array from '/'
|
||||||
const checkSplit = decodebase64.split("/");
|
const checkSplit = decodebase64.split("/");
|
||||||
setDocumentId(checkSplit[0]);
|
setDocumentId(checkSplit[0]);
|
||||||
|
setContact((prev) => ({ ...prev, email: checkSplit[1] }));
|
||||||
setEmail(checkSplit[1]);
|
setEmail(checkSplit[1]);
|
||||||
setContactId(checkSplit[2]);
|
const contactId = checkSplit?.[2];
|
||||||
|
setSendmail(checkSplit[3]);
|
||||||
|
if (!contactId) {
|
||||||
|
const params = { email: checkSplit[1], docId: checkSplit[0] };
|
||||||
|
try {
|
||||||
|
const linkContactRes = await Parse.Cloud.run(
|
||||||
|
"linkcontacttodoc",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
// console.log("linkContactRes ", linkContactRes);
|
||||||
|
setContactId(linkContactRes?.contactId);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in link ext contact", err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setContactId(checkSplit[2]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
setOTP(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
//send email OTP function
|
//send email OTP function
|
||||||
const SendOtp = async (e) => {
|
const SendOtp = async () => {
|
||||||
const serverUrl =
|
setLoading(true);
|
||||||
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
setEmail(email);
|
||||||
const parseId =
|
try {
|
||||||
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
const params = { email: email.toString(), docId: documentId };
|
||||||
if (serverUrl && localStorage) {
|
const Otp = await Parse.Cloud.run("SendOTPMailV1", params);
|
||||||
setLoading(true);
|
if (Otp) {
|
||||||
e.preventDefault();
|
setLoading(false);
|
||||||
setEmail(email);
|
setEnterOtp(true);
|
||||||
|
|
||||||
try {
|
|
||||||
let url = `${serverUrl}functions/SendOTPMailV1/`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseId
|
|
||||||
};
|
|
||||||
let body = {
|
|
||||||
email: email.toString(),
|
|
||||||
docId: documentId
|
|
||||||
};
|
|
||||||
let Otp = await axios.post(url, body, { headers: headers });
|
|
||||||
|
|
||||||
if (Otp) {
|
|
||||||
setLoading(false);
|
|
||||||
setEnterOtp(true);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
alert("something went wrong!");
|
|
||||||
}
|
}
|
||||||
} else {
|
} catch (error) {
|
||||||
alert("something went wrong!");
|
alert("something went wrong!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSendOTPBtn = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
await SendOtp();
|
||||||
|
};
|
||||||
|
|
||||||
//verify OTP send on via email
|
//verify OTP send on via email
|
||||||
const VerifyOTP = async (e) => {
|
const VerifyOTP = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -134,7 +133,8 @@ function GuestLogin() {
|
|||||||
`Parse/${parseId}/currentUser`,
|
`Parse/${parseId}/currentUser`,
|
||||||
JSON.stringify(_user)
|
JSON.stringify(_user)
|
||||||
);
|
);
|
||||||
if (contractUserDetails) {
|
// console.log("contractUserDetails ", contractUserDetails);
|
||||||
|
if (contractUserDetails && contractUserDetails.length > 0) {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
"Extand_Class",
|
"Extand_Class",
|
||||||
JSON.stringify(contractUserDetails)
|
JSON.stringify(contractUserDetails)
|
||||||
@@ -146,7 +146,13 @@ function GuestLogin() {
|
|||||||
//save isGuestSigner true in local to handle login flow header in mobile view
|
//save isGuestSigner true in local to handle login flow header in mobile view
|
||||||
localStorage.setItem("isGuestSigner", true);
|
localStorage.setItem("isGuestSigner", true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
navigate(`/load/recipientSignPdf/${documentId}/${contactId}`);
|
if (sendmail === "false") {
|
||||||
|
navigate(
|
||||||
|
`/load/recipientSignPdf/${documentId}/${contactId}?sendmail=${sendmail}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
navigate(`/load/recipientSignPdf/${documentId}/${contactId}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("err ", error);
|
console.log("err ", error);
|
||||||
@@ -155,156 +161,169 @@ function GuestLogin() {
|
|||||||
alert("Please Enter OTP!");
|
alert("Please Enter OTP!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleUserData = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const params = { ...contact, docId: documentId };
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const linkContactRes = await Parse.Cloud.run("linkcontacttodoc", params);
|
||||||
|
// console.log("linkContactRes ", linkContactRes);
|
||||||
|
setContactId(linkContactRes.contactId);
|
||||||
|
setEnterOtp(true);
|
||||||
|
await SendOtp();
|
||||||
|
} catch (err) {
|
||||||
|
setLoading(false);
|
||||||
|
alert("something went wron, please try agian later.");
|
||||||
|
console.log("Err in link ext contact", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleInputChange = (e) => {
|
||||||
|
setContact((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: "2rem", background: "white" }}>
|
<div className="p-[2rem]">
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div
|
<div className="flex flex-col justify-center items-center h-[100vh]">
|
||||||
style={{
|
<Loader />
|
||||||
display: "flex",
|
<span className="text-[13px] text-[gray]">{isLoading.message}</span>
|
||||||
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>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div className="m-1 md:m-2 p-[30px] text-base-content bg-base-100 op-card shadow-md">
|
||||||
style={{
|
<div className="md:w-[250px] md:h-[66px] inline-block overflow-hidden mt-2 mb-11">
|
||||||
margin: "10px",
|
{appLogo && (
|
||||||
border: "0.5px solid #c5c7c9",
|
<img src={appLogo} className="object-contain h-full" alt="logo" />
|
||||||
padding: "30px",
|
)}
|
||||||
boxShadow: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="main_head">
|
|
||||||
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
|
|
||||||
{appLogo && (
|
|
||||||
<img
|
|
||||||
src={appLogo}
|
|
||||||
className="object-contain h-full"
|
|
||||||
alt="logo"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
{contactId ? (
|
||||||
{!EnterOTP ? (
|
<>
|
||||||
<div className="row">
|
{!EnterOTP ? (
|
||||||
<div className="col-sm-6 KLO">
|
<div className="w-full md:w-[50%] text-base-content">
|
||||||
<span className="welcomeText">Welcome Back !</span>
|
<h1 className="text-2xl md:text-[30px]">Welcome Back!</h1>
|
||||||
<br />
|
<legend className="text-[12px] text-[#878787] mt-2">
|
||||||
<span className="KNLO">
|
Verification code is sent to your email
|
||||||
Verification code is sent to your email
|
</legend>
|
||||||
</span>
|
<div className="p-[20px] outline outline-1 outline-slate-300/50 my-2 op-card shadow-md">
|
||||||
<div className="card card-box" style={{ borderRadius: "0px" }}>
|
|
||||||
<div className="card-body">
|
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
name="mobile"
|
name="mobile"
|
||||||
value={email}
|
value={email}
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
disabled
|
disabled
|
||||||
className="loginInput"
|
|
||||||
/>
|
/>
|
||||||
<br />
|
</div>
|
||||||
|
<div className="mt-2">
|
||||||
|
<button
|
||||||
|
className="op-btn op-btn-primary"
|
||||||
|
onClick={(e) => handleSendOTPBtn(e)}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? "Loading..." : "Send OTP"}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="btnContainer">
|
) : (
|
||||||
{loading ? (
|
<form
|
||||||
<button
|
className="w-full md:w-[50%] text-base-content"
|
||||||
type="button"
|
onSubmit={VerifyOTP}
|
||||||
style={{
|
>
|
||||||
background: themeColor,
|
<h1 className="text-2xl md:text-[30px]">Welcome Back!</h1>
|
||||||
color: "white"
|
<legend className="text-[12px] text-[#878787] mt-2">
|
||||||
}}
|
You will get a OTP via Email
|
||||||
className="verifyBtn"
|
</legend>
|
||||||
disabled
|
<div className="p-[20px] pt-[15px] outline outline-1 outline-slate-300/50 op-card my-2 shadow-md">
|
||||||
>
|
<p className="text-sm">Enter Verification Code</p>
|
||||||
<span
|
|
||||||
className="spinner-border spinner-border-sm "
|
|
||||||
role="status"
|
|
||||||
aria-hidden="true"
|
|
||||||
></span>
|
|
||||||
Loading...
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
className="verifyBtn"
|
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white",
|
|
||||||
marginLeft: "0px !important"
|
|
||||||
}}
|
|
||||||
onClick={(e) => SendOtp(e)}
|
|
||||||
>
|
|
||||||
Send OTP
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-sm-6 KLO">
|
|
||||||
<span className="welcomeText">Welcome Back !</span>
|
|
||||||
<br />
|
|
||||||
<span className="KNLO">You will get a OTP via Email</span>
|
|
||||||
<div className="card card-box">
|
|
||||||
<div className="card-body">
|
|
||||||
<label>Enter Verification Code</label>
|
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
className="loginInput"
|
className="mt-2 op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
name="OTP"
|
name="OTP"
|
||||||
value={OTP}
|
value={OTP}
|
||||||
onChange={handleChange}
|
onChange={(e) => setOTP(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<br />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="mt-2">
|
||||||
<div>
|
|
||||||
{loading ? (
|
|
||||||
<button
|
<button
|
||||||
style={{
|
className="op-btn op-btn-primary"
|
||||||
background: themeColor,
|
type="submit"
|
||||||
color: "white"
|
disabled={loading}
|
||||||
}}
|
|
||||||
className="verifyBtn"
|
|
||||||
type="button"
|
|
||||||
disabled
|
|
||||||
>
|
>
|
||||||
<span
|
{loading ? "Loading..." : "Verify"}
|
||||||
className="spinner-border spinner-border-sm "
|
|
||||||
role="status"
|
|
||||||
aria-hidden="true"
|
|
||||||
></span>
|
|
||||||
Loading...
|
|
||||||
</button>
|
</button>
|
||||||
) : (
|
</div>
|
||||||
<button
|
</form>
|
||||||
type="button"
|
)}
|
||||||
onClick={(e) => VerifyOTP(e)}
|
</>
|
||||||
style={{
|
) : (
|
||||||
background: themeColor,
|
<div className="w-full md:w-[50%] text-base-content">
|
||||||
color: "white"
|
<h1 className="text-2xl md:text-[30px]">Welcome</h1>
|
||||||
}}
|
<legend className="text-[12px] text-[#878787] mt-2">
|
||||||
className="verifyBtn"
|
Provide your details
|
||||||
>
|
</legend>
|
||||||
Verify
|
<form
|
||||||
</button>
|
className="p-[20px] pt-[15px] outline outline-1 outline-slate-300/50 my-2 op-card shadow-md"
|
||||||
)}
|
onSubmit={handleUserData}
|
||||||
|
>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label
|
||||||
|
htmlFor="name"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
value={contact.name}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
disabled={loading}
|
||||||
|
required
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="mb-2">
|
||||||
|
<label
|
||||||
|
htmlFor="email"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Email
|
||||||
|
<span className="text-[red] text-[13px]"> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
value={contact.email}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
required
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<label
|
||||||
|
htmlFor="phone"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Phone
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="phone"
|
||||||
|
value={contact.phone}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex justify-start">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="op-btn op-btn-primary"
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? "Loading..." : "Next"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+154
-193
@@ -10,16 +10,13 @@ import { NavLink, useNavigate, useLocation } from "react-router-dom";
|
|||||||
import login_img from "../assets/images/login_img.svg";
|
import login_img from "../assets/images/login_img.svg";
|
||||||
import { useWindowSize } from "../hook/useWindowSize";
|
import { useWindowSize } from "../hook/useWindowSize";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import {
|
import { isEnableSubscription } from "../constant/const";
|
||||||
isEnableSubscription,
|
|
||||||
modalCancelBtnColor,
|
|
||||||
modalSubmitBtnColor
|
|
||||||
} from "../constant/const";
|
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import { appInfo } from "../constant/appinfo";
|
import { appInfo } from "../constant/appinfo";
|
||||||
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
||||||
import { showTenant } from "../redux/reducers/ShowTenant";
|
import { showTenant } from "../redux/reducers/ShowTenant";
|
||||||
import { fetchSubscription, getAppLogo } from "../constant/Utils";
|
import { fetchSubscription, getAppLogo, openInNewTab } from "../constant/Utils";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
function Login() {
|
function Login() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -45,6 +42,7 @@ function Login() {
|
|||||||
});
|
});
|
||||||
const [isModal, setIsModal] = useState(false);
|
const [isModal, setIsModal] = useState(false);
|
||||||
const [image, setImage] = useState();
|
const [image, setImage] = useState();
|
||||||
|
const [isLoginSSO, setIsLoginSSO] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("accesstoken")) {
|
if (localStorage.getItem("accesstoken")) {
|
||||||
@@ -263,7 +261,7 @@ function Login() {
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: results[0].get("Name"),
|
name: results[0].get("Name"),
|
||||||
email: results[0].get("Email"),
|
email: results[0].get("Email"),
|
||||||
phone: results[0].get("Phone"),
|
phone: results[0]?.get("Phone") || "",
|
||||||
company: results[0].get("Company")
|
company: results[0].get("Company")
|
||||||
};
|
};
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@@ -317,7 +315,7 @@ function Login() {
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: _user.name,
|
name: _user.name,
|
||||||
email: email,
|
email: email,
|
||||||
phone: _user.phone
|
phone: _user?.phone || ""
|
||||||
// company: results.get("Company"),
|
// company: results.get("Company"),
|
||||||
};
|
};
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@@ -868,7 +866,7 @@ function Login() {
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: results[0].get("Name"),
|
name: results[0].get("Name"),
|
||||||
email: results[0].get("Email"),
|
email: results[0].get("Email"),
|
||||||
phone: results[0].get("Phone"),
|
phone: results[0]?.get("Phone") || "",
|
||||||
company: results[0].get("Company")
|
company: results[0].get("Company")
|
||||||
};
|
};
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@@ -905,7 +903,7 @@ function Login() {
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: results[0].get("Name"),
|
name: results[0].get("Name"),
|
||||||
email: results[0].get("Email"),
|
email: results[0].get("Email"),
|
||||||
phone: results[0].get("Phone")
|
phone: results[0]?.get("Phone") || ""
|
||||||
// company: results.get("Company"),
|
// company: results.get("Company"),
|
||||||
};
|
};
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@@ -982,7 +980,7 @@ function Login() {
|
|||||||
userDetails: {
|
userDetails: {
|
||||||
name: userInformation.name,
|
name: userInformation.name,
|
||||||
email: userInformation.email,
|
email: userInformation.email,
|
||||||
phone: userInformation.phone,
|
phone: userInformation?.phone || "",
|
||||||
role: "contracts_User",
|
role: "contracts_User",
|
||||||
company: userDetails.Company,
|
company: userDetails.Company,
|
||||||
jobTitle: userDetails.Destination
|
jobTitle: userDetails.Destination
|
||||||
@@ -994,7 +992,7 @@ function Login() {
|
|||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: userInformation.name,
|
name: userInformation.name,
|
||||||
email: userInformation.email,
|
email: userInformation.email,
|
||||||
phone: userInformation.phone,
|
phone: userInformation?.phone || "",
|
||||||
company: userDetails.Company,
|
company: userDetails.Company,
|
||||||
jobTitle: userDetails.JobTitle
|
jobTitle: userDetails.JobTitle
|
||||||
};
|
};
|
||||||
@@ -1016,8 +1014,9 @@ function Login() {
|
|||||||
|
|
||||||
const handleCloseModal = () => {
|
const handleCloseModal = () => {
|
||||||
setIsModal(false);
|
setIsModal(false);
|
||||||
Parse.User.logOut();
|
if (Parse?.User?.current()) {
|
||||||
|
Parse.User.logOut();
|
||||||
|
}
|
||||||
let appdata = localStorage.getItem("userSettings");
|
let appdata = localStorage.getItem("userSettings");
|
||||||
let applogo = localStorage.getItem("appLogo");
|
let applogo = localStorage.getItem("appLogo");
|
||||||
let appName = localStorage.getItem("appName");
|
let appName = localStorage.getItem("appName");
|
||||||
@@ -1040,201 +1039,172 @@ function Login() {
|
|||||||
localStorage.setItem("baseUrl", baseUrl);
|
localStorage.setItem("baseUrl", baseUrl);
|
||||||
localStorage.setItem("parseAppId", appid);
|
localStorage.setItem("parseAppId", appid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// `handleSignInWithSSO` is trigger when user click sign in with sso and open sso authorize endpoint
|
||||||
|
const handleSignInWithSSO = () => {
|
||||||
|
if (isLoginSSO === false) {
|
||||||
|
if (state?.email) {
|
||||||
|
setIsLoginSSO(true);
|
||||||
|
const encodedEmail = encodeURIComponent(state.email);
|
||||||
|
const clientUrl = window.location.origin;
|
||||||
|
const domain = state.email.split("@")?.pop();
|
||||||
|
const ssoApiUrl =
|
||||||
|
process.env.SSO_API_URL || "https://sso.opensignlabs.com/api";
|
||||||
|
openInNewTab(
|
||||||
|
`${ssoApiUrl}/oauth/authorize?response_type=code&provider=saml&tenant=${domain}&product=OpenSign&redirect_uri=${clientUrl}/sso&state=${encodedEmail}`,
|
||||||
|
"_self"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
alert("Please provide email.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="bg-white">
|
<div>
|
||||||
<Title title={"Login Page"} />
|
<Title title={"Login Page"} />
|
||||||
{state.loading && (
|
{state.loading && (
|
||||||
<div
|
<div
|
||||||
aria-live="assertive"
|
aria-live="assertive"
|
||||||
style={{
|
className="fixed w-full h-full flex justify-center items-center bg-black bg-opacity-30 z-50"
|
||||||
position: "fixed",
|
|
||||||
width: "100vw",
|
|
||||||
height: "100vh",
|
|
||||||
backgroundColor: "rgba(0,0,0,0.2)",
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
zIndex: 2
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div
|
<Loader />
|
||||||
role="status"
|
|
||||||
style={{
|
|
||||||
position: "fixed",
|
|
||||||
fontSize: "50px",
|
|
||||||
color: "#3ac9d6",
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
transform: "translate(-50%, -50%)"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
>
|
|
||||||
<span className="sr-only">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{appInfo && appInfo.appId ? (
|
{appInfo && appInfo.appId ? (
|
||||||
<>
|
<>
|
||||||
<div aria-labelledby="loginHeading" role="region">
|
<div
|
||||||
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-4 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
aria-labelledby="loginHeading"
|
||||||
|
role="region"
|
||||||
|
className="md:p-10 lg:p-16"
|
||||||
|
>
|
||||||
|
<div className="md:p-4 lg:p-10 p-4 bg-base-100 text-base-content op-card">
|
||||||
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
|
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
|
||||||
{image && (
|
{image && (
|
||||||
<img
|
<img
|
||||||
src={image}
|
src={image}
|
||||||
className="object-contain h-full"
|
className="object-contain h-full"
|
||||||
alt="The image displays the OpenSign logo with a stylized blue square with an open corner, accompanied by the tagline Seal the Deal, Openly."
|
alt="applogo"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<form onSubmit={handleSubmit} aria-label="Login Form">
|
||||||
<form onSubmit={handleSubmit} aria-label="Login Form">
|
<h1 className="text-[30px] mt-6">Welcome Back!</h1>
|
||||||
<h1 className="text-[30px] mt-6">Welcome Back!</h1>
|
<fieldset>
|
||||||
<fieldset>
|
<legend className="text-[12px] text-[#878787]">
|
||||||
<legend className="text-[12px] text-[#878787]">
|
Login to your account
|
||||||
Login to your account
|
</legend>
|
||||||
</legend>
|
<div className="w-full px-6 py-3 my-1 op-card bg-base-100 shadow-md outline outline-1 outline-slate-300/50">
|
||||||
<div className="px-6 py-4 outline outline-1 outline-slate-300/50 my-2 rounded shadow-md">
|
<label className="block text-xs" htmlFor="email">
|
||||||
<label className="block text-xs" htmlFor="email">
|
Email
|
||||||
Username
|
</label>
|
||||||
</label>
|
<input
|
||||||
<input
|
id="email"
|
||||||
id="email"
|
type="email"
|
||||||
type="text"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded text-xs"
|
name="email"
|
||||||
name="email"
|
value={state.email}
|
||||||
value={state.email}
|
onChange={handleChange}
|
||||||
onChange={handleChange}
|
required
|
||||||
required
|
/>
|
||||||
/>
|
<hr className="my-1 border-none" />
|
||||||
<hr className="my-2 border-none" />
|
{!isLoginSSO && (
|
||||||
<label className="block text-xs" htmlFor="password">
|
<>
|
||||||
Password
|
<label className="block text-xs" htmlFor="password">
|
||||||
</label>
|
Password
|
||||||
<div className="relative">
|
</label>
|
||||||
<input
|
<div className="relative">
|
||||||
id="password"
|
<input
|
||||||
type={state.passwordVisible ? "text" : "password"}
|
id="password"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded text-xs"
|
type={
|
||||||
name="password"
|
state.passwordVisible ? "text" : "password"
|
||||||
value={state.password}
|
}
|
||||||
onChange={handleChange}
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
required
|
name="password"
|
||||||
/>
|
value={state.password}
|
||||||
<span
|
onChange={handleChange}
|
||||||
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer ${
|
required
|
||||||
state.passwordVisible
|
/>
|
||||||
? "text-[#007bff]"
|
<span
|
||||||
: "text-black"
|
className="absolute cursor-pointer top-[50%] right-[10px] -translate-y-[50%] text-base-content"
|
||||||
}`}
|
onClick={togglePasswordVisibility}
|
||||||
onClick={togglePasswordVisibility}
|
>
|
||||||
>
|
{state.passwordVisible ? (
|
||||||
{state.passwordVisible ? (
|
<i className="fa fa-eye-slash text-xs pb-1" /> // Close eye icon
|
||||||
<i className="fa fa-eye-slash text-xs pb-1" /> // Close eye icon
|
) : (
|
||||||
) : (
|
<i className="fa fa-eye text-xs pb-1 " /> // Open eye icon
|
||||||
<i className="fa fa-eye text-xs pb-1 " /> // Open eye icon
|
)}
|
||||||
)}
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
)}
|
||||||
</fieldset>
|
<div className="relative mt-1">
|
||||||
<div className="flex flex-row justify-between items-center ml-4 py-2">
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
className="form-check-label inline-block cursor-pointer"
|
|
||||||
htmlFor="rememberpassword"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
className="form-check-input mr-1"
|
|
||||||
value=""
|
|
||||||
id="rememberpassword"
|
|
||||||
/>
|
|
||||||
<span className="text-[13px]">
|
|
||||||
Remember Password
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<NavLink
|
<NavLink
|
||||||
to="/forgetpassword"
|
to="/forgetpassword"
|
||||||
className="text-[13px] underline focus:outline-none focus:ring-2 focus:ring-blue-600"
|
className="text-[13px] op-link op-link-primary underline-offset-1 focus:outline-none ml-1"
|
||||||
>
|
>
|
||||||
Forgot Password ?
|
Forgot Password?
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
</fieldset>
|
||||||
<button
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-center text-xs font-bold mt-2">
|
||||||
type="submit"
|
<button
|
||||||
className="rounded-sm bg-[#3ac9d6] text-white w-full py-3 shadow outline-none uppercase focus:ring-2 focus:ring-blue-600"
|
type="submit"
|
||||||
disabled={state.loading}
|
className="op-btn op-btn-primary"
|
||||||
>
|
disabled={state.loading}
|
||||||
{state.loading ? "Loading..." : "Login"}
|
>
|
||||||
</button>
|
{state.loading ? "Loading..." : "Login"}
|
||||||
<NavLink
|
</button>
|
||||||
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
|
<button
|
||||||
to={
|
type="button"
|
||||||
|
className="op-btn op-btn-accent"
|
||||||
|
disabled={state.loading}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(
|
||||||
location.search
|
location.search
|
||||||
? "/signup" + location.search
|
? "/signup" + location.search
|
||||||
: "/signup"
|
: "/signup"
|
||||||
}
|
)
|
||||||
style={width < 768 ? { textAlign: "center" } : {}}
|
}
|
||||||
>
|
>
|
||||||
Create Account
|
Create Account
|
||||||
</NavLink>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<br />
|
{(appInfo.googleClietId || isEnableSubscription) && (
|
||||||
{(appInfo.fbAppId || appInfo.googleClietId) && (
|
<div className="op-divider my-4 text-sm">OR</div>
|
||||||
<div className="text-sm flex justify-center items-center">
|
)}
|
||||||
<hr className="border-[1px] border-gray-300 w-full" />
|
<div className="flex flex-col justify-center items-center gap-y-3">
|
||||||
<span className="px-2 text-gray-500 cursor-default">
|
{/* {appInfo?.fbAppId && (
|
||||||
OR
|
|
||||||
</span>
|
|
||||||
<hr className="border-[1px] border-gray-300 w-full" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<br />
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
textAlign: "center",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* {appInfo.fbAppId && appInfo.fbAppId !== "" ? (
|
|
||||||
<LoginFacebook
|
<LoginFacebook
|
||||||
FBCred={appInfo.fbAppId}
|
FBCred={appInfo.fbAppId}
|
||||||
thirdpartyLoginfn={thirdpartyLoginfn}
|
thirdpartyLoginfn={thirdpartyLoginfn}
|
||||||
thirdpartyLoader={state.thirdpartyLoader}
|
thirdpartyLoader={state.thirdpartyLoader}
|
||||||
setThirdpartyLoader={setThirdpartyLoader}
|
setThirdpartyLoader={setThirdpartyLoader}
|
||||||
/>
|
/>
|
||||||
) : null} */}
|
)} */}
|
||||||
</div>
|
{appInfo?.googleClietId && (
|
||||||
<div style={{ margin: "10px 0" }}></div>
|
<GoogleSignInBtn
|
||||||
<div
|
GoogleCred={appInfo.googleClietId}
|
||||||
style={{
|
thirdpartyLoginfn={thirdpartyLoginfn}
|
||||||
textAlign: "center",
|
thirdpartyLoader={state.thirdpartyLoader}
|
||||||
display: "flex",
|
setThirdpartyLoader={setThirdpartyLoader}
|
||||||
alignItems: "center",
|
/>
|
||||||
justifyContent: "center"
|
)}
|
||||||
}}
|
{isEnableSubscription && (
|
||||||
>
|
<div
|
||||||
{appInfo.googleClietId && appInfo.googleClietId !== "" ? (
|
className="cursor-pointer border-[1px] border-gray-300 rounded px-[40px] py-2 font-semibold text-sm hover:border-[#d2e3fc] hover:bg-[#ecf3feb7]"
|
||||||
<GoogleSignInBtn
|
onClick={() => handleSignInWithSSO()}
|
||||||
GoogleCred={appInfo.googleClietId}
|
>
|
||||||
thirdpartyLoginfn={thirdpartyLoginfn}
|
Sign in with SSO
|
||||||
thirdpartyLoader={state.thirdpartyLoader}
|
</div>
|
||||||
setThirdpartyLoader={setThirdpartyLoader}
|
)}
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{width >= 768 && (
|
{width >= 768 && (
|
||||||
<div className="self-center">
|
<div className="place-self-center">
|
||||||
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
||||||
<img
|
<img
|
||||||
src={login_img}
|
src={login_img}
|
||||||
@@ -1249,18 +1219,18 @@ function Login() {
|
|||||||
<Alert type={state.alertType}>{state.alertMsg}</Alert>
|
<Alert type={state.alertType}>{state.alertMsg}</Alert>
|
||||||
</div>
|
</div>
|
||||||
<ModalUi isOpen={isModal} title="Additional Info" showClose={false}>
|
<ModalUi isOpen={isModal} title="Additional Info" showClose={false}>
|
||||||
<form className="px-4 py-3">
|
<form className="px-4 py-3 text-base-content">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label
|
<label
|
||||||
htmlFor="Company"
|
htmlFor="Company"
|
||||||
style={{ display: "flex" }}
|
style={{ display: "flex" }}
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
>
|
>
|
||||||
Company <span style={{ fontSize: 13, color: "red" }}>*</span>
|
Company <span className="text-[red] text-[13px]">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
id="Company"
|
id="Company"
|
||||||
value={userDetails.Company}
|
value={userDetails.Company}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -1279,11 +1249,11 @@ function Login() {
|
|||||||
className="block text-xs text-gray-700 font-semibold"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
>
|
>
|
||||||
Job Title
|
Job Title
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
<span className="text-[red] text-[13px]">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
id="JobTitle"
|
id="JobTitle"
|
||||||
value={userDetails.Destination}
|
value={userDetails.Destination}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -1295,23 +1265,18 @@ function Login() {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4">
|
<div className="mt-4 gap-2 flex flex-row">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="px-3 py-1.5 text-white rounded shadow-md text-center focus:outline-none "
|
className="op-btn op-btn-primary"
|
||||||
onClick={(e) => handleSubmitbtn(e)}
|
onClick={(e) => handleSubmitbtn(e)}
|
||||||
style={{
|
|
||||||
marginRight: 10,
|
|
||||||
backgroundColor: modalSubmitBtnColor
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="py-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
className="op-btn op-btn-ghost"
|
||||||
onClick={handleCloseModal}
|
onClick={handleCloseModal}
|
||||||
style={{ width: 75, backgroundColor: modalCancelBtnColor }}
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
@@ -1321,15 +1286,11 @@ function Login() {
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
aria-live="assertive"
|
||||||
position: "fixed",
|
className="fixed w-full h-full flex justify-center items-center z-50"
|
||||||
fontSize: "50px",
|
>
|
||||||
color: "#3ac9d6",
|
<Loader />
|
||||||
top: "50%",
|
</div>
|
||||||
left: "45%"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { toDataUrl } from "../constant/Utils";
|
|||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { appInfo } from "../constant/appinfo";
|
import { appInfo } from "../constant/appinfo";
|
||||||
import { SaveFileSize } from "../constant/saveFileSize";
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
const ManageSign = () => {
|
const ManageSign = () => {
|
||||||
const appName = appInfo.appname;
|
const appName = appInfo.appname;
|
||||||
const [penColor, setPenColor] = useState("blue");
|
const [penColor, setPenColor] = useState("blue");
|
||||||
@@ -17,7 +19,7 @@ const ManageSign = () => {
|
|||||||
const [isvalue, setIsValue] = useState(false);
|
const [isvalue, setIsValue] = useState(false);
|
||||||
const allColor = ["blue", "red", "black"];
|
const allColor = ["blue", "red", "black"];
|
||||||
const [isLoader, setIsLoader] = useState(true);
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
const [isSuccess, setIsSuccess] = useState(false);
|
const [isAlert, setIsAlert] = useState({ type: "success", message: "" });
|
||||||
const [Initials, setInitials] = useState("");
|
const [Initials, setInitials] = useState("");
|
||||||
const [isInitials, setIsInitials] = useState(false);
|
const [isInitials, setIsInitials] = useState(false);
|
||||||
const [id, setId] = useState("");
|
const [id, setId] = useState("");
|
||||||
@@ -185,12 +187,20 @@ const ManageSign = () => {
|
|||||||
updateSign.set("UserId", userId);
|
updateSign.set("UserId", userId);
|
||||||
const res = await updateSign.save();
|
const res = await updateSign.save();
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
setIsSuccess(true);
|
setIsAlert({
|
||||||
|
type: "success",
|
||||||
|
message: "Signature saved successfully."
|
||||||
|
});
|
||||||
|
setTimeout(() => setIsAlert({}), 2000);
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert(`${err.message}`);
|
setIsAlert({
|
||||||
|
type: "danger",
|
||||||
|
message: `${err.message}`
|
||||||
|
});
|
||||||
|
setTimeout(() => setIsAlert({}), 2000);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@@ -201,12 +211,20 @@ const ManageSign = () => {
|
|||||||
updateSign.set("UserId", userId);
|
updateSign.set("UserId", userId);
|
||||||
const res = await updateSign.save();
|
const res = await updateSign.save();
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
setIsSuccess(true);
|
setIsAlert({
|
||||||
|
type: "success",
|
||||||
|
message: "Signature saved successfully."
|
||||||
|
});
|
||||||
|
setTimeout(() => setIsAlert({}), 2000);
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert(`${err.message}`);
|
setIsAlert({
|
||||||
|
type: "success",
|
||||||
|
message: `${err.message}`
|
||||||
|
});
|
||||||
|
setTimeout(() => setIsAlert({}), 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -224,24 +242,13 @@ const ManageSign = () => {
|
|||||||
setIsValue(true);
|
setIsValue(true);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="relative h-full bg-white flex shadow rounded overflow-auto">
|
<div className="relative h-full bg-base-100 text-base-content flex shadow rounded overflow-auto">
|
||||||
{isLoader && (
|
{isLoader && (
|
||||||
<div className="absolute bg-black bg-opacity-75 z-50 w-full h-full flex justify-center items-center">
|
<div className="absolute bg-black bg-opacity-30 z-50 w-full h-full flex justify-center items-center">
|
||||||
<div
|
<Loader />
|
||||||
style={{ color: "#3dd3e0" }}
|
|
||||||
className="loader-37 text-[45px]"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{isSuccess && (
|
|
||||||
<div
|
|
||||||
className="alert alert-success successBox"
|
|
||||||
role="alert"
|
|
||||||
onAnimationEnd={() => setIsSuccess(false)}
|
|
||||||
>
|
|
||||||
Signature saved successfully!
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{isAlert?.message && <Alert type={isAlert.type}>{isAlert.message}</Alert>}
|
||||||
<div
|
<div
|
||||||
className="mainDiv"
|
className="mainDiv"
|
||||||
style={{
|
style={{
|
||||||
@@ -249,39 +256,13 @@ const ManageSign = () => {
|
|||||||
paddingRight: "10px"
|
paddingRight: "10px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ margin: 20 }}>
|
<div className="m-[20px]">
|
||||||
<div
|
<div className="font-[700] text-[15px] pb-[8px]">My Signature</div>
|
||||||
style={{
|
|
||||||
fontWeight: "700",
|
|
||||||
fontSize: 15,
|
|
||||||
color: "#000",
|
|
||||||
paddingBottom: 8
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
My Signature
|
|
||||||
</div>
|
|
||||||
<div className="signBlock mt-4">
|
<div className="signBlock mt-4">
|
||||||
<div>
|
<div>
|
||||||
<div style={{ position: "relative" }}>
|
<div className="relative">
|
||||||
<div
|
<div className="flex flex-row justify-between w-1/2 pl-[10px]">
|
||||||
style={{
|
<div className="flex flex-row justify-around items-center gap-[10px] mb-[10px]">
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
width: "50%",
|
|
||||||
paddingLeft: 10
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-around",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 10,
|
|
||||||
marginBottom: 10
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<>
|
<>
|
||||||
<span
|
<span
|
||||||
onClick={() => handleSignatureBtn()}
|
onClick={() => handleSignatureBtn()}
|
||||||
@@ -307,24 +288,14 @@ const ManageSign = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ position: "relative" }}>
|
<div className="relative">
|
||||||
<div>
|
<div>
|
||||||
{image ? (
|
{image ? (
|
||||||
<div
|
<div className="signatureCanvas relative border-[2px] border-[#888]">
|
||||||
style={{
|
|
||||||
position: "relative",
|
|
||||||
border: "2px solid #888"
|
|
||||||
}}
|
|
||||||
className="signatureCanvas"
|
|
||||||
>
|
|
||||||
<img
|
<img
|
||||||
alt="preview image"
|
alt="preview image"
|
||||||
src={image}
|
src={image}
|
||||||
style={{
|
className="w-full h-full object-contain"
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
objectFit: "contain"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -366,10 +337,10 @@ const ManageSign = () => {
|
|||||||
key === 0 && penColor === "blue"
|
key === 0 && penColor === "blue"
|
||||||
? "2px solid blue"
|
? "2px solid blue"
|
||||||
: key === 1 && penColor === "red"
|
: key === 1 && penColor === "red"
|
||||||
? "2px solid red"
|
? "2px solid red"
|
||||||
: key === 2 && penColor === "black"
|
: key === 2 && penColor === "black"
|
||||||
? "2px solid black"
|
? "2px solid black"
|
||||||
: "2px solid white"
|
: "2px solid white"
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (key === 0) {
|
if (key === 0) {
|
||||||
@@ -474,10 +445,10 @@ const ManageSign = () => {
|
|||||||
key === 0 && initialPen === "blue"
|
key === 0 && initialPen === "blue"
|
||||||
? "2px solid blue"
|
? "2px solid blue"
|
||||||
: key === 1 && initialPen === "red"
|
: key === 1 && initialPen === "red"
|
||||||
? "2px solid red"
|
? "2px solid red"
|
||||||
: key === 2 && initialPen === "black"
|
: key === 2 && initialPen === "black"
|
||||||
? "2px solid black"
|
? "2px solid black"
|
||||||
: "2px solid white"
|
: "2px solid white"
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (key === 0) {
|
if (key === 0) {
|
||||||
@@ -509,20 +480,11 @@ const ManageSign = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* {!warning && (
|
|
||||||
<div className="warning signWarning" style={{ fontSize: 12 }}>
|
|
||||||
<i
|
|
||||||
className="fas fa-exclamation-circle"
|
|
||||||
style={{ color: "#fab005", fontSize: 15 }}
|
|
||||||
></i>{" "}
|
|
||||||
Please upload signature/Image
|
|
||||||
</div>
|
|
||||||
)} */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ paddingTop: 10 }}>
|
<div style={{ paddingTop: 10 }}>
|
||||||
<button
|
<button
|
||||||
className="customBtn successBtn"
|
className="op-btn op-btn-primary"
|
||||||
onClick={(e) => handleSubmit(e)}
|
onClick={(e) => handleSubmit(e)}
|
||||||
>
|
>
|
||||||
save
|
save
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { useEffect, useState, useRef } from "react";
|
import React, { useEffect, useState, useRef } from "react";
|
||||||
import "../styles/opensigndrive.css";
|
import "../styles/opensigndrive.css";
|
||||||
import loader from "../assets/images/loader2.gif";
|
import { iconColor } from "../constant/const";
|
||||||
import { themeColor, iconColor } from "../constant/const";
|
|
||||||
import { getDrive } from "../constant/Utils";
|
import { getDrive } from "../constant/Utils";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
@@ -10,27 +9,15 @@ import ModalUi from "../primitives/ModalUi";
|
|||||||
import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
||||||
import Tour from "reactour";
|
import Tour from "reactour";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const DriveBody = React.lazy(
|
const DriveBody = React.lazy(
|
||||||
() => import("../components/opensigndrive/DriveBody")
|
() => import("../components/opensigndrive/DriveBody")
|
||||||
);
|
);
|
||||||
const Loader = () => {
|
const AppLoader = () => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="h-[100vh] flex justify-center items-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -279,7 +266,8 @@ function Opensigndrive() {
|
|||||||
setNewFolderName(value);
|
setNewFolderName(value);
|
||||||
};
|
};
|
||||||
//function for create folder
|
//function for create folder
|
||||||
const handleAddFolder = async () => {
|
const handleAddFolder = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
if (newFolderName) {
|
if (newFolderName) {
|
||||||
setIsFolderLoader(true);
|
setIsFolderLoader(true);
|
||||||
const getParentObjId = folderName[folderName.length - 1];
|
const getParentObjId = folderName[folderName.length - 1];
|
||||||
@@ -300,6 +288,7 @@ function Opensigndrive() {
|
|||||||
const exsitQuery = new Parse.Query(foldercls);
|
const exsitQuery = new Parse.Query(foldercls);
|
||||||
exsitQuery.equalTo("Name", newFolderName);
|
exsitQuery.equalTo("Name", newFolderName);
|
||||||
exsitQuery.equalTo("Type", "Folder");
|
exsitQuery.equalTo("Type", "Folder");
|
||||||
|
exsitQuery.notEqualTo("IsArchive", true);
|
||||||
if (parentId) {
|
if (parentId) {
|
||||||
exsitQuery.equalTo("Folder", folderPtr);
|
exsitQuery.equalTo("Folder", folderPtr);
|
||||||
}
|
}
|
||||||
@@ -449,21 +438,10 @@ function Opensigndrive() {
|
|||||||
<React.Fragment key={id}>
|
<React.Fragment key={id}>
|
||||||
<span
|
<span
|
||||||
onClick={() => handleRoute(id, folderData)}
|
onClick={() => handleRoute(id, folderData)}
|
||||||
style={{
|
className="text-[#a64b4e] font-normal cursor-pointer"
|
||||||
color: "#a64b4e",
|
|
||||||
fontWeight: "400",
|
|
||||||
cursor: "pointer"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{data.name}
|
{data.name}
|
||||||
<span
|
<span className="text-[#a64b4e] font-extralight cursor-pointer mx-[4px]">
|
||||||
style={{
|
|
||||||
color: "#a64b4e",
|
|
||||||
fontWeight: "200",
|
|
||||||
cursor: "pointer",
|
|
||||||
margin: "0 4px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -544,411 +522,290 @@ function Opensigndrive() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div style={{ backgroundColor: "white" }} className="folderComponent">
|
<div className="bg-base-100 text-base-content rounded-xl w-full">
|
||||||
<Title title={"OpenSign™ Drive"} drive={true} />
|
<Title title={"OpenSign™ Drive"} drive={true} />
|
||||||
|
<ModalUi
|
||||||
<div>
|
isOpen={isAlert.isShow}
|
||||||
<ModalUi
|
title={"Alert"}
|
||||||
headerColor={"#dc3545"}
|
handleClose={() => {
|
||||||
isOpen={isAlert.isShow}
|
setIsAlert({
|
||||||
title={"Alert"}
|
isShow: false,
|
||||||
handleClose={() => {
|
alertMessage: ""
|
||||||
setIsAlert({
|
});
|
||||||
isShow: false,
|
}}
|
||||||
alertMessage: ""
|
>
|
||||||
});
|
<div className="h-full p-[20px] pb-[15px]">
|
||||||
}}
|
<p>{isAlert.alertMessage}</p>
|
||||||
>
|
<div className="h-[1px] bg-[#9f9f9f] w-full my-[15px]"></div>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<button
|
||||||
<p>{isAlert.alertMessage}</p>
|
onClick={() =>
|
||||||
|
setIsAlert({
|
||||||
<div
|
isShow: false,
|
||||||
style={{
|
alertMessage: ""
|
||||||
height: "1px",
|
})
|
||||||
backgroundColor: "#9f9f9f",
|
}
|
||||||
width: "100%",
|
type="button"
|
||||||
marginTop: "15px",
|
className="op-btn op-btn-neutral op-btn-sm"
|
||||||
marginBottom: "15px"
|
>
|
||||||
}}
|
Close
|
||||||
></div>
|
</button>
|
||||||
<button
|
</div>
|
||||||
onClick={() =>
|
</ModalUi>
|
||||||
setIsAlert({
|
<ModalUi
|
||||||
isShow: false,
|
isOpen={isFolder}
|
||||||
alertMessage: ""
|
title={"Add New Folder"}
|
||||||
})
|
handleClose={oncloseFolder}
|
||||||
}
|
>
|
||||||
type="button"
|
<div className="h-full p-[20px] pt-[10px] pb-[15px]">
|
||||||
className="finishBtn cancelBtn"
|
{folderLoader ? (
|
||||||
|
<div className="h-[200px] flex justify-center items-center">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<form
|
||||||
|
onSubmit={handleAddFolder}
|
||||||
|
className="flex flex-col text-base-content"
|
||||||
>
|
>
|
||||||
Close
|
<label className="py-[8px] text-[15px] font-[400] mb-0">
|
||||||
</button>
|
Name
|
||||||
</div>
|
<span className="text-[red]">*</span>
|
||||||
</ModalUi>
|
</label>
|
||||||
<ModalUi
|
<input
|
||||||
isOpen={isFolder}
|
required
|
||||||
title={"Add New Folder"}
|
className="op-input op-input-bordered op-input-sm"
|
||||||
handleClose={oncloseFolder}
|
type="text"
|
||||||
>
|
value={newFolderName}
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
onChange={(e) => handleFolderName(e)}
|
||||||
{folderLoader ? (
|
/>
|
||||||
<div
|
<span className="text-[red] text-[12px] mt-[6px]">{error}</span>
|
||||||
style={{
|
<div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div>
|
||||||
height: "200px",
|
<div className="flex flex-row">
|
||||||
display: "flex",
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
flexDirection: "column",
|
Add
|
||||||
justifyContent: "center",
|
</button>
|
||||||
alignItems: "center"
|
<button
|
||||||
}}
|
type="button"
|
||||||
>
|
className="op-btn op-btn-ghost ml-1"
|
||||||
<img
|
onClick={oncloseFolder}
|
||||||
alt="loader img"
|
>
|
||||||
src={loader}
|
Close
|
||||||
style={{ width: "50px", height: "50px" }}
|
</button>
|
||||||
/>
|
|
||||||
<span style={{ fontSize: "13px", color: "gray" }}>
|
|
||||||
Loading...
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
</form>
|
||||||
<form
|
)}
|
||||||
onSubmit={(e) => {
|
</div>
|
||||||
e.preventDefault();
|
</ModalUi>
|
||||||
handleAddFolder();
|
{isLoading.isLoad ? (
|
||||||
}}
|
<div className="flex flex-col justify-center items-center h-[100vh] w-full">
|
||||||
style={{ display: "flex", flexDirection: "column" }}
|
<Loader />
|
||||||
>
|
<span className="text-[13px] text-[gray]">{isLoading.message}</span>
|
||||||
<label
|
</div>
|
||||||
style={{
|
) : handleError ? (
|
||||||
margin: "10px 0px 10px 0px",
|
<div className="flex justify-center items-center h-[100vh] w-full">
|
||||||
fontSize: "15px",
|
<span className="text-[20px] text-[gray]">{handleError}</span>
|
||||||
fontWeight: "400"
|
</div>
|
||||||
}}
|
) : (
|
||||||
>
|
<>
|
||||||
Name
|
<div className="flex flex-row justify-between items-center px-[25px] pt-[20px]">
|
||||||
<span style={{ color: "red" }}>*</span>
|
{tourData && (
|
||||||
</label>
|
<Tour
|
||||||
|
onRequestClose={closeTour}
|
||||||
<input
|
steps={tourData}
|
||||||
required
|
isOpen={isTour}
|
||||||
className="form-control inputStyle"
|
closeWithMask={false}
|
||||||
type="text"
|
scrollOffset={-100}
|
||||||
value={newFolderName}
|
rounded={5}
|
||||||
onChange={(e) => handleFolderName(e)}
|
/>
|
||||||
// className="addFolderInput"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{ color: "red", fontSize: "12px", marginTop: "6px" }}
|
|
||||||
>
|
|
||||||
{error}
|
|
||||||
</span>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
|
||||||
<button
|
|
||||||
style={{ background: themeColor }}
|
|
||||||
type="submit"
|
|
||||||
className="finishBtn"
|
|
||||||
>
|
|
||||||
Add
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="finishBtn cancelBtn"
|
|
||||||
onClick={oncloseFolder}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
<div
|
||||||
</ModalUi>
|
data-tut="reactourFirst"
|
||||||
|
onMouseEnter={(e) => handleMouseEnter(e)}
|
||||||
{isLoading.isLoad ? (
|
ref={scrollRef}
|
||||||
<div
|
className="w-full whitespace-nowrap cursor-pointer select-none overflow-x-auto"
|
||||||
style={{
|
>
|
||||||
display: "flex",
|
{handleFolderTab(folderName)}
|
||||||
justifyContent: "center",
|
</div>
|
||||||
alignItems: "center",
|
<div className="dropMenuBD">
|
||||||
height: "100vh",
|
|
||||||
width: "100%",
|
|
||||||
flexDirection: "column"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="loader img"
|
|
||||||
src={loader}
|
|
||||||
style={{ width: "80px", height: "80px" }}
|
|
||||||
/>
|
|
||||||
<span style={{ fontSize: "13px", color: "gray" }}>
|
|
||||||
{isLoading.message}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
) : handleError ? (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
height: "100vh",
|
|
||||||
width: "100%"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: "20px", color: "gray" }}>
|
|
||||||
{handleError}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="folderContainer">
|
|
||||||
{tourData && (
|
|
||||||
<Tour
|
|
||||||
onRequestClose={closeTour}
|
|
||||||
steps={tourData}
|
|
||||||
isOpen={isTour}
|
|
||||||
closeWithMask={false}
|
|
||||||
scrollOffset={-100}
|
|
||||||
rounded={5}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
data-tut="reactourFirst"
|
id="folder-menu"
|
||||||
onMouseEnter={(e) => handleMouseEnter(e)}
|
className={
|
||||||
ref={scrollRef}
|
isNewFol ? "dropdown show dropDownStyle" : "dropdown"
|
||||||
style={{
|
}
|
||||||
width: "100%"
|
onClick={() => setIsNewFol(!isNewFol)}
|
||||||
}}
|
|
||||||
className="folderPath"
|
|
||||||
>
|
>
|
||||||
{handleFolderTab(folderName)}
|
<div className="sort" data-tut="reactourSecond">
|
||||||
</div>
|
<i
|
||||||
<div className="dropMenuBD">
|
className="fa fa-plus-square"
|
||||||
<div
|
aria-hidden="true"
|
||||||
id="folder-menu"
|
style={{ fontSize: "25px", color: `${iconColor}` }}
|
||||||
className={
|
></i>
|
||||||
isNewFol ? "dropdown show dropDownStyle" : "dropdown"
|
|
||||||
}
|
|
||||||
onClick={() => setIsNewFol(!isNewFol)}
|
|
||||||
>
|
|
||||||
<div className="sort" data-tut="reactourSecond">
|
|
||||||
<i
|
|
||||||
className="fa fa-plus-square"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ fontSize: "25px", color: `${iconColor}` }}
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
isNewFol ? "dropdown-menu show" : "dropdown-menu"
|
|
||||||
}
|
|
||||||
aria-labelledby="dropdownMenuButton"
|
|
||||||
aria-expanded={isNewFol ? "true" : "false"}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="dropdown-item itemColor"
|
|
||||||
onClick={() => setIsFolder(true)}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
className="fa fa-plus"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
Create folder
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="dropdown-item itemColor"
|
|
||||||
onClick={() => navigate("/form/sHAnZphf69")}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
className="fas fa-pen-nib"
|
|
||||||
></i>
|
|
||||||
Sign Yourself
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="dropdown-item itemColor"
|
|
||||||
onClick={() => navigate("/form/8mZzFxbG1z")}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
<i
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
className="fa fa-file-signature"
|
|
||||||
></i>
|
|
||||||
Request Signatures{" "}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="menu-container"
|
className={isNewFol ? "dropdown-menu show" : "dropdown-menu"}
|
||||||
className={isShowSort ? "dropdown show" : "dropdown"}
|
aria-labelledby="dropdownMenuButton"
|
||||||
onClick={() => setIsShowSort(!isShowSort)}
|
aria-expanded={isNewFol ? "true" : "false"}
|
||||||
>
|
>
|
||||||
<div
|
<div className="flex flex-col">
|
||||||
data-tut="reactourThird"
|
|
||||||
className=" sort "
|
|
||||||
data-toggle="dropdown"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-sort-amount-asc"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{
|
|
||||||
marginRight: "5px",
|
|
||||||
fontSize: "14px",
|
|
||||||
color: `${iconColor}`
|
|
||||||
}}
|
|
||||||
></i>
|
|
||||||
<span
|
<span
|
||||||
style={{
|
className="dropdown-item itemColor"
|
||||||
fontSize: "15px",
|
onClick={() => setIsFolder(true)}
|
||||||
color: `${iconColor}`
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{selectedSort}
|
<i className="fa fa-plus mr-[5px]" aria-hidden="true"></i>
|
||||||
|
Create folder
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="dropdown-item itemColor"
|
||||||
|
onClick={() => navigate("/form/sHAnZphf69")}
|
||||||
|
>
|
||||||
|
<i className="fas fa-pen-nib mr-[5px"></i>
|
||||||
|
Sign Yourself
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="dropdown-item itemColor"
|
||||||
|
onClick={() => navigate("/form/8mZzFxbG1z")}
|
||||||
|
>
|
||||||
|
<i className="fa fa-file-signature mr-[5px"></i>
|
||||||
|
Request Signatures
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
className={
|
|
||||||
isShowSort ? "dropdown-menu show" : "dropdown-menu"
|
|
||||||
}
|
|
||||||
aria-labelledby="dropdownMenuButton"
|
|
||||||
aria-expanded={isShowSort ? "true" : "false"}
|
|
||||||
>
|
|
||||||
{sortingValue.map((value, ind) => {
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
key={ind}
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedSort(value);
|
|
||||||
sortingData(value, null, pdfData);
|
|
||||||
}}
|
|
||||||
className="dropdown-item itemColor"
|
|
||||||
style={{
|
|
||||||
paddingLeft: selectedSort !== value && "33px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{selectedSort === value && (
|
|
||||||
<i
|
|
||||||
className="fa fa-check"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
></i>
|
|
||||||
)}
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
<hr className="hrStyle" />
|
|
||||||
{sortOrder.map((order, ind) => {
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
key={ind}
|
|
||||||
onClick={() => {
|
|
||||||
setSortingOrder(order);
|
|
||||||
sortingData(null, order, pdfData);
|
|
||||||
}}
|
|
||||||
className="dropdown-item itemColor"
|
|
||||||
style={{
|
|
||||||
paddingLeft: sortingOrder !== order && "33px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{sortingOrder === order && (
|
|
||||||
<i
|
|
||||||
className="fa fa-check"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
></i>
|
|
||||||
)}
|
|
||||||
{order}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="menu-container"
|
||||||
|
className={isShowSort ? "dropdown show" : "dropdown"}
|
||||||
|
onClick={() => setIsShowSort(!isShowSort)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
data-tut="reactourThird"
|
||||||
|
className="sort "
|
||||||
|
data-toggle="dropdown"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-sort-amount-asc mr-[5px] text-[14px]"
|
||||||
|
aria-hidden="true"
|
||||||
|
style={{ color: `${iconColor}` }}
|
||||||
|
></i>
|
||||||
|
<span style={{ fontSize: "15px", color: `${iconColor}` }}>
|
||||||
|
{selectedSort}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
isShowSort ? "dropdown-menu show" : "dropdown-menu"
|
||||||
|
}
|
||||||
|
aria-labelledby="dropdownMenuButton"
|
||||||
|
aria-expanded={isShowSort ? "true" : "false"}
|
||||||
|
>
|
||||||
|
{sortingValue.map((value, ind) => {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
key={ind}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedSort(value);
|
||||||
|
sortingData(value, null, pdfData);
|
||||||
|
}}
|
||||||
|
className="dropdown-item itemColor"
|
||||||
|
style={{
|
||||||
|
paddingLeft: selectedSort !== value && "33px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedSort === value && (
|
||||||
|
<i
|
||||||
|
className="fa fa-check mr-[5px"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
)}
|
||||||
|
{value}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
<div>
|
<hr className="hrStyle" />
|
||||||
{isList ? (
|
{sortOrder.map((order, ind) => {
|
||||||
<div className="sort" onClick={() => setIsList(!isList)}>
|
return (
|
||||||
<i
|
<span
|
||||||
onClick={() => setIsList(!isList)}
|
key={ind}
|
||||||
className="fa fa-th-large"
|
onClick={() => {
|
||||||
style={{ fontSize: "24px", color: `${iconColor}` }}
|
setSortingOrder(order);
|
||||||
aria-hidden="true"
|
sortingData(null, order, pdfData);
|
||||||
></i>
|
}}
|
||||||
</div>
|
className="dropdown-item itemColor"
|
||||||
) : (
|
style={{
|
||||||
<div
|
paddingLeft: sortingOrder !== order && "33px"
|
||||||
data-tut="reactourForth"
|
}}
|
||||||
className="sort"
|
>
|
||||||
|
{sortingOrder === order && (
|
||||||
|
<i
|
||||||
|
className="fa fa-check mr-[5px"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
)}
|
||||||
|
{order}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{isList ? (
|
||||||
|
<div className="sort" onClick={() => setIsList(!isList)}>
|
||||||
|
<i
|
||||||
onClick={() => setIsList(!isList)}
|
onClick={() => setIsList(!isList)}
|
||||||
>
|
className="fa fa-th-large"
|
||||||
<i
|
style={{ fontSize: "24px", color: `${iconColor}` }}
|
||||||
className="fa fa-list"
|
aria-hidden="true"
|
||||||
aria-hidden="true"
|
></i>
|
||||||
style={{ fontSize: "23px", color: `${iconColor}` }}
|
</div>
|
||||||
></i>
|
) : (
|
||||||
</div>
|
<div
|
||||||
)}
|
data-tut="reactourForth"
|
||||||
</div>
|
className="sort"
|
||||||
|
onClick={() => setIsList(!isList)}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-list"
|
||||||
|
aria-hidden="true"
|
||||||
|
style={{ fontSize: "23px", color: `${iconColor}` }}
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{pdfData && pdfData.length === 0 ? (
|
{pdfData && pdfData.length === 0 ? (
|
||||||
<div
|
<div className="flex justify-center items-center w-full h-[50vh]">
|
||||||
style={{
|
<span className="text-base-content font-bold">
|
||||||
display: "flex",
|
No Data Found!
|
||||||
justifyContent: "center",
|
</span>
|
||||||
alignItems: "center",
|
</div>
|
||||||
height: "50vh",
|
) : (
|
||||||
width: "100%"
|
<div data-tut="reactourFifth">
|
||||||
}}
|
<React.Suspense fallback={<AppLoader />}>
|
||||||
>
|
<DriveBody
|
||||||
<span style={{ fontWeight: "bold" }}>No Data Found!</span>
|
dataTutSixth="reactourSixth"
|
||||||
</div>
|
dataTutSeventh="reactourSeventh"
|
||||||
) : (
|
pdfData={pdfData}
|
||||||
<div data-tut="reactourFifth">
|
setFolderName={setFolderName}
|
||||||
<React.Suspense fallback={<Loader />}>
|
setIsLoading={setIsLoading}
|
||||||
<DriveBody
|
setDocId={setDocId}
|
||||||
dataTutSixth="reactourSixth"
|
getPdfDocumentList={getPdfDocumentList}
|
||||||
dataTutSeventh="reactourSeventh"
|
isDocId={docId}
|
||||||
pdfData={pdfData}
|
setPdfData={setPdfData}
|
||||||
setFolderName={setFolderName}
|
isList={isList}
|
||||||
setIsLoading={setIsLoading}
|
setIsAlert={setIsAlert}
|
||||||
setDocId={setDocId}
|
setSkip={setSkip}
|
||||||
getPdfDocumentList={getPdfDocumentList}
|
sortingData={sortingData}
|
||||||
isDocId={docId}
|
/>
|
||||||
setPdfData={setPdfData}
|
{loading && (
|
||||||
isList={isList}
|
<div className="text-center pb-[20px]">Loading...</div>
|
||||||
setIsAlert={setIsAlert}
|
)}
|
||||||
setSkip={setSkip}
|
</React.Suspense>
|
||||||
sortingData={sortingData}
|
</div>
|
||||||
/>
|
)}
|
||||||
{loading && (
|
</>
|
||||||
<div style={{ textAlign: "center" }}>Loading...</div>
|
)}
|
||||||
)}
|
|
||||||
</React.Suspense>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,11 @@ import Title from "../components/Title";
|
|||||||
|
|
||||||
const PageNotFound = ({ prefix }) => {
|
const PageNotFound = ({ prefix }) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
<div className="flex items-center justify-center h-screen w-full bg-base-100 text-base-content rounded">
|
||||||
<Title title={"Page Not Found"} />
|
<Title title={"Page Not Found"} />
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h1 className="text-[60px] lg:text-[120px] font-semibold text-black">
|
<h1 className="text-[60px] lg:text-[120px] font-semibold">404</h1>
|
||||||
404
|
<p className="text-[30px] lg:text-[50px]">
|
||||||
</h1>
|
|
||||||
<p className="text-[30px] lg:text-[50px] text-black">
|
|
||||||
{prefix ? prefix : "Page"} Not Found
|
{prefix ? prefix : "Page"} Not Found
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ import { useNavigate, useLocation } from "react-router-dom";
|
|||||||
import { appInfo } from "../constant/appinfo";
|
import { appInfo } from "../constant/appinfo";
|
||||||
import { showTenant } from "../redux/reducers/ShowTenant";
|
import { showTenant } from "../redux/reducers/ShowTenant";
|
||||||
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const PgSignUp = () => {
|
const PgSignUp = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -127,7 +128,9 @@ const PgSignUp = () => {
|
|||||||
user.set("username", zohoRes.data.result.email);
|
user.set("username", zohoRes.data.result.email);
|
||||||
user.set("password", obj.password);
|
user.set("password", obj.password);
|
||||||
user.set("email", zohoRes.data.result.email);
|
user.set("email", zohoRes.data.result.email);
|
||||||
user.set("phone", zohoRes.data.result.phone);
|
if (zohoRes?.data?.result?.phone) {
|
||||||
|
user.set("phone", zohoRes.data.result.phone);
|
||||||
|
}
|
||||||
user.set("name", zohoRes.data.result.name);
|
user.set("name", zohoRes.data.result.name);
|
||||||
|
|
||||||
const res = await user.signUp();
|
const res = await user.signUp();
|
||||||
@@ -140,7 +143,7 @@ const PgSignUp = () => {
|
|||||||
company: zohoRes.data.result.company,
|
company: zohoRes.data.result.company,
|
||||||
name: zohoRes.data.result.name,
|
name: zohoRes.data.result.name,
|
||||||
email: zohoRes.data.result.email,
|
email: zohoRes.data.result.email,
|
||||||
phone: zohoRes.data.result.phone,
|
phone: zohoRes?.data?.result?.phone || "",
|
||||||
role: obj.role
|
role: obj.role
|
||||||
},
|
},
|
||||||
subscription: zohoRes.data.result.subscription
|
subscription: zohoRes.data.result.subscription
|
||||||
@@ -409,21 +412,8 @@ const PgSignUp = () => {
|
|||||||
<div className="bg-white">
|
<div className="bg-white">
|
||||||
<Title title={"Pgsignup page"} />
|
<Title title={"Pgsignup page"} />
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="flex justify-center items-center h-[100vh]">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<form id="signup" className="pgsignup-content" onSubmit={handleSubmit}>
|
<form id="signup" className="pgsignup-content" onSubmit={handleSubmit}>
|
||||||
|
|||||||
@@ -10,9 +10,8 @@ import { useDrag, useDrop } from "react-dnd";
|
|||||||
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
||||||
import WidgetComponent from "../components/pdf/WidgetComponent";
|
import WidgetComponent from "../components/pdf/WidgetComponent";
|
||||||
import Tour from "reactour";
|
import Tour from "reactour";
|
||||||
import loader from "../assets/images/loader2.gif";
|
|
||||||
import { useLocation, useParams } from "react-router-dom";
|
import { useLocation, useParams } from "react-router-dom";
|
||||||
import Loader from "../primitives/LoaderWithMsg";
|
import LoaderWithMsg from "../primitives/LoaderWithMsg";
|
||||||
import HandleError from "../primitives/HandleError";
|
import HandleError from "../primitives/HandleError";
|
||||||
import SignerListPlace from "../components/pdf/SignerListPlace";
|
import SignerListPlace from "../components/pdf/SignerListPlace";
|
||||||
import Header from "../components/pdf/PdfHeader";
|
import Header from "../components/pdf/PdfHeader";
|
||||||
@@ -49,7 +48,8 @@ import { SaveFileSize } from "../constant/saveFileSize";
|
|||||||
import { EmailBody } from "../components/pdf/EmailBody";
|
import { EmailBody } from "../components/pdf/EmailBody";
|
||||||
import Upgrade from "../primitives/Upgrade";
|
import Upgrade from "../primitives/Upgrade";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
import mail_sent_gif from "../assets/gif/mail_sent.gif";
|
||||||
function PlaceHolderSign() {
|
function PlaceHolderSign() {
|
||||||
const editorRef = useRef();
|
const editorRef = useRef();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -405,7 +405,7 @@ function PlaceHolderSign() {
|
|||||||
};
|
};
|
||||||
setHandleError("Error: Something went wrong!");
|
setHandleError("Error: Something went wrong!");
|
||||||
setIsLoading(loadObj);
|
setIsLoading(loadObj);
|
||||||
} else if (res[0] && res.length) {
|
} else if (res.length && res[0]?.objectId) {
|
||||||
setActiveMailAdapter(res[0]?.active_mail_adapter);
|
setActiveMailAdapter(res[0]?.active_mail_adapter);
|
||||||
setSignerUserId(res[0].objectId);
|
setSignerUserId(res[0].objectId);
|
||||||
const tourstatus = res[0].TourStatus && res[0].TourStatus;
|
const tourstatus = res[0].TourStatus && res[0].TourStatus;
|
||||||
@@ -936,6 +936,7 @@ function PlaceHolderSign() {
|
|||||||
Placeholders: filterPrefill,
|
Placeholders: filterPrefill,
|
||||||
SignedUrl: pdfUrl,
|
SignedUrl: pdfUrl,
|
||||||
Signers: signers,
|
Signers: signers,
|
||||||
|
SentToOthers: true,
|
||||||
ExpiryDate: {
|
ExpiryDate: {
|
||||||
iso: updateExpiryDate,
|
iso: updateExpiryDate,
|
||||||
__type: "Date"
|
__type: "Date"
|
||||||
@@ -945,7 +946,8 @@ function PlaceHolderSign() {
|
|||||||
data = {
|
data = {
|
||||||
Placeholders: filterPrefill,
|
Placeholders: filterPrefill,
|
||||||
SignedUrl: pdfUrl,
|
SignedUrl: pdfUrl,
|
||||||
Signers: signers
|
Signers: signers,
|
||||||
|
SentToOthers: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await axios
|
await axios
|
||||||
@@ -998,9 +1000,10 @@ function PlaceHolderSign() {
|
|||||||
for (let i = 0; i < signerMail.length; i++) {
|
for (let i = 0; i < signerMail.length; i++) {
|
||||||
const objectId = signerMail[i].objectId;
|
const objectId = signerMail[i].objectId;
|
||||||
const hostUrl = window.location.origin;
|
const hostUrl = window.location.origin;
|
||||||
|
const sendMail = false;
|
||||||
//encode this url value `${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}` to base64 using `btoa` function
|
//encode this url value `${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}` to base64 using `btoa` function
|
||||||
const encodeBase64 = btoa(
|
const encodeBase64 = btoa(
|
||||||
`${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}`
|
`${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}/${sendMail}`
|
||||||
);
|
);
|
||||||
let signPdf = `${hostUrl}/login/${encodeBase64}`;
|
let signPdf = `${hostUrl}/login/${encodeBase64}`;
|
||||||
shareLinkList.push({ signerEmail: signerMail[i].Email, url: signPdf });
|
shareLinkList.push({ signerEmail: signerMail[i].Email, url: signPdf });
|
||||||
@@ -1011,7 +1014,11 @@ function PlaceHolderSign() {
|
|||||||
className="flex flex-row justify-between items-center mb-1"
|
className="flex flex-row justify-between items-center mb-1"
|
||||||
key={ind}
|
key={ind}
|
||||||
>
|
>
|
||||||
{copied && <Alert type="success">Copied</Alert>}
|
{copied && (
|
||||||
|
<Alert type="success">
|
||||||
|
<div className="ml-3">Copied</div>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
<span className="w-[220px] md:w-[300px] whitespace-nowrap overflow-hidden text-ellipsis ">
|
<span className="w-[220px] md:w-[300px] whitespace-nowrap overflow-hidden text-ellipsis ">
|
||||||
{data.signerEmail}
|
{data.signerEmail}
|
||||||
</span>
|
</span>
|
||||||
@@ -1019,26 +1026,13 @@ function PlaceHolderSign() {
|
|||||||
<button
|
<button
|
||||||
onClick={() => copytoclipboard(data.url)}
|
onClick={() => copytoclipboard(data.url)}
|
||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center text-white font-[500]"
|
className="flex flex-row items-center op-link op-link-primary"
|
||||||
>
|
>
|
||||||
<i
|
<i className="fa-solid fa-link" aria-hidden="true"></i>
|
||||||
className="fa-solid fa-link underline text-blue-700"
|
<span className=" hidden md:block ml-1 ">Copy link</span>
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
<span className=" hidden md:block ml-1 underline text-blue-700">
|
|
||||||
Copy link
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
<RWebShare
|
<RWebShare data={{ url: data.url, title: "Sign url" }}>
|
||||||
data={{
|
<i className="fa-solid fa-share-from-square op-link op-link-secondary no-underline"></i>
|
||||||
url: data.url,
|
|
||||||
title: "Sign url"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa-solid fa-share-from-square cursor-pointer "
|
|
||||||
style={{ color: themeColor }}
|
|
||||||
></i>
|
|
||||||
</RWebShare>
|
</RWebShare>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1107,10 +1101,10 @@ function PlaceHolderSign() {
|
|||||||
document_title: documentName,
|
document_title: documentName,
|
||||||
sender_name: senderName,
|
sender_name: senderName,
|
||||||
sender_mail: senderEmail,
|
sender_mail: senderEmail,
|
||||||
sender_phone: senderPhone,
|
sender_phone: senderPhone || "",
|
||||||
receiver_name: signerMail[i].Name,
|
receiver_name: signerMail[i].Name,
|
||||||
receiver_email: signerMail[i].Email,
|
receiver_email: signerMail[i].Email,
|
||||||
receiver_phone: signerMail[i].Phone,
|
receiver_phone: signerMail[i]?.Phone || "",
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: orgName,
|
company_name: orgName,
|
||||||
signing_url: `<a href=${signPdf}>Sign here</a>`
|
signing_url: `<a href=${signPdf}>Sign here</a>`
|
||||||
@@ -1162,40 +1156,45 @@ function PlaceHolderSign() {
|
|||||||
}
|
}
|
||||||
if (sendMail.data.result.status === "success") {
|
if (sendMail.data.result.status === "success") {
|
||||||
setMailStatus("success");
|
setMailStatus("success");
|
||||||
|
try {
|
||||||
if (
|
let data;
|
||||||
requestBody &&
|
if (
|
||||||
requestSubject &&
|
requestBody &&
|
||||||
isCustomize &&
|
requestSubject &&
|
||||||
(isSubscribe || !isEnableSubscription)
|
isCustomize &&
|
||||||
) {
|
(isSubscribe || !isEnableSubscription)
|
||||||
try {
|
) {
|
||||||
const data = {
|
data = {
|
||||||
RequestBody: htmlReqBody,
|
RequestBody: htmlReqBody,
|
||||||
RequestSubject: requestSubject
|
RequestSubject: requestSubject,
|
||||||
|
SendMail: true
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
data = {
|
||||||
|
SendMail: true
|
||||||
};
|
};
|
||||||
|
|
||||||
await axios
|
|
||||||
.put(
|
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
|
||||||
"_appName"
|
|
||||||
)}_Document/${documentId}`,
|
|
||||||
data,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(() => {})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("axois err ", err);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.log("error", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await axios
|
||||||
|
.put(
|
||||||
|
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||||
|
"_appName"
|
||||||
|
)}_Document/${documentId}`,
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(() => {})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log("axois err ", err);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log("error", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsSend(true);
|
setIsSend(true);
|
||||||
@@ -1625,32 +1624,18 @@ function PlaceHolderSign() {
|
|||||||
<Title title={state?.title ? state.title : "New Document"} />
|
<Title title={state?.title ? state.title : "New Document"} />
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
{isLoading.isLoad ? (
|
{isLoading.isLoad ? (
|
||||||
<Loader isLoading={isLoading} />
|
<LoaderWithMsg isLoading={isLoading} />
|
||||||
) : handleError ? (
|
) : handleError ? (
|
||||||
<HandleError handleError={handleError} />
|
<HandleError handleError={handleError} />
|
||||||
) : (
|
) : (
|
||||||
<div className="signatureContainer" ref={divRef}>
|
<div
|
||||||
|
className="op-card overflow-hidden flex flex-row justify-between bg-base-300 relative"
|
||||||
|
ref={divRef}
|
||||||
|
>
|
||||||
{isUiLoading && (
|
{isUiLoading && (
|
||||||
<div
|
<div className="absolute h-[100vh] w-full flex flex-col justify-center items-center z-[999] bg-[#e6f2f2] bg-opacity-80">
|
||||||
style={{
|
<Loader />
|
||||||
position: "absolute",
|
<span className="text-[13px] font-bold">
|
||||||
height: "100vh",
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center",
|
|
||||||
zIndex: "999",
|
|
||||||
backgroundColor: "#e6f2f2",
|
|
||||||
opacity: 0.8
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="no img"
|
|
||||||
src={loader}
|
|
||||||
style={{ width: "100px", height: "100px" }}
|
|
||||||
/>
|
|
||||||
<span style={{ fontSize: "13px", fontWeight: "bold" }}>
|
|
||||||
This might take some time
|
This might take some time
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1696,11 +1681,6 @@ function PlaceHolderSign() {
|
|||||||
{/* this modal is used show alert set placeholder for all signers before send mail */}
|
{/* this modal is used show alert set placeholder for all signers before send mail */}
|
||||||
|
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={
|
|
||||||
isSendAlert.mssg === "sure" || isSendAlert.mssg === textWidget
|
|
||||||
? "#dc3545"
|
|
||||||
: isSendAlert.mssg === "confirm" && themeColor
|
|
||||||
}
|
|
||||||
isOpen={isSendAlert.alert}
|
isOpen={isSendAlert.alert}
|
||||||
title={
|
title={
|
||||||
isSendAlert.mssg === "sure" || isSendAlert.mssg === textWidget
|
isSendAlert.mssg === "sure" || isSendAlert.mssg === textWidget
|
||||||
@@ -1710,10 +1690,7 @@ function PlaceHolderSign() {
|
|||||||
handleClose={() => setIsSendAlert({})}
|
handleClose={() => setIsSendAlert({})}
|
||||||
showHeaderMessage={isSendAlert.mssg === "confirm"}
|
showHeaderMessage={isSendAlert.mssg === "confirm"}
|
||||||
>
|
>
|
||||||
<div
|
<div className="max-h-96 overflow-y-scroll scroll-hide p-[20px] text-base-content">
|
||||||
className="max-h-96 overflow-y-scroll scroll-hide"
|
|
||||||
style={{ padding: 20 }}
|
|
||||||
>
|
|
||||||
{isSendAlert.mssg === "sure" ? (
|
{isSendAlert.mssg === "sure" ? (
|
||||||
<span>
|
<span>
|
||||||
Please ensure there's at least one signature widget
|
Please ensure there's at least one signature widget
|
||||||
@@ -1724,88 +1701,67 @@ function PlaceHolderSign() {
|
|||||||
) : (
|
) : (
|
||||||
isSendAlert.mssg === "confirm" && (
|
isSendAlert.mssg === "confirm" && (
|
||||||
<>
|
<>
|
||||||
<>
|
{!isCustomize && (
|
||||||
{!isCustomize && (
|
<span>
|
||||||
<span>
|
Are you sure you want to send out this document for
|
||||||
Are you sure you want to send out this document
|
signatures?
|
||||||
for signatures?
|
</span>
|
||||||
</span>
|
)}
|
||||||
)}
|
{isCustomize &&
|
||||||
{isCustomize &&
|
(!isEnableSubscription || isSubscribe) && (
|
||||||
(!isEnableSubscription || isSubscribe) && (
|
<>
|
||||||
<>
|
<EmailBody
|
||||||
<EmailBody
|
editorRef={editorRef}
|
||||||
editorRef={editorRef}
|
requestBody={requestBody}
|
||||||
requestBody={requestBody}
|
requestSubject={requestSubject}
|
||||||
requestSubject={requestSubject}
|
handleOnchangeRequest={handleOnchangeRequest}
|
||||||
handleOnchangeRequest={handleOnchangeRequest}
|
setRequestSubject={setRequestSubject}
|
||||||
setRequestSubject={setRequestSubject}
|
/>
|
||||||
/>
|
<div
|
||||||
<div
|
className="flex justify-end items-center gap-1 mt-2 op-link op-link-primary"
|
||||||
className={
|
onClick={() => {
|
||||||
"flex justify-end items-center gap-1 mt-2 underline text-blue-700 focus:outline-none cursor-pointer "
|
setRequestBody(defaultBody);
|
||||||
}
|
setRequestSubject(defaultSubject);
|
||||||
onClick={() => {
|
|
||||||
setRequestBody(defaultBody);
|
|
||||||
setRequestSubject(defaultSubject);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>Reset to default</span>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
"flex flex-row md:items-center gap-2 md:gap-6 mt-2 "
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="flex flex-row gap-2">
|
|
||||||
<button
|
|
||||||
onClick={() => sendEmailToSigners()}
|
|
||||||
className=" shadow rounded-[2px] py-[3px] px-[25px] font-[500] text-sm "
|
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Send
|
<span>Reset to default</span>
|
||||||
</button>
|
|
||||||
{isCustomize && (
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setIsCustomize(false);
|
|
||||||
}}
|
|
||||||
className=" shadow rounded-[2px] py-[3px] px-[25px] font-[500] text-sm border-[0.1px] border-gray-300"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{!isCustomize &&
|
|
||||||
(isSubscribe || !isEnableSubscription) && (
|
|
||||||
<span
|
|
||||||
className={
|
|
||||||
"cursor-pointer underline text-blue-700 focus:outline-none"
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
setIsCustomize(!isCustomize);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cutomize Email
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isSubscribe && isEnableSubscription && (
|
|
||||||
<div className="mt-2">
|
|
||||||
<Upgrade
|
|
||||||
message="Upgrade to customize Email"
|
|
||||||
newWindow={true}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<div className="flex flex-row md:items-center gap-2 md:gap-6 mt-2">
|
||||||
|
<div className="flex flex-row gap-2">
|
||||||
|
<button
|
||||||
|
onClick={() => sendEmailToSigners()}
|
||||||
|
className="op-btn op-btn-primary font-[500] text-sm shadow"
|
||||||
|
>
|
||||||
|
Send
|
||||||
|
</button>
|
||||||
|
{isCustomize && (
|
||||||
|
<button
|
||||||
|
onClick={() => setIsCustomize(false)}
|
||||||
|
className="op-btn op-btn-ghost font-[500] text-sm"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
|
{!isCustomize &&
|
||||||
|
(isSubscribe || !isEnableSubscription) && (
|
||||||
|
<span
|
||||||
|
className="op-link op-link-accent text-sm"
|
||||||
|
onClick={() => setIsCustomize(!isCustomize)}
|
||||||
|
>
|
||||||
|
Cutomize Email
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isSubscribe && isEnableSubscription && (
|
||||||
|
<div className="mt-2">
|
||||||
|
<Upgrade message="Upgrade to customize Email" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
@@ -1813,28 +1769,15 @@ function PlaceHolderSign() {
|
|||||||
{isSendAlert.mssg === "confirm" && (
|
{isSendAlert.mssg === "confirm" && (
|
||||||
<>
|
<>
|
||||||
<div className="flex justify-center items-center mt-3">
|
<div className="flex justify-center items-center mt-3">
|
||||||
<span
|
<span className="h-[1px] w-[20%] bg-[#ccc]"></span>
|
||||||
style={{
|
|
||||||
height: 1,
|
|
||||||
width: "20%",
|
|
||||||
backgroundColor: "#ccc"
|
|
||||||
}}
|
|
||||||
></span>
|
|
||||||
<span className="ml-[5px] mr-[5px]">or</span>
|
<span className="ml-[5px] mr-[5px]">or</span>
|
||||||
<span
|
<span className="h-[1px] w-[20%] bg-[#ccc]"></span>
|
||||||
style={{
|
|
||||||
height: 1,
|
|
||||||
width: "20%",
|
|
||||||
backgroundColor: "#ccc"
|
|
||||||
}}
|
|
||||||
></span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3 mb-3">{handleShareList()}</div>
|
<div className="mt-3 mb-3">{handleShareList()}</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
|
|
||||||
{/* this modal is used show send mail message and after send mail success message */}
|
{/* this modal is used show send mail message and after send mail success message */}
|
||||||
<ModalUi
|
<ModalUi
|
||||||
isOpen={isSend}
|
isOpen={isSend}
|
||||||
@@ -1844,77 +1787,61 @@ function PlaceHolderSign() {
|
|||||||
setSignerPos([]);
|
setSignerPos([]);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-[100%] p-[20px]">
|
||||||
{mailStatus === "success" ? (
|
{mailStatus === "success" ? (
|
||||||
<p>You have successfully sent mails to all recipients!</p>
|
<div className="text-center mb-[10px]">
|
||||||
|
<img
|
||||||
|
src={mail_sent_gif}
|
||||||
|
className="w-[120px] h-[120px] mx-auto"
|
||||||
|
/>
|
||||||
|
<p>You have successfully sent mails to all recipients!</p>
|
||||||
|
{isCurrUser && (
|
||||||
|
<p>Do you want to sign documents right now ?</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<p>Please setup mail adapter to send mail!</p>
|
<p>Please setup mail adapter to send mail!</p>
|
||||||
)}
|
)}
|
||||||
{isCurrUser && (
|
{!mailStatus && (
|
||||||
<p>Do you want to sign documents right now ?</p>
|
<div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div>
|
||||||
)}
|
)}
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
{isCurrUser && (
|
{isCurrUser && (
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => handleRecipientSign()}
|
||||||
handleRecipientSign();
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn"
|
className="op-btn op-btn-primary mr-1"
|
||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsSend(false);
|
setIsSend(false);
|
||||||
setSignerPos([]);
|
setSignerPos([]);
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-ghost"
|
||||||
>
|
>
|
||||||
{isCurrUser ? "No" : "Close"}
|
{isCurrUser ? "No" : "Close"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
|
||||||
isOpen={isShowEmail}
|
isOpen={isShowEmail}
|
||||||
title={"signers alert"}
|
title={"signers alert"}
|
||||||
handleClose={() => {
|
handleClose={() => {
|
||||||
setIsShowEmail(false);
|
setIsShowEmail(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-[100%] p-[20px]">
|
||||||
<p>Please select signer for add placeholder!</p>
|
<p>Please select signer for add placeholder!</p>
|
||||||
<div
|
<div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div>
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsShowEmail(false);
|
setIsShowEmail(false);
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
Ok
|
Ok
|
||||||
</button>
|
</button>
|
||||||
@@ -2068,12 +1995,13 @@ function PlaceHolderSign() {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<div className="signerComponent" aria-disabled>
|
<div
|
||||||
|
className="hidden md:block w-[180px] h-full bg-base-100"
|
||||||
|
aria-disabled
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{ maxHeight: window.innerHeight - 70 + "px" }}
|
||||||
maxHeight: window.innerHeight - 70 + "px"
|
className="overflow-y-auto hide-scrollbar"
|
||||||
}}
|
|
||||||
className="autoSignScroll"
|
|
||||||
>
|
>
|
||||||
<SignerListPlace
|
<SignerListPlace
|
||||||
signerPos={signerPos}
|
signerPos={signerPos}
|
||||||
@@ -2119,33 +2047,22 @@ function PlaceHolderSign() {
|
|||||||
</DndProvider>
|
</DndProvider>
|
||||||
<div>
|
<div>
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
|
||||||
isOpen={isAlreadyPlace.status}
|
isOpen={isAlreadyPlace.status}
|
||||||
title={"Document Alert"}
|
title={"Document Alert"}
|
||||||
showClose={false}
|
showClose={false}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-[100%] p-[20px]">
|
||||||
<p>{isAlreadyPlace.message}</p>
|
<p>{isAlreadyPlace.message}</p>
|
||||||
|
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => handleRecipientSign()}
|
onClick={() => handleRecipientSign()}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
View
|
View
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
|
|
||||||
<LinkUserModal
|
<LinkUserModal
|
||||||
handleAddUser={handleAddUser}
|
handleAddUser={handleAddUser}
|
||||||
isAddUser={isAddUser}
|
isAddUser={isAddUser}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import checkmark from "../assets/images/checkmark.png";
|
|||||||
import plansArr from "../json/plansArr";
|
import plansArr from "../json/plansArr";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
import { openInNewTab } from "../constant/Utils";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
const listItemStyle = {
|
const listItemStyle = {
|
||||||
paddingLeft: "20px", // Add padding to create space for the image
|
paddingLeft: "20px", // Add padding to create space for the image
|
||||||
backgroundImage: `url(${checkmark})`, // Set your image as the list style image
|
backgroundImage: `url(${checkmark})`, // Set your image as the list style image
|
||||||
@@ -16,8 +18,17 @@ const PlanSubscriptions = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [yearlyVisible, setYearlyVisible] = useState(false);
|
const [yearlyVisible, setYearlyVisible] = useState(false);
|
||||||
const [isLoader, setIsLoader] = useState(true);
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
|
const extUser =
|
||||||
const userDetails = JSON.parse(localStorage.getItem("userDetails"));
|
localStorage.getItem("Extand_Class") &&
|
||||||
|
JSON.parse(localStorage.getItem("Extand_Class"))?.[0];
|
||||||
|
const user = {
|
||||||
|
name: extUser?.Name,
|
||||||
|
email: extUser?.Email,
|
||||||
|
company: extUser?.Company,
|
||||||
|
phone: extUser?.Phone
|
||||||
|
};
|
||||||
|
const userDetails = JSON.parse(localStorage.getItem("userDetails")) || user;
|
||||||
|
// console.log("userDetails ", userDetails);
|
||||||
const name =
|
const name =
|
||||||
userDetails && userDetails.name
|
userDetails && userDetails.name
|
||||||
? "first_name=" + encodeURIComponent(userDetails.name)
|
? "first_name=" + encodeURIComponent(userDetails.name)
|
||||||
@@ -75,55 +86,33 @@ const PlanSubscriptions = () => {
|
|||||||
<>
|
<>
|
||||||
<Title title={"Subscriptions"} />
|
<Title title={"Subscriptions"} />
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="flex items-center justify-center h-screen">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div className="overflow-y-auto max-h-full">
|
||||||
style={{
|
|
||||||
backgroundColor: "white",
|
|
||||||
overflowY: "auto",
|
|
||||||
maxHeight: "100%"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="block my-2">
|
<div className="block my-2">
|
||||||
<div className="flex flex-col justify-center items-center w-full">
|
<div className="flex flex-col justify-center items-center w-full">
|
||||||
<div className="mb-6 mt-2 flex flex-row border-[1px] p-2 border-gray-300 rounded text-sm">
|
<div
|
||||||
<span
|
role="tablist"
|
||||||
|
className="op-tabs op-tabs-boxed bg-base-100 my-2 shadow-lg transition-all"
|
||||||
|
>
|
||||||
|
<a
|
||||||
onClick={() => setYearlyVisible(false)}
|
onClick={() => setYearlyVisible(false)}
|
||||||
className={`${
|
role="tab"
|
||||||
!yearlyVisible
|
className={`${!yearlyVisible ? "op-tab-active" : ""} op-tab`}
|
||||||
? "bg-[#002862] text-white"
|
|
||||||
: "bg-white text-black"
|
|
||||||
} px-4 py-1 rounded cursor-pointer`}
|
|
||||||
>
|
>
|
||||||
Monthly
|
Monthly
|
||||||
</span>
|
</a>
|
||||||
<span
|
<a
|
||||||
onClick={() => setYearlyVisible(true)}
|
onClick={() => setYearlyVisible(true)}
|
||||||
className={`${
|
role="tab"
|
||||||
yearlyVisible
|
className={`${yearlyVisible ? "op-tab-active" : ""} op-tab`}
|
||||||
? "bg-[#002862] text-white"
|
|
||||||
: "bg-white text-black"
|
|
||||||
} px-4 py-1 rounded cursor-pointer`}
|
|
||||||
>
|
>
|
||||||
Yearly (10% off)
|
Yearly (10% off)
|
||||||
</span>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ul className="flex flex-col md:flex-row h-full bg-white justify-center">
|
<ul className="op-card flex flex-col md:flex-row h-full bg-base-100 justify-center shadow-lg">
|
||||||
{plansArr.map((item) => (
|
{plansArr.map((item) => (
|
||||||
<li
|
<li
|
||||||
className="flex flex-col text-center border-collapse border-[1px] border-gray-300 max-w-[250px]"
|
className="flex flex-col text-center border-collapse border-[1px] border-gray-300 max-w-[250px]"
|
||||||
@@ -198,9 +187,7 @@ const PlanSubscriptions = () => {
|
|||||||
<ul className="mx-1 p-3 text-left break-words text-sm list-none">
|
<ul className="mx-1 p-3 text-left break-words text-sm list-none">
|
||||||
{item.benefits.map((subitem, index) => (
|
{item.benefits.map((subitem, index) => (
|
||||||
<li style={listItemStyle} key={index} className="m-1">
|
<li style={listItemStyle} key={index} className="m-1">
|
||||||
<span style={{ position: "relative" }}>
|
<span className="relative">{subitem}</span>
|
||||||
{subitem}
|
|
||||||
</span>
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -208,22 +195,23 @@ const PlanSubscriptions = () => {
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm flex justify-center items-center">
|
<div className="text-sm flex justify-center items-center mt-3 mb-2">
|
||||||
<hr className="border-[1px] border-gray-300 w-[20%]" />
|
<hr className="border-[2px] border-gray-350 w-[20%]" />
|
||||||
<span className="px-2 text-gray-500 cursor-default">or</span>
|
<span className="px-2 text-base-content cursor-default">or</span>
|
||||||
<hr className="border-[1px] border-gray-300 w-[20%]" />
|
<hr className="border-[2px] border-gray-350 w-[20%]" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col justify-center w-full items-center">
|
<div className="flex flex-col justify-center items-center">
|
||||||
<h3 className="text-[#002862] mt-1 mb-2">
|
<h3 className="text-[#002862] mt-1 mb-2">
|
||||||
Host it yourself for free
|
Host it yourself for free
|
||||||
</h3>
|
</h3>
|
||||||
<NavLink
|
<div
|
||||||
to={"https://github.com/OpenSignLabs/OpenSign"}
|
className="op-btn op-btn-primary w-[200px]"
|
||||||
className="bg-[#002862] w-[200px] text-center text-white py-2 rounded uppercase hover:no-underline hover:text-white cursor-pointer"
|
onClick={() =>
|
||||||
target={"_blank"}
|
openInNewTab("https://github.com/OpenSignLabs/OpenSign")
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Visit Github
|
Visit Github
|
||||||
</NavLink>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useParams } from "react-router-dom";
|
|||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import PageNotFound from "./PageNotFound";
|
import PageNotFound from "./PageNotFound";
|
||||||
import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
const Report = () => {
|
const Report = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -173,21 +174,8 @@ const Report = () => {
|
|||||||
<>
|
<>
|
||||||
<Title title={reportName} />
|
<Title title={reportName} />
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="h-[100vh] flex justify-center items-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -0,0 +1,384 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
|
import Parse from "parse";
|
||||||
|
import axios from "axios";
|
||||||
|
import { appInfo } from "../constant/appinfo";
|
||||||
|
import { isEnableSubscription } from "../constant/const";
|
||||||
|
import { fetchSubscription } from "../constant/Utils";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { showTenant } from "../redux/reducers/ShowTenant";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
|
const SSOVerify = () => {
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const [isModal, setIsModal] = useState(false);
|
||||||
|
const [message, setMessage] = useState("Verifying SSO...");
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [userDetails, setUserDetails] = useState({
|
||||||
|
name: "",
|
||||||
|
email: "",
|
||||||
|
phone: "",
|
||||||
|
Destination: "",
|
||||||
|
Company: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
linkUserWithSSO();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// `linkUserWithSSO` is used to sign in or sign up a user using an SSO code and check if the user is present in the extended class
|
||||||
|
const linkUserWithSSO = async () => {
|
||||||
|
const param = new URLSearchParams(location.search);
|
||||||
|
const code = param?.get("code");
|
||||||
|
const state = param?.get("state");
|
||||||
|
try {
|
||||||
|
// The `ssosign` cloud function is used to sign in or sign up a user
|
||||||
|
const ssosign = await Parse.Cloud.run("ssosign", {
|
||||||
|
code: code,
|
||||||
|
email: state
|
||||||
|
});
|
||||||
|
localStorage.setItem("accesstoken", ssosign.sessiontoken);
|
||||||
|
// `checkExtUser` checks if the user is present in the extended class `contracts_Users` and if not, initiates the new user flow
|
||||||
|
await checkExtUser(ssosign);
|
||||||
|
} catch (err) {
|
||||||
|
setMessage("Error: " + err.message);
|
||||||
|
console.log("err", err.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const checkExtUser = async (ssosign) => {
|
||||||
|
const params = { email: ssosign?.email };
|
||||||
|
try {
|
||||||
|
// `isextenduser` checks if the current user is present in the extended class
|
||||||
|
const extRes = await Parse.Cloud.run("isextenduser", params);
|
||||||
|
if (extRes?.isUserExist) {
|
||||||
|
// `getUserDetails` retrieves the current user's details from the extended class
|
||||||
|
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
||||||
|
if (ssosign && ssosign.sessiontoken) {
|
||||||
|
const LocalUserDetails = {
|
||||||
|
name: extRes.Name,
|
||||||
|
email: extRes.email,
|
||||||
|
phone: extRes?.get("Phone") || "",
|
||||||
|
company: extRes.get("Company")
|
||||||
|
};
|
||||||
|
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||||
|
thirdpartyLoginfn(ssosign.sessiontoken);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsModal(true);
|
||||||
|
setUserDetails((prev) => ({
|
||||||
|
...prev,
|
||||||
|
name: ssosign.name,
|
||||||
|
email: ssosign.email,
|
||||||
|
phone: ssosign?.phone || ""
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in isextenduser or getuserdetails cloud function", err);
|
||||||
|
setMessage("Error: " + err.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// `handleSubmitbtn` is used to create a user in the extended class
|
||||||
|
const handleSubmitbtn = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsLoader(true);
|
||||||
|
let phone;
|
||||||
|
if (userDetails?.phone) {
|
||||||
|
phone = validateInput(userDetails?.phone);
|
||||||
|
} else {
|
||||||
|
phone = true;
|
||||||
|
}
|
||||||
|
if (userDetails.Destination && userDetails.Company && phone) {
|
||||||
|
const payload = { sessionToken: localStorage.getItem("accesstoken") };
|
||||||
|
if (payload && payload.sessionToken) {
|
||||||
|
const params = {
|
||||||
|
userDetails: {
|
||||||
|
name: userDetails.name,
|
||||||
|
email: userDetails.email,
|
||||||
|
phone: userDetails?.phone || "",
|
||||||
|
role: "contracts_User",
|
||||||
|
company: userDetails.Company,
|
||||||
|
jobTitle: userDetails.Destination
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const userSignUp = await Parse.Cloud.run("usersignup", params);
|
||||||
|
if (userSignUp && userSignUp.sessionToken) {
|
||||||
|
const LocalUserDetails = params.userDetails;
|
||||||
|
localStorage.setItem(
|
||||||
|
"userDetails",
|
||||||
|
JSON.stringify(LocalUserDetails)
|
||||||
|
);
|
||||||
|
await thirdpartyLoginfn(userSignUp.sessionToken);
|
||||||
|
setIsLoader(false);
|
||||||
|
} else {
|
||||||
|
alert(userSignUp.message);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("error in usersignup", err);
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
alert("Something went wrong.");
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
alert("Internal server error.");
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("Please fill required details correctly.");
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// `thirdpartyLoginfn` is used to save necessary parameters locally for the logged-in user
|
||||||
|
const thirdpartyLoginfn = async (sessionToken) => {
|
||||||
|
const baseUrl = localStorage.getItem("baseUrl");
|
||||||
|
const parseAppId = localStorage.getItem("parseAppId");
|
||||||
|
try {
|
||||||
|
const validUser = await Parse.User.become(sessionToken);
|
||||||
|
if (validUser) {
|
||||||
|
localStorage.setItem("accesstoken", sessionToken);
|
||||||
|
const _user = JSON.parse(JSON.stringify(validUser));
|
||||||
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
|
if (_user.ProfilePic) {
|
||||||
|
localStorage.setItem("profileImg", _user.ProfilePic);
|
||||||
|
} else {
|
||||||
|
localStorage.setItem("profileImg", "");
|
||||||
|
}
|
||||||
|
// Check extended class user role and tenentId
|
||||||
|
try {
|
||||||
|
let userRoles = [];
|
||||||
|
const userSettings = appInfo.settings;
|
||||||
|
//Get Current user roles
|
||||||
|
const url = `${baseUrl}functions/UserGroups`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessionToken: _user.sessionToken
|
||||||
|
};
|
||||||
|
const body = { appname: appInfo.appname };
|
||||||
|
const UserGroupsRes = await axios.post(url, JSON.stringify(body), {
|
||||||
|
headers: headers
|
||||||
|
});
|
||||||
|
userRoles = (UserGroupsRes.data && UserGroupsRes.data.result) || [];
|
||||||
|
if (userRoles) {
|
||||||
|
let _currentRole = "";
|
||||||
|
const excludeRoles = ["contracts_Guest", `contracts_appeditor`];
|
||||||
|
const filteredRole = userRoles.filter(
|
||||||
|
(x) => !excludeRoles.includes(x)
|
||||||
|
);
|
||||||
|
if (filteredRole?.length > 1) {
|
||||||
|
console.log("user has two roles");
|
||||||
|
// _currentRole = filteredRole.filter((x) => x === "contracts_User");
|
||||||
|
} else {
|
||||||
|
_currentRole = filteredRole?.[0] || "";
|
||||||
|
}
|
||||||
|
if (_currentRole) {
|
||||||
|
const roleSetting = userSettings?.find(
|
||||||
|
(setting) => setting.role === _currentRole
|
||||||
|
);
|
||||||
|
const redirectUrl =
|
||||||
|
location?.state?.from ||
|
||||||
|
`/${roleSetting.pageType}/${roleSetting.pageId}`;
|
||||||
|
const _role = _currentRole.replace(`${appInfo.appname}_`, "");
|
||||||
|
localStorage.setItem("_user_role", _role);
|
||||||
|
// Get TenentID from Extendend Class
|
||||||
|
localStorage.setItem(
|
||||||
|
"extended_class",
|
||||||
|
roleSetting.extended_class
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
const extUser = await Parse.Cloud.run("getUserDetails", {
|
||||||
|
email: _user.email
|
||||||
|
});
|
||||||
|
if (extUser) {
|
||||||
|
const _extUser = JSON.parse(JSON.stringify(extUser));
|
||||||
|
localStorage.setItem("userEmail", _extUser.Email);
|
||||||
|
localStorage.setItem("username", _extUser.Name);
|
||||||
|
localStorage.setItem("scriptId", true);
|
||||||
|
let tenentInfo = [];
|
||||||
|
const results = [extUser];
|
||||||
|
if (results) {
|
||||||
|
let extendedInfo_stringify = JSON.stringify(results);
|
||||||
|
localStorage.setItem(
|
||||||
|
"Extand_Class",
|
||||||
|
extendedInfo_stringify
|
||||||
|
);
|
||||||
|
if (_extUser.TenantId) {
|
||||||
|
const obj = {
|
||||||
|
tenentId: _extUser.TenantId.objectId,
|
||||||
|
tenentName: _extUser.TenantId.TenantName || ""
|
||||||
|
};
|
||||||
|
localStorage.setItem("TenantId", obj.tenentId);
|
||||||
|
tenentInfo.push(obj);
|
||||||
|
dispatch(showTenant(obj.tenentName || ""));
|
||||||
|
localStorage.setItem("TenantName", obj.tenentName || "");
|
||||||
|
}
|
||||||
|
localStorage.setItem("PageLanding", roleSetting.pageId);
|
||||||
|
localStorage.setItem("defaultmenuid", roleSetting.menuId);
|
||||||
|
localStorage.setItem("pageType", roleSetting.pageType);
|
||||||
|
if (isEnableSubscription) {
|
||||||
|
const res = await fetchSubscription();
|
||||||
|
const plan = res.plan;
|
||||||
|
const billingDate = res.billingDate;
|
||||||
|
if (plan === "freeplan") {
|
||||||
|
navigate(redirectUrl);
|
||||||
|
} else if (billingDate) {
|
||||||
|
if (new Date(billingDate) > new Date()) {
|
||||||
|
localStorage.removeItem("userDetails");
|
||||||
|
navigate(redirectUrl);
|
||||||
|
} else {
|
||||||
|
navigate(`/subscription`, {
|
||||||
|
replace: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
navigate(`/subscription`, {
|
||||||
|
replace: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
navigate(redirectUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
alert("user not exist.");
|
||||||
|
setMessage("Error: User not exist.");
|
||||||
|
console.log("err in get extUser", err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("Role does not exists.");
|
||||||
|
setMessage("Error: Role does not exists.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("Role does not exists.");
|
||||||
|
setMessage("Error: Role does not exists.");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in usergroups", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err in become method", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// `handleCloseModal` is triggered when the user wants to close the new user flow modal
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
setIsModal(false);
|
||||||
|
if (Parse?.User?.current()) {
|
||||||
|
Parse.User.logOut();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// `validateInput` is used to verify the phone pattern
|
||||||
|
function validateInput(input) {
|
||||||
|
if (input) {
|
||||||
|
const pattern = /^(?!.*\+.*\+)[\d+-]*$/;
|
||||||
|
return pattern.test(input);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="w-full h-screen flex flex-col justify-center items-center text-sm md:text-xl ">
|
||||||
|
{message === "Verifying SSO..." && <Loader />}
|
||||||
|
<div className="text-base-content">{message}</div>
|
||||||
|
</div>
|
||||||
|
<ModalUi isOpen={isModal} title="Additional Info" showClose={false}>
|
||||||
|
<div className="relative">
|
||||||
|
{isLoader && (
|
||||||
|
<div className="absolute w-full h-full bg-black bg-opacity-25 flex justify-center items-center">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<form
|
||||||
|
className="px-4 py-3 text-base-content"
|
||||||
|
onSubmit={handleSubmitbtn}
|
||||||
|
>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="Company" className="block text-xs font-semibold">
|
||||||
|
Phone <span className="text-[13px] text-[red]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
id="Phone"
|
||||||
|
value={userDetails.phone}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
phone: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
disabled={isLoader}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<p className="text-[10px] text-[red] ml-2">
|
||||||
|
{!validateInput(userDetails.phone) && "Invalid phone value"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="Company" className="block text-xs font-semibold">
|
||||||
|
Company <span className="text-[13px] text-[red]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
id="Company"
|
||||||
|
value={userDetails.Company}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
Company: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
disabled={isLoader}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="JobTitle" className="block text-xs font-semibold">
|
||||||
|
Job Title
|
||||||
|
<span className="text-[13px] text-[red]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
|
id="JobTitle"
|
||||||
|
value={userDetails.Destination}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
Destination: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
disabled={isLoader}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="op-btn op-btn-ghost ml-2"
|
||||||
|
onClick={handleCloseModal}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SSOVerify;
|
||||||
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
|
|||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import { useNavigate, NavLink, useLocation } from "react-router-dom";
|
import { useNavigate, useLocation } from "react-router-dom";
|
||||||
import login_img from "../assets/images/login_img.svg";
|
import login_img from "../assets/images/login_img.svg";
|
||||||
import { useWindowSize } from "../hook/useWindowSize";
|
import { useWindowSize } from "../hook/useWindowSize";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
@@ -11,7 +11,8 @@ import { useDispatch } from "react-redux";
|
|||||||
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
import { fetchAppInfo } from "../redux/reducers/infoReducer";
|
||||||
import { showTenant } from "../redux/reducers/ShowTenant";
|
import { showTenant } from "../redux/reducers/ShowTenant";
|
||||||
import { isEnableSubscription } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { getAppLogo } from "../constant/Utils";
|
import { getAppLogo, openInNewTab } from "../constant/Utils";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
const Signup = () => {
|
const Signup = () => {
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -33,7 +34,7 @@ const Signup = () => {
|
|||||||
const [lengthValid, setLengthValid] = useState(false);
|
const [lengthValid, setLengthValid] = useState(false);
|
||||||
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||||
const [specialCharValid, setSpecialCharValid] = useState(false);
|
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||||
|
const [isAuthorize, setIsAuthorize] = useState(false);
|
||||||
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
||||||
|
|
||||||
const clearStorage = async () => {
|
const clearStorage = async () => {
|
||||||
@@ -501,80 +502,58 @@ const Signup = () => {
|
|||||||
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
|
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="bg-white">
|
<div className="">
|
||||||
{state.loading && (
|
{state.loading && (
|
||||||
<div
|
<div className="fixed w-full h-full flex justify-center items-center bg-black bg-opacity-30 z-50">
|
||||||
style={{
|
<Loader />
|
||||||
position: "fixed",
|
|
||||||
width: "100vw",
|
|
||||||
height: "100vh",
|
|
||||||
backgroundColor: "rgba(0,0,0,0.2)",
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
zIndex: 2
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "fixed",
|
|
||||||
fontSize: "50px",
|
|
||||||
color: "#3ac9d6",
|
|
||||||
top: "50%",
|
|
||||||
left: "45%"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Title title={"Signup page"} />
|
<Title title={"Signup page"} />
|
||||||
|
|
||||||
{appInfo && appInfo.applogo ? (
|
{appInfo && appInfo.applogo ? (
|
||||||
<div>
|
<div className="md:p-10 lg:p-16">
|
||||||
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
<div className="md:p-4 lg:p-10 p-4 bg-base-100 text-base-content op-card">
|
||||||
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
|
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
|
||||||
{image && (
|
{image && (
|
||||||
<img src={image} className="object-contain h-full" alt="logo" />
|
<img src={image} className="object-contain h-full" alt="logo" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
||||||
<div className="">
|
<div>
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<h2 className="text-[30px] mt-6">Create Account !</h2>
|
<h2 className="text-[30px] mt-6">Create Account !</h2>
|
||||||
<div className="outline outline-1 outline-slate-300/50 shadow-md rounded my-4">
|
<div className="w-full my-4 op-card bg-base-100 shadow-md outline outline-1 outline-slate-300/50">
|
||||||
<div className="px-6 py-4 text-xs">
|
<div className="px-6 py-4 text-xs">
|
||||||
<label className="block ">
|
<label className="block ">
|
||||||
Name{" "}
|
Name <span className="text-[red] text-[13px]">*</span>
|
||||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={name}
|
value={name}
|
||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<hr className="my-2 border-none" />
|
<hr className="my-2 border-none" />
|
||||||
<label>
|
<label>
|
||||||
Email{" "}
|
Email <span className="text-[red] text-[13px]">*</span>
|
||||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="email"
|
id="email"
|
||||||
type="text"
|
type="email"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) =>
|
||||||
|
setEmail(e.target.value?.toLowerCase())
|
||||||
|
}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<hr className="my-2 border-none" />
|
<hr className="my-2 border-none" />
|
||||||
<label>
|
<label>
|
||||||
Phone{" "}
|
Phone <span className="text-[red] text-[13px]">*</span>
|
||||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="tel"
|
type="tel"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={phone}
|
value={phone}
|
||||||
onChange={(e) => setPhone(e.target.value)}
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
required
|
required
|
||||||
@@ -582,11 +561,11 @@ const Signup = () => {
|
|||||||
<hr className="my-2 border-none" />
|
<hr className="my-2 border-none" />
|
||||||
<label>
|
<label>
|
||||||
Company{" "}
|
Company{" "}
|
||||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
<span className="text-[red] text-[13px]">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={company}
|
value={company}
|
||||||
onChange={(e) => setCompany(e.target.value)}
|
onChange={(e) => setCompany(e.target.value)}
|
||||||
required
|
required
|
||||||
@@ -594,11 +573,11 @@ const Signup = () => {
|
|||||||
<hr className="my-2 border-none" />
|
<hr className="my-2 border-none" />
|
||||||
<label>
|
<label>
|
||||||
Job Title{" "}
|
Job Title{" "}
|
||||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
<span className="text-[red] text-[13px]">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
value={jobTitle}
|
value={jobTitle}
|
||||||
onChange={(e) => setJobTitle(e.target.value)}
|
onChange={(e) => setJobTitle(e.target.value)}
|
||||||
required
|
required
|
||||||
@@ -606,21 +585,19 @@ const Signup = () => {
|
|||||||
<hr className="my-2 border-none" />
|
<hr className="my-2 border-none" />
|
||||||
<label>
|
<label>
|
||||||
Password{" "}
|
Password{" "}
|
||||||
<span style={{ color: "red", fontSize: 13 }}>*</span>
|
<span className="text-[red] text-[13px]">*</span>
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<input
|
<input
|
||||||
type={showPassword ? "text" : "password"}
|
type={showPassword ? "text" : "password"}
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
name="password"
|
name="password"
|
||||||
value={password}
|
value={password}
|
||||||
onChange={(e) => handlePasswordChange(e)}
|
onChange={(e) => handlePasswordChange(e)}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer ${
|
className={`absolute top-[50%] right-[10px] -translate-y-[50%] cursor-pointer text-base-content`}
|
||||||
showPassword ? "text-[#007bff]" : "text-black"
|
|
||||||
}`}
|
|
||||||
onClick={togglePasswordVisibility}
|
onClick={togglePasswordVisibility}
|
||||||
>
|
>
|
||||||
{showPassword ? (
|
{showPassword ? (
|
||||||
@@ -658,34 +635,62 @@ const Signup = () => {
|
|||||||
{specialCharValid ? "✓" : "✗"} Password should
|
{specialCharValid ? "✓" : "✗"} Password should
|
||||||
contain special character
|
contain special character
|
||||||
</p>
|
</p>
|
||||||
{/* </>
|
|
||||||
)} */}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<div className="mt-2.5 ml-1 flex flex-row items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="op-checkbox op-checkbox-sm"
|
||||||
|
id="termsandcondition"
|
||||||
|
checked={isAuthorize}
|
||||||
|
onChange={(e) => setIsAuthorize(e.target.checked)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="text-xs cursor-pointer ml-1 mb-0"
|
||||||
|
htmlFor="termsandcondition"
|
||||||
|
>
|
||||||
|
I agree to the
|
||||||
|
</label>
|
||||||
|
<span
|
||||||
|
className="underline cursor-pointer ml-1"
|
||||||
|
onClick={() =>
|
||||||
|
openInNewTab(
|
||||||
|
"https://www.opensignlabs.com/terms-and-conditions"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Terms of Service
|
||||||
|
</span>
|
||||||
|
<span>.</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col md:flex-row justify-between items-stretch gap-8 text-center text-xs font-bold mt-2">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-center text-xs font-bold mt-2">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="rounded-sm bg-[#3ac9d6] text-white w-full py-3 shadow uppercase"
|
className="op-btn op-btn-primary"
|
||||||
disabled={state.loading}
|
disabled={state.loading}
|
||||||
>
|
>
|
||||||
{state.loading ? "Loading..." : "Register"}
|
{state.loading ? "Loading..." : "Register"}
|
||||||
</button>
|
</button>
|
||||||
<NavLink
|
<button
|
||||||
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
|
type="button"
|
||||||
to={location.search ? "/" + location.search : "/"}
|
className="op-btn op-btn-secondary"
|
||||||
style={width < 768 ? { textAlign: "center" } : {}}
|
disabled={state.loading}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(location.search ? "/" + location.search : "/")
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</NavLink>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{width >= 768 && (
|
{width >= 768 && (
|
||||||
<div className="self-center">
|
<div className="self-center">
|
||||||
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
||||||
<img src={login_img} alt="bisec" width="100%" />
|
<img src={login_img} alt="loader" width="100%" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -694,16 +699,9 @@ const Signup = () => {
|
|||||||
<Alert type={state.alertType}>{state.alertMsg}</Alert>
|
<Alert type={state.alertType}>{state.alertMsg}</Alert>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div className="fixed w-full h-full flex justify-center items-center z-50">
|
||||||
style={{
|
<Loader />
|
||||||
position: "fixed",
|
</div>
|
||||||
fontSize: "50px",
|
|
||||||
color: "#3ac9d6",
|
|
||||||
top: "50%",
|
|
||||||
left: "45%"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import React, { useState, useRef, useEffect } from "react";
|
|||||||
import { PDFDocument } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { isEnableSubscription, themeColor } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
|
import Confetti from "react-confetti";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Loader from "../primitives/LoaderWithMsg";
|
import LoaderWithMsg from "../primitives/LoaderWithMsg";
|
||||||
import loader from "../assets/images/loader2.gif";
|
|
||||||
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
||||||
import { DndProvider } from "react-dnd";
|
import { DndProvider } from "react-dnd";
|
||||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||||
@@ -47,7 +47,7 @@ import Title from "../components/Title";
|
|||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
|
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
|
||||||
import VerifyEmail from "../components/pdf/VerifyEmail";
|
import VerifyEmail from "../components/pdf/VerifyEmail";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
//For signYourself inProgress section signer can add sign and complete doc sign.
|
//For signYourself inProgress section signer can add sign and complete doc sign.
|
||||||
function SignYourSelf() {
|
function SignYourSelf() {
|
||||||
const [pdfDetails, setPdfDetails] = useState([]);
|
const [pdfDetails, setPdfDetails] = useState([]);
|
||||||
@@ -70,7 +70,6 @@ function SignYourSelf() {
|
|||||||
const [dragKey, setDragKey] = useState();
|
const [dragKey, setDragKey] = useState();
|
||||||
const [signKey, setSignKey] = useState();
|
const [signKey, setSignKey] = useState();
|
||||||
const [imgWH, setImgWH] = useState({});
|
const [imgWH, setImgWH] = useState({});
|
||||||
const [isCeleb, setIsCeleb] = useState(false);
|
|
||||||
const [pdfNewWidth, setPdfNewWidth] = useState();
|
const [pdfNewWidth, setPdfNewWidth] = useState();
|
||||||
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
||||||
const [successEmail, setSuccessEmail] = useState(false);
|
const [successEmail, setSuccessEmail] = useState(false);
|
||||||
@@ -109,6 +108,7 @@ function SignYourSelf() {
|
|||||||
const [isDontShow, setIsDontShow] = useState(false);
|
const [isDontShow, setIsDontShow] = useState(false);
|
||||||
const [extUserId, setExtUserId] = useState("");
|
const [extUserId, setExtUserId] = useState("");
|
||||||
const [isCompleted, setIsCompleted] = useState(false);
|
const [isCompleted, setIsCompleted] = useState(false);
|
||||||
|
const [isCelebration, setIsCelebration] = useState(false);
|
||||||
const [pdfArrayBuffer, setPdfArrayBuffer] = useState("");
|
const [pdfArrayBuffer, setPdfArrayBuffer] = useState("");
|
||||||
const [activeMailAdapter, setActiveMailAdapter] = useState("");
|
const [activeMailAdapter, setActiveMailAdapter] = useState("");
|
||||||
const [isEmailVerified, setIsEmailVerified] = useState(true);
|
const [isEmailVerified, setIsEmailVerified] = useState(true);
|
||||||
@@ -229,8 +229,12 @@ function SignYourSelf() {
|
|||||||
setIsUiLoading(false);
|
setIsUiLoading(false);
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
setIsEmail(true);
|
setIsEmail(true);
|
||||||
|
setIsCelebration(true);
|
||||||
setXyPostion([]);
|
setXyPostion([]);
|
||||||
setSignBtnPosition([]);
|
setSignBtnPosition([]);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsCelebration(false);
|
||||||
|
}, 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
@@ -649,10 +653,6 @@ function SignYourSelf() {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
setIsCeleb(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
setIsCeleb(false);
|
|
||||||
}, 3000);
|
|
||||||
setIsUiLoading(true);
|
setIsUiLoading(true);
|
||||||
const existingPdfBytes = pdfArrayBuffer;
|
const existingPdfBytes = pdfArrayBuffer;
|
||||||
// Load a PDFDocument from the existing PDF bytes
|
// Load a PDFDocument from the existing PDF bytes
|
||||||
@@ -1092,38 +1092,29 @@ function SignYourSelf() {
|
|||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
<Title title={"Self Sign"} />
|
<Title title={"Self Sign"} />
|
||||||
{isLoading.isLoad ? (
|
{isLoading.isLoad ? (
|
||||||
<Loader isLoading={isLoading} />
|
<LoaderWithMsg isLoading={isLoading} />
|
||||||
) : handleError ? (
|
) : handleError ? (
|
||||||
<HandleError handleError={handleError} />
|
<HandleError handleError={handleError} />
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
{isUiLoading && (
|
{isUiLoading && (
|
||||||
<div
|
<div className="absolute h-[100vh] w-full z-[999] flex flex-col justify-center items-start bg-[#e6f2f2] bg-opacity-80">
|
||||||
style={{
|
<Loader />
|
||||||
position: "absolute",
|
<span className="font-bold text-[13px]">
|
||||||
height: "100vh",
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center",
|
|
||||||
zIndex: "999",
|
|
||||||
backgroundColor: "#e6f2f2",
|
|
||||||
opacity: 0.8
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="no img"
|
|
||||||
src={loader}
|
|
||||||
style={{ width: "100px", height: "100px" }}
|
|
||||||
/>
|
|
||||||
<span style={{ fontSize: "13px", fontWeight: "bold" }}>
|
|
||||||
This might take some time
|
This might take some time
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{isCelebration && (
|
||||||
|
<div className="relative z-[999]">
|
||||||
|
<Confetti width={window.innerWidth} height={window.innerHeight} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="signatureContainer" ref={divRef}>
|
<div
|
||||||
|
className="relative op-card overflow-hidden flex flex-col md:flex-row justify-between bg-base-300"
|
||||||
|
ref={divRef}
|
||||||
|
>
|
||||||
{!isEmailVerified && (
|
{!isEmailVerified && (
|
||||||
<VerifyEmail
|
<VerifyEmail
|
||||||
isVerifyModal={isVerifyModal}
|
isVerifyModal={isVerifyModal}
|
||||||
@@ -1168,7 +1159,6 @@ function SignYourSelf() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
|
||||||
isOpen={isAlert.isShow}
|
isOpen={isAlert.isShow}
|
||||||
title={isAlert?.header || "Alert"}
|
title={isAlert?.header || "Alert"}
|
||||||
handleClose={() => {
|
handleClose={() => {
|
||||||
@@ -1178,7 +1168,7 @@ function SignYourSelf() {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="p-[20px] h-full">
|
||||||
<p>{isAlert.alertMessage}</p>
|
<p>{isAlert.alertMessage}</p>
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
@@ -1186,25 +1176,16 @@ function SignYourSelf() {
|
|||||||
{/* this modal is used show this document is already sign */}
|
{/* this modal is used show this document is already sign */}
|
||||||
<ModalUi
|
<ModalUi
|
||||||
isOpen={showAlreadySignDoc.status}
|
isOpen={showAlreadySignDoc.status}
|
||||||
title={"Sign Documents"}
|
title={"Document signed"}
|
||||||
handleClose={() => {
|
handleClose={() => {
|
||||||
setShowAlreadySignDoc({ status: false });
|
setShowAlreadySignDoc({ status: false });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="p-[20px] h-full">
|
||||||
<p>{showAlreadySignDoc.mssg}</p>
|
<p>{showAlreadySignDoc.mssg}</p>
|
||||||
|
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
<button
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-ghost shadow-md"
|
||||||
onClick={() => setShowAlreadySignDoc({ status: false })}
|
onClick={() => setShowAlreadySignDoc({ status: false })}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
@@ -1258,7 +1239,6 @@ function SignYourSelf() {
|
|||||||
<EmailComponent
|
<EmailComponent
|
||||||
isEmail={isEmail}
|
isEmail={isEmail}
|
||||||
pdfUrl={pdfUrl}
|
pdfUrl={pdfUrl}
|
||||||
isCeleb={isCeleb}
|
|
||||||
setIsEmail={setIsEmail}
|
setIsEmail={setIsEmail}
|
||||||
pdfName={pdfDetails[0] && pdfDetails[0].Name}
|
pdfName={pdfDetails[0] && pdfDetails[0].Name}
|
||||||
setSuccessEmail={setSuccessEmail}
|
setSuccessEmail={setSuccessEmail}
|
||||||
@@ -1331,7 +1311,7 @@ function SignYourSelf() {
|
|||||||
maxHeight: window.innerHeight - 70 + "px",
|
maxHeight: window.innerHeight - 70 + "px",
|
||||||
backgroundColor: "white"
|
backgroundColor: "white"
|
||||||
}}
|
}}
|
||||||
className="autoSignScroll"
|
className="overflow-y-auto hide-scrollbar"
|
||||||
>
|
>
|
||||||
{!isCompleted ? (
|
{!isCompleted ? (
|
||||||
<div>
|
<div>
|
||||||
@@ -1343,7 +1323,6 @@ function SignYourSelf() {
|
|||||||
handleDivClick={handleDivClick}
|
handleDivClick={handleDivClick}
|
||||||
handleMouseLeave={handleMouseLeave}
|
handleMouseLeave={handleMouseLeave}
|
||||||
isDragSign={isDragSign}
|
isDragSign={isDragSign}
|
||||||
themeColor={themeColor}
|
|
||||||
dragStamp={dragStamp}
|
dragStamp={dragStamp}
|
||||||
dragRef={dragRef}
|
dragRef={dragRef}
|
||||||
isDragStamp={isDragStamp}
|
isDragStamp={isDragStamp}
|
||||||
@@ -1364,31 +1343,22 @@ function SignYourSelf() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
|
||||||
isOpen={validateAlert}
|
isOpen={validateAlert}
|
||||||
title={"Validation alert"}
|
title={"Validation alert"}
|
||||||
handleClose={() => {
|
handleClose={() => {
|
||||||
setValidateAlert(false);
|
setValidateAlert(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="p-[20px] h-full">
|
||||||
<p>
|
<p>
|
||||||
The input does not meet the criteria set by the regular expression.
|
The input does not meet the criteria set by the regular expression.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div
|
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setValidateAlert(false)}
|
onClick={() => setValidateAlert(false)}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-ghost shadow-md"
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
|||||||
import { useParams, useNavigate } from "react-router-dom";
|
import { useParams, useNavigate } from "react-router-dom";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import { isEnableSubscription, themeColor } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { DndProvider } from "react-dnd";
|
import { DndProvider } from "react-dnd";
|
||||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||||
import { useDrag, useDrop } from "react-dnd";
|
import { useDrag, useDrop } from "react-dnd";
|
||||||
import WidgetComponent from "../components/pdf/WidgetComponent";
|
import WidgetComponent from "../components/pdf/WidgetComponent";
|
||||||
import Tour from "reactour";
|
import Tour from "reactour";
|
||||||
import Loader from "../primitives/LoaderWithMsg";
|
import LoaderWithMsg from "../primitives/LoaderWithMsg";
|
||||||
import HandleError from "../primitives/HandleError";
|
import HandleError from "../primitives/HandleError";
|
||||||
import SignerListPlace from "../components/pdf/SignerListPlace";
|
import SignerListPlace from "../components/pdf/SignerListPlace";
|
||||||
import Header from "../components/pdf/PdfHeader";
|
import Header from "../components/pdf/PdfHeader";
|
||||||
@@ -36,6 +36,7 @@ import AddRoleModal from "../components/pdf/AddRoleModal";
|
|||||||
import PlaceholderCopy from "../components/pdf/PlaceholderCopy";
|
import PlaceholderCopy from "../components/pdf/PlaceholderCopy";
|
||||||
import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
import TourContentWithBtn from "../primitives/TourContentWithBtn";
|
||||||
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
|
import DropdownWidgetOption from "../components/pdf/DropdownWidgetOption";
|
||||||
|
import Parse from "parse";
|
||||||
const TemplatePlaceholder = () => {
|
const TemplatePlaceholder = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { templateId } = useParams();
|
const { templateId } = useParams();
|
||||||
@@ -704,35 +705,29 @@ const TemplatePlaceholder = () => {
|
|||||||
Name: pdfDetails[0]?.Name || "",
|
Name: pdfDetails[0]?.Name || "",
|
||||||
Note: pdfDetails[0]?.Note || "",
|
Note: pdfDetails[0]?.Note || "",
|
||||||
Description: pdfDetails[0]?.Description || "",
|
Description: pdfDetails[0]?.Description || "",
|
||||||
SendinOrder: pdfDetails[0]?.SendinOrder || false
|
SendinOrder: pdfDetails[0]?.SendinOrder || false,
|
||||||
|
AutomaticReminders: pdfDetails[0]?.AutomaticReminders,
|
||||||
|
RemindOnceInEvery: parseInt(pdfDetails[0]?.RemindOnceInEvery),
|
||||||
|
NextReminderDate: pdfDetails[0]?.NextReminderDate
|
||||||
};
|
};
|
||||||
|
const updateTemplate = new Parse.Object("contracts_Template");
|
||||||
|
updateTemplate.id = templateId;
|
||||||
|
for (const key in data) {
|
||||||
|
updateTemplate.set(key, data[key]);
|
||||||
|
}
|
||||||
|
await updateTemplate.save(null, {
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
});
|
||||||
|
|
||||||
await axios
|
setIsCreateDocModal(true);
|
||||||
.put(
|
setIsMailSend(true);
|
||||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
const loadObj = {
|
||||||
"_appName"
|
isLoad: false
|
||||||
)}_Template/${templateId}`,
|
};
|
||||||
data,
|
setIsLoading(loadObj);
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
setIsCreateDocModal(true);
|
|
||||||
setIsMailSend(true);
|
|
||||||
const loadObj = {
|
|
||||||
isLoad: false
|
|
||||||
};
|
|
||||||
setIsLoading(loadObj);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("axois err ", err);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
setIsLoading(false);
|
||||||
|
alert("Something went wrong, please try again later.");
|
||||||
console.log("error", e);
|
console.log("error", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1207,17 +1202,19 @@ const TemplatePlaceholder = () => {
|
|||||||
setIsCheckbox(false);
|
setIsCheckbox(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("signerpos", signerPos);
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Title title={"Template"} />
|
<Title title={"Template"} />
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
{isLoading.isLoad ? (
|
{isLoading.isLoad ? (
|
||||||
<Loader isLoading={isLoading} />
|
<LoaderWithMsg isLoading={isLoading} />
|
||||||
) : handleError ? (
|
) : handleError ? (
|
||||||
<HandleError handleError={handleError} />
|
<HandleError handleError={handleError} />
|
||||||
) : (
|
) : (
|
||||||
<div className="signatureContainer" ref={divRef}>
|
<div
|
||||||
|
className="op-card overflow-hidden flex flex-row justify-between bg-base-300 relative"
|
||||||
|
ref={divRef}
|
||||||
|
>
|
||||||
{/* this component used for UI interaction and show their functionality */}
|
{/* this component used for UI interaction and show their functionality */}
|
||||||
{!checkTourStatus && (
|
{!checkTourStatus && (
|
||||||
//this tour component used in your html component where you want to put
|
//this tour component used in your html component where you want to put
|
||||||
@@ -1260,23 +1257,21 @@ const TemplatePlaceholder = () => {
|
|||||||
>
|
>
|
||||||
{/* this modal is used show alert set placeholder for all signers before send mail */}
|
{/* this modal is used show alert set placeholder for all signers before send mail */}
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
|
||||||
isOpen={isSendAlert}
|
isOpen={isSendAlert}
|
||||||
title={"Fields required"}
|
title={"Fields required"}
|
||||||
handleClose={() => setIsSendAlert(false)}
|
handleClose={() => setIsSendAlert(false)}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-full p-[20px]">
|
||||||
<p>Please add at least one signature field for all roles.</p>
|
<p>Please add at least one signature field for all roles.</p>
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
|
||||||
isOpen={!IsReceipent}
|
isOpen={!IsReceipent}
|
||||||
title={"Roles"}
|
title={"Roles"}
|
||||||
handleClose={() => setIsReceipent(true)}
|
handleClose={() => setIsReceipent(true)}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-full p-[20px] text-center font-medium">
|
||||||
<p>Please add a role</p>
|
<p>Please add roles first</p>
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
{/* this modal is used show send mail message and after send mail success message */}
|
{/* this modal is used show send mail message and after send mail success message */}
|
||||||
@@ -1285,32 +1280,18 @@ const TemplatePlaceholder = () => {
|
|||||||
title={"Create Document"}
|
title={"Create Document"}
|
||||||
handleClose={() => setIsCreateDocModal(false)}
|
handleClose={() => setIsCreateDocModal(false)}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-full p-[20px]">
|
||||||
<p>
|
<p>
|
||||||
Do you want to create a document using the template you just
|
Do you want to create a document using the template you just
|
||||||
created ?
|
created ?
|
||||||
</p>
|
</p>
|
||||||
<div
|
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
{currentEmail.length > 0 && (
|
{currentEmail.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => handleCreateDocModal()}
|
||||||
handleCreateDocModal();
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
background: themeColor,
|
|
||||||
color: "white"
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn"
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
@@ -1319,7 +1300,7 @@ const TemplatePlaceholder = () => {
|
|||||||
setIsCreateDocModal(false);
|
setIsCreateDocModal(false);
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-secondary ml-2"
|
||||||
>
|
>
|
||||||
No
|
No
|
||||||
</button>
|
</button>
|
||||||
@@ -1327,32 +1308,21 @@ const TemplatePlaceholder = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ModalUi>
|
</ModalUi>
|
||||||
{isCreateDoc && <Loader isLoading={isLoading} />}
|
{isCreateDoc && <LoaderWithMsg isLoading={isLoading} />}
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
|
||||||
isOpen={isShowEmail}
|
isOpen={isShowEmail}
|
||||||
title={"signers alert"}
|
title={"signers alert"}
|
||||||
handleClose={() => {
|
handleClose={() => {
|
||||||
setIsShowEmail(false);
|
setIsShowEmail(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ height: "100%", padding: 20 }}>
|
<div className="h-full p-[20px]">
|
||||||
<p>Please select signer for add placeholder!</p>
|
<p>Please select signer for add placeholder!</p>
|
||||||
<div
|
<div className="h-[1px] w-full my-[15px] bg-[#9f9f9f]"></div>
|
||||||
style={{
|
|
||||||
height: "1px",
|
|
||||||
backgroundColor: "#9f9f9f",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "15px",
|
|
||||||
marginBottom: "15px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => setIsShowEmail(false)}
|
||||||
setIsShowEmail(false);
|
|
||||||
}}
|
|
||||||
type="button"
|
type="button"
|
||||||
className="finishBtn cancelBtn"
|
className="op-btn op-btn-primary"
|
||||||
>
|
>
|
||||||
Ok
|
Ok
|
||||||
</button>
|
</button>
|
||||||
@@ -1402,7 +1372,7 @@ const TemplatePlaceholder = () => {
|
|||||||
// signerObjId={signerObjId}
|
// signerObjId={signerObjId}
|
||||||
Id={uniqueId}
|
Id={uniqueId}
|
||||||
/>
|
/>
|
||||||
{/* pdf header which contain funish back button */}
|
{/* pdf header which contain finish, back button */}
|
||||||
<Header
|
<Header
|
||||||
completeBtnTitle={"Save"}
|
completeBtnTitle={"Save"}
|
||||||
isPlaceholder={true}
|
isPlaceholder={true}
|
||||||
@@ -1505,10 +1475,10 @@ const TemplatePlaceholder = () => {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<div className="signerComponent">
|
<div className="hidden md:block w-[180px] h-full bg-base-100">
|
||||||
<div
|
<div
|
||||||
style={{ maxHeight: window.innerHeight - 70 + "px" }}
|
style={{ maxHeight: window.innerHeight - 70 + "px" }}
|
||||||
className="autoSignScroll"
|
className="overflow-y-auto hide-scrollbar"
|
||||||
>
|
>
|
||||||
<SignerListPlace
|
<SignerListPlace
|
||||||
isMailSend={isMailSend}
|
isMailSend={isMailSend}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, {
|
||||||
|
useState,
|
||||||
|
useEffect
|
||||||
|
// useRef
|
||||||
|
} from "react";
|
||||||
import { Navigate, useNavigate } from "react-router-dom";
|
import { Navigate, useNavigate } from "react-router-dom";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { SaveFileSize } from "../constant/saveFileSize";
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
@@ -8,10 +12,11 @@ import sanitizeFileName from "../primitives/sanitizeFileName";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
||||||
import Tooltip from "../primitives/Tooltip";
|
import Tooltip from "../primitives/Tooltip";
|
||||||
import { isEnableSubscription, rejectBtn, submitBtn } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { checkIsSubscribed, handleSendOTP } from "../constant/Utils";
|
import { checkIsSubscribed, handleSendOTP } from "../constant/Utils";
|
||||||
import Upgrade from "../primitives/Upgrade";
|
import Upgrade from "../primitives/Upgrade";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
function UserProfile() {
|
function UserProfile() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -27,6 +32,10 @@ function UserProfile() {
|
|||||||
const [percentage, setpercentage] = useState(0);
|
const [percentage, setpercentage] = useState(0);
|
||||||
const [isDisableDocId, setIsDisableDocId] = useState(false);
|
const [isDisableDocId, setIsDisableDocId] = useState(false);
|
||||||
const [isSubscribe, setIsSubscribe] = useState(false);
|
const [isSubscribe, setIsSubscribe] = useState(false);
|
||||||
|
// const [publicUserName, setPublicUserName] = useState(
|
||||||
|
// extendUser && extendUser?.[0]?.UserName
|
||||||
|
// );
|
||||||
|
// const previousPublicUserName = useRef(publicUserName);
|
||||||
const [company, setCompany] = useState(
|
const [company, setCompany] = useState(
|
||||||
extendUser && extendUser?.[0]?.Company
|
extendUser && extendUser?.[0]?.Company
|
||||||
);
|
);
|
||||||
@@ -37,6 +46,7 @@ function UserProfile() {
|
|||||||
const [otp, setOtp] = useState("");
|
const [otp, setOtp] = useState("");
|
||||||
const [otpLoader, setOtpLoader] = useState(false);
|
const [otpLoader, setOtpLoader] = useState(false);
|
||||||
const [isEmailVerified, setIsEmailVerified] = useState(false);
|
const [isEmailVerified, setIsEmailVerified] = useState(false);
|
||||||
|
// const [userNameError, setUserNameError] = useState("");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUserDetail();
|
getUserDetail();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -74,46 +84,72 @@ function UserProfile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//function to check public username already exist
|
||||||
|
// const handleCheckPublicUserName = async () => {
|
||||||
|
// try {
|
||||||
|
// const res = await Parse.Cloud.run("getpublicusername", {
|
||||||
|
// username: publicUserName
|
||||||
|
// });
|
||||||
|
// if (res) {
|
||||||
|
// setIsLoader(false);
|
||||||
|
// setUserNameError("user name already exist");
|
||||||
|
// setTimeout(() => {
|
||||||
|
// setUserNameError("");
|
||||||
|
// }, 3000);
|
||||||
|
// return res;
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// console.log("error in getpublicusername cloud function");
|
||||||
|
// }
|
||||||
|
// };
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsLoader(true);
|
let phn = Phone,
|
||||||
let phn = Phone;
|
res = "";
|
||||||
|
//condition to call cloud function when user change publicUserName
|
||||||
try {
|
// if (previousPublicUserName.current !== publicUserName) {
|
||||||
const tour = Parse.Object.extend("_User");
|
// res = await handleCheckPublicUserName();
|
||||||
const query = new Parse.Query(tour);
|
// }
|
||||||
|
if (!res) {
|
||||||
await query.get(UserProfile.objectId).then((object) => {
|
setIsLoader(true);
|
||||||
object.set("name", name);
|
try {
|
||||||
object.set("ProfilePic", Image);
|
const userQuery = Parse.Object.extend("_User");
|
||||||
object.set("phone", phn);
|
const query = new Parse.Query(userQuery);
|
||||||
|
await query.get(UserProfile.objectId).then((object) => {
|
||||||
object.save().then(
|
object.set("name", name);
|
||||||
async (response) => {
|
object.set("ProfilePic", Image);
|
||||||
if (response) {
|
object.set("phone", phn || "");
|
||||||
let res = response.toJSON();
|
object.save().then(
|
||||||
let rr = JSON.stringify(res);
|
async (response) => {
|
||||||
localStorage.setItem("UserInformation", rr);
|
if (response) {
|
||||||
SetName(res.name);
|
let res = response.toJSON();
|
||||||
SetPhone(res.phone);
|
let rr = JSON.stringify(res);
|
||||||
setImage(res.ProfilePic);
|
localStorage.setItem("UserInformation", rr);
|
||||||
localStorage.setItem("username", res.name);
|
SetName(res.name);
|
||||||
localStorage.setItem("profileImg", res.ProfilePic);
|
SetPhone(res?.phone || "");
|
||||||
await updateExtUser({ Name: res.name, Phone: res.phone });
|
setImage(res.ProfilePic);
|
||||||
alert("Profile updated successfully.");
|
localStorage.setItem("username", res.name);
|
||||||
setEditMode(false);
|
localStorage.setItem("profileImg", res.ProfilePic);
|
||||||
navigate("/dashboard/35KBoSgoAK");
|
await updateExtUser({
|
||||||
|
Name: res.name,
|
||||||
|
Phone: res?.phone || ""
|
||||||
|
});
|
||||||
|
alert("Profile updated successfully.");
|
||||||
|
setEditMode(false);
|
||||||
|
setIsLoader(false);
|
||||||
|
//navigate("/dashboard/35KBoSgoAK");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
alert("Something went wrong.");
|
||||||
|
console.error("Error while updating tour", error);
|
||||||
|
setIsLoader(false);
|
||||||
}
|
}
|
||||||
},
|
);
|
||||||
(error) => {
|
});
|
||||||
alert("Something went wrong.");
|
} catch (error) {
|
||||||
console.error("Error while updating tour", error);
|
console.log("err", error);
|
||||||
setIsLoader(false);
|
}
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log("err", error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -122,14 +158,15 @@ function UserProfile() {
|
|||||||
const extClass = localStorage.getItem("extended_class");
|
const extClass = localStorage.getItem("extended_class");
|
||||||
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
|
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||||
const ExtUserId = extData[0].objectId;
|
const ExtUserId = extData[0].objectId;
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
Phone: obj.Phone,
|
Phone: obj?.Phone || "",
|
||||||
Name: obj.Name,
|
Name: obj.Name,
|
||||||
HeaderDocId: isDisableDocId,
|
HeaderDocId: isDisableDocId,
|
||||||
JobTitle: jobTitle,
|
JobTitle: jobTitle,
|
||||||
Company: company
|
Company: company
|
||||||
|
// UserName: publicUserName || ""
|
||||||
};
|
};
|
||||||
|
|
||||||
await axios.put(
|
await axios.put(
|
||||||
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
|
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
|
||||||
body,
|
body,
|
||||||
@@ -147,7 +184,6 @@ function UserProfile() {
|
|||||||
|
|
||||||
const json = JSON.parse(JSON.stringify([res]));
|
const json = JSON.parse(JSON.stringify([res]));
|
||||||
const extRes = JSON.stringify(json);
|
const extRes = JSON.stringify(json);
|
||||||
|
|
||||||
localStorage.setItem("Extand_Class", extRes);
|
localStorage.setItem("Extand_Class", extRes);
|
||||||
// console.log("updateRes ", updateRes);
|
// console.log("updateRes ", updateRes);
|
||||||
};
|
};
|
||||||
@@ -241,29 +277,45 @@ function UserProfile() {
|
|||||||
setOtpLoader(false);
|
setOtpLoader(false);
|
||||||
alert("OTP sent on you email");
|
alert("OTP sent on you email");
|
||||||
};
|
};
|
||||||
|
//function to handle onchange username and restrict 6-characters username for free users
|
||||||
|
// const handleOnchangeUserName = (e) => {
|
||||||
|
// const value = e.target.value;
|
||||||
|
// if (value.length > 6 && !isSubscribe) {
|
||||||
|
// setUserNameError("Please upgrade to allow more than 6 characters.");
|
||||||
|
// setTimeout(() => {
|
||||||
|
// setUserNameError("");
|
||||||
|
// }, 2000);
|
||||||
|
// } else {
|
||||||
|
// setPublicUserName(e.target.value);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
const handleCancel = () => {
|
||||||
|
setEditMode(false);
|
||||||
|
SetName(localStorage.getItem("username"));
|
||||||
|
SetPhone(UserProfile && UserProfile.phone);
|
||||||
|
setImage(localStorage.getItem("profileImg"));
|
||||||
|
// setPublicUserName(extendUser && extendUser?.[0]?.UserName);
|
||||||
|
setCompany(extendUser && extendUser?.[0]?.Company);
|
||||||
|
setJobTitle(extendUser?.[0]?.JobTitle);
|
||||||
|
setIsDisableDocId(extendUser?.[0]?.HeaderDocId);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Title title={"Profile"} />
|
<Title title={"Profile"} />
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="h-[100vh] flex justify-center items-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex justify-center items-center w-full">
|
<div className="flex justify-center items-center w-full relative">
|
||||||
<div className="bg-white flex flex-col justify-center shadow rounded w-[450px]">
|
{/* {userNameError && (
|
||||||
|
<div
|
||||||
|
className={`z-[1000] fixed top-[50%] transform border-[1px] text-sm border-[#f0a8a8] bg-[#f4bebe] text-[#c42121] rounded py-[.75rem] px-[1.25rem]`}
|
||||||
|
>
|
||||||
|
{userNameError}
|
||||||
|
</div>
|
||||||
|
)} */}
|
||||||
|
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow rounded-xl w-[450px]">
|
||||||
<div className="flex flex-col justify-center items-center my-4">
|
<div className="flex flex-col justify-center items-center my-4">
|
||||||
<div className="w-[200px] h-[200px] overflow-hidden rounded-full">
|
<div className="w-[200px] h-[200px] overflow-hidden rounded-full">
|
||||||
<img
|
<img
|
||||||
@@ -275,7 +327,7 @@ function UserProfile() {
|
|||||||
{editmode && (
|
{editmode && (
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
className="max-w-[270px] text-sm py-1 px-2 mt-4 border-[1px] border-[#15b4e9] text-black rounded"
|
className="op-file-input op-file-input-bordered op-file-input-sm max-w-[270px] mt-4 text-sm"
|
||||||
accept="image/png, image/gif, image/jpeg"
|
accept="image/png, image/gif, image/jpeg"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
let files = e.target.files;
|
let files = e.target.files;
|
||||||
@@ -301,7 +353,7 @@ function UserProfile() {
|
|||||||
<ul className="w-full flex flex-col p-2 text-sm">
|
<ul className="w-full flex flex-col p-2 text-sm">
|
||||||
<li
|
<li
|
||||||
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
||||||
editmode ? "py-1" : "py-2"
|
editmode ? "py-1.5" : "py-2"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="font-semibold">Name:</span>{" "}
|
<span className="font-semibold">Name:</span>{" "}
|
||||||
@@ -309,7 +361,7 @@ function UserProfile() {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={name}
|
value={name}
|
||||||
className="py-1 px-2 text-sm border-[1px] border-[#15b4e9] text-black rounded"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-sm"
|
||||||
onChange={(e) => SetName(e.target.value)}
|
onChange={(e) => SetName(e.target.value)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -318,14 +370,14 @@ function UserProfile() {
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
||||||
editmode ? "py-1" : "py-2"
|
editmode ? "py-1.5" : "py-2"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="font-semibold">Phone:</span>{" "}
|
<span className="font-semibold">Phone:</span>{" "}
|
||||||
{editmode ? (
|
{editmode ? (
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="py-1 px-2 text-sm border-[1px] border-[#15b4e9] text-black rounded"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-sm"
|
||||||
onChange={(e) => SetPhone(e.target.value)}
|
onChange={(e) => SetPhone(e.target.value)}
|
||||||
value={Phone}
|
value={Phone}
|
||||||
/>
|
/>
|
||||||
@@ -339,7 +391,7 @@ function UserProfile() {
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
||||||
editmode ? "py-1" : "py-2"
|
editmode ? "py-1.5" : "py-2"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="font-semibold">Company:</span>{" "}
|
<span className="font-semibold">Company:</span>{" "}
|
||||||
@@ -347,7 +399,7 @@ function UserProfile() {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={company}
|
value={company}
|
||||||
className="py-1 px-2 text-sm border-[1px] border-[#15b4e9] text-black rounded"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-sm"
|
||||||
onChange={(e) => setCompany(e.target.value)}
|
onChange={(e) => setCompany(e.target.value)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -356,7 +408,7 @@ function UserProfile() {
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
|
||||||
editmode ? "py-1" : "py-2"
|
editmode ? "py-1.5" : "py-2"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="font-semibold">Job title:</span>{" "}
|
<span className="font-semibold">Job title:</span>{" "}
|
||||||
@@ -364,7 +416,7 @@ function UserProfile() {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={jobTitle}
|
value={jobTitle}
|
||||||
className="py-1 px-2 text-sm border-[1px] border-[#15b4e9] text-black rounded"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-sm"
|
||||||
onChange={(e) => setJobTitle(e.target.value)}
|
onChange={(e) => setJobTitle(e.target.value)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -390,6 +442,37 @@ function UserProfile() {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
{/* {isEnableSubscription && (
|
||||||
|
<li className="flex justify-between items-center border-t-[1px] border-gray-300 py-2 break-all">
|
||||||
|
<span className="font-semibold">
|
||||||
|
Public profile :{" "}
|
||||||
|
<Tooltip
|
||||||
|
message={`this is your public URL. Copy or share it
|
||||||
|
with the signer, and you will be able to see
|
||||||
|
all your publicly set templates.`}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<div className="flex text-xs items-center">
|
||||||
|
<span>opensign-me.vercel.app/</span>
|
||||||
|
{editmode ? (
|
||||||
|
<input
|
||||||
|
onChange={handleOnchangeUserName}
|
||||||
|
value={publicUserName}
|
||||||
|
disabled={!editmode}
|
||||||
|
placeholder="enter user name"
|
||||||
|
className="op-input op-input-bordered focus:outline-none hover:border-base-content op-input-xs"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<input
|
||||||
|
value={extendUser?.[0]?.UserName}
|
||||||
|
disabled
|
||||||
|
placeholder="enter user name"
|
||||||
|
className="op-input op-input-bordered op-input-xs"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
)} */}
|
||||||
<li className="border-y-[1px] border-gray-300 break-all">
|
<li className="border-y-[1px] border-gray-300 break-all">
|
||||||
<div className="flex justify-between items-center py-2">
|
<div className="flex justify-between items-center py-2">
|
||||||
<span
|
<span
|
||||||
@@ -404,27 +487,23 @@ function UserProfile() {
|
|||||||
url={
|
url={
|
||||||
"https://docs.opensignlabs.com/docs/help/Settings/disabledocumentid"
|
"https://docs.opensignlabs.com/docs/help/Settings/disabledocumentid"
|
||||||
}
|
}
|
||||||
/>{" "}
|
/>
|
||||||
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
{!isSubscribe && isEnableSubscription && <Upgrade />}
|
||||||
</span>{" "}
|
</span>
|
||||||
<label
|
<label
|
||||||
className={
|
className={`${
|
||||||
isSubscribe || !isEnableSubscription
|
isSubscribe || !isEnableSubscription
|
||||||
? `${
|
? `${editmode ? "cursor-pointer" : ""}`
|
||||||
editmode ? "cursor-pointer" : ""
|
: "pointer-events-none opacity-50"
|
||||||
} relative inline-flex items-center mb-0`
|
} relative block items-center mb-0`}
|
||||||
: "relative inline-flex items-center mb-0 pointer-events-none opacity-50"
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
disabled={editmode ? false : true}
|
disabled={editmode ? false : true}
|
||||||
|
type="checkbox"
|
||||||
|
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white"
|
||||||
checked={isDisableDocId}
|
checked={isDisableDocId}
|
||||||
onChange={handleDisableDocId}
|
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-1 peer-focus:ring-black 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-black peer-checked:bg-blue-600"></div>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{!isEnableSubscription && (
|
{!isEnableSubscription && (
|
||||||
@@ -436,44 +515,29 @@ function UserProfile() {
|
|||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div className="flex justify-center pt-2 pb-3 md:pt-3 md:pb-4">
|
<div className="flex justify-center gap-2 pt-2 pb-3 md:pt-3 md:pb-4">
|
||||||
{editmode ? (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={handleSubmit}
|
|
||||||
className="rounded shadow focus:outline-none border-[2px] border-[#15b4e9] bg-white text-[#15b4e9] px-4 py-2 mr-4"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => {
|
|
||||||
setEditMode(true);
|
|
||||||
}}
|
|
||||||
className="rounded shadow focus:outline-none text-white bg-[#e7505a] px-4 py-2 mr-4"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={(e) =>
|
||||||
if (editmode) {
|
editmode ? handleSubmit(e) : setEditMode(true)
|
||||||
setEditMode(false);
|
}
|
||||||
} else {
|
className="op-btn op-btn-primary"
|
||||||
navigate("/changepassword");
|
>
|
||||||
}
|
{editmode ? "Save" : "Edit"}
|
||||||
}}
|
</button>
|
||||||
className={`rounded shadow focus:outline-none text-white bg-[#3598dc] ${
|
<button
|
||||||
editmode ? "px-4 py-2 " : "p-2"
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
editmode ? handleCancel() : navigate("/changepassword")
|
||||||
|
}
|
||||||
|
className={`op-btn ${
|
||||||
|
editmode ? "op-btn-ghost" : "op-btn-secondary"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{editmode ? "Cancel" : "Change Password"}
|
{editmode ? "Cancel" : "Change Password"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isVerifyModal && (
|
{isVerifyModal && (
|
||||||
<ModalUi
|
<ModalUi
|
||||||
isOpen
|
isOpen
|
||||||
@@ -481,43 +545,29 @@ function UserProfile() {
|
|||||||
handleClose={handleCloseVerifyModal}
|
handleClose={handleCloseVerifyModal}
|
||||||
>
|
>
|
||||||
{otpLoader ? (
|
{otpLoader ? (
|
||||||
<div
|
<div className="h-[150px] flex justify-center items-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "150px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<form onSubmit={(e) => handleVerifyEmail(e)}>
|
<form onSubmit={(e) => handleVerifyEmail(e)}>
|
||||||
<div className="px-6 py-3">
|
<div className="px-6 py-3 text-base-content">
|
||||||
<label className="mb-2">Enter OTP</label>
|
<label className="mb-2">Enter OTP</label>
|
||||||
<input
|
<input
|
||||||
required
|
required
|
||||||
type="tel"
|
type="tel"
|
||||||
pattern="[0-9]{4}"
|
pattern="[0-9]{4}"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="w-full op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
placeholder="Enter OTP received over email"
|
placeholder="Enter OTP received over email"
|
||||||
value={otp}
|
value={otp}
|
||||||
onChange={(e) => setOtp(e.target.value)}
|
onChange={(e) => setOtp(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<div className="px-6 mb-3">
|
||||||
<div className="px-6 my-3">
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
<button type="submit" className={submitBtn}>
|
|
||||||
Verify
|
Verify
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`${rejectBtn} ml-2`}
|
className="op-btn op-btn-secondary ml-2"
|
||||||
onClick={(e) => handleResend(e)}
|
onClick={(e) => handleResend(e)}
|
||||||
>
|
>
|
||||||
Resend
|
Resend
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import axios from "axios";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
import ModalUi from "../primitives/ModalUi";
|
||||||
import { isEnableSubscription, rejectBtn, submitBtn } from "../constant/const";
|
import { isEnableSubscription } from "../constant/const";
|
||||||
import { checkIsSubscribed, openInNewTab } from "../constant/Utils";
|
import { checkIsSubscribed, openInNewTab } from "../constant/Utils";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
import PremiumAlertHeader from "../primitives/PremiumAlertHeader";
|
||||||
import Tooltip from "../primitives/Tooltip";
|
import Tooltip from "../primitives/Tooltip";
|
||||||
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
function Webhook() {
|
function Webhook() {
|
||||||
const navigation = useNavigate();
|
const navigation = useNavigate();
|
||||||
@@ -97,28 +98,15 @@ function Webhook() {
|
|||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Title title={"Webhook"} />
|
<Title title={"Webhook"} />
|
||||||
{isGenerate && <Alert type="success">Webhook added successfully!</Alert>}
|
{isGenerate && <Alert type="success">Webhook added successfully.</Alert>}
|
||||||
{isErr && <Alert type="danger">Something went wrong!</Alert>}
|
{isErr && <Alert type="danger">Something went wrong.</Alert>}
|
||||||
|
|
||||||
{isLoader ? (
|
{isLoader ? (
|
||||||
<div
|
<div className="h-[100vh] flex justify-center items-center">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-white flex flex-col justify-center shadow rounded">
|
<div className="bg-base-100 text-base-content flex flex-col justify-center shadow rounded">
|
||||||
{!isEnableSubscription && <PremiumAlertHeader />}
|
{!isEnableSubscription && <PremiumAlertHeader />}
|
||||||
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
<h1 className={"ml-4 mt-3 mb-2 font-semibold"}>
|
||||||
OpenSign™ Webhook{" "}
|
OpenSign™ Webhook{" "}
|
||||||
@@ -146,14 +134,14 @@ function Webhook() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleModal}
|
onClick={handleModal}
|
||||||
className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-4 py-2 text-xs md:text-base focus:outline-none"
|
className="op-btn op-btn-primary "
|
||||||
>
|
>
|
||||||
{webhook ? "Update Webhook" : "Add Webhook"}
|
{webhook ? "Update Webhook" : "Add Webhook"}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div className="flex items-center justify-center ">
|
<div className="flex items-center justify-center ">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -161,7 +149,7 @@ function Webhook() {
|
|||||||
"https://docs.opensignlabs.com/docs/API-docs/save-update-webhook"
|
"https://docs.opensignlabs.com/docs/API-docs/save-update-webhook"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="rounded hover:bg-[#15b4e9] border-[1px] my-2 border-[#15b4e9] text-[#15b4e9] hover:text-white px-11 py-2 text-xs md:text-base focus:outline-none"
|
className="op-btn op-btn-secondary my-2"
|
||||||
>
|
>
|
||||||
View Docs
|
View Docs
|
||||||
</button>
|
</button>
|
||||||
@@ -203,24 +191,27 @@ function Webhook() {
|
|||||||
>
|
>
|
||||||
{error && <Alert type="danger">{error}</Alert>}
|
{error && <Alert type="danger">{error}</Alert>}
|
||||||
<div className="m-[20px]">
|
<div className="m-[20px]">
|
||||||
<div className="text-lg font-normal text-black">
|
<div className="text-lg font-normal text-base-content">
|
||||||
<label className="text-sm ml-2">Webhook</label>
|
<label className="text-sm ml-2">Webhook</label>
|
||||||
<input
|
<input
|
||||||
value={webhook}
|
value={webhook}
|
||||||
onChange={(e) => setWebhook(e.target.value)}
|
onChange={(e) => setWebhook(e.target.value)}
|
||||||
placeholder="Enter webhook url"
|
placeholder="Enter webhook url"
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<hr className="bg-[#ccc] mt-4 " />
|
<hr className="bg-[#ccc] mt-3" />
|
||||||
<div className="flex items-center mt-3 gap-2 text-white">
|
<div className="flex items-center mt-3 gap-2">
|
||||||
<button
|
<button
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
className={submitBtn + "ml-[2px]"}
|
className="op-btn op-btn-primary ml-[2px]"
|
||||||
>
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
<button onClick={handleModal} className={rejectBtn}>
|
<button
|
||||||
|
onClick={handleModal}
|
||||||
|
className="op-btn op-btn-secondary"
|
||||||
|
>
|
||||||
No
|
No
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// below code is used to handle undefined Promise.withResolvers for safari
|
||||||
|
if (typeof Promise.withResolvers === "undefined") {
|
||||||
|
Promise.withResolvers = function () {
|
||||||
|
let resolve, reject;
|
||||||
|
const promise = new Promise((res, rej) => {
|
||||||
|
resolve = res;
|
||||||
|
reject = rej;
|
||||||
|
});
|
||||||
|
return { promise, resolve, reject };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage:
|
||||||
|
// const { promise, resolve, reject } = Promise.withResolvers()
|
||||||
|
// console.log(promise, resolve, reject) // Promise { <pending> } [Function (anonymous)] [Function (anonymous)]
|
||||||
|
// ... Do something async and then call resolve or reject!
|
||||||
+38
-39
@@ -2,7 +2,8 @@ import React, { useState, useEffect } from "react";
|
|||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import "../styles/AddUser.css";
|
import "../styles/AddUser.css";
|
||||||
const AddUser = (props) => {
|
import Loader from "./Loader";
|
||||||
|
const AddContact = (props) => {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
const [phone, setPhone] = useState("");
|
const [phone, setPhone] = useState("");
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
@@ -21,7 +22,7 @@ const AddUser = (props) => {
|
|||||||
);
|
);
|
||||||
if (savedUserDetails && addYourself) {
|
if (savedUserDetails && addYourself) {
|
||||||
setName(savedUserDetails.name);
|
setName(savedUserDetails.name);
|
||||||
setPhone(savedUserDetails.phone);
|
setPhone(savedUserDetails?.phone || "");
|
||||||
setEmail(savedUserDetails.email);
|
setEmail(savedUserDetails.email);
|
||||||
}
|
}
|
||||||
}, [addYourself]);
|
}, [addYourself]);
|
||||||
@@ -50,7 +51,9 @@ const AddUser = (props) => {
|
|||||||
try {
|
try {
|
||||||
const contactQuery = new Parse.Object("contracts_Contactbook");
|
const contactQuery = new Parse.Object("contracts_Contactbook");
|
||||||
contactQuery.set("Name", name);
|
contactQuery.set("Name", name);
|
||||||
contactQuery.set("Phone", phone);
|
if (phone) {
|
||||||
|
contactQuery.set("Phone", phone);
|
||||||
|
}
|
||||||
contactQuery.set("Email", email);
|
contactQuery.set("Email", email);
|
||||||
contactQuery.set("UserRole", "contracts_Guest");
|
contactQuery.set("UserRole", "contracts_Guest");
|
||||||
|
|
||||||
@@ -68,8 +71,10 @@ const AddUser = (props) => {
|
|||||||
_user.set("name", name);
|
_user.set("name", name);
|
||||||
_user.set("username", email);
|
_user.set("username", email);
|
||||||
_user.set("email", email);
|
_user.set("email", email);
|
||||||
_user.set("phone", phone);
|
_user.set("password", email);
|
||||||
_user.set("password", phone);
|
if (phone) {
|
||||||
|
_user.set("phone", phone);
|
||||||
|
}
|
||||||
|
|
||||||
const user = await _user.save();
|
const user = await _user.save();
|
||||||
if (user) {
|
if (user) {
|
||||||
@@ -191,40 +196,36 @@ const AddUser = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="addusercontainer">
|
<div className="h-full px-[20px] py-[10px]">
|
||||||
{isLoader && (
|
{isLoader && (
|
||||||
<div className="loaderdiv">
|
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30">
|
||||||
<div
|
<Loader />
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="form-wrapper">
|
<div className="w-full mx-auto p-[8px]">
|
||||||
<div style={{ fontSize: 14, fontWeight: "700" }}>Add User</div>
|
<div className="text-[14px] font-[700]">Add User</div>
|
||||||
|
|
||||||
{isUserExist && (
|
{isUserExist && (
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem] flex items-center mt-1">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="addYourself"
|
id="addYourself"
|
||||||
checked={addYourself}
|
checked={addYourself}
|
||||||
onChange={handleAddYourselfChange}
|
onChange={handleAddYourselfChange}
|
||||||
className="form-checkbox"
|
className="op-checkbox op-checkbox-sm"
|
||||||
/>
|
/>
|
||||||
<label htmlFor="addYourself" className="checkbox-label ">
|
<label
|
||||||
|
htmlFor="addYourself"
|
||||||
|
className="ml-[0.5rem] text-base-content mb-0"
|
||||||
|
>
|
||||||
Add Yourself
|
Add Yourself
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<form onSubmit={handleSubmit}>
|
<form className="text-base-content" onSubmit={handleSubmit}>
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem]">
|
||||||
<label htmlFor="name" style={{ fontSize: 13 }}>
|
<label htmlFor="name" className="text-[13px]">
|
||||||
Name
|
Name
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[13px] text-[red]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -233,48 +234,46 @@ const AddUser = (props) => {
|
|||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
required
|
required
|
||||||
disabled={addYourself}
|
disabled={addYourself}
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem]">
|
||||||
<label htmlFor="email" style={{ fontSize: 13 }}>
|
<label htmlFor="email" className="text-[13px]">
|
||||||
Email
|
Email
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
<span className="text-[13px] text-[red]"> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
id="email"
|
id="email"
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value?.toLowerCase())}
|
||||||
required
|
required
|
||||||
disabled={addYourself}
|
disabled={addYourself}
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs lowercase"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-section">
|
<div className="mb-[0.75rem]">
|
||||||
<label htmlFor="phone" style={{ fontSize: 13 }}>
|
<label htmlFor="phone" className="text-[13px]">
|
||||||
Phone
|
Phone
|
||||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="phone"
|
id="phone"
|
||||||
value={phone}
|
value={phone}
|
||||||
onChange={(e) => setPhone(e.target.value)}
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
required
|
|
||||||
disabled={addYourself}
|
disabled={addYourself}
|
||||||
className="addUserInput"
|
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="buttoncontainer">
|
<div className="mt-6 flex justify-start gap-2">
|
||||||
<button type="submit" className="submitbutton">
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleReset()}
|
onClick={() => handleReset()}
|
||||||
className="resetbutton"
|
className="op-btn op-btn-secondary"
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
@@ -285,4 +284,4 @@ const AddUser = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AddUser;
|
export default AddContact;
|
||||||
@@ -5,25 +5,25 @@ const Alert = ({ children, type }) => {
|
|||||||
function theme(color) {
|
function theme(color) {
|
||||||
switch (color) {
|
switch (color) {
|
||||||
case "success":
|
case "success":
|
||||||
return "border-[#c3e6cb] bg-[#d4edda] text-[#155724]";
|
return "op-alert-success";
|
||||||
case "info":
|
case "info":
|
||||||
return "border-[#adcdeb] bg-[#c1daf0] text-[#153756]";
|
return "op-alert-info";
|
||||||
case "danger":
|
case "danger":
|
||||||
return "border-[#f0a8a8] bg-[#f4bebe] text-[#c42121]";
|
return "op-alert-error";
|
||||||
|
case "warning":
|
||||||
|
return "op-alert-warning";
|
||||||
default:
|
default:
|
||||||
return "border-[#d6d6d6] bg-[#d9d9d9] text-[#575757]";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
children && (
|
||||||
{children && (
|
<div className="z-[1000] fixed top-20 left-1/2 transform -translate-x-1/2 text-sm">
|
||||||
<div
|
<div className={`op-alert ${textcolor}`}>
|
||||||
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`}
|
<span>{children}</span>
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</>
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,15 +2,8 @@ import React from "react";
|
|||||||
|
|
||||||
function HandleError({ handleError }) {
|
function HandleError({ handleError }) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="flex justify-center items-center h-[100vh]">
|
||||||
style={{
|
<span className="text-[20px] text-[gray]">{handleError}</span>
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
height: "100vh"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: "20px", color: "gray" }}>{handleError}</span>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,12 @@
|
|||||||
import React, { Suspense } from "react";
|
import React, { Suspense } from "react";
|
||||||
|
import Loader from "./Loader";
|
||||||
|
|
||||||
const LazyPage = ({ Page }) => {
|
const LazyPage = ({ Page }) => {
|
||||||
return (
|
return (
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<div
|
<div className="flex justify-center items-center h-[100vh]">
|
||||||
style={{
|
<Loader />
|
||||||
height: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import SelectSigners from "../components/shared/fields/SelectSigners";
|
import SelectSigners from "../components/shared/fields/SelectSigners";
|
||||||
import AddUser from "./AddUser";
|
import AddContact from "./AddContact";
|
||||||
import ModalUi from "./ModalUi";
|
import ModalUi from "./ModalUi";
|
||||||
|
|
||||||
const LinkUserModal = (props) => {
|
const LinkUserModal = (props) => {
|
||||||
@@ -18,32 +18,8 @@ const LinkUserModal = (props) => {
|
|||||||
closePopup={props.closePopup}
|
closePopup={props.closePopup}
|
||||||
signersData={props?.signersData}
|
signersData={props?.signersData}
|
||||||
/>
|
/>
|
||||||
<div
|
<div className="op-divider text-base-content mx-[25%] my-1">or</div>
|
||||||
style={{
|
<AddContact details={props.handleAddUser} closePopup={props.closePopup} />
|
||||||
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>
|
</ModalUi>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Loader = () => {
|
||||||
|
return (
|
||||||
|
<div className="op-loading op-loading-infinity w-[5rem] text-accent"></div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Loader;
|
||||||
@@ -1,27 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import loader from "../assets/images/loader2.gif";
|
import Loader from "./Loader";
|
||||||
|
|
||||||
function Loader({ isLoading }) {
|
function LoaderWithMsg({ isLoading }) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="flex flex-col justify-center items-center h-[100vh]">
|
||||||
style={{
|
{/* <img alt="loader" src={loader} className="w-[80px] h-[80px]" /> */}
|
||||||
display: "flex",
|
<Loader />
|
||||||
justifyContent: "center",
|
<span className="text-[13px] text-base-cotent">{isLoading.message}</span>
|
||||||
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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Loader;
|
export default LoaderWithMsg;
|
||||||
|
|||||||
@@ -6,39 +6,35 @@ const ModalUi = ({
|
|||||||
children,
|
children,
|
||||||
title,
|
title,
|
||||||
isOpen,
|
isOpen,
|
||||||
headColor,
|
|
||||||
handleClose,
|
handleClose,
|
||||||
showHeader = true,
|
showHeader = true,
|
||||||
showClose = true,
|
showClose = true,
|
||||||
styleClass,
|
reduceWidth,
|
||||||
showHeaderMessage
|
showHeaderMessage
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<div className="fixed z-[999] 2 top-0 left-0 w-[100%] h-[100%] bg-black bg-opacity-[75%]">
|
<dialog className="op-modal op-modal-open">
|
||||||
<div
|
<div
|
||||||
className={
|
className={`${
|
||||||
styleClass
|
reduceWidth || "md:min-w-[500px]"
|
||||||
? styleClass
|
} op-modal-box p-0 max-h-90 min-w-[90%] overflow-y-auto hide-scrollbar text-sm`}
|
||||||
: "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 && (
|
{showHeader && (
|
||||||
<div
|
<>
|
||||||
className="flex justify-between rounded-t items-center py-[15px] px-[20px] text-white"
|
<h3 className="text-base-content font-bold text-lg pt-[15px] px-[20px]">
|
||||||
style={{ background: headColor ? headColor : "#32a3ac" }}
|
{title}
|
||||||
>
|
</h3>
|
||||||
<div className="text-[1.2rem] font-normal">{title}</div>
|
|
||||||
{showClose && (
|
{showClose && (
|
||||||
<div
|
<button
|
||||||
className="text-[1.5rem] cursor-pointer"
|
className="op-btn op-btn-sm op-btn-circle op-btn-ghost text-base-content absolute right-2 top-2"
|
||||||
onClick={() => handleClose && handleClose()}
|
onClick={() => handleClose && handleClose()}
|
||||||
>
|
>
|
||||||
×
|
✕
|
||||||
</div>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</>
|
||||||
)}
|
)}
|
||||||
{!isEnableSubscription && showHeaderMessage && (
|
{!isEnableSubscription && showHeaderMessage && (
|
||||||
<PremiumAlertHeader
|
<PremiumAlertHeader
|
||||||
@@ -49,7 +45,7 @@ const ModalUi = ({
|
|||||||
)}
|
)}
|
||||||
<div>{children}</div>
|
<div>{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import { rejectBtn } from "../constant/const";
|
|
||||||
|
|
||||||
function CustomModal({
|
function CustomModal({
|
||||||
show,
|
show,
|
||||||
@@ -12,12 +11,12 @@ function CustomModal({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
show && (
|
show && (
|
||||||
<div className="bg-black bg-opacity-[75%] absolute z-[999] flex flex-col items-center justify-center w-full h-full rounded">
|
<dialog className="op-modal op-modal-open absolute z-[1999]">
|
||||||
<div className="bg-white rounded outline-none md:w-[40%] w-[80%]">
|
<div className="w-[80%] md:w-[40%] op-modal-box p-0 overflow-y-auto hide-scrollbar text-sm">
|
||||||
<div className="bg-[#de4337] text-white p-[10px] rounded-t">
|
<h3 className="text-[#de4337] font-bold text-lg pt-[15px] px-[20px]">
|
||||||
{headMsg && headMsg}
|
{headMsg && headMsg}
|
||||||
</div>
|
</h3>
|
||||||
<div className="p-[15px]">
|
<div className="p-[10px] px-[20px]">
|
||||||
<p className="text-[15px]">{bodyMssg && bodyMssg}</p>
|
<p className="text-[15px]">{bodyMssg && bodyMssg}</p>
|
||||||
</div>
|
</div>
|
||||||
{footerMessage && (
|
{footerMessage && (
|
||||||
@@ -25,8 +24,7 @@ function CustomModal({
|
|||||||
<div className="h-[1px] bg-[#9f9f9f] w-full"></div>
|
<div className="h-[1px] bg-[#9f9f9f] w-full"></div>
|
||||||
<div className="m-[15px] ">
|
<div className="m-[15px] ">
|
||||||
<button
|
<button
|
||||||
className={`${rejectBtn} text-white mr-2`}
|
className="op-btn op-btn-primary mr-2"
|
||||||
style={{ background: "#de4337" }}
|
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => declineDoc()}
|
onClick={() => declineDoc()}
|
||||||
>
|
>
|
||||||
@@ -34,7 +32,7 @@ function CustomModal({
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={rejectBtn}
|
className="op-btn op-btn-secondary"
|
||||||
onClick={() => setIsDecline({ isDeclined: false })}
|
onClick={() => setIsDecline({ isDeclined: false })}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
@@ -43,7 +41,7 @@ function CustomModal({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,22 +12,14 @@ export default function TourContentWithBtn({ message, isChecked }) {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>{message}</p>
|
<p>{message}</p>
|
||||||
<label
|
<label className="flex items-center justify-center mb-0">
|
||||||
style={{
|
|
||||||
textAlign: "center",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
style={{ marginRight: 3 }}
|
className="op-checkbox op-checkbox-xs mr-1"
|
||||||
checked={isCheck}
|
checked={isCheck}
|
||||||
onChange={handleCheck}
|
onChange={handleCheck}
|
||||||
/>{" "}
|
/>
|
||||||
<span style={{ color: "#787878", fontSize: 12 }}>
|
<span className="#787878 text-[12px]">Don't show this again</span>
|
||||||
Don't show this again
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { openInNewTab } from "../constant/Utils";
|
import { openInNewTab } from "../constant/Utils";
|
||||||
|
|
||||||
function Upgrade({ message, newWindow }) {
|
function Upgrade({ message }) {
|
||||||
const navigation = useNavigate();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<sup>
|
<sup>
|
||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (newWindow) {
|
const url = window.location.origin + "/subscription";
|
||||||
const url = window.location.origin + "/subscription";
|
openInNewTab(url);
|
||||||
openInNewTab(url);
|
|
||||||
} else {
|
|
||||||
navigation("/subscription");
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
className="text-blue-800 text-sm cursor-pointer underline"
|
className="text-blue-800 text-sm cursor-pointer underline"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -49,13 +49,10 @@ const Validate = () => {
|
|||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<ModalUi title={"Session Expired"} isOpen={true} showClose={false}>
|
<ModalUi showHeader={false} isOpen={true} showClose={false}>
|
||||||
<div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5">
|
<div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5">
|
||||||
<p className="text-xl font-normal">Your session has expired.</p>
|
<p className="text-xl font-medium">Your session has expired.</p>
|
||||||
<button
|
<button onClick={handleLoginBtn} className="op-btn op-btn-neutral">
|
||||||
onClick={handleLoginBtn}
|
|
||||||
className="text-base px-3 py-1.5 rounded shadow-md text-white bg-[#1ab6ce]"
|
|
||||||
>
|
|
||||||
Login
|
Login
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -90,7 +90,6 @@
|
|||||||
background-size: 1rem auto;
|
background-size: 1rem auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 375px) {
|
@media (max-width: 375px) {
|
||||||
.validationlist {
|
.validationlist {
|
||||||
background-position: right 0.5rem top 50%;
|
background-position: right 0.5rem top 50%;
|
||||||
|
|||||||
@@ -1,197 +0,0 @@
|
|||||||
.loginInput {
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 4px;
|
|
||||||
width: 100%;
|
|
||||||
font-size: 0.75rem;
|
|
||||||
border: 1px solid #e2dddd;
|
|
||||||
background-color: #e0e5f5;
|
|
||||||
color: black;
|
|
||||||
padding-left: 1rem !important;
|
|
||||||
padding-right: 1rem !important;
|
|
||||||
padding-top: 0.5rem !important;
|
|
||||||
font-family: inherit;
|
|
||||||
font-feature-settings: inherit;
|
|
||||||
font-variation-settings: inherit;
|
|
||||||
font-weight: inherit;
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
.loginInput:focus {
|
|
||||||
outline: none;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
.verifyBtn {
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
|
|
||||||
padding: 3px 30px;
|
|
||||||
color: white;
|
|
||||||
font-weight: 500 !important;
|
|
||||||
font-size: 14px !important;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
.verifyBtn:focus {
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.verifyBtn:hover {
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.18);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.fakeimg {
|
|
||||||
height: 200px;
|
|
||||||
background: #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.GTRY {
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
margin-top: 75px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main_head {
|
|
||||||
width: 100%;
|
|
||||||
height: 66px;
|
|
||||||
background-color: #fff;
|
|
||||||
margin-bottom: 52px;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-logo {
|
|
||||||
width: 250px;
|
|
||||||
height: 66px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-box {
|
|
||||||
background: #fff;
|
|
||||||
min-height: 50px;
|
|
||||||
box-shadow: 0 20px 20px rgba(0, 0, 0, 0.1);
|
|
||||||
position: relative;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
transition: 0.5s;
|
|
||||||
border: 1px solid #f2f2f2;
|
|
||||||
border-radius: 7px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.LKJH {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.GTR {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.JUI {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-info {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #15b4e9;
|
|
||||||
border-color: #15b4e9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-info:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #15b4e9;
|
|
||||||
border-color: #15b4e9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-reg {
|
|
||||||
color: #15b4e9;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-color: #15b4e9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-reg:hover {
|
|
||||||
color: #15b4e9;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-color: #15b4e9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SYTU {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.MLKI {
|
|
||||||
float: right;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-btn {
|
|
||||||
width: 100% !important;
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 667px) {
|
|
||||||
.MLKI {
|
|
||||||
float: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-btn {
|
|
||||||
width: 210px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.MLKI a {
|
|
||||||
color: #212529;
|
|
||||||
}
|
|
||||||
|
|
||||||
.KNLO {
|
|
||||||
color: #878787;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-check-label {
|
|
||||||
margin-left: 17px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
.welcomeText {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
|
||||||
.KLO1 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.MLKI a {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-check-label {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.MKUY {
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main_head {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding-top: 10px;
|
|
||||||
border-bottom: 1px dashed #eeeeee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 366px) {
|
|
||||||
.main-logo {
|
|
||||||
width: 150px;
|
|
||||||
height: 46px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.welcomeText {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
.KNLO {
|
|
||||||
color: #878787;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
.btnContainer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -208,7 +208,6 @@
|
|||||||
height: 100px;
|
height: 100px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user