mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-04 00:38:57 +02:00
Compare commits
193
Commits
v1.0.4
...
v1.0.7-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3a1c74a45 | ||
|
|
2544651ff1 | ||
|
|
93297b972a | ||
|
|
7165ed82f5 | ||
|
|
17422427a8 | ||
|
|
9ef2bc9ee2 | ||
|
|
12ec1bad0f | ||
|
|
fd552cedec | ||
|
|
5784378073 | ||
|
|
e0448cd4fa | ||
|
|
9ae0334249 | ||
|
|
eb355f562b | ||
|
|
92dc13185b | ||
|
|
65ec4e78ad | ||
|
|
944370134a | ||
|
|
c1621f64e6 | ||
|
|
e8c06d0836 | ||
|
|
a6295a6e56 | ||
|
|
47ae52c881 | ||
|
|
f2f0b55596 | ||
|
|
0c415de598 | ||
|
|
411941d9f7 | ||
|
|
3c54f2287c | ||
|
|
dfa121fe57 | ||
|
|
52b17730ef | ||
|
|
346d69124c | ||
|
|
7f35074acd | ||
|
|
b9e9694d61 | ||
|
|
ee4a787b81 | ||
|
|
d801680846 | ||
|
|
d84ab89a9b | ||
|
|
26d38f4ca2 | ||
|
|
745e519eec | ||
|
|
45b3e739d7 | ||
|
|
5ce50db001 | ||
|
|
a8c7b60c1b | ||
|
|
16860bc7b8 | ||
|
|
57f20ae1c0 | ||
|
|
d3b0c614ff | ||
|
|
e28f929ffc | ||
|
|
9f8f9a0992 | ||
|
|
60857638ba | ||
|
|
8041151243 | ||
|
|
7faed512b8 | ||
|
|
5d99a4a9c8 | ||
|
|
25c50d5387 | ||
|
|
5719dcca79 | ||
|
|
db1e81a249 | ||
|
|
ecd3395453 | ||
|
|
06e8140be4 | ||
|
|
14e9330651 | ||
|
|
636910a78e | ||
|
|
e4f9152de8 | ||
|
|
e0b9df9ba5 | ||
|
|
a20bd407a8 | ||
|
|
5630dd45a7 | ||
|
|
20220dd8c9 | ||
|
|
db4b8ec0ee | ||
|
|
2ee9ae16fb | ||
|
|
e50a55403d | ||
|
|
23ae72738d | ||
|
|
8619021f30 | ||
|
|
6c579178c0 | ||
|
|
01e19632a9 | ||
|
|
79ff8fd71d | ||
|
|
8700fd837d | ||
|
|
cdc8eb5bf6 | ||
|
|
95200e234f | ||
|
|
d94527e31a | ||
|
|
903066e6fa | ||
|
|
8c8015fe4a | ||
|
|
a002ac779c | ||
|
|
5c9bfbbdfe | ||
|
|
4a1e6d1318 | ||
|
|
90dc7c738a | ||
|
|
777028f3a7 | ||
|
|
c5a0ff4021 | ||
|
|
bf9f42e94d | ||
|
|
5556de2ef5 | ||
|
|
1b3508a9ef | ||
|
|
3992a9be94 | ||
|
|
eaf875be06 | ||
|
|
e62897e729 | ||
|
|
4c58fe2040 | ||
|
|
298068207e | ||
|
|
d0abe615cb | ||
|
|
87c65e4bea | ||
|
|
be49cb9d6d | ||
|
|
2b73087b7e | ||
|
|
d11dff2987 | ||
|
|
8ac82b1214 | ||
|
|
c46fa19bbb | ||
|
|
2fa2f56bac | ||
|
|
ef50aaa417 | ||
|
|
a1d7275fcd | ||
|
|
080acc9ed6 | ||
|
|
30b888f3a0 | ||
|
|
df11a77971 | ||
|
|
03e660527d | ||
|
|
f7bd439df5 | ||
|
|
2a55c03788 | ||
|
|
f712532793 | ||
|
|
cbdeaf8cc9 | ||
|
|
6bb353fd1f | ||
|
|
523dd43b4d | ||
|
|
bd0216fc39 | ||
|
|
50c40bfec1 | ||
|
|
0e2b6ee180 | ||
|
|
359d86e17b | ||
|
|
0b19c87a50 | ||
|
|
4a35eab7c6 | ||
|
|
b178a3c91e | ||
|
|
9fb0fecba4 | ||
|
|
cfc7408a52 | ||
|
|
aed0b8a3db | ||
|
|
910bd801ac | ||
|
|
22dad33b2e | ||
|
|
4d3ed0232e | ||
|
|
6d83f05b13 | ||
|
|
66cc2e1f2f | ||
|
|
f773fc6e3c | ||
|
|
dc83f21f5e | ||
|
|
0186c48d59 | ||
|
|
43f20508ae | ||
|
|
f678dd02cb | ||
|
|
5c2d6cddcb | ||
|
|
1bbf64fe83 | ||
|
|
296f43101e | ||
|
|
ed6f44fd62 | ||
|
|
776b1a7b43 | ||
|
|
06cdb660b3 | ||
|
|
db9268e1af | ||
|
|
83ce3a1c21 | ||
|
|
bda31de345 | ||
|
|
cdfc952a3f | ||
|
|
9434315775 | ||
|
|
47bb4cac38 | ||
|
|
11d3e6c696 | ||
|
|
0173727bc5 | ||
|
|
3cfa2639e5 | ||
|
|
502400ee56 | ||
|
|
4a3276f4e3 | ||
|
|
750e48ca2e | ||
|
|
823e6a9e2f | ||
|
|
642ef334f6 | ||
|
|
939a67b2c5 | ||
|
|
e1f8481aa2 | ||
|
|
b8e8cd127a | ||
|
|
876a2d78d5 | ||
|
|
16f287fdc0 | ||
|
|
d396a4f71d | ||
|
|
6bee566d8d | ||
|
|
79acd8ae13 | ||
|
|
01666b49cf | ||
|
|
a20ebbf08f | ||
|
|
26cf9c5310 | ||
|
|
3ad58ee52b | ||
|
|
2b67af6097 | ||
|
|
f61dae35ff | ||
|
|
dead3088d6 | ||
|
|
45d65cfbe2 | ||
|
|
6d2010facb | ||
|
|
48d3166049 | ||
|
|
82992d324d | ||
|
|
9a549fa35d | ||
|
|
93a891c8b6 | ||
|
|
2ede742b10 | ||
|
|
c43690faa8 | ||
|
|
a482a92d34 | ||
|
|
1d429cbe36 | ||
|
|
0a36550907 | ||
|
|
09610112fc | ||
|
|
a14454227c | ||
|
|
0d8767ee98 | ||
|
|
f463dc7af7 | ||
|
|
407b01565a | ||
|
|
6c565a144a | ||
|
|
141351de49 | ||
|
|
edecf3ea23 | ||
|
|
e708dad596 | ||
|
|
48012c9343 | ||
|
|
009a24e943 | ||
|
|
04a3251968 | ||
|
|
82694a24f2 | ||
|
|
748cc042dd | ||
|
|
6b8bca0802 | ||
|
|
fed1cff0cb | ||
|
|
b2eba6409f | ||
|
|
81af6a6c61 | ||
|
|
b5dbc69188 | ||
|
|
db4494c463 | ||
|
|
d208a90107 | ||
|
|
f81f72a147 |
@@ -178,6 +178,24 @@
|
||||
"contributions": [
|
||||
"a11y"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Govinda04",
|
||||
"name": "Govinda Kocharekar",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/50038172?v=4",
|
||||
"profile": "https://github.com/Govinda04",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "crediblebilal",
|
||||
"name": "Bilal Ahmad Bhat",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/55330484?v=4",
|
||||
"profile": "https://bilal.cc",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+9
-2
@@ -39,11 +39,18 @@ DO_ACCESS_KEY_ID=
|
||||
DO_SECRET_ACCESS_KEY=
|
||||
# Digital ocean spaces region or AWS s3 region
|
||||
DO_REGION=us-west
|
||||
# Set this to true id you are using local storage instead of s3 compatible storage
|
||||
# USE_LOCAL=TRUE
|
||||
|
||||
# Email mailgun config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
||||
MAILGUN_API_KEY=
|
||||
# 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=XXXXX
|
||||
MAILGUN_DOMAIN=mail.yourdomain.com
|
||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||
SMTP_ENABLE=
|
||||
SMTP_HOST=
|
||||
SMTP_PORT=
|
||||
SMTP_USER_EMAIL=
|
||||
SMTP_PASS=
|
||||
|
||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||
PFX_BASE64=
|
||||
|
||||
+63
-58
@@ -42,69 +42,74 @@ DO_SECRET_ACCESS_KEY=
|
||||
# Digital ocean spaces region or AWS s3 region
|
||||
DO_REGION=us-west
|
||||
# local storage
|
||||
USE_LOCAL=FALSE
|
||||
USE_LOCAL=TRUE
|
||||
|
||||
# Email mailgun 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=XXXXX
|
||||
MAILGUN_DOMAIN=mail.yourdomain.com
|
||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||
SMTP_ENABLE=
|
||||
SMTP_HOST=
|
||||
SMTP_PORT=
|
||||
SMTP_USER_EMAIL=
|
||||
SMTP_PASS=
|
||||
|
||||
|
||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||
PFX_BASE64='MIIKLwIBAzCCCeUGCSqGSIb3DQEHAaCCCdYEggnSMIIJzjCCBEIGCSqGSIb3DQEH
|
||||
BqCCBDMwggQvAgEAMIIEKAYJKoZIhvcNAQcBMFcGCSqGSIb3DQEFDTBKMCkGCSqG
|
||||
SIb3DQEFDDAcBAh6cQqVpHfTzAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQME
|
||||
ASoEEFKEIGJTTRo3voO/FvsXs7yAggPAI7rMCboTFFBfdMuuV3Y9/xfphAgdGD7P
|
||||
0xAN10CcmXlMtedc8cRxOaD9n3Q7zJx5iIbqEGDTc0dgp5EtdWsGl7MP76iHkSfB
|
||||
ZUPc13nbnRU4Nq4hNFcSj1m6NVa0lT9UobbTsG+wUkJn8aLfijzZ1OY82KLlKUoJ
|
||||
lqLsQ1yZkeLiLKI0aEew/2vzfiLUX9A99qnCRoryo8ZbLiWl0Vu/FEKM5mqIRFEp
|
||||
BKeSUsRxBfJCMZ2Ks5t4/MTCV+yrcsuhLPF/AJpzKfIinEFDhm7MxP4RXtk2LWNe
|
||||
+EO2GuFRjZCfsMO0oNWybFmDeNDMCHZj5TeoqL1JwAV5e1lEeqR38v4Wcr4OVefY
|
||||
DfdrJ2xdvm7XbBZ8Lgx8L4fwugw7oDyTpR2jJqHMlpOsQrxipN6UKkN6EVYeCC5K
|
||||
4dF5LHdCcIa7L/OI/feD5g/zz8SGCTc91husVN7zi+CVO0lQLRkAj02+VbiXPPDD
|
||||
eQm/QBieG2yVe5IRfcnIs2aszulbQbgHdguSYSQa/7DEvN/9/uxUIRFbItwrreRI
|
||||
VAUUNS02L680Zok9xzDed1I/WJoPr2+5n2eV1jc5zoH7mAni0+Z1d5qLoYV6pNaN
|
||||
P9okvBf75LLNoJKsb/eWlkk73rmlH6/Qz+hudgnlkxUJuU/b79AMQpd0EWEWhcim
|
||||
ZeB4d9lPLLwyvY/FN4aCGWzsoAW69RK9E1DyGZAZRYRwCKHSWXmCaenR1ilxcPFx
|
||||
TDavpybObIISPtylv5Z/IGBjE19Lw0UHc6Waln/jx0YXXGGDWs1F/MrdJ/8mkVXf
|
||||
tHB/5ds4u5md+CmXpaCITO3Cg9GltGSWyDoEJsz1u/Wzq4X4FYmolXiqQvMPQrxu
|
||||
iThTnPDGbz9VqFSyNKPKswIQ8CUbvZ209A5vjERPzE0Lp1pO39K51fnHD9oD968t
|
||||
tGbGmNiQ0++Orze79cH0UVwDa6NLGCmnE0oBgke1JDPlaU3kkx7+R9SAS0Zytsmj
|
||||
aLxW5Z1cOFaqqBLjwgHUxOqRO+cl6P9ORox34wJjiwZKy1L+0ppw22Na/unwi2Rk
|
||||
a8jvK7+ycOLaiSmI77T0l7VCWgKsRsWLvBA3cjX5XAGtatFXrY/7Imoxl0nWGLjG
|
||||
n5Sv5XuDek4e4QAPeJmhpURMnzLDsSXAYOSYZvS/kgENYhYSnQLQp50TxrzquA2c
|
||||
lAeFIEqqAJy9tAMfp5UAqMeOC60Ttn6ySsdOle003F2NrRilhPynNDZ3h1ZQknur
|
||||
Y9zWUm9qBmXCjhPzdmzHz3Ozj2Bi6kd4MIIFhAYJKoZIhvcNAQcBoIIFdQSCBXEw
|
||||
ggVtMIIFaQYLKoZIhvcNAQwKAQKgggUxMIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkq
|
||||
hkiG9w0BBQwwHAQIZenzippqfSQCAggAMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUD
|
||||
BAEqBBCddSIj/wfxowZAO1j3W9FwBIIE0C/guzeZtV/vPsaIDAtWEkmepCvhm9Rg
|
||||
aUgOoR66wjyYx7upeuZJ+pYJdsEqUmTgGYN+ClBpsU0bqCM7PI0mepvIT9kLD6ZL
|
||||
UkprtNAYP87NBA/e5dpXlGAf9ibDRT0F2Y+lCSF83rCIYKG8n7h5834F6Saf+dU7
|
||||
6y5bgorbf2Fnxy123XfUSg5qdCraZZM+DwE1gpQdBGrFyq8cwlQ8hJpKHDWup7WA
|
||||
f2HcT/X0Wjb24L6JWjC1FvTbTNdS/lzTOcqLYUc31iuU9rF6O4qtX9PK/yGWc+YE
|
||||
qakuV+HrsF4je/YdVZRYHtkbbcYXW9PjtMv+4D1ut5X2SPeHwpj3WmGAb7Zno6SD
|
||||
SfohMihXvDbIjVSMDBpW97bhgk0h7iS4ISIYoQJUGJv3QQ3XJq91LoIP3zpiO/Cq
|
||||
ZuuHuGvZmO6lb0PGShRT7mFg3k3rswTfFyKdtY76zAVJIR2bz/6bRf4uQI48SOLR
|
||||
NX1Z6lavUNiE4nPNlnfBp480C+YANKs/bdev0wkRVmFxPMyb5FFLXwLSqcfdSQag
|
||||
RayrKd8xPOm6lor3cTvrkO3XH2Hf9TgFHjeIAQ3VZ1Cncb9jfra3V4zvIocek4dC
|
||||
GREirPbEyL/js5O0aAa0mg9EontMWKRqncomKhUOckheP2dYiQOazDFDFP9OQCYV
|
||||
MBb0RDwm3+hiMU0lPeO+NAjAv2SfFK7G4maMb2SL7inT7An7ZPPpnDNXLDt+nOgo
|
||||
IKuaJpy8JX/OKB4ntYsdnQG4E0J3vpHWjYPKif7j1njIYFd76bIgNVlqWuQFArBy
|
||||
U9BuPyF+eYouJc+TpX9R5ybPvabRR4NUjnrttr2E5AzQfIgNGrSFiewjvYZHQOKd
|
||||
WyVR9YV0cUv591xyUDdXMoHh+J0v0xK1WCHe/9enY5y/C8YohL8h5tEvInAQconj
|
||||
lJ2r9qX8iBmIupJij5M5Ebza8HQ4aVMdHu/s05Vj9BC6K0ok3h+DFTj2gUBD24sp
|
||||
APHic0DmNnciUQuHuuoW/1SVb6I1HJswsgcC8CekvoXF26ygwWhJPyqw+5djip2w
|
||||
I/l3uOnPPUWZQHKhnBH4noZydrzBBJN1po9dkxb8LKuKZDEcnKo+tQrTnZJaFRXK
|
||||
pQDsAjQ0HcYi8ZqN/GPezXOqzRgvObevXeDYTJrNejr46B1HqjPw8doai+AEf//1
|
||||
iiM9EK4y3bGbX837oebTByRi112AOctISHTWbF0zdFMiBO9X9PML4n3i14ToqLH1
|
||||
EUp0WtCdKLJmrRnO9PKJUMpce3yNu6oRSBzB4EkgUMOTVx9tM66h/gcR3wr+qKJP
|
||||
1EABMbbCsJeYYLujhQHVh0JluqLBXYuCmr5n6o8qmonj5tEfTn9zs2gi0OvKTliH
|
||||
wRXWsar004alt8D8o4M/Oqu3qyVV1O8BlVEofUC1CfAMIh/T1NJBeKG/FPfAFoEz
|
||||
9liLLkoDvGvFVJ4Ezy4BaPtg+G3yU/SeiruwsCB3unHRD7G6VvS4jY2B8vEYl0yM
|
||||
Z1mLFbKK8CIEvg8+v/vbc0noYUOzd6bkwh6Y6cziR/u78y2nALYZpQK+3XiVVH/v
|
||||
SaVoDckZgUwAX+dMd1P4U3a487MPXBZZmLVFMHTuv3NvW6NIQCMd4l35ViRd7YcS
|
||||
V2QDKTnUtPN2MSUwIwYJKoZIhvcNAQkVMRYEFMSz7PlBO5VzTDqC/foidPWrMjkw
|
||||
MEEwMTANBglghkgBZQMEAgEFAAQgPlLuG+67SxPOEPbgFuEnVgewvY6LUzFmrprx
|
||||
c6yryFgECIld0S5kDk7JAgIIAA=='
|
||||
PFX_BASE64='MIIKCQIBAzCCCc8GCSqGSIb3DQEHAaCCCcAEggm8MIIJuDCCBG8GCSqGSIb3DQEH
|
||||
BqCCBGAwggRcAgEAMIIEVQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIpumu
|
||||
bFabBWACAggAgIIEKDqHS7Icd5MzIBk1dBokGK2s+5a2fA4308WA1QzEWmczqVYI
|
||||
z6lYmW8qsiZIw4PFkRzdIx1+zCmP8jgWiiqh5RKnbHYmh1JPNyx9SqmUDILDXmjg
|
||||
KxO9agRw9LXge4hgRL7YW0TxYZYw4EeXV9Yr7kcOq9DoO2MoRikJ+2Tuvvq/hfuV
|
||||
9zFHsz4jpf7W95k1IeH6bZ92klz5R1e/EK8JuHy592i/u+BxxW1vTkiPpTaHD6s9
|
||||
1lDSkT1j0LIDU6l9gVvJvFBV8j88vet/Z4QkTbHPMYvBnKNRstKuOvDasEJE4RkA
|
||||
PV4TfBwFF6uvREZI1vBboM/18pzeyjoRX+mlJNfcH3kh1tkck+Jg+M2bLXAH1EdD
|
||||
GRwENvnTNW1CFIn37VVja7SFBQNXA+E6rejmqtUmZ5XktSINDBUyjow9XuYTUtI/
|
||||
sgcRSC0aB0EKKpphbFPp1niKCLm1ef33e+bWyWbtR2L2Kc3ETmhjNADpyapAGmzc
|
||||
LP2BafGaKj18KiLAG4GL6+kXk0GUz7Fw5q8H8RY1T33o+xjWvC0+aJgvr65qWdKw
|
||||
+ug6wuu4Cr2kFEuXxPKsnYqmE5NT/x+lfunlZ5iEQN3w2XO5J2u2eMXVRUsPH2T6
|
||||
0sJKomjY0RB1JsqZBnyleWm+tYo0RpVAyJ3NGBp9dVb7a3Qw6jNZBG/xMW+gvtUJ
|
||||
q6hfK/cD3cagD0NQFVD5STMOuGOSqq/bbwAKjZ/lrPmCCYATKwkjAFybYfHJVrrW
|
||||
Y2tQgCQ/zrZLIxQjp7F17hU0+gT54x0MpF6AoqIM/qqNnHrQ0fi50ECmLvx3SqYa
|
||||
nvjvt/HZhMZfqRXiXjeicIwpnNoG7+uQknySk+7cc9GNhHZR7cfPfkTpgvuuebrQ
|
||||
l5YW+k9tG+xrX8g72nvtFMnammlBixlFwECJaEszEQk5tc2ti8uG2z+kGnFoDoBV
|
||||
M6ZVMpKDJzXPxLdzT6ChIPyatjIkqOKe6vDpnmzcoEhbBhmtkVjWFA2dfX846ugV
|
||||
y1QiecWgk8pMNWhh3IDd05v/wzbFwNcq+Gi+1dZsPmFH+egIcrQKZu2r3jCJtGHh
|
||||
DNG/nyf/anqvKXF90bi4hRT3vdDXXuWgY7EUwfn9h5jYabCO6HsQxQOBjFYNmBrh
|
||||
MfaiBZe72E8fzNAfIlwDcJ4AWY1SOM7hi8bqfRWw1NtNxuMUiRFoR31O6XkQauye
|
||||
9hAmpdlZHZXtJ6LM0QaWkPJmG3058GMtIn/qS60V9nINh+zXhwza/1pnFB+e9MWc
|
||||
hAPgo0nn55FusM//g1nM31PKe+nOm3Jyp0nEQ4m8aDtJS63o2fvp3e2KJbPWQMHE
|
||||
a83W975diWg4NTdevV9lFpNllHclVoPoavUHIzHd7HF9TcPpjbXJSUZ7cITHHefr
|
||||
kQTa/2G9cWuRhN9GKIHBdr13nfEvMIIFQQYJKoZIhvcNAQcBoIIFMgSCBS4wggUq
|
||||
MIIFJgYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECDgnjfOf
|
||||
AjArAgIIAASCBMgkbVuptroBdyMY5gl/eBQj5+iAV02YSaF969ihStLSWI4x5FAf
|
||||
HuDgqCyEMSl4RHG8ZvNaO9JoNfIpMK/TPQBoQRCzE2Vjf66VTERaQtU6h7tZrbQt
|
||||
K96n9eqvohm/vXbXe08fsodYp2s79kAvKgpuGG5iX77qYVzJHBPed87cvczo4ToP
|
||||
CpurDpByt8fGEmjtcikal8o+H9uoHjcFwqMigX1Q7IEjuKXrb5e6wTvxMRob8yfv
|
||||
LVl6ahteKSkWCMb6rLZ5f12jDoCGX/YXRrSsU9t/lXe0Nxv5i7c8flb2EsNtwygD
|
||||
fexVvn5u6ble6RDYNpuQkPgF41HyZh+JvGAF6i1r4tJPL9Pf4HnjEB8Y8IHgon+w
|
||||
T5I+8LTgcrWyhptzblXMjKySTEp9OEa2cCVwZkl4z43PWJ5oIAQ2IDTOQ603/5o/
|
||||
d9KA76/zMPQ5O0gv17OA7kwFv98v6sTcR4vgkQZqnyDpJSEPHyNxhw2MSBqS3jq3
|
||||
YPhRz+3Ei1oFp9uYFhzn39f9gzNi++X9pOjSrDb8v3mcDXZKNrxQLuoRMSf0eQNI
|
||||
dgJRqj/fuqNZ5ac3kd4P5BALCsnA1tM27zYrgUdpOnrc2D9FBthEjpRlQKMMzhQf
|
||||
cNMFWmoNjakDilvvLcsQeQ3P6cXbN1ODoNnjgK3VzcmeKyzW2PrTXEPHARUM3j4V
|
||||
sZzGaUOVKLqaaDrXWQKC0vrTvxP2WMfjQ1dTdXQP/kSZTXRC5rtB9tky38flBor0
|
||||
N9rhUDIGMs5qBvyrkV2hKXiW39G69p1KWY+Cw28AzY+CNSjePRi60TsnUxgcOS7i
|
||||
0AT25Gx3A4YqxmTY38MPB4wPcBPcw4hjNoQamaC9mqs+KVHcP5YHUlqykMeH0YVi
|
||||
J+ehytJE9xuDcfBOjxjadxp3/q/Lku4rky89gdJGFQWuuz75VulDywPRZRwmQTel
|
||||
sjEGMHR1zTOlPJdTDWhqaKmWvL4GhbCgEPIKwmqd1QKRTl/3Baa1nYllJeYVwiTT
|
||||
qLCkbA6qXrLGj1ENZxrKn9yqr8HwOoApjwhARu4LF/BRMgdkzelK2kOXHnZ26sZ2
|
||||
NY/MMtVmq4c59y6iQwmsbHr9tWGz3ahyXcZZufjNXU/AVnO1c92g7umAWZF4RohL
|
||||
gMmh57cAhN9PEbEv6j/6BT3XXp8jB0ywcRriYxfxwidviCKH/76Q4sytYJQaDFI1
|
||||
fnzmv0aDotbG2BdpWSiYPDOPm+3cmfjlULsn1FYWL4NDCX1f+C4lNtKVX9LU8c5M
|
||||
m8dA1DUlDfnuNO5/BShuoGXG2z4O/XwxIaRFizMxWS2sWurbAEFJ6oNw3kC7WSah
|
||||
NIe8aUC1umpc1Gk3X2f4Ytzj9OEqn0y55qoqLINJuejXMffF/gjopxHWadLVaVaj
|
||||
Q1SewrECuEXdSbBR/a10po24wmRtkmlvRJXJl7sG95xE5ZCqp+m6sRPWGdf1yKbV
|
||||
vyWNUe4Qvkxe4a0VAJpTyIGr980CKz/jkvtNQMobGl7AfhxKJ450wg454WcexMct
|
||||
BYXvZMSdUDCgMLlh0nHJHl5btrFWqE0Z/fqWmIknZL2jZ4J+2hdVl/xB/sUt6kcu
|
||||
txw+RfL+vNE8PxhTNaOdJFwD8yeN1mJ3yMUA8HHYpw9yljgxJTAjBgkqhkiG9w0B
|
||||
CRUxFgQUDYlgGVxSxuOknhQc256x3++7BDwwMTAhMAkGBSsOAwIaBQAEFFjASdYl
|
||||
3pXAXxZuvVvv9tsb4bdrBAhyb+KCIjp/gAICCAA='
|
||||
|
||||
# Provide Pass pharse of above PFX or p12 document
|
||||
PASS_PHRASE=
|
||||
PASS_PHRASE=opensign
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
name: "Bug Report"
|
||||
labels: ["bug","up-for-grabs"]
|
||||
title: "[Bug]: "
|
||||
assignees:
|
||||
- andrew-opensignlabs
|
||||
description: Create a bug report to help us make OpenSign™ the world's best document e-signature platform
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Issue Description
|
||||
description: Please provide a clear & concise description of the problem.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: Describe what you expected to happen.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
description: Describe what is happening instead.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please provide step-by-step instructions to reproduce the issue. Include code snippets, URLs, error messages and any other relevant information.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots of the issue(optional)
|
||||
description: Add screenshots to better explain the issue.
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating System [e.g. MacOS Sonoma 14.1, Windows 11]
|
||||
- type: dropdown
|
||||
id: browsers
|
||||
attributes:
|
||||
label: What browsers are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Chrome
|
||||
- Firefox
|
||||
- Safari
|
||||
- Microsoft Edge
|
||||
default: 0
|
||||
- type: input
|
||||
attributes:
|
||||
label: What version of OpenSign™ are you seeing this issue on? [e.g. 1.0.6]
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: environment
|
||||
attributes:
|
||||
label: What environment are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Production (app.opensignlabs.com)
|
||||
- Staging (staging-app.opensignlabs.com)
|
||||
- Hosted (app.yourdomain.com)
|
||||
- Dev (localhost or vercel)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please check the boxes that apply to this issue report.
|
||||
options:
|
||||
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://www.opensignlabs.com)
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||
required: true
|
||||
@@ -0,0 +1,70 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for OpenSign™
|
||||
title: "Feature Request: [Short Description]"
|
||||
labels: [feature request, needs triage]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Thanks for taking the time to fill out this feature request!
|
||||
|
||||
- type: input
|
||||
id: title
|
||||
attributes:
|
||||
label: Feature Title
|
||||
description: What would you call this feature?
|
||||
placeholder: e.g., Advanced Signature Verification
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description: |
|
||||
Please provide a detailed description of the feature you're proposing.
|
||||
placeholder: |
|
||||
e.g., I'm proposing an advanced signature verification feature that...
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: featuretype
|
||||
attributes:
|
||||
label: What type of feature are you requesting?
|
||||
multiple: true
|
||||
options:
|
||||
- UI/UX Improvement
|
||||
- Security / Compliance
|
||||
- Performance / Optimization
|
||||
- 3rd party integration
|
||||
- Other
|
||||
- type: dropdown
|
||||
id: importance
|
||||
attributes:
|
||||
label: Importance
|
||||
description: How important is this feature to you?
|
||||
options:
|
||||
- Critical
|
||||
- High
|
||||
- Medium
|
||||
- Low
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Any other context or screenshots about the feature request here.
|
||||
placeholder: Additional details, examples, or screenshots...
|
||||
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://www.opensignlabs.com)
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||
required: true
|
||||
+3
-4
@@ -1,5 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx eslint '**/*.{js,jsx}'
|
||||
npx pretty-quick --staged '**/*.{js,jsx}'
|
||||
npm run lint-staged-changes
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"*.js": "prettier --write"
|
||||
}
|
||||
+1
-2
@@ -98,8 +98,7 @@ Environment Varaibles:
|
||||
| PUBLIC_URL | http://localhost:3000 | Set it to the URL form where the app home page will be accessed |
|
||||
| GENERATE_SOURCEMAP | false | Set it to true if you want to generate the Sourcemap for debugging |
|
||||
| REACT_APP_SERVERURL | http://localhost:8080/app | Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead) |
|
||||
| REACT_APP_APPID | http://localhost:3000 | Set it to the URL form where the app home page will be accessed |
|
||||
| PUBLIC_URL | opensignstgn | A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API. |
|
||||
| REACT_APP_APPID | opensignstgn | A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API. |
|
||||
| APP_ID | opensignstgn | A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App. |
|
||||
| appName | open_sign_server | Name of the app. It will be visible in the verification emails sent out. |
|
||||
| MASTER_KEY | XnAadwKxxByMr | A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database. |
|
||||
|
||||
@@ -2,7 +2,7 @@ build:
|
||||
cp .env.local_dev .env
|
||||
rm -rf apps/OpenSign/public/mfbuild
|
||||
cd microfrontends/SignDocuments && npm install && npm run build
|
||||
docker compose up -d
|
||||
docker compose up --build --force-recreate
|
||||
|
||||
run:
|
||||
cp .env.local_dev .env
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<h1 align="center"><a href='https://www.opensignlabs.com'>OpenSign™</a></h1>
|
||||
|
||||
<div align="center">
|
||||
<h1 align="center"><a href='https://www.opensignlabs.com'><img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/e518cc9c-5de3-47da-950b-f93336b9f14e></a>
|
||||
</h1><div align="center">
|
||||
|
||||
The free and open source alternative to DocuSign
|
||||
[The free and open source alternative to DocuSign](https://www.opensignlabs.com)
|
||||
|
||||
[](http://isitmaintained.com/project/opensignlabs/opensign "Average time to resolve an issue")
|
||||
[](#contributors)
|
||||
@@ -23,7 +22,7 @@ The free and open source alternative to DocuSign
|
||||
<a href="https://www.linkedin.com/company/opensign%E2%84%A2/about/">LinkedIn</a>
|
||||
|
||||
|
||||
## An open-source document e-signing solution
|
||||
## The open-source document e-signing solution
|
||||
|
||||
---
|
||||
</div>
|
||||
@@ -48,14 +47,18 @@ Welcome to OpenSign, an open-source document e-signing solution designed to prov
|
||||
|
||||
### Features
|
||||
|
||||
- **Secure Signing**: Utilizes state-of-the-art cryptographic algorithms to ensure the security & integrity of your documents.
|
||||
- **User-Friendly Interface**: Designed with usability in mind, making it easy for both technical and non-technical users.
|
||||
- **Multi-Platform Support**: Compatible with various browsers and devices.
|
||||
- **Invite & collaborate users**: Bring multiple people from your team into the signing process, all within your own infrastructure.
|
||||
- **Secure**: Allows for the easy, secure and seamless organization of your documents using 'OpenSigDrive'.
|
||||
- **Audit Trails**: Keeps a detailed log of all activities related to the document signing process including IP addresses and access timings.
|
||||
- **Completion Certificate**: Generate secure completion certificate as soon as a document is signed by all participants.
|
||||
- **API Support**: Provides a robust API for integration into other software and services.
|
||||
- **Secure PDF E-Signing:** With the help of Robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility.
|
||||
- **Annotate Documents:** OpenSign™ allows you to annotate PDF documents with an advanced signing pad that comes with hand drawn signatures support as well as uploaded images & saved signatures for the simplest signing experience.
|
||||
- **User-Friendly Interface:** OpenSign™ was built while keeping Intuitive design in mind for ease of use. Features like "Sign yourself", "One click signatures" and "OpenSign Drive" makes it stand out of the crowd and even makes it better than a lot of so-called industry leaders.
|
||||
- **Multi-signer Support:** OpenSign's ability to invite multiple signers for signing along with the ability to invite witnesses & being able to enforce signing in a sequence makes it the only open source solution that is fully loaded and allows it to compete head-to-head with established players.
|
||||
- **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address.
|
||||
- **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign it. Not just this, OpenSign also allows signers to reject signing a document.
|
||||
- **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates.
|
||||
- **PDF Template Creation(coming soon):** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time.
|
||||
- **OpenSign™ Drive:** It is a centralised secure vault for your signed documents that makes storing, signing, organizing, sharing & achieving your docs a breeze.
|
||||
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
|
||||
- **API Support(coming soon):** OpenSign™ API allows seamless integration into existing systems and software. APIs will soon be available as a cloud hosted solution.
|
||||
- **Integrations:** Seamless integrations with various Cloud storage systems, CRMs & enterprise platforms is coming soon.
|
||||
|
||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
|
||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
||||
@@ -125,6 +128,8 @@ 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/rishabjasrotia"><img src="https://avatars.githubusercontent.com/u/33950743?v=4?s=100" width="100px;" alt="Rishab"/><br /><sub><b>Rishab</b></sub></a><br /><a href="#code-rishabjasrotia" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://session.it"><img src="https://avatars.githubusercontent.com/u/327285?v=4?s=100" width="100px;" alt="Maurizio Pillitu"/><br /><sub><b>Maurizio Pillitu</b></sub></a><br /><a href="#bug-maoo" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://luisparra.dev"><img src="https://avatars.githubusercontent.com/u/16653744?v=4?s=100" width="100px;" alt="Luis Parra"/><br /><sub><b>Luis Parra</b></sub></a><br /><a href="#a11y-lsprr" title="Accessibility">️️️️♿️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Govinda04"><img src="https://avatars.githubusercontent.com/u/50038172?v=4?s=100" width="100px;" alt="Govinda Kocharekar"/><br /><sub><b>Govinda Kocharekar</b></sub></a><br /><a href="#code-Govinda04" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://bilal.cc"><img src="https://avatars.githubusercontent.com/u/55330484?v=4?s=100" width="100px;" alt="Bilal Ahmad Bhat"/><br /><sub><b>Bilal Ahmad Bhat</b></sub></a><br /><a href="#code-crediblebilal" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
# production
|
||||
/build
|
||||
/mfbuild
|
||||
|
||||
# misc
|
||||
.env
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
"scripts": {
|
||||
"start": "serve -s build",
|
||||
"start-dev": "mf-cra start",
|
||||
"build": "rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
||||
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
|
||||
"build": "npm run version && rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
||||
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
@@ -85,4 +86,4 @@
|
||||
"pretty-quick": "^3.1.3",
|
||||
"tailwindcss": "^3.3.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
|
||||
|
||||
<title>Open sign</title>
|
||||
<title>OpenSign™</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -50,4 +50,4 @@
|
||||
-->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
v1.0.5-beta
|
||||
@@ -32,6 +32,7 @@ const AppendFormInForm = (props) => {
|
||||
try {
|
||||
const query = new Parse.Query("contracts_Contactbook");
|
||||
query.equalTo("CreatedBy", user);
|
||||
query.notEqualTo("IsDeleted", true);
|
||||
query.equalTo("Email", user.getEmail());
|
||||
const res = await query.first();
|
||||
// console.log(res);
|
||||
@@ -241,26 +242,6 @@ const AppendFormInForm = (props) => {
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label
|
||||
htmlFor="phone"
|
||||
className="block text-xs text-gray-700 font-semibold"
|
||||
>
|
||||
Phone
|
||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="phone"
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
required
|
||||
disabled={addYourself}
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label
|
||||
htmlFor="email"
|
||||
@@ -279,6 +260,24 @@ const AppendFormInForm = (props) => {
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<label
|
||||
htmlFor="phone"
|
||||
className="block text-xs text-gray-700 font-semibold"
|
||||
>
|
||||
Phone
|
||||
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="phone"
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
required
|
||||
disabled={addYourself}
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex justify-start">
|
||||
<button
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Package from "../../package.json";
|
||||
|
||||
import axios from "axios";
|
||||
const Footer = () => {
|
||||
const [showButton, setShowButton] = useState(false);
|
||||
const [version, setVersion] = useState("");
|
||||
useEffect(() => {
|
||||
axios
|
||||
.get("/version.txt")
|
||||
.then((response) => {
|
||||
setVersion(response.data); // Set the retrieved data to the state variable
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error reading the file:", error);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleScroll = () => {
|
||||
if (window.pageYOffset >= 50) {
|
||||
setShowButton(true);
|
||||
@@ -25,16 +37,12 @@ const Footer = () => {
|
||||
}, []);
|
||||
|
||||
const appName = "OpenSign™";
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-[#222c3c] text-[#98a6ba] text-center text-[13px] py-3">
|
||||
All Rights Reserved © {new Date().getFullYear()}
|
||||
{appName}{" "}
|
||||
(version:{" "}
|
||||
{localStorage.getItem("appVersion") &&
|
||||
`${Package.version}.${localStorage.getItem("appVersion")}`}
|
||||
)
|
||||
{appName} ( version: {version ? version : `${Package.version} `})
|
||||
</div>
|
||||
<button
|
||||
className={`${
|
||||
|
||||
@@ -27,14 +27,14 @@ const LoginFacebook = ({
|
||||
setThirdpartyLoader(true);
|
||||
const details = {
|
||||
Email: response.email,
|
||||
Name: response.name,
|
||||
Name: response.name
|
||||
};
|
||||
setUserDetails({ ...userDetails, ...details });
|
||||
const fDetails = {
|
||||
Id: response.userID,
|
||||
AccessToken: response.accessToken,
|
||||
Name: response.name,
|
||||
Email: response.email,
|
||||
Email: response.email
|
||||
};
|
||||
setFBDetails({ ...fBDetails, ...fDetails });
|
||||
const res = await checkExtUser(fDetails);
|
||||
@@ -42,9 +42,11 @@ const LoginFacebook = ({
|
||||
};
|
||||
|
||||
const checkExtUser = async (details) => {
|
||||
const extUser = new Parse.Query("contracts_Users");
|
||||
extUser.equalTo("Email", details.Email);
|
||||
const extRes = await extUser.first();
|
||||
// const extUser = new Parse.Query("contracts_Users");
|
||||
// extUser.equalTo("Email", details.Email);
|
||||
// const extRes = await extUser.first();
|
||||
const params = { email: details.Email };
|
||||
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
||||
// console.log("extRes ", extRes);
|
||||
if (extRes) {
|
||||
const params = { ...details, Phone: extRes.get("Phone") };
|
||||
@@ -209,18 +211,19 @@ const LoginFacebook = ({
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={() => setIsModal(false)}
|
||||
style={{ marginRight: 10, width: 90 }}
|
||||
onClick={() => handleSubmitbtn()}
|
||||
className="btn btn-info"
|
||||
style={{ marginRight: 10 }}
|
||||
>
|
||||
Cancel
|
||||
Sign up
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleSubmitbtn()}
|
||||
className="btn btn-info"
|
||||
className="btn btn-secondary"
|
||||
onClick={() => setIsModal(false)}
|
||||
style={{ width: 90 }}
|
||||
>
|
||||
Sign up
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -42,7 +42,42 @@ const GoogleSignInBtn = ({
|
||||
width: "187px"
|
||||
});
|
||||
});
|
||||
const clearStorage = async () => {
|
||||
if (Parse.User.current()) {
|
||||
await Parse.User.logOut();
|
||||
}
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
let applogo = localStorage.getItem("appLogo");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let appversion = localStorage.getItem("appVersion");
|
||||
let appTitle = localStorage.getItem("appTitle");
|
||||
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||
let PageLanding = localStorage.getItem("PageLanding");
|
||||
let _appName = localStorage.getItem("_appName");
|
||||
let _app_objectId = localStorage.getItem("_app_objectId");
|
||||
let appName = localStorage.getItem("appName");
|
||||
let userSettings = localStorage.getItem("userSettings");
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
localStorage.setItem("appLogo", applogo);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("appversion", appversion);
|
||||
localStorage.setItem("appTitle", appTitle);
|
||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("_appName", _appName);
|
||||
localStorage.setItem("_app_objectId", _app_objectId);
|
||||
localStorage.setItem("appName", appName);
|
||||
localStorage.setItem("userSettings", userSettings);
|
||||
localStorage.setItem("baseUrl", baseUrl);
|
||||
localStorage.setItem("parseAppId", appid);
|
||||
};
|
||||
const responseGoogle = async (response) => {
|
||||
clearStorage();
|
||||
setThirdpartyLoader(true);
|
||||
// console.log("response ", response);
|
||||
if (response.credential) {
|
||||
@@ -66,9 +101,11 @@ const GoogleSignInBtn = ({
|
||||
}
|
||||
};
|
||||
const checkExtUser = async (details) => {
|
||||
const extUser = new Parse.Query("contracts_Users");
|
||||
extUser.equalTo("Email", details.Gmail);
|
||||
const extRes = await extUser.first();
|
||||
// const extUser = new Parse.Query("contracts_Users");
|
||||
// extUser.equalTo("Email", details.Gmail);
|
||||
// const extRes = await extUser.first();
|
||||
const params = { email: details.Gmail };
|
||||
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
||||
// console.log("extRes ", extRes);
|
||||
if (extRes) {
|
||||
const params = { ...details, Phone: extRes.get("Phone") };
|
||||
@@ -261,17 +298,17 @@ const GoogleSignInBtn = ({
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="Destination"
|
||||
htmlFor="JobTitle"
|
||||
style={{ display: "flex" }}
|
||||
className="col-form-label"
|
||||
>
|
||||
Destination{" "}
|
||||
Job Title{" "}
|
||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="Destination"
|
||||
id="JobTitle"
|
||||
value={userDetails.Destination}
|
||||
onChange={(e) =>
|
||||
setUserDetails({
|
||||
@@ -285,18 +322,19 @@ const GoogleSignInBtn = ({
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-[#6c757d] p-2 text-white rounded"
|
||||
onClick={handleCloseModal}
|
||||
style={{ marginRight: 10, width: 90 }}
|
||||
className="bg-[#17a2b8] p-2 text-white rounded"
|
||||
onClick={() => handleSubmitbtn()}
|
||||
style={{ marginRight: 10 }}
|
||||
>
|
||||
Cancel
|
||||
Sign up
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-[#17a2b8] p-2 text-white rounded"
|
||||
onClick={() => handleSubmitbtn()}
|
||||
className="bg-[#6c757d] p-2 text-white rounded"
|
||||
onClick={handleCloseModal}
|
||||
style={{ width: 90 }}
|
||||
>
|
||||
Sign up
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -49,12 +49,9 @@ const TreeWidget = (props) => {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
var emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
res = await q.first();
|
||||
res = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
if (res) res = res.toJSON();
|
||||
}
|
||||
if (res) {
|
||||
@@ -79,12 +76,9 @@ const TreeWidget = (props) => {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
res = await q.first();
|
||||
res = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
if (res) res = res.toJSON();
|
||||
}
|
||||
|
||||
@@ -121,10 +115,15 @@ const TreeWidget = (props) => {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
emp = Parse.Object.extend(localStorage.getItem("extended_class"));
|
||||
q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
res = await q.first();
|
||||
// emp = Parse.Object.extend(localStorage.getItem("extended_class"));
|
||||
// q = new Parse.Query(emp);
|
||||
// q.equalTo("UserId", currentUser);
|
||||
// res = await q.first();
|
||||
// if (res) res = res.toJSON();
|
||||
const currentUser = Parse.User.current();
|
||||
res = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
if (res) res = res.toJSON();
|
||||
}
|
||||
|
||||
@@ -473,6 +472,8 @@ const TreeWidget = (props) => {
|
||||
props.schema.data.FolderTypeField,
|
||||
props.schema.data.FolderTypeValue
|
||||
);
|
||||
const currentUser = Parse.User.current();
|
||||
folder.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||
if (tabList.length > 0) {
|
||||
let len = tabList.length - 1;
|
||||
folder.set(props.schema.data.ParentFolderField, {
|
||||
@@ -532,7 +533,7 @@ const TreeWidget = (props) => {
|
||||
padding: 0
|
||||
},
|
||||
overlay: {
|
||||
width:"100%",
|
||||
width: "100%",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
||||
zIndex: 50
|
||||
}
|
||||
@@ -699,7 +700,7 @@ const TreeWidget = (props) => {
|
||||
))}
|
||||
<hr />
|
||||
</div>
|
||||
{editable && (
|
||||
{/* {editable && (
|
||||
<TreeEditForm
|
||||
FormId={props.schema.data.FormId}
|
||||
objectId={editId}
|
||||
@@ -708,7 +709,7 @@ const TreeWidget = (props) => {
|
||||
selectFolderHandle();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
{isAddField && !loader && !editable && (
|
||||
<TreeFormComponent
|
||||
Id={props.schema.data.FormId}
|
||||
@@ -796,7 +797,7 @@ const TreeWidget = (props) => {
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{fldr[props.schema.data.FolderTypeField] ===
|
||||
{/* {fldr[props.schema.data.FolderTypeField] ===
|
||||
props.schema.data.FolderTypeValue && (
|
||||
<a
|
||||
className="float-right"
|
||||
@@ -816,7 +817,7 @@ const TreeWidget = (props) => {
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</a>
|
||||
)}
|
||||
)} */}
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
import Parse from "parse";
|
||||
import onSearchFilter from "../../constant/searchQuery";
|
||||
import getReplacedHashQuery from "../../constant/getReplacedHashQuery";
|
||||
import "../../styles/loader.css";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -35,14 +34,9 @@ const DashboardCard = (props) => {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
var emp = Parse.Object.extend(localStorage.getItem("extended_class"));
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUser
|
||||
res = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
res = await q.first();
|
||||
if (res) res = res.toJSON();
|
||||
}
|
||||
if (res) {
|
||||
@@ -50,12 +44,7 @@ const DashboardCard = (props) => {
|
||||
var reg = /(\#.*?\#)/gi; // eslint-disable-line
|
||||
var str = props.Data.query;
|
||||
var test = "";
|
||||
if (str.includes("#filterCondition#")) {
|
||||
str = str.replace(
|
||||
"#filterCondition#",
|
||||
onSearchFilter(props.DefaultQuery)
|
||||
);
|
||||
}
|
||||
|
||||
if (props.Data.extendkey) {
|
||||
let a = props.Data.extendkey.split(".");
|
||||
if (a.length > 0) {
|
||||
@@ -110,13 +99,10 @@ const DashboardCard = (props) => {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
resr = data[0];
|
||||
} else {
|
||||
let emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
let q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
let t = await q.first();
|
||||
resr = t.toJSON();
|
||||
resr = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
if (resr) resr = resr.toJSON();
|
||||
}
|
||||
|
||||
let json = resr;
|
||||
@@ -150,47 +136,65 @@ const DashboardCard = (props) => {
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
};
|
||||
await axios.get(url, { headers: headers }).then((res) => {
|
||||
if (res.data.results.length > 0) {
|
||||
setLoading(false);
|
||||
if (props.Data.key !== "count") {
|
||||
setresponse(res.data.results[0][props.Data.key]);
|
||||
} else {
|
||||
if (props.Label === "Need your Signature") {
|
||||
const listData = res.data?.results.filter(
|
||||
(x) => x.Signers.length > 0
|
||||
// handle need your sign report count
|
||||
if (props.Data.Redirect_id === "4Hhwbp482K") {
|
||||
const params = {
|
||||
reportId: props.Data.Redirect_id,
|
||||
skip: 0,
|
||||
limit: 200
|
||||
};
|
||||
const url = `${parseBaseUrl}/functions/getReport`;
|
||||
await axios
|
||||
.post(url, params, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
sessiontoken: localStorage.getItem("accesstoken")
|
||||
}
|
||||
})
|
||||
.then((res) => {
|
||||
const listData = res.data?.result.filter(
|
||||
(x) => x.Signers.length > 0
|
||||
);
|
||||
let arr = [];
|
||||
for (const obj of listData) {
|
||||
const isSigner = obj.Signers.some(
|
||||
(item) => item.UserId.objectId === currentUser.id
|
||||
);
|
||||
let arr = [];
|
||||
for (const obj of listData) {
|
||||
const isSigner = obj.Signers.some(
|
||||
(item) => item.UserId.objectId === currentUser.id
|
||||
);
|
||||
if (isSigner) {
|
||||
let isRecord;
|
||||
if (obj?.AuditTrail && obj?.AuditTrail.length > 0) {
|
||||
isRecord = obj?.AuditTrail.some(
|
||||
(item) =>
|
||||
item?.UserPtr?.UserId?.objectId === currentUser.id &&
|
||||
item.Activity === "Signed"
|
||||
);
|
||||
} else {
|
||||
isRecord = false;
|
||||
}
|
||||
if (isRecord === false) {
|
||||
arr.push(obj);
|
||||
}
|
||||
if (isSigner) {
|
||||
let isRecord;
|
||||
if (obj?.AuditTrail && obj?.AuditTrail.length > 0) {
|
||||
isRecord = obj?.AuditTrail.some(
|
||||
(item) =>
|
||||
item?.UserPtr?.UserId?.objectId === currentUser.id &&
|
||||
item.Activity === "Signed"
|
||||
);
|
||||
} else {
|
||||
isRecord = false;
|
||||
}
|
||||
if (isRecord === false) {
|
||||
arr.push(obj);
|
||||
}
|
||||
}
|
||||
setresponse(arr.length);
|
||||
}
|
||||
setresponse(arr.length);
|
||||
setLoading(false);
|
||||
});
|
||||
} else {
|
||||
await axios.get(url, { headers: headers }).then((res) => {
|
||||
if (res.data.results.length > 0) {
|
||||
setLoading(false);
|
||||
if (props.Data.key !== "count") {
|
||||
setresponse(res.data.results[0][props.Data.key]);
|
||||
} else {
|
||||
setresponse(res.data[props.Data.key]);
|
||||
}
|
||||
} else {
|
||||
setresponse(0);
|
||||
setLoading(false);
|
||||
}
|
||||
} else {
|
||||
setresponse(0);
|
||||
setLoading(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
setLoading(false);
|
||||
@@ -227,13 +231,10 @@ const DashboardCard = (props) => {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
var emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
let resr = await q.first();
|
||||
res = resr.toJSON();
|
||||
let resr = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
if (res) res = resr.toJSON();
|
||||
}
|
||||
|
||||
let json = res;
|
||||
|
||||
@@ -9,39 +9,60 @@ function DashboardReport(props) {
|
||||
const [isLoader, setIsLoader] = useState(true);
|
||||
const [reportName, setReportName] = useState("");
|
||||
const [actions, setActions] = useState([]);
|
||||
const [heading, setHeading] = useState([]);
|
||||
const [isNextRecord, setIsNextRecord] = useState(false);
|
||||
const [isMoreDocs, setIsMoreDocs] = useState(true);
|
||||
const abortController = new AbortController();
|
||||
const docPerPage = 5;
|
||||
|
||||
useEffect(() => {
|
||||
setReportName("");
|
||||
getReportData(props.Record.reportId);
|
||||
|
||||
// Function returned from useEffect is called on unmount
|
||||
return () => {
|
||||
setIsLoader(true);
|
||||
setList([]);
|
||||
setIsNextRecord(false);
|
||||
// Here it'll abort the fetch
|
||||
abortController.abort();
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
}, [props.Record.reportId]);
|
||||
|
||||
const getReportData = async (id) => {
|
||||
// below useEffect call when isNextRecord state is true and fetch next record
|
||||
useEffect(() => {
|
||||
if (isNextRecord) {
|
||||
getReportData(props.Record.reportId, List.length, 200);
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [isNextRecord]);
|
||||
|
||||
const getReportData = async (id, skipUserRecord = 0, limit = 200) => {
|
||||
setIsLoader(true);
|
||||
const json = reportJson(id);
|
||||
if (json) {
|
||||
setActions(json.actions);
|
||||
setReportName(json.reportName);
|
||||
const { className, params, keys, orderBy } = json;
|
||||
setHeading(json.heading);
|
||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||
Parse.initialize(localStorage.getItem("AppID12"));
|
||||
const serverURL =
|
||||
localStorage.getItem("BaseUrl12") + "classes/" + className;
|
||||
const currentUser = Parse.User.current().id;
|
||||
|
||||
const strParams = JSON.stringify(params);
|
||||
const strKeys = keys.join();
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
sessiontoken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
try {
|
||||
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&include=AuditTrail.UserPtr`;
|
||||
const res = await axios.get(url, { headers: headers });
|
||||
// console.log("res ", res.data?.results);
|
||||
const params = { reportId: id, skip: skipUserRecord, limit: limit };
|
||||
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
|
||||
const res = await axios.post(url, params, {
|
||||
headers: headers,
|
||||
signal: abortController.signal // is used to cancel fetch query
|
||||
});
|
||||
if (id === "5Go51Q7T8r") {
|
||||
const currentUser = Parse.User.current().id;
|
||||
const listData = res.data?.results.filter(
|
||||
(x) => x.Signers.length > 0
|
||||
);
|
||||
const listData = res.data?.result.filter((x) => x.Signers.length > 0);
|
||||
let arr = [];
|
||||
for (const obj of listData) {
|
||||
const isSigner = obj.Signers.some(
|
||||
@@ -63,14 +84,34 @@ function DashboardReport(props) {
|
||||
}
|
||||
}
|
||||
}
|
||||
setList(arr);
|
||||
if (arr.length === docPerPage) {
|
||||
setIsMoreDocs(true);
|
||||
} else {
|
||||
setIsMoreDocs(false);
|
||||
}
|
||||
setList((prevRecord) =>
|
||||
prevRecord.length > 0 ? [...prevRecord, ...arr] : arr
|
||||
);
|
||||
} else {
|
||||
setList(res.data?.results);
|
||||
if (res.data.result.length === docPerPage) {
|
||||
setIsMoreDocs(true);
|
||||
} else {
|
||||
setIsMoreDocs(false);
|
||||
}
|
||||
setIsNextRecord(false);
|
||||
setList((prevRecord) =>
|
||||
prevRecord.length > 0
|
||||
? [...prevRecord, ...res.data.result]
|
||||
: res.data.result
|
||||
);
|
||||
}
|
||||
setIsLoader(false);
|
||||
} catch (err) {
|
||||
console.log("err ", err);
|
||||
setIsLoader(false);
|
||||
const isCancel = axios.isCancel(err);
|
||||
if (!isCancel) {
|
||||
console.log("err ", err);
|
||||
setIsLoader(false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setIsLoader(false);
|
||||
@@ -101,8 +142,12 @@ function DashboardReport(props) {
|
||||
<ReportTable
|
||||
ReportName={reportName}
|
||||
List={List}
|
||||
act={"Sign"}
|
||||
setList={setList}
|
||||
actions={actions}
|
||||
heading={heading}
|
||||
setIsNextRecord={setIsNextRecord}
|
||||
isMoreDocs={isMoreDocs}
|
||||
docPerPage={docPerPage}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex items-center justify-center h-[100px] w-full bg-white rounded">
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useState, Suspense, lazy } from "react";
|
||||
import moment from "moment";
|
||||
import React, { Suspense, lazy } from "react";
|
||||
import ErrorBoundary from "../ErrorBoundary";
|
||||
|
||||
const DashboardCard = lazy(() => import("./DashboardCard"));
|
||||
@@ -7,258 +6,6 @@ const DashboardCard = lazy(() => import("./DashboardCard"));
|
||||
const DashboardReport = lazy(() => import("./DashboardReport"));
|
||||
|
||||
const GetDashboard = (props) => {
|
||||
const [filter, setfilter] = useState("");
|
||||
const [option, setoption] = useState("");
|
||||
|
||||
const onSearchFilter = (e) => {
|
||||
let _search = e.target.value;
|
||||
localStorage.setItem("DashboardDefaultFilter", _search);
|
||||
switch (_search) {
|
||||
case "Today": {
|
||||
let d = new Date();
|
||||
let formDate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Todate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query = `'$gte':'${formDate}','$lte':'${Todate}'`;
|
||||
setfilter(Query);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Yesterday": {
|
||||
let d1 = new Date();
|
||||
d1.setDate(d1.getDate() - 1);
|
||||
let yesFrDate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let YesTodate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query1 = `'$gte':'${yesFrDate}','$lte':'${YesTodate}'`;
|
||||
setfilter(Query1);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "This week": {
|
||||
let oneDay = 24 * 60 * 60 * 1000;
|
||||
let curr = new Date(); // get current date
|
||||
let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
|
||||
|
||||
let firstday = new Date(
|
||||
new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
0,
|
||||
0,
|
||||
0
|
||||
)
|
||||
).setDate(first)
|
||||
).toISOString();
|
||||
let diffDays = Math.round(
|
||||
Math.abs(
|
||||
(new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
) -
|
||||
new Date(firstday)) /
|
||||
oneDay
|
||||
)
|
||||
); //Days since last week
|
||||
let last = first + diffDays;
|
||||
let lastday = new Date(
|
||||
new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).setDate(last)
|
||||
).toISOString();
|
||||
let Query2 = `'$gte':'${firstday}','$lte':'${lastday}'`;
|
||||
setfilter(Query2);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last 7 days": {
|
||||
let d7 = new Date();
|
||||
let d7l = new Date();
|
||||
d7.setDate(d7.getDate() - 7);
|
||||
let l7t = new Date(
|
||||
Date.UTC(d7l.getFullYear(), d7l.getMonth(), d7l.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let date7 = new Date(
|
||||
Date.UTC(d7.getFullYear(), d7.getMonth(), d7.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Query7 = `'$gte':'${date7}','$lte':'${l7t}'`;
|
||||
setfilter(Query7);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last 14 days": {
|
||||
let d14 = new Date();
|
||||
let d14l = new Date();
|
||||
let l14t = new Date(
|
||||
Date.UTC(
|
||||
d14l.getFullYear(),
|
||||
d14l.getMonth(),
|
||||
d14l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d14.setDate(d14.getDate() - 14);
|
||||
let date14 = new Date(
|
||||
Date.UTC(d14.getFullYear(), d14.getMonth(), d14.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let Query14 = `'$gte':'${date14}','$lte':'${l14t}'`;
|
||||
setfilter(Query14);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last 30 days": {
|
||||
let d30 = new Date();
|
||||
let d30l = new Date();
|
||||
let l30t = new Date(
|
||||
Date.UTC(
|
||||
d30l.getFullYear(),
|
||||
d30l.getMonth(),
|
||||
d30l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d30.setDate(d30.getDate() - 30);
|
||||
let date30 = new Date(
|
||||
Date.UTC(d30.getFullYear(), d30.getMonth(), d30.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Query30 = `'$gte':'${date30}','$lte':'${l30t}'`;
|
||||
setfilter(Query30);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last week": {
|
||||
const from_date = moment().startOf("week").subtract(7, "days");
|
||||
const to_date = moment().endOf("week").subtract(7, "days");
|
||||
let Queryl = `'$gte':'${from_date.toISOString()}','$lte':'${to_date.toISOString()}'`;
|
||||
setfilter(Queryl);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "This month": {
|
||||
const tdate = new Date();
|
||||
let tfirstDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
let tlastDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth() + 1,
|
||||
0
|
||||
).toISOString();
|
||||
let Querylt = `'$gte':'${tfirstDay}','$lte':'${tlastDay}'`;
|
||||
setfilter(Querylt);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last month": {
|
||||
const ldate = new Date();
|
||||
var lfirstDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth() - 1,
|
||||
2
|
||||
).toISOString();
|
||||
var llastDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
let Queryltl = `'$gte':'${lfirstDay}','$lte':'${llastDay}'`;
|
||||
setfilter(Queryltl);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "All": {
|
||||
let fall = new Date(
|
||||
new Date().getFullYear() - 100,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let fall_year = `'$gte':'${fall}'`;
|
||||
setfilter(fall_year);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "This year": {
|
||||
let fcy = new Date(
|
||||
new Date().getFullYear(),
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let lcy = new Date(
|
||||
new Date().getFullYear(),
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let cur_year = `'$gte':'${fcy}','$lte':'${lcy}'`;
|
||||
setfilter(cur_year);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last year": {
|
||||
let fly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let lly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let last_year = `'$gte':'${fly}','$lte':'${lly}'`;
|
||||
setfilter(last_year);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
const renderSwitchWithTour = (col) => {
|
||||
switch (col.widget.type) {
|
||||
case "Card":
|
||||
@@ -272,7 +19,6 @@ const GetDashboard = (props) => {
|
||||
<DashboardCard
|
||||
Icon={col.widget.icon}
|
||||
Label={col.widget.label}
|
||||
Filter={filter}
|
||||
Format={col.widget.format && col.widget.format}
|
||||
Data={col.widget.data}
|
||||
FilterData={col.widget.filter}
|
||||
@@ -281,50 +27,12 @@ const GetDashboard = (props) => {
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
case "customeHtml":
|
||||
return (
|
||||
<div data-tut={col.widget.data.tourSection}>
|
||||
<select
|
||||
id="searchFiltr"
|
||||
className="form-control"
|
||||
value={
|
||||
option ||
|
||||
localStorage.getItem("DashboardDefaultFilter") ||
|
||||
col.widget.data[0].default
|
||||
}
|
||||
onChange={onSearchFilter}
|
||||
>
|
||||
{col.widget.data[0].options.map((opt) => (
|
||||
<option key={opt} value={opt}>
|
||||
{opt}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
|
||||
case "customeTag":
|
||||
return (
|
||||
<h3
|
||||
data-tut={col.widget.data.tourSection}
|
||||
style={{
|
||||
marginBottom: "4px",
|
||||
color: "currentColor",
|
||||
marginLeft: "4px"
|
||||
}}
|
||||
>
|
||||
{col.widget.label}
|
||||
</h3>
|
||||
);
|
||||
case "report": {
|
||||
let _filter = `${col.widget.filterKey}:${filter}`;
|
||||
return (
|
||||
<div data-tut={col.widget.data.tourSection}>
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<div className="mb-4 md:mb-0">
|
||||
<DashboardReport Filter={_filter} Record={col.widget} />
|
||||
<DashboardReport Record={col.widget} />
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
@@ -346,7 +54,6 @@ const GetDashboard = (props) => {
|
||||
<DashboardCard
|
||||
Icon={col.widget.icon}
|
||||
Label={col.widget.label}
|
||||
Filter={filter}
|
||||
Format={col.widget.format && col.widget.format}
|
||||
Data={col.widget.data}
|
||||
FilterData={col.widget.filter}
|
||||
@@ -355,48 +62,11 @@ const GetDashboard = (props) => {
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
case "customeHtml":
|
||||
return (
|
||||
<div>
|
||||
<select
|
||||
id="searchFiltr"
|
||||
className="form-control"
|
||||
value={
|
||||
option ||
|
||||
localStorage.getItem("DashboardDefaultFilter") ||
|
||||
col.widget.data[0].default
|
||||
}
|
||||
onChange={onSearchFilter}
|
||||
>
|
||||
{col.widget.data[0].options.map((opt) => (
|
||||
<option key={opt} value={opt}>
|
||||
{opt}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
|
||||
case "customeTag":
|
||||
return (
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: "4px",
|
||||
color: "currentColor",
|
||||
marginLeft: "4px"
|
||||
}}
|
||||
>
|
||||
{col.widget.label}
|
||||
</h3>
|
||||
);
|
||||
case "report": {
|
||||
let _filter = `${col.widget.filterKey}:${filter}`;
|
||||
return (
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<div className="mb-4 md:mb-0">
|
||||
<DashboardReport Filter={_filter} Record={col.widget} />
|
||||
<DashboardReport Record={col.widget} />
|
||||
</div>
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import { useDropScript } from "../../hook/useScript";
|
||||
|
||||
const DROPBOX_APP_KEY = process.env.REACT_APP_DROPBOX_API_KEY; // App key
|
||||
const DROPBOX_SDK_URL = "https://www.dropbox.com/static/api/2/dropins.js";
|
||||
const DROPBOX_SCRIPT_ID = "dropboxjs";
|
||||
|
||||
export default function DropboxChooser({ children, onSuccess, onCancel }) {
|
||||
useDropScript(DROPBOX_SDK_URL, {
|
||||
attrs: {
|
||||
id: DROPBOX_SCRIPT_ID,
|
||||
"data-app-key": DROPBOX_APP_KEY
|
||||
}
|
||||
});
|
||||
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
// Required. Called when a user selects an item in the Chooser.
|
||||
success: (files) => {
|
||||
// console.log("success", files);
|
||||
onSuccess && onSuccess(files);
|
||||
},
|
||||
// Optional. Called when the user closes the dialog without selecting a file
|
||||
// and does not include any parameters.
|
||||
cancel: () => {
|
||||
console.log("cancel");
|
||||
onCancel && onCancel();
|
||||
},
|
||||
|
||||
// Optional. "preview" (default) is a preview link to the document for sharing,
|
||||
// "direct" is an expiring link to download the contents of the file. For more
|
||||
linkType: "direct", // or "preview"
|
||||
multiselect: false, // 是否支持多选
|
||||
extensions: [".pdf"],
|
||||
|
||||
// Optional. A value of false (default) limits selection to files,
|
||||
// while true allows the user to select both folders and files.
|
||||
// You cannot specify `linkType: "direct"` when using `folderselect: true`.
|
||||
folderselect: false // or true
|
||||
}),
|
||||
[onSuccess, onCancel]
|
||||
);
|
||||
|
||||
const handleChoose = useCallback(() => {
|
||||
if (window.Dropbox) {
|
||||
window.Dropbox.choose(options);
|
||||
}
|
||||
}, [options]);
|
||||
|
||||
return (
|
||||
<div onClick={handleChoose}>
|
||||
{children || (
|
||||
<button className="px-2 py-[2px] text-2xl rounded border-[1px] text-blue-400 border-gray-300 w-full">
|
||||
<i className="fa-brands fa-dropbox"></i>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2,14 +2,12 @@ import React, { useState, useEffect } from "react";
|
||||
import { SaveFileSize } from "../../constant/saveFileSize";
|
||||
import Parse from "parse";
|
||||
import sanitizeFileName from "../../primitives/sanitizeFileName";
|
||||
|
||||
import DropboxChooser from "./DropboxChoose";
|
||||
const FileUpload = (props) => {
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [_fileupload, setFileUpload] = useState("");
|
||||
const [fileload, setfileload] = useState(false);
|
||||
|
||||
const [localValue, setLocalValue] = useState("");
|
||||
const [Message] = useState(false);
|
||||
const [percentage, setpercentage] = useState(0);
|
||||
|
||||
@@ -25,7 +23,6 @@ const FileUpload = (props) => {
|
||||
const onChange = (e) => {
|
||||
try {
|
||||
let files = e.target.files;
|
||||
setLocalValue(e.target.files);
|
||||
if (typeof files[0] !== "undefined") {
|
||||
if (props.schema.filetypes && props.schema.filetypes.length > 0) {
|
||||
var fileName = files[0].name;
|
||||
@@ -106,6 +103,56 @@ const FileUpload = (props) => {
|
||||
console.error("Error uploading file:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const dropboxSuccess = async (files) => {
|
||||
// console.log("file ", files);
|
||||
setfileload(true);
|
||||
const file = files[0];
|
||||
const url = file.link;
|
||||
const size = file.bytes;
|
||||
const mb = Math.round(file.bytes / Math.pow(1024, 2));
|
||||
|
||||
if (mb > 10) {
|
||||
setTimeout(() => {
|
||||
alert(
|
||||
`The selected file size is too large. Please select a file less than 10 MB`
|
||||
);
|
||||
}, 500);
|
||||
return;
|
||||
} else {
|
||||
const name = sanitizeFileName(file.name);
|
||||
|
||||
const parseFile = new Parse.File(name, { uri: url });
|
||||
|
||||
try {
|
||||
const response = await parseFile.save({
|
||||
progress: (progressValue, loaded, total, { type }) => {
|
||||
if (type === "upload" && progressValue !== null) {
|
||||
const percentCompleted = Math.round((loaded * 100) / total);
|
||||
// console.log("percentCompleted ", percentCompleted);
|
||||
setpercentage(percentCompleted);
|
||||
}
|
||||
}
|
||||
});
|
||||
// console.log("response.url() ", response.url());
|
||||
setFileUpload(response.url());
|
||||
props.onChange(response.url());
|
||||
setfileload(false);
|
||||
|
||||
if (response.url()) {
|
||||
SaveFileSize(size, response.url());
|
||||
return response.url();
|
||||
}
|
||||
} catch (error) {
|
||||
setfileload(false);
|
||||
setpercentage(0);
|
||||
console.error("Error uploading file:", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
const dropboxCancel = async () => {
|
||||
console.log("cancel clicked ");
|
||||
};
|
||||
let fileView =
|
||||
props.formData &&
|
||||
props.schema.uploadtype === "s3viajw" ? null : props.formData &&
|
||||
@@ -207,55 +254,51 @@ const FileUpload = (props) => {
|
||||
</div>
|
||||
|
||||
<>
|
||||
{localValue ? (
|
||||
<input
|
||||
type="file"
|
||||
id="hashfile"
|
||||
style={{
|
||||
border: "1px solid #ccc",
|
||||
color: "gray",
|
||||
backgroundColor: "white",
|
||||
padding: "5px 10px",
|
||||
borderRadius: "4px",
|
||||
fontSize: "13px",
|
||||
width: "100%",
|
||||
fontWeight: "bold"
|
||||
}}
|
||||
accept="application/pdf,application/vnd.ms-excel"
|
||||
onChange={onChange}
|
||||
/>
|
||||
) : props.formData ? (
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid #ccc",
|
||||
color: "gray",
|
||||
backgroundColor: "white",
|
||||
padding: "5px 10px",
|
||||
borderRadius: "4px",
|
||||
fontSize: "13px",
|
||||
width: "100%",
|
||||
fontWeight: "bold"
|
||||
}}
|
||||
>
|
||||
file selected : {props.formData.split("/")[3]}
|
||||
{props.formData ? (
|
||||
<div className="flex gap-2 justify-center items-center">
|
||||
<div className="flex justify-between items-center px-2 py-[3px] w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]">
|
||||
<div className="break-all">
|
||||
file selected : {props.formData.split("/")[3]}
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
console.log("clicked");
|
||||
setFileUpload([]);
|
||||
props.onChange(undefined);
|
||||
}}
|
||||
className="cursor-pointer px-[10px] text-[20px] font-bold bg-white text-red-500"
|
||||
>
|
||||
<i className="fa-solid fa-xmark"></i>
|
||||
</div>
|
||||
</div>
|
||||
<DropboxChooser
|
||||
onSuccess={dropboxSuccess}
|
||||
onCancel={dropboxCancel}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<input
|
||||
type="file"
|
||||
id="hashfile"
|
||||
style={{
|
||||
border: "1px solid #ccc",
|
||||
color: "gray",
|
||||
backgroundColor: "white",
|
||||
padding: "5px 10px",
|
||||
borderRadius: "4px",
|
||||
fontSize: "13px",
|
||||
width: "100%",
|
||||
fontWeight: "bold"
|
||||
}}
|
||||
accept="application/pdf,application/vnd.ms-excel"
|
||||
onChange={onChange}
|
||||
/>
|
||||
<div className="flex gap-2 justify-center items-center">
|
||||
<input
|
||||
type="file"
|
||||
id="hashfile"
|
||||
style={{
|
||||
border: "1px solid #ccc",
|
||||
color: "gray",
|
||||
backgroundColor: "white",
|
||||
padding: "5px 10px",
|
||||
borderRadius: "4px",
|
||||
fontSize: "13px",
|
||||
width: "100%",
|
||||
fontWeight: "bold"
|
||||
}}
|
||||
accept="application/pdf,application/vnd.ms-excel"
|
||||
onChange={onChange}
|
||||
/>
|
||||
<DropboxChooser
|
||||
onSuccess={dropboxSuccess}
|
||||
onCancel={dropboxCancel}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Component } from "react";
|
||||
import Parse from "parse";
|
||||
import axios from "axios";
|
||||
// import axios from "axios";
|
||||
|
||||
export class HiddenField extends Component {
|
||||
state = {
|
||||
@@ -37,31 +37,46 @@ export class HiddenField extends Component {
|
||||
this.setState({ _fields: custome_Filed });
|
||||
} else {
|
||||
if (currentUser) {
|
||||
let url = `${this.state.baseUrl}classes/${localStorage.getItem(
|
||||
"extended_class"
|
||||
)}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${
|
||||
currentUser.id
|
||||
}"}}&keys=${this.props.schema.data.valueKey}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": this.state.parseAppId
|
||||
};
|
||||
await axios.get(url, { headers: headers }).then((res) => {
|
||||
let custome_Filed = "";
|
||||
let _rdata = res.data.results;
|
||||
let splitArray = this.props.schema.data.valueKey.split(".");
|
||||
if (splitArray.length > 1) {
|
||||
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
||||
} else {
|
||||
console.log(_rdata[0][splitArray[0]]);
|
||||
custome_Filed = _rdata[0][splitArray[0]];
|
||||
}
|
||||
this.setState({ _fields: custome_Filed });
|
||||
// let url = `${this.state.baseUrl}classes/${localStorage.getItem(
|
||||
// "extended_class"
|
||||
// )}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${
|
||||
// currentUser.id
|
||||
// }"}}&keys=${this.props.schema.data.valueKey}`;
|
||||
// const headers = {
|
||||
// "Content-Type": "application/json",
|
||||
// "X-Parse-Application-Id": this.state.parseAppId
|
||||
// };
|
||||
// await axios.get(url, { headers: headers }).then((res) => {
|
||||
// let custome_Filed = "";
|
||||
// let _rdata = res.data.results;
|
||||
// let splitArray = this.props.schema.data.valueKey.split(".");
|
||||
// if (splitArray.length > 1) {
|
||||
// custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
||||
// } else {
|
||||
// console.log(_rdata[0][splitArray[0]]);
|
||||
// custome_Filed = _rdata[0][splitArray[0]];
|
||||
// }
|
||||
// this.setState({ _fields: custome_Filed });
|
||||
// });
|
||||
|
||||
const res = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
let custome_Filed = "";
|
||||
const result = res.toJSON();
|
||||
let _rdata = [result];
|
||||
let splitArray = this.props.schema.data.valueKey.split(".");
|
||||
if (splitArray.length > 1) {
|
||||
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
||||
} else {
|
||||
console.log(_rdata[0][splitArray[0]]);
|
||||
custome_Filed = _rdata[0][splitArray[0]];
|
||||
}
|
||||
this.setState({ _fields: custome_Filed });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('err', error)
|
||||
console.log("err", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,12 +120,10 @@ const Level1Dropdown = (props) => {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
var emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
res = await q.first();
|
||||
const currentUser = Parse.User.current();
|
||||
res = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
if (res) res = res.toJSON();
|
||||
}
|
||||
|
||||
@@ -339,7 +337,7 @@ const Level1Dropdown = (props) => {
|
||||
x.className = x.className.replace("show", "");
|
||||
}, 5000);
|
||||
} catch (error) {
|
||||
console.log("Err", error)
|
||||
console.log("Err", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,9 +42,8 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={`${isOpen ? "block" : "hidden"
|
||||
} bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 ${isOpen ? "translate-x-0" : "-translate-x-full"
|
||||
}`}
|
||||
className={`bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 md:translate-x-0
|
||||
${isOpen ? "translate-x-0 block" : "-translate-x-full hidden"}`}
|
||||
>
|
||||
<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">
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
import moment from "moment";
|
||||
|
||||
export default function onSearchFilter(_search) {
|
||||
switch (_search) {
|
||||
case "Today": {
|
||||
let d = new Date();
|
||||
let formDate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Todate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query = `'$gte':'${formDate}','$lte':'${Todate}'`;
|
||||
return Query;
|
||||
}
|
||||
case "Yesterday": {
|
||||
let d1 = new Date();
|
||||
d1.setDate(d1.getDate() - 1);
|
||||
let yesFrDate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let YesTodate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query1 = `'$gte':'${yesFrDate}','$lte':'${YesTodate}'`;
|
||||
return Query1;
|
||||
}
|
||||
|
||||
case "This week": {
|
||||
let oneDay = 24 * 60 * 60 * 1000;
|
||||
let curr = new Date(); // get current date
|
||||
let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
|
||||
|
||||
let firstday = new Date(
|
||||
new Date(
|
||||
Date.UTC(curr.getFullYear(), curr.getMonth(), curr.getDate(), 0, 0, 0)
|
||||
).setDate(first)
|
||||
).toISOString();
|
||||
let diffDays = Math.round(
|
||||
Math.abs(
|
||||
(new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
) -
|
||||
new Date(firstday)) /
|
||||
oneDay
|
||||
)
|
||||
); //Days since last week
|
||||
let last = first + diffDays;
|
||||
let lastday = new Date(
|
||||
new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).setDate(last)
|
||||
).toISOString();
|
||||
let Query2 = `'$gte':'${firstday}','$lte':'${lastday}'`;
|
||||
return Query2;
|
||||
}
|
||||
|
||||
case "Last 7 days": {
|
||||
let d7 = new Date();
|
||||
let d7l = new Date();
|
||||
d7.setDate(d7.getDate() - 7);
|
||||
let l7t = new Date(
|
||||
Date.UTC(d7l.getFullYear(), d7l.getMonth(), d7l.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let date7 = new Date(
|
||||
Date.UTC(d7.getFullYear(), d7.getMonth(), d7.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Query7 = `'$gte':'${date7}','$lte':'${l7t}'`;
|
||||
return Query7;
|
||||
}
|
||||
case "Last 14 days": {
|
||||
let d14 = new Date();
|
||||
let d14l = new Date();
|
||||
let l14t = new Date(
|
||||
Date.UTC(
|
||||
d14l.getFullYear(),
|
||||
d14l.getMonth(),
|
||||
d14l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d14.setDate(d14.getDate() - 14);
|
||||
let date14 = new Date(
|
||||
Date.UTC(d14.getFullYear(), d14.getMonth(), d14.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let Query14 = `'$gte':'${date14}','$lte':'${l14t}'`;
|
||||
return Query14;
|
||||
}
|
||||
|
||||
case "Last 30 days": {
|
||||
let d30 = new Date();
|
||||
let d30l = new Date();
|
||||
let l30t = new Date(
|
||||
Date.UTC(
|
||||
d30l.getFullYear(),
|
||||
d30l.getMonth(),
|
||||
d30l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d30.setDate(d30.getDate() - 30);
|
||||
let date30 = new Date(
|
||||
Date.UTC(d30.getFullYear(), d30.getMonth(), d30.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
return `'$gte':'${date30}','$lte':'${l30t}'`;
|
||||
}
|
||||
case "Last week": {
|
||||
const from_date = moment().startOf("week").subtract(7, "days");
|
||||
const to_date = moment().endOf("week").subtract(7, "days");
|
||||
return `'$gte':'${from_date.toISOString()}','$lte':'${to_date.toISOString()}'`;
|
||||
}
|
||||
case "This month": {
|
||||
var tdate = new Date();
|
||||
var tfirstDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
var tlastDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth() + 1,
|
||||
0
|
||||
).toISOString();
|
||||
let Querylt = `'$gte':'${tfirstDay}','$lte':'${tlastDay}'`;
|
||||
return Querylt;
|
||||
}
|
||||
case "Last month": {
|
||||
var ldate = new Date();
|
||||
var lfirstDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth() - 1,
|
||||
2
|
||||
).toISOString();
|
||||
var llastDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
let Queryltl = `'$gte':'${lfirstDay}','$lte':'${llastDay}'`;
|
||||
return Queryltl;
|
||||
}
|
||||
case "All": {
|
||||
let fall = new Date(
|
||||
new Date().getFullYear() - 100,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let fall_year = `'$gte':'${fall}'`;
|
||||
return fall_year;
|
||||
}
|
||||
case "This year": {
|
||||
let fcy = new Date(new Date().getFullYear(), 0, 1, 0, 0, 0).toISOString();
|
||||
let lcy = new Date(
|
||||
new Date().getFullYear(),
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let cur_year = `'$gte':'${fcy}','$lte':'${lcy}'`;
|
||||
return cur_year;
|
||||
}
|
||||
case "Last year": {
|
||||
let fly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let lly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let last_year = `'$gte':'${fly}','$lte':'${lly}'`;
|
||||
return last_year;
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -15,3 +15,20 @@ export const useScript = (url, onload) => {
|
||||
};
|
||||
}, [url, onload]);
|
||||
};
|
||||
|
||||
/**`useScript` hook is generated scripte for google sign in button */
|
||||
export const useDropScript = (url, onload) => {
|
||||
useEffect(() => {
|
||||
const script = document.createElement("script");
|
||||
//add url parameter to the script src, for load and it will remove after load in return
|
||||
script.src = url;
|
||||
script.async = true;
|
||||
script.defer = true;
|
||||
script.id = "dropboxjs";
|
||||
script.setAttribute("data-app-key", "8k0thg9r1t7asqg");
|
||||
document.head.appendChild(script);
|
||||
return () => {
|
||||
document.head.removeChild(script);
|
||||
};
|
||||
}, [url, onload]);
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ export const formJson = (id) => {
|
||||
type: "string",
|
||||
title: "Select Document",
|
||||
filetypes: [],
|
||||
maxfilesizeKB: "5000",
|
||||
maxfilesizeKB: "10000",
|
||||
uploadtype: "regular",
|
||||
helpbody: "",
|
||||
helplink: ""
|
||||
@@ -147,7 +147,7 @@ export const formJson = (id) => {
|
||||
class: "contracts_Contactbook",
|
||||
displayKey: "Name",
|
||||
valueKey: "objectId",
|
||||
query: `where={"CreatedBy":${userPtr}}&keys=Name`,
|
||||
query: `where={"CreatedBy":${userPtr},"IsDeleted":{"$ne":true}}&keys=Name`,
|
||||
isPointer: true,
|
||||
helpbody: "",
|
||||
helplink: "",
|
||||
@@ -582,4 +582,3 @@ export const formJson = (id) => {
|
||||
return formData;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,35 +1,13 @@
|
||||
import Parse from "parse";
|
||||
export default function reportJson(id) {
|
||||
const currentUserId = Parse.User.current().id;
|
||||
// console.log("json ", json);
|
||||
|
||||
const head = ["Sr.No", "Name", "Note", "Folder", "File", "Owner", "Signers"];
|
||||
const contactbook = ["Sr.No", "Name", "Email", "Phone"];
|
||||
switch (id) {
|
||||
// draft documents report
|
||||
case "ByHuevtCFY":
|
||||
return {
|
||||
reportName: "Draft Documents",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: null,
|
||||
$or: [
|
||||
{ Signers: null, SignedUrl: null },
|
||||
{ Signers: { $exists: true }, Placeholders: null }
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "sign",
|
||||
@@ -45,27 +23,7 @@ export default function reportJson(id) {
|
||||
case "4Hhwbp482K":
|
||||
return {
|
||||
reportName: "Need your sign",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
},
|
||||
Placeholders: { $ne: null }
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name",
|
||||
"Signers.UserId",
|
||||
"AuditTrail"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "sign",
|
||||
@@ -81,31 +39,7 @@ export default function reportJson(id) {
|
||||
case "1MwEuxLEkF":
|
||||
return {
|
||||
reportName: "In-progress documents",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
Signers: { $ne: null },
|
||||
Placeholders: { $ne: null },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
@@ -121,27 +55,7 @@ export default function reportJson(id) {
|
||||
case "kQUoW4hUXz":
|
||||
return {
|
||||
reportName: "Completed Documents",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: null,
|
||||
IsCompleted: true,
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
IsDeclined: { $ne: true }
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name",
|
||||
"TimeToCompleteDays"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
@@ -153,63 +67,11 @@ export default function reportJson(id) {
|
||||
}
|
||||
]
|
||||
};
|
||||
// OpenSignDrive™ documents Drafts
|
||||
case "VRFDmUmw5B":
|
||||
return {
|
||||
reportName: "OpenSignDrive™ Drafts",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: "AIDoc",
|
||||
$or: [
|
||||
{ Signers: null, SignedUrl: null },
|
||||
{ Signers: { $exists: true }, Placeholders: null }
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "edit",
|
||||
btnColor: "#3ac9d6",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9MZWdhR2VuaWUtTWljcm9hcHBWMi9yZW1vdGVFbnRyeS5qcw==&moduleToLoad=AppRoutes&remoteName=legageniemicroapp/legagenie"
|
||||
}
|
||||
]
|
||||
};
|
||||
// declined documents report
|
||||
case "UPr2Fm5WY3":
|
||||
return {
|
||||
reportName: "Declined Documents",
|
||||
className: "contracts_Document",
|
||||
params: { Type: null, IsDeclined: true },
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
@@ -225,39 +87,7 @@ export default function reportJson(id) {
|
||||
case "zNqBHXHsYH":
|
||||
return {
|
||||
reportName: "Expired Documents",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
Type: { $ne: "Folder" },
|
||||
$and: [
|
||||
{
|
||||
$or: [
|
||||
{ Signers: { $ne: null }, SignedUrl: { $ne: null } },
|
||||
{ Placeholders: { $ne: null } }
|
||||
]
|
||||
},
|
||||
{
|
||||
ExpiryDate: {
|
||||
$lt: { __type: "Date", iso: new Date().toISOString() }
|
||||
}
|
||||
}
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
@@ -273,31 +103,7 @@ export default function reportJson(id) {
|
||||
case "d9k3UfYHBc":
|
||||
return {
|
||||
reportName: "Recently sent for signatures",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
Signers: { $ne: null },
|
||||
Placeholders: { $ne: null },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
@@ -313,27 +119,7 @@ export default function reportJson(id) {
|
||||
case "5Go51Q7T8r":
|
||||
return {
|
||||
reportName: "Recent signature requests",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
},
|
||||
Placeholders: { $ne: null }
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name",
|
||||
"Signers.UserId",
|
||||
"AuditTrail"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "Sign",
|
||||
@@ -349,28 +135,7 @@ export default function reportJson(id) {
|
||||
case "kC5mfynCi4":
|
||||
return {
|
||||
reportName: "Drafts",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: null,
|
||||
$or: [
|
||||
{ Signers: null, SignedUrl: null },
|
||||
{ Signers: { $exists: true }, Placeholders: null }
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
heading: head,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "sign",
|
||||
@@ -382,6 +147,20 @@ export default function reportJson(id) {
|
||||
}
|
||||
]
|
||||
};
|
||||
// contactbook report
|
||||
case "5KhaPr482K":
|
||||
return {
|
||||
reportName: "Contactbook",
|
||||
heading: contactbook,
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "",
|
||||
btnColor: "#f55a42",
|
||||
textColor: "white",
|
||||
btnIcon: "fa-solid fa-trash"
|
||||
}
|
||||
]
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"subtitle": "Free for life One click install.",
|
||||
"btnText": "Visit github",
|
||||
"url": "https://github.com/opensignlabs/opensign",
|
||||
"target": "_blank",
|
||||
"benefits": [
|
||||
"Sign Unlimited Documents",
|
||||
"S3 Doc Storage",
|
||||
@@ -26,9 +27,10 @@
|
||||
"planName": "THANKS PLAN",
|
||||
"currency": "$",
|
||||
"price": "29.99",
|
||||
"subtitle": "Use code 'FREEBETA' to get this for free(First 100 users)",
|
||||
"subtitle": "Use code 'FREEBETA' to get this for free(First 1000 users)",
|
||||
"btnText": "Subscribe",
|
||||
"url": "https://subscriptions.zoho.in/subscribe/ef798486e6a0a11ea65f2bae8f2af901dbadf3175d495584fd25b9af5d2f2b9e/thanks",
|
||||
"target": "_self",
|
||||
"benefits": [
|
||||
"Sign Unlimited Documents",
|
||||
"Unlimited Secure Doc Storage with OpenSignDrive",
|
||||
@@ -50,6 +52,7 @@
|
||||
"subtitle": "Customization available Priority support.",
|
||||
"btnText": "Contact us",
|
||||
"url": "https://www.opensignlabs.com/contact-us",
|
||||
"target": "_blank",
|
||||
"benefits": [
|
||||
"All features",
|
||||
"Custom domain",
|
||||
|
||||
@@ -6,10 +6,10 @@ import { useWindowSize } from "../hook/useWindowSize";
|
||||
import Tour from "reactour";
|
||||
import axios from "axios";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import Parse from "parse";
|
||||
const HomeLayout = ({ children }) => {
|
||||
const { width } = useWindowSize();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isOpen, setIsOpen] = useState(true);
|
||||
const arr = useSelector((state) => state.TourSteps);
|
||||
|
||||
// reactour state
|
||||
@@ -19,13 +19,11 @@ const HomeLayout = ({ children }) => {
|
||||
const [tourConfigs, setTourConfigs] = useState([]);
|
||||
|
||||
const showSidebar = () => {
|
||||
setIsOpen(!isOpen);
|
||||
setIsOpen(value => !value);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (width && width <= 768) {
|
||||
setIsOpen(false);
|
||||
} else {
|
||||
setIsOpen(true);
|
||||
}
|
||||
}, [width]);
|
||||
|
||||
@@ -124,20 +122,11 @@ const HomeLayout = ({ children }) => {
|
||||
};
|
||||
|
||||
async function checkTourStatus() {
|
||||
const serverUrl = localStorage.getItem("baseUrl");
|
||||
const appId = localStorage.getItem("AppID12");
|
||||
const extUserClass = localStorage.getItem("extended_class");
|
||||
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
const extUserId = json && json.length > 0 && json[0].objectId;
|
||||
// console.log("extUserId ", extUserId);
|
||||
const res = await axios.get(
|
||||
serverUrl + "classes/" + extUserClass + "/" + extUserId,
|
||||
{
|
||||
headers: {
|
||||
"X-Parse-Application-Id": appId
|
||||
}
|
||||
}
|
||||
);
|
||||
const currentUser = Parse.User.current();
|
||||
const cloudRes = await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
});
|
||||
const res = { data: cloudRes.toJSON() };
|
||||
if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) {
|
||||
const tourStatus = res.data.TourStatus;
|
||||
// console.log("res ", res.data.TourStatus);
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
import React, { useState, useEffect, useMemo } from "react";
|
||||
import pad from "../assets/images/pad.svg";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import axios from "axios";
|
||||
import "../styles/report.css";
|
||||
const ReportTable = ({
|
||||
ReportName,
|
||||
List,
|
||||
setList,
|
||||
actions,
|
||||
heading,
|
||||
setIsNextRecord,
|
||||
isMoreDocs
|
||||
isMoreDocs,
|
||||
docPerPage
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const docPerPage = 10;
|
||||
// const pageNumbers = [];
|
||||
|
||||
const [actLoader, setActLoader] = useState({});
|
||||
const [isAlert, setIsAlert] = useState(false);
|
||||
const [isErr, setIsErr] = useState(false);
|
||||
// For loop is used to calculate page numbers visible below table
|
||||
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
|
||||
const pageNumbers = useMemo(() => {
|
||||
@@ -22,7 +26,7 @@ const ReportTable = ({
|
||||
calculatedPageNumbers.push(i);
|
||||
}
|
||||
return calculatedPageNumbers;
|
||||
}, [List]);
|
||||
}, [List, docPerPage]);
|
||||
// below useEffect reset currenpage to 1 if user change route
|
||||
useEffect(() => {
|
||||
return () => setCurrentPage(1);
|
||||
@@ -57,8 +61,34 @@ const ReportTable = ({
|
||||
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||
// localStorage.setItem("rowlevelMicro");
|
||||
};
|
||||
const handlebtn = () => {
|
||||
console.log("clicked");
|
||||
const handlebtn = async (item) => {
|
||||
if (ReportName === "Contactbook") {
|
||||
setActLoader({ [item.objectId]: true });
|
||||
try {
|
||||
const url =
|
||||
process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/";
|
||||
const body = { IsDeleted: true };
|
||||
const res = await axios.put(url + item.objectId, body, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
});
|
||||
// console.log("Res ", res.data);
|
||||
if (res.data && res.data.updatedAt) {
|
||||
setActLoader({});
|
||||
setIsAlert(true);
|
||||
const upldatedList = List.filter((x) => x.objectId !== item.objectId);
|
||||
setList(upldatedList);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("err", err);
|
||||
setIsAlert(true);
|
||||
setIsErr(true);
|
||||
setActLoader({});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Get current list
|
||||
@@ -73,17 +103,27 @@ const ReportTable = ({
|
||||
|
||||
return (
|
||||
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
||||
{isAlert && (
|
||||
<div
|
||||
className={`alert alert-${isErr ? "danger" : "success"} alertBox`}
|
||||
role="alert"
|
||||
onAnimationEnd={() => setIsAlert(false)}
|
||||
>
|
||||
{isErr
|
||||
? "Something went wrong, Please try again later!"
|
||||
: "Record deleted successfully!"}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
||||
<table className="table-auto w-full border-collapse">
|
||||
<thead className="text-[14px]">
|
||||
<tr className="border-y-[1px]">
|
||||
<th className="px-4 py-2 font-thin">Sr.No</th>
|
||||
<th className="px-4 py-2 font-thin">Name</th>
|
||||
<th className="px-4 py-2 font-thin">Note</th>
|
||||
<th className="px-4 py-2 font-thin">Folder</th>
|
||||
<th className="px-4 py-2 font-thin">File</th>
|
||||
<th className="px-4 py-2 font-thin">Owner</th>
|
||||
<th className="px-4 py-2 font-thin">Signers</th>
|
||||
{heading?.map((item, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<th className="px-4 py-2 font-thin">{item}</th>
|
||||
</React.Fragment>
|
||||
))}
|
||||
{actions?.length > 0 && (
|
||||
<th className="px-4 py-2 font-thin">Action</th>
|
||||
)}
|
||||
@@ -92,61 +132,115 @@ const ReportTable = ({
|
||||
<tbody className="text-[12px]">
|
||||
{List?.length > 0 ? (
|
||||
<>
|
||||
{currentLists.map((item, index) => (
|
||||
<tr className="border-y-[1px]" key={index}>
|
||||
<td className="px-4 py-2">{index + 1}</td>
|
||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
||||
<td className="px-4 py-2">
|
||||
{item?.Folder?.Name || "OpenSignDrive"}
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title={item?.URL}
|
||||
href={item?.URL}
|
||||
download={item?.URL}
|
||||
className="text-[blue] hover:text-[blue] hover:underline"
|
||||
>
|
||||
{item?.URL ? "Download" : "-"}
|
||||
</a>
|
||||
</td>
|
||||
{currentLists.map((item, index) =>
|
||||
ReportName === "Contactbook" ? (
|
||||
<tr className="border-y-[1px]" key={index}>
|
||||
<td className="px-4 py-2">{index + 1}</td>
|
||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||
<td className="px-4 py-2">{item?.Email || "-"}</td>
|
||||
<td className="px-4 py-2">{item?.Phone || "-"}</td>
|
||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
||||
{actions?.length > 0 &&
|
||||
actions.map((act, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() =>
|
||||
act?.redirectUrl
|
||||
? handlemicroapp(item, act.redirectUrl)
|
||||
: handlebtn(item)
|
||||
}
|
||||
className={`flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
||||
style={{
|
||||
backgroundColor: act.btnColor
|
||||
? act.btnColor
|
||||
: "#3ac9d6",
|
||||
color: act?.textColor ? act?.textColor : "white"
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
{act?.btnIcon && (
|
||||
<i
|
||||
className={
|
||||
actLoader[item.objectId]
|
||||
? "fa-solid fa-spinner fa-spin-pulse"
|
||||
: act.btnIcon
|
||||
}
|
||||
></i>
|
||||
)}
|
||||
</span>
|
||||
{act?.btnLabel && (
|
||||
<span className="uppercase">
|
||||
{act?.btnLabel ? act.btnLabel : "View"}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</td>
|
||||
</tr>
|
||||
) : (
|
||||
<tr className="border-y-[1px]" key={index}>
|
||||
<td className="px-4 py-2">{index + 1}</td>
|
||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
||||
<td className="px-4 py-2">
|
||||
{item?.Folder?.Name || "OpenSignDrive"}
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title={item?.URL}
|
||||
href={item?.URL}
|
||||
download={item?.URL}
|
||||
className="text-[blue] hover:text-[blue] hover:underline"
|
||||
>
|
||||
{item?.URL ? "Download" : "-"}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td className="px-4 py-2">{formatRow(item?.ExtUserPtr)}</td>
|
||||
<td className="px-4 py-2">
|
||||
{item?.Signers ? formatRow(item?.Signers) : "-"}
|
||||
</td>
|
||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
||||
{actions?.length > 0 &&
|
||||
actions.map((act, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() =>
|
||||
act?.redirectUrl
|
||||
? handlemicroapp(item, act.redirectUrl)
|
||||
: handlebtn(item)
|
||||
}
|
||||
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
||||
style={{
|
||||
backgroundColor: act.btnColor
|
||||
? act.btnColor
|
||||
: "#3ac9d6",
|
||||
color: act?.textColor ? act?.textColor : "white"
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
{act?.btnIcon && <i className={act.btnIcon}></i>}
|
||||
</span>
|
||||
<span className="uppercase">
|
||||
{act?.btnLabel ? act.btnLabel : "view"}
|
||||
</span>
|
||||
</button>
|
||||
// )
|
||||
))}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
<td className="px-4 py-2">{formatRow(item?.ExtUserPtr)}</td>
|
||||
<td className="px-4 py-2">
|
||||
{item?.Signers ? formatRow(item?.Signers) : "-"}
|
||||
</td>
|
||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
||||
{actions?.length > 0 &&
|
||||
actions.map((act, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() =>
|
||||
act?.redirectUrl
|
||||
? handlemicroapp(item, act.redirectUrl)
|
||||
: handlebtn(item)
|
||||
}
|
||||
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
||||
style={{
|
||||
backgroundColor: act.btnColor
|
||||
? act.btnColor
|
||||
: "#3ac9d6",
|
||||
color: act?.textColor ? act?.textColor : "white"
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
{act?.btnIcon && (
|
||||
<i
|
||||
className={
|
||||
actLoader[item.objectId]
|
||||
? "fa-solid fa-spinner fa-spin-pulse"
|
||||
: act.btnIcon
|
||||
}
|
||||
></i>
|
||||
)}
|
||||
</span>
|
||||
<span className="uppercase">
|
||||
{act?.btnLabel ? act.btnLabel : "view"}
|
||||
</span>
|
||||
</button>
|
||||
// )
|
||||
))}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
@@ -154,7 +248,7 @@ const ReportTable = ({
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="flex flex-wrap items-center gap-2 p-2 ">
|
||||
{List.length > 10 && (
|
||||
{List.length > docPerPage && (
|
||||
<>
|
||||
{currentPage > 1 && (
|
||||
<button
|
||||
@@ -178,7 +272,7 @@ const ReportTable = ({
|
||||
{isMoreDocs && (
|
||||
<button className="text-black rounded px-1 py-2">...</button>
|
||||
)}
|
||||
{List.length > 10 && (
|
||||
{List.length > docPerPage && (
|
||||
<>
|
||||
{pageNumbers.includes(currentPage + 1) && (
|
||||
<button
|
||||
|
||||
@@ -11,7 +11,8 @@ export const fetchAppInfo = (str, burl, app_id) => async (dispatch) => {
|
||||
let _base = ""; // Define _base here and initialize it to an empty string
|
||||
if (response && response.baseurl) {
|
||||
_base = response.baseurl.charAt(response.baseurl.length - 1);
|
||||
} localStorage.removeItem("baseUrl");
|
||||
}
|
||||
localStorage.removeItem("baseUrl");
|
||||
localStorage.setItem("_appName", response.appname);
|
||||
localStorage.setItem("_app_objectId", response.objectId);
|
||||
if (_base === "/") {
|
||||
@@ -120,16 +121,11 @@ export const login = (username, password) => async (dispatch) => {
|
||||
localStorage.setItem("_user_role", _role);
|
||||
}
|
||||
try {
|
||||
const tour = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
let _tour = new Parse.Query(tour);
|
||||
_tour.equalTo("UserId", {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: resultjson.objectId
|
||||
});
|
||||
await _tour.first().then(
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
})
|
||||
.then(
|
||||
(results) => {
|
||||
let userinfo = results.toJSON();
|
||||
if (userinfo.TenantId) {
|
||||
@@ -142,7 +138,7 @@ export const login = (username, password) => async (dispatch) => {
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.log("err ", error)
|
||||
console.log("err ", error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,11 +2,12 @@ import React, { useState, useEffect } from "react";
|
||||
import Parse from "parse";
|
||||
import "../styles/loader.css";
|
||||
import GetDashboard from "../components/dashboard/GetDashboard";
|
||||
import { Navigate, useParams } from "react-router-dom";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import Title from "../components/Title";
|
||||
import { save_tourSteps } from "../redux/actions";
|
||||
import { connect } from "react-redux";
|
||||
const Dashboard = (props) => {
|
||||
const navigate = useNavigate();
|
||||
const { id } = useParams();
|
||||
const [dashboard, setdashboard] = useState([]);
|
||||
const [classnameArray, setclassnameArray] = useState([]);
|
||||
@@ -15,6 +16,19 @@ const Dashboard = (props) => {
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [defaultQuery, setDefaultQuery] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
if (localStorage.getItem("accesstoken")) {
|
||||
if (id !== undefined) {
|
||||
getDashboard(id);
|
||||
} else {
|
||||
getDashboard(localStorage.getItem("PageLanding"));
|
||||
}
|
||||
} else {
|
||||
navigate("/", { replace: true });
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [id]);
|
||||
|
||||
const getDashboard = async (id) => {
|
||||
setloading(true);
|
||||
try {
|
||||
@@ -93,20 +107,6 @@ const Dashboard = (props) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (id !== undefined) {
|
||||
getDashboard(id);
|
||||
} else {
|
||||
getDashboard(localStorage.getItem("PageLanding"));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
}, [id]);
|
||||
|
||||
if (localStorage.getItem("accesstoken") === "" || null) {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
|
||||
let _dash = (
|
||||
<GetDashboard
|
||||
dashboard={dashboard}
|
||||
|
||||
@@ -10,9 +10,11 @@ import GoogleSignInBtn from "../components/LoginGoogle";
|
||||
// import LoginFacebook from "../components/LoginFacebook";
|
||||
import { NavLink, useNavigate } from "react-router-dom";
|
||||
import login_img from "../assets/images/login_img.svg";
|
||||
import { useWindowSize } from "../hook/useWindowSize";
|
||||
|
||||
function Login(props) {
|
||||
const navigate = useNavigate();
|
||||
const { width } = useWindowSize();
|
||||
const [state, setState] = useState({
|
||||
email: "",
|
||||
toastColor: "#5cb85c",
|
||||
@@ -21,7 +23,6 @@ function Login(props) {
|
||||
passwordVisible: false,
|
||||
mobile: "",
|
||||
phone: "",
|
||||
hideNav: "",
|
||||
scanResult: "",
|
||||
baseUrl: localStorage.getItem("baseUrl"),
|
||||
parseAppId: localStorage.getItem("parseAppId"),
|
||||
@@ -47,26 +48,11 @@ function Login(props) {
|
||||
);
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
resize();
|
||||
window.addEventListener("resize", resize());
|
||||
return () => {
|
||||
window.removeEventListener("resize", resize());
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
const handleChange = (event) => {
|
||||
const { name, value } = event.target;
|
||||
setState({ ...state, [name]: value });
|
||||
};
|
||||
|
||||
const resize = () => {
|
||||
let currentHideNav = window.innerWidth <= 760;
|
||||
if (currentHideNav !== state.hideNav) {
|
||||
setState({ ...state, hideNav: currentHideNav });
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
localStorage.removeItem("accesstoken");
|
||||
event.preventDefault();
|
||||
@@ -129,7 +115,7 @@ function Login(props) {
|
||||
);
|
||||
if (rolesfiltered.length > 0) {
|
||||
_currentRole = rolesfiltered[0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const rolesfiltered = userRoles.filter(
|
||||
(x) => !valuesToExclude.includes(x)
|
||||
@@ -162,15 +148,13 @@ function Login(props) {
|
||||
element.userpointer
|
||||
);
|
||||
|
||||
const extendedClass = Parse.Object.extend(
|
||||
element.extended_class
|
||||
);
|
||||
let query = new Parse.Query(extendedClass);
|
||||
query.equalTo("UserId", Parse.User.current());
|
||||
query.include("TenantId");
|
||||
await query.find().then(
|
||||
(results) => {
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
}).then(
|
||||
(result) => {
|
||||
let tenentInfo = [];
|
||||
const results = [result];
|
||||
if (results) {
|
||||
let extendedInfo_stringify =
|
||||
JSON.stringify(results);
|
||||
@@ -280,10 +264,14 @@ function Login(props) {
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
);
|
||||
} else {
|
||||
navigate(`/subscription`);
|
||||
navigate(`/subscription`, {
|
||||
replace: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
navigate(`/subscription`);
|
||||
navigate(`/subscription`, {
|
||||
replace: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
navigate(
|
||||
@@ -320,7 +308,9 @@ function Login(props) {
|
||||
);
|
||||
const billingDate = "";
|
||||
if (billingDate) {
|
||||
navigate(`/subscription`);
|
||||
navigate(`/subscription`, {
|
||||
replace: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
navigate(
|
||||
@@ -334,23 +324,6 @@ function Login(props) {
|
||||
sessionToken: user.getSessionToken()
|
||||
};
|
||||
handleSubmitbtn(payload);
|
||||
// setState({
|
||||
// ...state,
|
||||
// loading: false,
|
||||
// toastColor: "#d9534f",
|
||||
// toastDescription:
|
||||
// "You dont have access to this application."
|
||||
// });
|
||||
|
||||
// const x = document.getElementById("snackbar");
|
||||
// x.className = "show";
|
||||
// setTimeout(function () {
|
||||
// x.className = x.className.replace(
|
||||
// "show",
|
||||
// ""
|
||||
// );
|
||||
// }, 2000);
|
||||
// localStorage.setItem("accesstoken", null);
|
||||
console.error(
|
||||
"Error while fetching Follow",
|
||||
error
|
||||
@@ -472,7 +445,7 @@ function Login(props) {
|
||||
);
|
||||
if (rolesfiltered.length > 0) {
|
||||
_currentRole = rolesfiltered[0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const rolesfiltered = userRoles.filter(
|
||||
(x) => !valuesToExclude.includes(x)
|
||||
@@ -502,16 +475,13 @@ function Login(props) {
|
||||
element.extended_class
|
||||
);
|
||||
localStorage.setItem("userpointer", element.userpointer);
|
||||
|
||||
const extendedClass = Parse.Object.extend(
|
||||
element.extended_class
|
||||
);
|
||||
let query = new Parse.Query(extendedClass);
|
||||
query.equalTo("UserId", Parse.User.current());
|
||||
query.include("TenantId");
|
||||
await query.find().then(
|
||||
(results) => {
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
}).then(
|
||||
(result) => {
|
||||
let tenentInfo = [];
|
||||
const results = [result];
|
||||
if (results) {
|
||||
let extendedInfo_stringify =
|
||||
JSON.stringify(results);
|
||||
@@ -596,20 +566,26 @@ function Login(props) {
|
||||
setThirdpartyLoader(false);
|
||||
setState({ ...state, loading: false });
|
||||
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||
if (billingDate) {
|
||||
if (billingDate > new Date()) {
|
||||
localStorage.removeItem("userDetails");
|
||||
navigate(
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
);
|
||||
if (billingDate) {
|
||||
if (billingDate > new Date()) {
|
||||
localStorage.removeItem("userDetails");
|
||||
navigate(
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
);
|
||||
} else {
|
||||
navigate(`/subscription`, {
|
||||
replace: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
navigate(`/subscription`);
|
||||
navigate(`/subscription`, { replace: true });
|
||||
}
|
||||
} else {
|
||||
navigate(`/subscription`);
|
||||
navigate(
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
localStorage.setItem("PageLanding", element.pageId);
|
||||
localStorage.setItem(
|
||||
@@ -620,21 +596,25 @@ function Login(props) {
|
||||
setState({ ...state, loading: false });
|
||||
setThirdpartyLoader(false);
|
||||
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||
if (billingDate) {
|
||||
if (billingDate > new Date()) {
|
||||
localStorage.removeItem("userDetails");
|
||||
navigate(
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
);
|
||||
if (billingDate) {
|
||||
if (billingDate > new Date()) {
|
||||
localStorage.removeItem("userDetails");
|
||||
navigate(
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
);
|
||||
} else {
|
||||
navigate(`/subscription`, { replace: true });
|
||||
}
|
||||
} else {
|
||||
navigate(`/subscription`);
|
||||
navigate(`/subscription`, { replace: true });
|
||||
}
|
||||
} else {
|
||||
navigate(`/subscription`);
|
||||
navigate(
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
(error) => {
|
||||
const payload = {
|
||||
sessionToken: sessionToken
|
||||
@@ -655,7 +635,6 @@ function Login(props) {
|
||||
} else {
|
||||
setThirdpartyLoader(false);
|
||||
setState({ ...state, loading: false });
|
||||
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -717,9 +696,10 @@ function Login(props) {
|
||||
|
||||
await axios
|
||||
.post(url, JSON.stringify(body), { headers: headers1 })
|
||||
.then((roles) => {
|
||||
.then((axiosres) => {
|
||||
const roles = axiosres.data.result;
|
||||
if (roles) {
|
||||
userRoles = roles.data.result;
|
||||
userRoles = roles;
|
||||
let _currentRole = "";
|
||||
if (userRoles.length > 1) {
|
||||
if (
|
||||
@@ -767,15 +747,13 @@ function Login(props) {
|
||||
element.extended_class
|
||||
);
|
||||
|
||||
const extendedClass = Parse.Object.extend(
|
||||
element.extended_class
|
||||
);
|
||||
let query = new Parse.Query(extendedClass);
|
||||
query.equalTo("UserId", Parse.User.current());
|
||||
query.include("TenantId");
|
||||
await query.find().then(
|
||||
(results) => {
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
}).then(
|
||||
(result) => {
|
||||
let tenentInfo = [];
|
||||
const results = [result];
|
||||
if (results) {
|
||||
let extendedInfo_stringify = JSON.stringify(results);
|
||||
let extendedInfo = JSON.parse(extendedInfo_stringify);
|
||||
@@ -1066,7 +1044,7 @@ function Login(props) {
|
||||
<NavLink
|
||||
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
|
||||
to="/signup"
|
||||
style={state.hideNav ? { textAlign: "center" } : {}}
|
||||
style={width < 768 ? { textAlign: "center" } : {}}
|
||||
>
|
||||
Create Account
|
||||
</NavLink>
|
||||
@@ -1134,7 +1112,7 @@ function Login(props) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!state.hideNav && (
|
||||
{width >= 768 && (
|
||||
<div className="self-center">
|
||||
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
||||
<img
|
||||
@@ -1171,7 +1149,9 @@ function Login(props) {
|
||||
<div className="modal-dialog" role="document">
|
||||
<div className="modal-content">
|
||||
<div className="modal-header">
|
||||
<h5 className="modal-title">Login form</h5>
|
||||
<h5 className="modal-title font-semibold">
|
||||
Additional Info
|
||||
</h5>
|
||||
<span>
|
||||
<span></span>
|
||||
</span>
|
||||
@@ -1203,17 +1183,17 @@ function Login(props) {
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label
|
||||
htmlFor="Destination"
|
||||
htmlFor="JobTitle"
|
||||
style={{ display: "flex" }}
|
||||
className="col-form-label"
|
||||
>
|
||||
Destination{" "}
|
||||
Job Title
|
||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="Destination"
|
||||
id="JobTitle"
|
||||
value={userDetails.Destination}
|
||||
onChange={(e) =>
|
||||
setUserDetails({
|
||||
@@ -1227,18 +1207,19 @@ function Login(props) {
|
||||
<div className="mt-4">
|
||||
<button
|
||||
type="button"
|
||||
className="bg-[#6c757d] text-sm p-2 text-white rounded uppercase"
|
||||
onClick={handleCloseModal}
|
||||
style={{ marginRight: 10, width: 90 }}
|
||||
className="bg-[#17a2b8] text-sm p-2 text-white rounded uppercase"
|
||||
onClick={(e) => handleSubmitbtn(e)}
|
||||
style={{ marginRight: 10 }}
|
||||
>
|
||||
Cancel
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-[#17a2b8] text-sm p-2 text-white rounded uppercase"
|
||||
onClick={(e) => handleSubmitbtn(e)}
|
||||
className="bg-[#6c757d] text-sm p-2 text-white rounded uppercase"
|
||||
onClick={handleCloseModal}
|
||||
style={{ width: 90 }}
|
||||
>
|
||||
Login
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -21,6 +21,9 @@ const PgSignUp = (props) => {
|
||||
});
|
||||
const [validationMessage, setValidationMessage] = useState("");
|
||||
const [isLoader, setIsLoader] = useState(true);
|
||||
const [lengthValid, setLengthValid] = useState(false);
|
||||
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||
|
||||
// below useEffect is used to fetch App data and save to redux state
|
||||
useEffect(() => {
|
||||
@@ -67,9 +70,8 @@ const PgSignUp = (props) => {
|
||||
const userSettings = JSON.parse(localStorage.getItem("userSettings"));
|
||||
const extClass = userSettings[0].extended_class;
|
||||
// console.log("extClass ", extClass);
|
||||
const checkUser = new Parse.Query(extClass);
|
||||
checkUser.equalTo("Email", userDetails.email);
|
||||
const res = await checkUser.first();
|
||||
const params = { email: userDetails.email };
|
||||
const res = await Parse.Cloud.run("getUserDetails", params);
|
||||
// console.log("res", res);
|
||||
if (res) {
|
||||
const checkUser = new Parse.Query(extClass);
|
||||
@@ -105,21 +107,23 @@ const PgSignUp = (props) => {
|
||||
// "handleSubmit" is used to save user details signup him/her who come from plan-pricing page
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
setIsLoader(true);
|
||||
if (formData.password === formData.confirmPassword) {
|
||||
const url = window.location.href;
|
||||
let paramString = url.split("?")[1];
|
||||
let queryString = new URLSearchParams(paramString);
|
||||
// console.log("url ", queryString);
|
||||
if (lengthValid && caseDigitValid && specialCharValid) {
|
||||
setIsLoader(true);
|
||||
if (formData.password === formData.confirmPassword) {
|
||||
const url = window.location.href;
|
||||
let paramString = url.split("?")[1];
|
||||
let queryString = new URLSearchParams(paramString);
|
||||
// console.log("url ", queryString);
|
||||
|
||||
let obj = { ...formData };
|
||||
for (let pair of queryString.entries()) {
|
||||
// console.log("Key is: " + pair[0]);
|
||||
// console.log("Value is: " + pair[1]);
|
||||
obj = { ...obj, [pair[0]]: pair[1] };
|
||||
let obj = { ...formData };
|
||||
for (let pair of queryString.entries()) {
|
||||
// console.log("Key is: " + pair[0]);
|
||||
// console.log("Value is: " + pair[1]);
|
||||
obj = { ...obj, [pair[0]]: pair[1] };
|
||||
}
|
||||
saveUser(obj);
|
||||
// console.log("obj ", obj);}
|
||||
}
|
||||
saveUser(obj);
|
||||
// console.log("obj ", obj);}
|
||||
}
|
||||
};
|
||||
const saveUser = async (obj) => {
|
||||
@@ -152,6 +156,7 @@ const PgSignUp = (props) => {
|
||||
if (res) {
|
||||
const params = {
|
||||
userDetails: {
|
||||
jobTitle: zohoRes.data.result.jobTitle,
|
||||
company: zohoRes.data.result.company,
|
||||
name: zohoRes.data.result.name,
|
||||
email: zohoRes.data.result.email,
|
||||
@@ -194,6 +199,15 @@ const PgSignUp = (props) => {
|
||||
const newPassword = e.target.value;
|
||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
validatePasswords(newPassword, formData.confirmPassword);
|
||||
|
||||
// Check conditions separately
|
||||
setLengthValid(newPassword.length >= 8);
|
||||
setCaseDigitValid(
|
||||
/[a-z]/.test(newPassword) &&
|
||||
/[A-Z]/.test(newPassword) &&
|
||||
/\d/.test(newPassword)
|
||||
);
|
||||
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
|
||||
};
|
||||
const handleConFirmPassowordChange = (e) => {
|
||||
const newConfirmPassword = e.target.value;
|
||||
@@ -279,13 +293,6 @@ const PgSignUp = (props) => {
|
||||
""
|
||||
);
|
||||
localStorage.setItem("_user_role", _role);
|
||||
|
||||
if (element.enableCart) {
|
||||
localStorage.setItem("EnableCart", element.enableCart);
|
||||
props.setEnableCart(element.enableCart);
|
||||
} else {
|
||||
localStorage.removeItem("EnableCart");
|
||||
}
|
||||
// Get TenentID from Extendend Class
|
||||
localStorage.setItem(
|
||||
"extended_class",
|
||||
@@ -293,14 +300,12 @@ const PgSignUp = (props) => {
|
||||
);
|
||||
localStorage.setItem("userpointer", element.userpointer);
|
||||
|
||||
const extendedClass = Parse.Object.extend(
|
||||
element.extended_class
|
||||
);
|
||||
let query = new Parse.Query(extendedClass);
|
||||
query.equalTo("UserId", Parse.User.current());
|
||||
query.include("TenantId");
|
||||
await query.find().then(
|
||||
(results) => {
|
||||
const currentUser = Parse.User.current();
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: currentUser.get("email")
|
||||
}).then(
|
||||
(result) => {
|
||||
const results = [result];
|
||||
let tenentInfo = [];
|
||||
if (results) {
|
||||
let extendedInfo_stringify =
|
||||
@@ -415,7 +420,7 @@ const PgSignUp = (props) => {
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('err', err)
|
||||
console.log("err", err);
|
||||
setIsLoader(false);
|
||||
});
|
||||
}
|
||||
@@ -448,10 +453,10 @@ const PgSignUp = (props) => {
|
||||
) : (
|
||||
<form id="signup" className="pgsignup-content" onSubmit={handleSubmit}>
|
||||
<div className="pgsignup-container">
|
||||
<h1 className="text-4xl font-bold">Choose Password</h1>
|
||||
<h1 className="text-2xl md:text-3xl font-bold">Choose Password</h1>
|
||||
<hr className="hrt" />
|
||||
<label htmlFor="password">
|
||||
<b>Password</b>
|
||||
<b className="text-[13px]">Password</b>
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
@@ -464,7 +469,7 @@ const PgSignUp = (props) => {
|
||||
/>
|
||||
|
||||
<label htmlFor="confirmPassword">
|
||||
<b>Confirm Password</b>
|
||||
<b className="text-[13px]">Confirm Password</b>
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
@@ -494,6 +499,33 @@ const PgSignUp = (props) => {
|
||||
>
|
||||
{validationMessage}
|
||||
</div>
|
||||
{formData.password.length > 0 && (
|
||||
<div className="mt-1 text-[11px]">
|
||||
<p
|
||||
className={`${
|
||||
lengthValid ? "text-green-600" : "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{lengthValid ? "✓" : "✗"} Password should be 8 characters long
|
||||
</p>
|
||||
<p
|
||||
className={`${
|
||||
caseDigitValid ? "text-green-600" : "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{caseDigitValid ? "✓" : "✗"} Password should contain uppercase
|
||||
letter, lowercase letter, digit
|
||||
</p>
|
||||
<p
|
||||
className={`${
|
||||
specialCharValid ? "text-green-600" : "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{specialCharValid ? "✓" : "✗"} Password should contain special
|
||||
character
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="clearfix">
|
||||
<button type="submit" className="signupbtn">
|
||||
Submit
|
||||
|
||||
@@ -2,14 +2,14 @@ import React, { useState, useEffect } from "react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import checkmark from "../assets/images/checkmark.png";
|
||||
import plansArr from '../json/plansArr.json'
|
||||
import plansArr from "../json/plansArr.json";
|
||||
import Title from "../components/Title";
|
||||
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
|
||||
backgroundPosition: 'left',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: '16px 16px', // Adjust the size of the image
|
||||
backgroundPosition: "left",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: "16px 16px" // Adjust the size of the image
|
||||
};
|
||||
|
||||
const PlanSubscriptions = () => {
|
||||
@@ -28,7 +28,12 @@ const PlanSubscriptions = () => {
|
||||
: "";
|
||||
const phone =
|
||||
userDetails && userDetails.phone ? "&mobile=" + userDetails.phone : "";
|
||||
const details = "?" + name + email + company + phone;
|
||||
const details =
|
||||
"?shipping_country_code=US&billing_country_code=US&billing_state_code=CA&" +
|
||||
name +
|
||||
email +
|
||||
company +
|
||||
phone;
|
||||
useEffect(() => {
|
||||
if (localStorage.getItem("accesstoken")) {
|
||||
setIsLoader(false);
|
||||
@@ -41,7 +46,7 @@ const PlanSubscriptions = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title title={"Subscriptions"} />
|
||||
<Title title={"Subscriptions"} />
|
||||
{isLoader ? (
|
||||
<div
|
||||
style={{
|
||||
@@ -131,15 +136,18 @@ const PlanSubscriptions = () => {
|
||||
<p>{item.subtitle}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-[#002862] w-full text-white py-2 rounded">
|
||||
<NavLink
|
||||
to={item.url + details}
|
||||
className="rounded uppercase hover:no-underline hover:text-white"
|
||||
target="_self"
|
||||
>
|
||||
{item.btnText}
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<NavLink
|
||||
to={
|
||||
item.btnText === "Subscribe"
|
||||
? item.url + details
|
||||
: item.url
|
||||
}
|
||||
className="bg-[#002862] w-full text-white py-2 rounded uppercase hover:no-underline hover:text-white"
|
||||
target={item.target}
|
||||
>
|
||||
{item.btnText}
|
||||
</NavLink>
|
||||
</div>
|
||||
<hr className="w-full bg-gray-300 p-[.5px]" />
|
||||
<ul className="mx-1 p-3 text-left break-words text-sm list-none">
|
||||
|
||||
@@ -12,9 +12,11 @@ const Report = () => {
|
||||
const [isLoader, setIsLoader] = useState(true);
|
||||
const [reportName, setReportName] = useState("");
|
||||
const [actions, setActions] = useState([]);
|
||||
const [heading, setHeading] = useState([]);
|
||||
const [isNextRecord, setIsNextRecord] = useState(false);
|
||||
const [isMoreDocs, setIsMoreDocs] = useState(true);
|
||||
const abortController = new AbortController();
|
||||
const docPerPage = 10;
|
||||
|
||||
// below useEffect is call when id param change
|
||||
useEffect(() => {
|
||||
@@ -46,31 +48,26 @@ const Report = () => {
|
||||
const json = reportJson(id);
|
||||
if (json) {
|
||||
setActions(json.actions);
|
||||
setHeading(json.heading);
|
||||
setReportName(json.reportName);
|
||||
const { className, params, keys, orderBy } = json;
|
||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||
Parse.initialize(localStorage.getItem("AppID12"));
|
||||
const currentUser = Parse.User.current().id;
|
||||
const serverURL =
|
||||
localStorage.getItem("BaseUrl12") + "classes/" + className;
|
||||
|
||||
const strParams = JSON.stringify(params);
|
||||
const strKeys = keys.join();
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
sessiontoken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
try {
|
||||
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skipUserRecord}&limit=${limit}&include=AuditTrail.UserPtr`;
|
||||
const res = await axios.get(url, {
|
||||
const params = { reportId: id, skip: skipUserRecord, limit: limit };
|
||||
const url = `${localStorage.getItem("BaseUrl12")}/functions/getReport`;
|
||||
const res = await axios.post(url, params, {
|
||||
headers: headers,
|
||||
signal: abortController.signal // is used to cancel fetch query
|
||||
});
|
||||
if (id === "4Hhwbp482K") {
|
||||
const listData = res.data?.results.filter(
|
||||
(x) => x.Signers.length > 0
|
||||
);
|
||||
const listData = res.data?.result.filter((x) => x.Signers.length > 0);
|
||||
let arr = [];
|
||||
for (const obj of listData) {
|
||||
const isSigner = obj.Signers.some(
|
||||
@@ -92,7 +89,7 @@ const Report = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arr.length === 10) {
|
||||
if (arr.length === docPerPage) {
|
||||
setIsMoreDocs(true);
|
||||
} else {
|
||||
setIsMoreDocs(false);
|
||||
@@ -101,17 +98,16 @@ const Report = () => {
|
||||
prevRecord.length > 0 ? [...prevRecord, ...arr] : arr
|
||||
);
|
||||
} else {
|
||||
if (res.data.results.length === 10) {
|
||||
if (res.data.result.length === docPerPage) {
|
||||
setIsMoreDocs(true);
|
||||
console.log("here");
|
||||
} else {
|
||||
setIsMoreDocs(false);
|
||||
}
|
||||
setIsNextRecord(false);
|
||||
setList((prevRecord) =>
|
||||
prevRecord.length > 0
|
||||
? [...prevRecord, ...res.data.results]
|
||||
: res.data.results
|
||||
? [...prevRecord, ...res.data.result]
|
||||
: res.data.result
|
||||
);
|
||||
}
|
||||
setIsLoader(false);
|
||||
@@ -152,9 +148,12 @@ const Report = () => {
|
||||
<ReportTable
|
||||
ReportName={reportName}
|
||||
List={List}
|
||||
setList={setList}
|
||||
actions={actions}
|
||||
heading={heading}
|
||||
setIsNextRecord={setIsNextRecord}
|
||||
isMoreDocs={isMoreDocs}
|
||||
docPerPage={docPerPage}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||
|
||||
+181
-137
@@ -6,8 +6,10 @@ import Title from "../components/Title";
|
||||
import { fetchAppInfo, showTenantName } from "../redux/actions";
|
||||
import { useNavigate, NavLink } from "react-router-dom";
|
||||
import login_img from "../assets/images/login_img.svg";
|
||||
import { useWindowSize } from "../hook/useWindowSize";
|
||||
|
||||
const Signup = (props) => {
|
||||
const { width } = useWindowSize();
|
||||
const navigate = useNavigate();
|
||||
const [name, setName] = useState("");
|
||||
const [phone, setPhone] = useState("");
|
||||
@@ -18,122 +20,143 @@ const Signup = (props) => {
|
||||
const [company, setCompany] = useState("");
|
||||
const [jobTitle, setJobTitle] = useState("");
|
||||
const [state, setState] = useState({
|
||||
hideNav: "",
|
||||
loading: false,
|
||||
toastColor: "#5cb85c",
|
||||
toastDescription: ""
|
||||
});
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [lengthValid, setLengthValid] = useState(false);
|
||||
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||
|
||||
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
||||
const image = props.appInfo.applogo;
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
setState({ loading: true });
|
||||
const userDetails = {
|
||||
name: name,
|
||||
email: email,
|
||||
phone: phone,
|
||||
company: company,
|
||||
jobTitle: jobTitle
|
||||
};
|
||||
localStorage.setItem("userDetails", JSON.stringify(userDetails));
|
||||
try {
|
||||
event.preventDefault();
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
event.preventDefault();
|
||||
var user = new Parse.User();
|
||||
user.set("name", name);
|
||||
user.set("email", email);
|
||||
user.set("password", password);
|
||||
user.set("phone", phone);
|
||||
user.set("username", email);
|
||||
let res = user.save();
|
||||
res
|
||||
.then(async (r) => {
|
||||
if (r) {
|
||||
let roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
sessionToken:
|
||||
r.getSessionToken() || localStorage.getItem("accesstoken")
|
||||
};
|
||||
let body = {
|
||||
appName: props.appInfo.appname,
|
||||
roleName: props.appInfo.defaultRole,
|
||||
userId: r.id
|
||||
};
|
||||
await axios.post(roleurl, body, { headers: headers });
|
||||
const clearStorage = async () => {
|
||||
if (Parse.User.current()) {
|
||||
await Parse.User.logOut();
|
||||
}
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
let applogo = localStorage.getItem("appLogo");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let appversion = localStorage.getItem("appVersion");
|
||||
let appTitle = localStorage.getItem("appTitle");
|
||||
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||
let PageLanding = localStorage.getItem("PageLanding");
|
||||
let _appName = localStorage.getItem("_appName");
|
||||
let _app_objectId = localStorage.getItem("_app_objectId");
|
||||
let appName = localStorage.getItem("appName");
|
||||
let userSettings = localStorage.getItem("userSettings");
|
||||
|
||||
let roleData = props.appInfo.settings;
|
||||
if (roleData && roleData.length > 0) {
|
||||
roleData.forEach((rld) => {
|
||||
if (rld.role === props.appInfo.defaultRole) {
|
||||
const extCls = Parse.Object.extend(rld.extended_class);
|
||||
const newObj = new extCls();
|
||||
newObj.set("UserId", {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: r.id
|
||||
});
|
||||
newObj.set("UserRole", props.appInfo.defaultRole);
|
||||
newObj.set("Email", email);
|
||||
newObj.set("Name", name);
|
||||
newObj.set("Phone", phone);
|
||||
newObj.set("Company", company);
|
||||
newObj.set("JobTitle", jobTitle);
|
||||
newObj
|
||||
.save()
|
||||
.then((ex) => {
|
||||
if (ex) {
|
||||
handleNavigation(r.getSessionToken());
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
alert(err.message);
|
||||
setState({ loading: false });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(async (err) => {
|
||||
if (err.code === 202) {
|
||||
const userQuery = new Parse.Query("contracts_Users");
|
||||
userQuery.equalTo("Email", email);
|
||||
const res = await userQuery.first();
|
||||
// console.log("Res ", res);
|
||||
if (res) {
|
||||
alert("User already exists with this username!");
|
||||
setState({ loading: false });
|
||||
} else {
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let parseAppId = localStorage.getItem("AppID12");
|
||||
// console.log("state.email ", email);
|
||||
try {
|
||||
Parse.serverURL = baseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
await Parse.User.requestPasswordReset(email).then(
|
||||
async function (res1) {
|
||||
if (res1.data === undefined) {
|
||||
alert("Email has been sent to your mail!");
|
||||
}
|
||||
localStorage.clear();
|
||||
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
localStorage.setItem("appLogo", applogo);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("appversion", appversion);
|
||||
localStorage.setItem("appTitle", appTitle);
|
||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("_appName", _appName);
|
||||
localStorage.setItem("_app_objectId", _app_objectId);
|
||||
localStorage.setItem("appName", appName);
|
||||
localStorage.setItem("userSettings", userSettings);
|
||||
localStorage.setItem("baseUrl", baseUrl);
|
||||
localStorage.setItem("parseAppId", appid);
|
||||
};
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
if (lengthValid && caseDigitValid && specialCharValid) {
|
||||
clearStorage();
|
||||
setState({ loading: true });
|
||||
const userDetails = {
|
||||
name: name,
|
||||
email: email,
|
||||
phone: phone,
|
||||
company: company,
|
||||
jobTitle: jobTitle
|
||||
};
|
||||
localStorage.setItem("userDetails", JSON.stringify(userDetails));
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
event.preventDefault();
|
||||
var user = new Parse.User();
|
||||
user.set("name", name);
|
||||
user.set("email", email);
|
||||
user.set("password", password);
|
||||
user.set("phone", phone);
|
||||
user.set("username", email);
|
||||
let res = user.save();
|
||||
res
|
||||
.then(async (r) => {
|
||||
if (r) {
|
||||
let roleData = props.appInfo.settings;
|
||||
if (roleData && roleData.length > 0) {
|
||||
const params = {
|
||||
userDetails: {
|
||||
jobTitle: jobTitle,
|
||||
company: company,
|
||||
name: name,
|
||||
email: email,
|
||||
phone: phone,
|
||||
role: props.appInfo.defaultRole
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
};
|
||||
try {
|
||||
const usersignup = await Parse.Cloud.run(
|
||||
"usersignup",
|
||||
params
|
||||
);
|
||||
if (usersignup) {
|
||||
handleNavigation(r.getSessionToken());
|
||||
}
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
setState({ loading: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(async (err) => {
|
||||
if (err.code === 202) {
|
||||
const params = { email: email };
|
||||
const res = await Parse.Cloud.run("getUserDetails", params);
|
||||
// console.log("Res ", res);
|
||||
if (res) {
|
||||
alert("User already exists with this username!");
|
||||
setState({ loading: false });
|
||||
} else {
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let parseAppId = localStorage.getItem("AppID12");
|
||||
// console.log("state.email ", email);
|
||||
try {
|
||||
Parse.serverURL = baseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
await Parse.User.requestPasswordReset(email).then(
|
||||
async function (res1) {
|
||||
if (res1.data === undefined) {
|
||||
alert(
|
||||
"Verification mail has been sent to your E-mail!"
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
setState({ loading: false });
|
||||
}
|
||||
} else {
|
||||
alert(err.message);
|
||||
setState({ loading: false });
|
||||
}
|
||||
} else {
|
||||
alert(err.message);
|
||||
setState({ loading: false });
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("err ", error);
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("err ", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -208,13 +231,6 @@ const Signup = (props) => {
|
||||
""
|
||||
);
|
||||
localStorage.setItem("_user_role", _role);
|
||||
|
||||
if (element.enableCart) {
|
||||
localStorage.setItem("EnableCart", element.enableCart);
|
||||
props.setEnableCart(element.enableCart);
|
||||
} else {
|
||||
localStorage.removeItem("EnableCart");
|
||||
}
|
||||
// Get TenentID from Extendend Class
|
||||
localStorage.setItem(
|
||||
"extended_class",
|
||||
@@ -222,15 +238,12 @@ const Signup = (props) => {
|
||||
);
|
||||
localStorage.setItem("userpointer", element.userpointer);
|
||||
|
||||
const extendedClass = Parse.Object.extend(
|
||||
element.extended_class
|
||||
);
|
||||
let query = new Parse.Query(extendedClass);
|
||||
query.equalTo("UserId", Parse.User.current());
|
||||
query.include("TenantId");
|
||||
await query.find().then(
|
||||
(results) => {
|
||||
await Parse.Cloud.run("getUserDetails", {
|
||||
email: email
|
||||
}).then(
|
||||
(result) => {
|
||||
let tenentInfo = [];
|
||||
const results = [result];
|
||||
if (results) {
|
||||
let extendedInfo_stringify =
|
||||
JSON.stringify(results);
|
||||
@@ -318,7 +331,7 @@ const Signup = (props) => {
|
||||
);
|
||||
setState({ loading: false });
|
||||
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||
navigate("/subscription");
|
||||
navigate(`/subscription`, { replace: true });
|
||||
} else {
|
||||
alert("Registered user successfully");
|
||||
navigate(
|
||||
@@ -336,7 +349,7 @@ const Signup = (props) => {
|
||||
localStorage.setItem("pageType", element.pageType);
|
||||
setState({ loading: false });
|
||||
if (process.env.REACT_APP_ENABLE_SUBSCRIPTION) {
|
||||
navigate("/subscription");
|
||||
navigate(`/subscription`, { replace: true });
|
||||
} else {
|
||||
navigate(
|
||||
`/${element.pageType}/${element.pageId}`
|
||||
@@ -421,23 +434,26 @@ const Signup = (props) => {
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
window.addEventListener("resize", resize);
|
||||
props.fetchAppInfo(
|
||||
localStorage.getItem("domain"),
|
||||
localStorage.getItem("BaseUrl12"),
|
||||
localStorage.getItem("AppID12")
|
||||
);
|
||||
return () => {
|
||||
window.removeEventListener("resize", resize);
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const resize = () => {
|
||||
let currentHideNav = window.innerWidth <= 760;
|
||||
if (currentHideNav !== state.hideNav) {
|
||||
setState({ hideNav: currentHideNav });
|
||||
}
|
||||
const handlePasswordChange = (e) => {
|
||||
const newPassword = e.target.value;
|
||||
setPassword(newPassword);
|
||||
|
||||
// Check conditions separately
|
||||
setLengthValid(newPassword.length >= 8);
|
||||
setCaseDigitValid(
|
||||
/[a-z]/.test(newPassword) &&
|
||||
/[A-Z]/.test(newPassword) &&
|
||||
/\d/.test(newPassword)
|
||||
);
|
||||
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
|
||||
};
|
||||
return (
|
||||
<div className="bg-white">
|
||||
@@ -472,11 +488,7 @@ const Signup = (props) => {
|
||||
<div>
|
||||
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
||||
<div className="w-[250px] h-[66px] inline-block">
|
||||
{state.hideNav ? (
|
||||
<img src={image} width="100%" alt="" />
|
||||
) : (
|
||||
<img src={image} width="100%" alt="" />
|
||||
)}
|
||||
<img src={image} width="100%" alt="" />
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
||||
<div className="">
|
||||
@@ -555,7 +567,7 @@ const Signup = (props) => {
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
name="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
onChange={(e) => handlePasswordChange(e)}
|
||||
required
|
||||
/>
|
||||
<span
|
||||
@@ -571,6 +583,38 @@ const Signup = (props) => {
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
{password.length > 0 && (
|
||||
<div className="mt-1 text-[11px]">
|
||||
<p
|
||||
className={`${
|
||||
lengthValid ? "text-green-600" : "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{lengthValid ? "✓" : "✗"} Password should be 8
|
||||
characters long
|
||||
</p>
|
||||
<p
|
||||
className={`${
|
||||
caseDigitValid ? "text-green-600" : "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{caseDigitValid ? "✓" : "✗"} Password should contain
|
||||
uppercase letter, lowercase letter, digit
|
||||
</p>
|
||||
<p
|
||||
className={`${
|
||||
specialCharValid
|
||||
? "text-green-600"
|
||||
: "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{specialCharValid ? "✓" : "✗"} Password should
|
||||
contain special character
|
||||
</p>
|
||||
{/* </>
|
||||
)} */}
|
||||
</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">
|
||||
@@ -584,14 +628,14 @@ const Signup = (props) => {
|
||||
<NavLink
|
||||
className="rounded-sm cursor-pointer bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] w-full py-3 shadow uppercase"
|
||||
to="/"
|
||||
style={state.hideNav ? { textAlign: "center" } : {}}
|
||||
style={width < 768 ? { textAlign: "center" } : {}}
|
||||
>
|
||||
Login
|
||||
</NavLink>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{!state.hideNav && (
|
||||
{width >= 768 && (
|
||||
<div className="self-center">
|
||||
<div className="mx-auto md:w-[300px] lg:w-[400px] xl:w-[500px]">
|
||||
<img src={login_img} alt="bisec" width="100%" />
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SaveFileSize } from "../constant/saveFileSize";
|
||||
import dp from "../assets/images/dp.png";
|
||||
import Title from "../components/Title";
|
||||
import sanitizeFileName from "../primitives/sanitizeFileName";
|
||||
|
||||
import axios from "axios";
|
||||
function UserProfile() {
|
||||
const navigate = useNavigate();
|
||||
let UserProfile = JSON.parse(localStorage.getItem("UserInformation"));
|
||||
@@ -16,6 +16,8 @@ function UserProfile() {
|
||||
const [Phone, SetPhone] = useState(UserProfile && UserProfile.phone);
|
||||
const [Image, setImage] = useState(localStorage.getItem("profileImg"));
|
||||
const [isLoader, setIsLoader] = useState(false);
|
||||
const [percentage, setpercentage] = useState(0);
|
||||
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const handleSubmit = async (e) => {
|
||||
@@ -44,7 +46,7 @@ function UserProfile() {
|
||||
await updateExtUser({ Name: res.name, Phone: res.phone });
|
||||
alert("Profile updated successfully.");
|
||||
setEditMode(false);
|
||||
navigate("/");
|
||||
navigate("/dashboard/35KBoSgoAK");
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
@@ -64,18 +66,24 @@ function UserProfile() {
|
||||
const extClass = localStorage.getItem("extended_class");
|
||||
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
const ExtUserId = extData[0].objectId;
|
||||
// console.log("extData ", extData);
|
||||
// console.log("UserId ", ExtUserId);
|
||||
const body = { Phone: obj.Phone, Name: obj.Name };
|
||||
await axios.put(
|
||||
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
|
||||
body,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
);
|
||||
const res = await Parse.Cloud.run("getUserDetails", {
|
||||
email: extData[0].Email
|
||||
});
|
||||
|
||||
const extQuery = new Parse.Query(extClass);
|
||||
const update = await extQuery.get(ExtUserId);
|
||||
// console.log("update ", update);
|
||||
|
||||
update.set("Phone", obj.Phone);
|
||||
update.set("Name", obj.Name);
|
||||
const updateRes = await update.save();
|
||||
|
||||
const json = JSON.parse(JSON.stringify([updateRes]));
|
||||
const json = JSON.parse(JSON.stringify([res]));
|
||||
const extRes = JSON.stringify(json);
|
||||
|
||||
localStorage.setItem("Extand_Class", extRes);
|
||||
@@ -96,7 +104,15 @@ function UserProfile() {
|
||||
const parseFile = new Parse.File(name, pdfFile);
|
||||
|
||||
try {
|
||||
const response = await parseFile.save();
|
||||
const response = await parseFile.save({
|
||||
progress: (progressValue, loaded, total, { type }) => {
|
||||
if (type === "upload" && progressValue !== null) {
|
||||
const percentCompleted = Math.round((loaded * 100) / total);
|
||||
// console.log("percentCompleted ", percentCompleted);
|
||||
setpercentage(percentCompleted);
|
||||
}
|
||||
}
|
||||
});
|
||||
// // The response object will contain information about the uploaded file
|
||||
// console.log("File uploaded:", response);
|
||||
|
||||
@@ -105,6 +121,7 @@ function UserProfile() {
|
||||
if (response.url()) {
|
||||
setImage(response.url());
|
||||
localStorage.setItem("profileImg", response.url());
|
||||
setpercentage(0);
|
||||
SaveFileSize(size, response.url());
|
||||
return response.url();
|
||||
}
|
||||
@@ -154,14 +171,25 @@ function UserProfile() {
|
||||
<input
|
||||
type="file"
|
||||
className="max-w-[270px] text-sm py-1 px-2 mt-4 border-[1px] border-[#15b4e9] text-black rounded"
|
||||
accept="image/png, image/gif, image/jpeg"
|
||||
onChange={(e) => {
|
||||
let files = e.target.files;
|
||||
fileUpload(files[0]);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{percentage !== 0 && (
|
||||
<div className="flex items-center gap-x-2">
|
||||
<div className="h-2 rounded-full w-[200px] md:w-[400px] bg-gray-200">
|
||||
<div
|
||||
className="h-2 rounded-full bg-blue-500"
|
||||
style={{ width: `${percentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<span className="text-black text-sm">{percentage}%</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-base font-semibold pt-4">
|
||||
{" "}
|
||||
{localStorage.getItem("_user_role")}
|
||||
</div>
|
||||
</div>
|
||||
@@ -214,26 +242,11 @@ function UserProfile() {
|
||||
</li>
|
||||
</ul>
|
||||
<div className="flex justify-center pb-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
if (editmode) {
|
||||
setEditMode(false);
|
||||
} else {
|
||||
navigate("/changepassword");
|
||||
}
|
||||
}}
|
||||
className={`rounded shadow text-white bg-[#3598dc] mr-4 ${
|
||||
editmode ? "px-4 py-2 " : "p-2"
|
||||
}`}
|
||||
>
|
||||
{editmode ? "Cancel" : "Change Password"}
|
||||
</button>
|
||||
{editmode ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleSubmit}
|
||||
className="rounded bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] px-4 py-2"
|
||||
className="rounded bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] px-4 py-2 mr-4"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
@@ -243,11 +256,26 @@ function UserProfile() {
|
||||
onClick={() => {
|
||||
setEditMode(true);
|
||||
}}
|
||||
className="rounded shadow text-white bg-[#e7505a] px-4 py-2"
|
||||
className="rounded shadow text-white bg-[#e7505a] px-4 py-2 mr-4"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
if (editmode) {
|
||||
setEditMode(false);
|
||||
} else {
|
||||
navigate("/changepassword");
|
||||
}
|
||||
}}
|
||||
className={`rounded shadow text-white bg-[#3598dc] ${
|
||||
editmode ? "px-4 py-2 " : "p-2"
|
||||
}`}
|
||||
>
|
||||
{editmode ? "Cancel" : "Change Password"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/* Full-width input fields */
|
||||
.inputt {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin: 5px 0 22px 0;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
/* margin: 5px 0 14px 0; */
|
||||
display: inline-block;
|
||||
border: none;
|
||||
background: #f1f1f1;
|
||||
color: black;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Add a background color when the inputs get focus */
|
||||
@@ -18,11 +20,12 @@
|
||||
|
||||
.confirmInputt {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin: 5px 0 1px 0;
|
||||
padding: 8px;
|
||||
/* margin: 5px 0 14px 0; */
|
||||
display: inline-block;
|
||||
background: #f1f1f1;
|
||||
color: black;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.inputt::placeholder,
|
||||
@@ -42,11 +45,10 @@
|
||||
.signupbtn {
|
||||
background-color: #15b4e9;
|
||||
color: white;
|
||||
padding: 14px 20px;
|
||||
padding: 12px 12px;
|
||||
margin: 8px 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
opacity: 0.9;
|
||||
float: left;
|
||||
width: 50%;
|
||||
@@ -87,7 +89,7 @@
|
||||
margin: 5% auto 15% auto;
|
||||
/* 5% from the top, 15% from the bottom and centered */
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
width: 50%;
|
||||
/* Could be more or less, depending on screen size */
|
||||
}
|
||||
|
||||
@@ -111,8 +113,26 @@
|
||||
}
|
||||
|
||||
/* Change styles for cancel button and signup button on extra small screens */
|
||||
@media screen and (max-width: 300px) {
|
||||
@media screen and (max-width: 768px) {
|
||||
|
||||
/* pgsignup Content/Box */
|
||||
.pgsignup-content {
|
||||
background-color: #fefefe;
|
||||
margin: 5% auto 15% auto;
|
||||
/* 5% from the top, 15% from the bottom and centered */
|
||||
border: 1px solid #888;
|
||||
width: 90%;
|
||||
/* Could be more or less, depending on screen size */
|
||||
}
|
||||
|
||||
.signupbtn {
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Style the horizontal ruler */
|
||||
.hrt {
|
||||
border: 1px solid #f1f1f1;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
.alertBox {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 13px;
|
||||
animation: inAnimation 2s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes inAnimation {
|
||||
0% {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
25% {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
75% {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,10 @@ import sendMailOTPv1 from './parsefunction/SendMailOTPv1.js';
|
||||
import SendMailv1 from './parsefunction/SendMailv1.js';
|
||||
import AuthLoginAsMail from './parsefunction/AuthLoginAsMail.js';
|
||||
import getUserId from './parsefunction/getUserId.js';
|
||||
import getUserDetails from './parsefunction/getUserDetails.js';
|
||||
import getDocument from './parsefunction/getDocument.js';
|
||||
import getDrive from './parsefunction/getDrive.js';
|
||||
import getReport from './parsefunction/getReport.js';
|
||||
|
||||
Parse.Cloud.define('AddUserToRole', addUserToGroups);
|
||||
Parse.Cloud.define('UserGroups', getUserGroups);
|
||||
@@ -29,3 +33,7 @@ Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1);
|
||||
Parse.Cloud.define('sendmail', SendMailv1);
|
||||
Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
|
||||
Parse.Cloud.define('getUserId', getUserId);
|
||||
Parse.Cloud.define('getUserDetails', getUserDetails);
|
||||
Parse.Cloud.define('getDocument', getDocument);
|
||||
Parse.Cloud.define('getDrive', getDrive)
|
||||
Parse.Cloud.define('getReport', getReport)
|
||||
@@ -16,6 +16,7 @@ async function ContactbookAftersave(request) {
|
||||
acl.setWriteAccess(object.get('UserId'), true);
|
||||
|
||||
object.setACL(acl);
|
||||
object.set('IsDeleted', false)
|
||||
// Continue saving the object
|
||||
return object.save(null, { useMasterKey: true });
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ async function SendMailv1(request) {
|
||||
const recipient = request.params.email;
|
||||
const otp = request.params.otp;
|
||||
const res = await Parse.Cloud.sendEmail({
|
||||
from: 'Test user' + ' <' + process.env.MAILGUN_SENDER + '>',
|
||||
from: 'Test user' + ' <' + process.env.SMTP_ENABLE ? process.env.SMTP_USER_EMAIL : process.env.MAILGUN_SENDER + '>',
|
||||
recipient: recipient,
|
||||
subject: 'Your OpenSign™ OTP',
|
||||
text: 'This email is a test.',
|
||||
|
||||
@@ -46,15 +46,20 @@ export default async function ZohoDetails(request) {
|
||||
(userData.data.data.subscription.customer &&
|
||||
userData.data.data.subscription.customer.company_name) ||
|
||||
'';
|
||||
const jobTitle =
|
||||
(userData.data.data.subscription.customer &&
|
||||
userData.data.data.subscription.customer.cd_job_title) ||
|
||||
'';
|
||||
const resData = {
|
||||
phone: userData.data.data.subscription.contactpersons[0].mobile,
|
||||
name: first_name + ' ' + last_name,
|
||||
email: userData.data.data.subscription.contactpersons[0].email,
|
||||
nextBillingDate: userData.data.expiring_time,
|
||||
nextBillingDate: userData.data.data.subscription.next_billing_at,
|
||||
company: company_name,
|
||||
plan: userData.data.data.subscription.plan,
|
||||
customer_id: userData.data.data.subscription.customer_id,
|
||||
subscription_id: userData.data.data.subscription.subscription_id,
|
||||
jobTitle: jobTitle,
|
||||
};
|
||||
return resData;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import axios from 'axios';
|
||||
|
||||
export default async function getDocument(request) {
|
||||
const serverUrl = process.env.SERVER_URL;
|
||||
const docId = request.params.docId;
|
||||
|
||||
try {
|
||||
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||
headers: {
|
||||
'X-Parse-Application-Id': process.env.APP_ID,
|
||||
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||
},
|
||||
});
|
||||
const userId = userRes.data && userRes.data.objectId;
|
||||
if (docId && userId) {
|
||||
try {
|
||||
const query = new Parse.Query('contracts_Document');
|
||||
query.equalTo('objectId', docId);
|
||||
query.include('ExtUserPtr');
|
||||
query.include('CreatedBy');
|
||||
query.include('Signers');
|
||||
query.include('AuditTrail.UserPtr');
|
||||
query.include('Placeholders');
|
||||
const res = await query.first({ useMasterKey: true });
|
||||
if (res) {
|
||||
const acl = res.getACL();
|
||||
if (acl && acl.getReadAccess(userId)) {
|
||||
return res;
|
||||
} else {
|
||||
return { error: "You don't have access of this document!" };
|
||||
}
|
||||
} else {
|
||||
return { error: "You don't have access of this document!" };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
return { error: 'Please pass required parameters!' };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err');
|
||||
if (err.code == 209) {
|
||||
return { error: 'Invalid session token' };
|
||||
} else {
|
||||
return { error: "You don't have access of this document!" };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import axios from 'axios';
|
||||
export default async function getDrive(request) {
|
||||
const serverUrl = process.env.SERVER_URL;
|
||||
const appId = process.env.APP_ID;
|
||||
|
||||
const classUrl = serverUrl + '/classes/contracts_Document';
|
||||
const docId = request.params.docId;
|
||||
try {
|
||||
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||
headers: {
|
||||
'X-Parse-Application-Id': appId,
|
||||
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||
},
|
||||
});
|
||||
const userId = userRes.data && userRes.data.objectId;
|
||||
if (userId) {
|
||||
let url;
|
||||
if (docId) {
|
||||
url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&include=ExtUserPtr,Signers,Folder`;
|
||||
} else {
|
||||
url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&include=ExtUserPtr,Signers`;
|
||||
}
|
||||
try {
|
||||
const res = await axios.get(url, {
|
||||
headers: {
|
||||
'X-Parse-Application-Id': appId,
|
||||
'X-Parse-Master-key': process.env.MASTER_KEY,
|
||||
},
|
||||
});
|
||||
// console.log('res.data.results ', res.data.results);
|
||||
if (res.data && res.data.results) {
|
||||
return res.data.results;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
return { error: "You don't have access to drive" };
|
||||
}
|
||||
} else {
|
||||
return { error: 'Please provide required parameter!' };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
if (err.code == 209) {
|
||||
return { error: 'Invalid session token' };
|
||||
} else {
|
||||
return { error: "You don't have access!" };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import reportJson from './reportsJson.js';
|
||||
import axios from 'axios';
|
||||
|
||||
export default async function getReport(request) {
|
||||
const reportId = request.params.reportId;
|
||||
const limit = request.params.limit;
|
||||
const skip = request.params.skip;
|
||||
|
||||
const serverUrl = process.env.SERVER_URL;
|
||||
const appId = process.env.APP_ID;
|
||||
|
||||
try {
|
||||
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||
headers: {
|
||||
'X-Parse-Application-Id': appId,
|
||||
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||
},
|
||||
});
|
||||
const userId = userRes.data && userRes.data.objectId;
|
||||
if (userId) {
|
||||
const json = reportId && reportJson(reportId, userId);
|
||||
const clsName = reportId === '5KhaPr482K' ? 'contracts_Contactbook' : 'contracts_Document';
|
||||
if (json) {
|
||||
const { params, keys } = json;
|
||||
const orderBy = '-updatedAt';
|
||||
const strParams = JSON.stringify(params);
|
||||
const strKeys = keys.join();
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Parse-Application-Id': appId,
|
||||
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
||||
};
|
||||
const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr`;
|
||||
const res = await axios.get(url, { headers: headers });
|
||||
if (res.data && res.data.results) {
|
||||
return res.data.results;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
return { error: 'Report is not available!' };
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
if (err.code == 209) {
|
||||
return { error: 'Invalid session token' };
|
||||
} else {
|
||||
return { error: "You don't have access!" };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
async function getUserDetails(request) {
|
||||
try {
|
||||
const userQuery = new Parse.Query('contracts_Users');
|
||||
userQuery.equalTo('Email', request.params.email);
|
||||
userQuery.include('TenantId');
|
||||
userQuery.include('UserId')
|
||||
const res = await userQuery.first({ useMasterKey: true });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.log('Err ', err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
export default getUserDetails;
|
||||
+4
-4
@@ -79,7 +79,7 @@ async function sendCompletedMail(e) {
|
||||
url: a,
|
||||
from: 'OpenSign™',
|
||||
recipient: e.receiver,
|
||||
subject: `Document ${s} has beeen signed by all parties`,
|
||||
subject: `Document ${s} has been signed by all parties`,
|
||||
pdfName: s,
|
||||
html:
|
||||
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=https://qikinnovation.ams3.digitaloceanspaces.com/logo.png height='50' style='padding:20px'/> </div><div style='padding:2px;font-family:system-ui; background-color: #47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',> Document sign successfully</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>All parties have successfully signed the document" +
|
||||
@@ -105,7 +105,7 @@ async function PDF(s, r) {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Parse-Application-Id': APPID,
|
||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
||||
'X-Parse-Master-Key': masterKEY,
|
||||
},
|
||||
}),
|
||||
d = await axios.get(serverUrl + '/users/me', {
|
||||
@@ -132,7 +132,7 @@ async function PDF(s, r) {
|
||||
: ((a = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, {
|
||||
headers: {
|
||||
'X-Parse-Application-Id': APPID,
|
||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
||||
'X-Parse-Master-Key': masterKEY,
|
||||
},
|
||||
})),
|
||||
'contracts_Users')
|
||||
@@ -142,7 +142,7 @@ async function PDF(s, r) {
|
||||
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
|
||||
headers: {
|
||||
'X-Parse-Application-Id': APPID,
|
||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
||||
'X-Parse-Master-Key': masterKEY,
|
||||
},
|
||||
})).data && 0 < c.data.results.length
|
||||
? ((a = c), 'contracts_Users')
|
||||
|
||||
+22
-22
@@ -1,28 +1,28 @@
|
||||
import{DEFAULT_BYTE_RANGE_PLACEHOLDER,DEFAULT_SIGNATURE_LENGTH,SUBFILTER_ADOBE_PKCS7_DETACHED}from"./const.min.js";import PDFKitReferenceMock from"./PDFKitReferenceMock.min.js";import PNG from"png-js";import zlib from"zlib";import fs from"node:fs";const specialCharacters=["á","Á","é","É","í","Í","ó","Ó","ö","Ö","ő","Ő","ú","Ú","ű","Ű"],MARKERS=[65472,65473,65474,65475,65477,65478,65479,65480,65481,65482,65483,65484,65485,65486,65487],COLOR_SPACE_MAP={1:"DeviceGray",3:"DeviceRGB",4:"DeviceCMYK"};function getImage(e,t){let n;if(255===e[0]&&216===e[1])n=getJpgImage(t,e);else{if(137!==e[0]||"PNG"!==e.toString("ascii",1,4))throw new Error("Unknown image format.");n=getPngImage(t,e)}return n}function getAnnotationApparance(e,t,n){return e.ref({CropBox:[0,0,197,70],Type:"XObject",FormType:1,BBox:[0,0,197,70],Resources:`<</XObject <<
|
||||
import{DEFAULT_BYTE_RANGE_PLACEHOLDER,DEFAULT_SIGNATURE_LENGTH,SUBFILTER_ADOBE_PKCS7_DETACHED}from"./const.min.js";import PDFKitReferenceMock from"./PDFKitReferenceMock.min.js";import PNG from"png-js";import zlib from"zlib";const specialCharacters=["á","Á","é","É","í","Í","ó","Ó","ö","Ö","ő","Ő","ú","Ú","ű","Ű"],MARKERS=[65472,65473,65474,65475,65477,65478,65479,65480,65481,65482,65483,65484,65485,65486,65487],COLOR_SPACE_MAP={1:"DeviceGray",3:"DeviceRGB",4:"DeviceCMYK"};function getImage(e,t){let n;if(255===e[0]&&216===e[1])n=getJpgImage(t,e);else{if(137!==e[0]||"PNG"!==e.toString("ascii",1,4))throw new Error("Unknown image format.");n=getPngImage(t,e)}return n}function getAnnotationApparance(e,t,n){return e.ref({CropBox:[0,10,200,60],Type:"XObject",FormType:1,BBox:[0,10,200,60],Resources:`<</XObject <<
|
||||
/Img${t.index} ${t.index} 0 R
|
||||
>>
|
||||
/Font <<
|
||||
/f1 ${n.index} 0 R
|
||||
>>
|
||||
>>`,MediaBox:[0,0,197,70],Subtype:"Form"},null,getStream(t.index))}const getStream=e=>getConvertedText(`
|
||||
1.0 1.0 1.0 rg
|
||||
0.0 0.0 0.0 RG
|
||||
q
|
||||
q
|
||||
200 0 0 50 0 10 cm
|
||||
/Img${e} Do
|
||||
Q
|
||||
0 0 0 rg
|
||||
BT
|
||||
0 Tr
|
||||
/f1 10.0 Tf
|
||||
1.4 0 0 1 20 45.97412 Tm
|
||||
ET
|
||||
BT
|
||||
0 Tr
|
||||
/f1 10.0 Tf
|
||||
1.4 0 0 1 20 33.56006 Tm
|
||||
ET
|
||||
Q`),getFont=(e,t)=>e.ref({Type:"Font",BaseFont:t,Encoding:"WinAnsiEncoding",Subtype:"Type1"}),getJpgImage=(e,t)=>{if(65496!==t.readUInt16BE(0))throw"SOI not found in JPEG";let n=2,a;for(;n<t.length&&(a=t.readUInt16BE(n),n+=2,!MARKERS.includes(a));)n+=t.readUInt16BE(n);if(!MARKERS.includes(a))throw"Invalid JPEG.";n+=2;var r=t[n++],o=t.readUInt16BE(n),i=(n+=2,t.readUInt16BE(n)),l=(n+=2,t[n++]),l=COLOR_SPACE_MAP[l],r={Type:"XObject",Subtype:"Image",BitsPerComponent:r,Width:i,Height:o,ColorSpace:l,Filter:"DCTDecode"},i=("DeviceCMYK"===l&&(r.Decode=[1,0,1,0,1,0,1,0]),e.ref(r,null,t));return i},getPngImage=(e,t)=>{var t=new PNG(t),n=t.hasAlphaChannel,a={Type:"XObject",Subtype:"Image",BitsPerComponent:n?8:t.bits,Width:t.width,Height:t.height,Filter:"FlateDecode"};if(n||(r=e.ref({Predictor:15,Colors:t.colors,BitsPerComponent:t.bits,Columns:t.width}),a.DecodeParms=r),0===t.palette.length?a.ColorSpace=t.colorSpace:(r=e.ref({stream:new Buffer(t.palette)}),a.ColorSpace=["Indexed","DeviceRGB",t.palette.length/3-1,r]),null!=t.transparency.grayscale){var r=t.transparency.grayscale;a.Mask=[r,r]}else if(t.transparency.rgb){var o,r=t.transparency["rgb"],i=[];for(o of r)i.push(o,o);a.Mask=i}else t.transparency.indexed?loadIndexedAlphaChannel(t):n&&(splitAlphaChannel(t),r=getSmask(e,t),a.Mask=r);return e.ref(a,null,t.imgData)},loadIndexedAlphaChannel=e=>{const o=e.transparency.indexed;return e.decodePixels(n=>{var a=new Buffer(e.width*e.height);let r=0;for(let e=0,t=n.length;e<t;e++)a[r++]=o[n[e]];e.alphaChannel=zlib.deflateSync(a)})},splitAlphaChannel=d=>{d.decodePixels(t=>{let e,n;var a=d.colors,r=d.width*d.height,o=new Buffer(r*a),i=new Buffer(r);let l=n=e=0;for(var g=t.length,c=16===d.bits?1:0;l<g;){for(let e=0;e<a;e++)o[n++]=t[l++],l+=c;i[e++]=t[l++],l+=c}d.imgData=zlib.deflateSync(o),d.alphaChannel=zlib.deflateSync(i)})},getSmask=(e,t)=>{let n;return console.log("image.hasAlphaChannel ",t.hasAlphaChannel),t.hasAlphaChannel&&(console.log("image.alphaChannel ",t.alphaChannel),n=e.ref({Type:"XObject",Subtype:"Image",Height:t.height,Width:t.width,BitsPerComponent:8,Filter:"FlateDecode",ColorSpace:"DeviceGray",Decode:[0,1],stream:t.alphaChannel})),n},getConvertedText=e=>e.split("").map(e=>specialCharacters.includes(e)?getOctalCodeFromCharacter(e):e).join(""),getOctalCodeFromCharacter=e=>"\\"+e.charCodeAt(0).toString(8),pdfkitAddPlaceholder=({pdf:e,pdfBuffer:a,reason:r,contactInfo:t="emailfromp1289@gmail.com",name:n="Name from p12",location:o="Location from p12",signatureLength:i=DEFAULT_SIGNATURE_LENGTH,byteRangePlaceholder:l=DEFAULT_BYTE_RANGE_PLACEHOLDER,subFilter:g=SUBFILTER_ADOBE_PKCS7_DETACHED,sign:c})=>{var d=getFont(e,"Helvetica"),s=getFont(e,"ZapfDingbats"),f=getFont(e,"Helvetica"),p=c.Base64,p=getAnnotationApparance(e,getImage(Buffer.from(p,"base64"),e),f),f=e.ref({Type:"Sig",Filter:"Adobe.PPKLite",SubFilter:g,ByteRange:[0,l,l,l],Contents:Buffer.from(String.fromCharCode(0).repeat(i)),Reason:new String(r),M:new Date,ContactInfo:new String(t),Name:new String(n),Location:new String(o)}),h=a.lastIndexOf("/Type /AcroForm"),g=-1!==h;let m=[],C;if(g){let e=h;var S=h-10;let t="",n=11;for(n;n<22;n+=1){var A=a.slice(h-n,S).toString();if("\n"===A[0])break;t=A,e=h-n}l=a.slice(e),i=l.slice(0,l.indexOf("endobj")).toString(),r=(C=parseInt(t),i.slice(i.indexOf("/Fields [")+9,i.indexOf("]")));m=r.split(" ").filter((e,t)=>t%3==0).map(e=>new PDFKitReferenceMock(e))}m.length;t=c.Left,n=c.Bottom,o=t+c.Width,l=n+c.Height,i=e.ref({Type:"Annot",Subtype:"Widget",FT:"Sig",Rect:[t,n,o,l],V:f,T:new String("Signature"+(m.length+1)),F:4,P:e.page.dictionary,AP:`<</N ${p.index} 0 R>>`,DA:new String("/Helvetica 0 Tf 0 g")});e.page.dictionary.data.Annots=[i];let T;return T=g?e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i],DR:`<</Font
|
||||
>>`,MediaBox:[0,10,200,60],Subtype:"Form"},null,getStream(t.index))}const getStream=e=>getConvertedText(`
|
||||
1.0 1.0 1.0 rg
|
||||
0.0 0.0 0.0 RG
|
||||
q
|
||||
q
|
||||
200 0 0 50 0 10 cm
|
||||
/Img${e} Do
|
||||
Q
|
||||
0 0 0 rg
|
||||
BT
|
||||
0 Tr
|
||||
/f1 10.0 Tf
|
||||
1.4 0 0 1 20 45.97412 Tm
|
||||
ET
|
||||
BT
|
||||
0 Tr
|
||||
/f1 10.0 Tf
|
||||
1.4 0 0 1 20 33.56006 Tm
|
||||
ET
|
||||
Q`),getFont=(e,t)=>e.ref({Type:"Font",BaseFont:t,Encoding:"WinAnsiEncoding",Subtype:"Type1"}),getJpgImage=(e,t)=>{if(65496!==t.readUInt16BE(0))throw"SOI not found in JPEG";let n=2,a;for(;n<t.length&&(a=t.readUInt16BE(n),n+=2,!MARKERS.includes(a));)n+=t.readUInt16BE(n);if(!MARKERS.includes(a))throw"Invalid JPEG.";n+=2;var r=t[n++],o=t.readUInt16BE(n),i=(n+=2,t.readUInt16BE(n)),l=(n+=2,t[n++]),l=COLOR_SPACE_MAP[l],r={Type:"XObject",Subtype:"Image",BitsPerComponent:r,Width:i,Height:o,ColorSpace:l,Filter:"DCTDecode"},i=("DeviceCMYK"===l&&(r.Decode=[1,0,1,0,1,0,1,0]),e.ref(r,null,t));return i},getPngImage=(e,t)=>{var t=new PNG(t),n=t.hasAlphaChannel,a={Type:"XObject",Subtype:"Image",BitsPerComponent:n?8:t.bits,Width:t.width,Height:t.height,Filter:"FlateDecode"};if(n||(r=e.ref({Predictor:15,Colors:t.colors,BitsPerComponent:t.bits,Columns:t.width}),a.DecodeParms=r),0===t.palette.length?a.ColorSpace=t.colorSpace:(r=e.ref({stream:new Buffer(t.palette)}),a.ColorSpace=["Indexed","DeviceRGB",t.palette.length/3-1,r]),null!=t.transparency.grayscale){var r=t.transparency.grayscale;a.Mask=[r,r]}else if(t.transparency.rgb){var o,r=t.transparency["rgb"],i=[];for(o of r)i.push(o,o);a.Mask=i}else t.transparency.indexed?loadIndexedAlphaChannel(t):n&&(splitAlphaChannel(t),r=getSmask(e,t),a.Mask=r);return e.ref(a,null,t.imgData)},loadIndexedAlphaChannel=e=>{const o=e.transparency.indexed;return e.decodePixels(n=>{var a=new Buffer(e.width*e.height);let r=0;for(let e=0,t=n.length;e<t;e++)a[r++]=o[n[e]];e.alphaChannel=zlib.deflateSync(a)})},splitAlphaChannel=d=>{d.decodePixels(t=>{let e,n;var a=d.colors,r=d.width*d.height,o=new Buffer(r*a),i=new Buffer(r);let l=n=e=0;for(var c=t.length,g=16===d.bits?1:0;l<c;){for(let e=0;e<a;e++)o[n++]=t[l++],l+=g;i[e++]=t[l++],l+=g}d.imgData=zlib.deflateSync(o),d.alphaChannel=zlib.deflateSync(i)})},getSmask=(e,t)=>{let n;return console.log("image.hasAlphaChannel ",t.hasAlphaChannel),t.hasAlphaChannel&&(console.log("image.alphaChannel ",t.alphaChannel),n=e.ref({Type:"XObject",Subtype:"Image",Height:t.height,Width:t.width,BitsPerComponent:8,Filter:"FlateDecode",ColorSpace:"DeviceGray",Decode:[0,1],stream:t.alphaChannel})),n},getConvertedText=e=>e.split("").map(e=>specialCharacters.includes(e)?getOctalCodeFromCharacter(e):e).join(""),getOctalCodeFromCharacter=e=>"\\"+e.charCodeAt(0).toString(8),pdfkitAddPlaceholder=({pdf:e,pdfBuffer:a,reason:r,contactInfo:t="emailfromp1289@gmail.com",name:n="Name from p12",location:o="Location from p12",signatureLength:i=DEFAULT_SIGNATURE_LENGTH,byteRangePlaceholder:l=DEFAULT_BYTE_RANGE_PLACEHOLDER,subFilter:c=SUBFILTER_ADOBE_PKCS7_DETACHED,sign:g})=>{var d=getFont(e,"Helvetica"),s=getFont(e,"ZapfDingbats"),p=getFont(e,"Helvetica"),f=g.Base64,f=getAnnotationApparance(e,getImage(Buffer.from(f,"base64"),e),p,g),p=e.ref({Type:"Sig",Filter:"Adobe.PPKLite",SubFilter:c,ByteRange:[0,l,l,l],Contents:Buffer.from(String.fromCharCode(0).repeat(i)),Reason:new String(r),M:new Date,ContactInfo:new String(t),Name:new String(n),Location:new String(o)}),h=a.lastIndexOf("/Type /AcroForm"),c=-1!==h;let m=[],C;if(c){let e=h;var S=h-10;let t="",n=11;for(n;n<22;n+=1){var A=a.slice(h-n,S).toString();if("\n"===A[0])break;t=A,e=h-n}l=a.slice(e),i=l.slice(0,l.indexOf("endobj")).toString(),r=(C=parseInt(t),i.slice(i.indexOf("/Fields [")+9,i.indexOf("]")));m=r.split(" ").filter((e,t)=>t%3==0).map(e=>new PDFKitReferenceMock(e))}t=g.Left,n=g.Bottom,o=t+g.Width,l=n+g.Height,i=e.ref({Type:"Annot",Subtype:"Widget",FT:"Sig",Rect:[t,n,o,l],V:p,T:new String("Signature"+(m.length+1)),F:4,P:e.page.dictionary,AP:`<</N ${f.index} 0 R>>`,DA:new String("/Helvetica 0 Tf 0 g")});e.page.dictionary.data.Annots=[i];let T;return T=c?e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i],DR:`<</Font
|
||||
<</Helvetica ${d.index} 0 R/ZapfDingbats ${s.index} 0 R>>
|
||||
>>`},C):e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i]}),{signature:f,form:e._root.data.AcroForm=T,widget:i}};export default pdfkitAddPlaceholder;
|
||||
>>`},C):e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i]}),{signature:p,form:e._root.data.AcroForm=T,widget:i}};export default pdfkitAddPlaceholder;
|
||||
@@ -0,0 +1,218 @@
|
||||
export default function reportJson(id, userId) {
|
||||
const currentUserId = userId;
|
||||
|
||||
switch (id) {
|
||||
// draft documents report
|
||||
case 'ByHuevtCFY':
|
||||
return {
|
||||
reportName: 'Draft Documents',
|
||||
params: {
|
||||
Type: null,
|
||||
$or: [
|
||||
{ Signers: null, SignedUrl: null },
|
||||
{ Signers: { $exists: true }, Placeholders: null },
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
},
|
||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||
};
|
||||
// Need your sign report
|
||||
case '4Hhwbp482K':
|
||||
return {
|
||||
reportName: 'Need your sign',
|
||||
params: {
|
||||
Type: { $ne: 'Folder' },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
ExpiryDate: {
|
||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||
},
|
||||
Placeholders: { $ne: null },
|
||||
},
|
||||
keys: [
|
||||
'Name',
|
||||
'Note',
|
||||
'Folder.Name',
|
||||
'URL',
|
||||
'ExtUserPtr.Name',
|
||||
'Signers.Name',
|
||||
'Signers.UserId',
|
||||
'AuditTrail',
|
||||
],
|
||||
};
|
||||
// In progess report
|
||||
case '1MwEuxLEkF':
|
||||
return {
|
||||
reportName: 'In-progress documents',
|
||||
params: {
|
||||
Type: { $ne: 'Folder' },
|
||||
Signers: { $ne: null },
|
||||
Placeholders: { $ne: null },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
ExpiryDate: {
|
||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||
},
|
||||
},
|
||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||
};
|
||||
// completed documents report
|
||||
case 'kQUoW4hUXz':
|
||||
return {
|
||||
reportName: 'Completed Documents',
|
||||
params: {
|
||||
Type: null,
|
||||
IsCompleted: true,
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
IsDeclined: { $ne: true },
|
||||
},
|
||||
keys: [
|
||||
'Name',
|
||||
'Note',
|
||||
'Folder.Name',
|
||||
'URL',
|
||||
'ExtUserPtr.Name',
|
||||
'Signers.Name',
|
||||
'TimeToCompleteDays',
|
||||
],
|
||||
};
|
||||
|
||||
// declined documents report
|
||||
case 'UPr2Fm5WY3':
|
||||
return {
|
||||
reportName: 'Declined Documents',
|
||||
params: {
|
||||
Type: null,
|
||||
IsDeclined: true,
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
},
|
||||
|
||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||
};
|
||||
// Expired Documents report
|
||||
case 'zNqBHXHsYH':
|
||||
return {
|
||||
reportName: 'Expired Documents',
|
||||
params: {
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
Type: { $ne: 'Folder' },
|
||||
$and: [
|
||||
{
|
||||
$or: [
|
||||
{ Signers: { $ne: null }, SignedUrl: { $ne: null } },
|
||||
{ Placeholders: { $ne: null } },
|
||||
],
|
||||
},
|
||||
{
|
||||
ExpiryDate: {
|
||||
$lt: { __type: 'Date', iso: new Date().toISOString() },
|
||||
},
|
||||
},
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
},
|
||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||
};
|
||||
// Recently sent for signatures report show on dashboard
|
||||
case 'd9k3UfYHBc':
|
||||
return {
|
||||
reportName: 'Recently sent for signatures',
|
||||
params: {
|
||||
Type: { $ne: 'Folder' },
|
||||
Signers: { $ne: null },
|
||||
Placeholders: { $ne: null },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
ExpiryDate: {
|
||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||
},
|
||||
},
|
||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||
};
|
||||
// Recent signature requests report show on dashboard
|
||||
case '5Go51Q7T8r':
|
||||
return {
|
||||
reportName: 'Recent signature requests',
|
||||
params: {
|
||||
Type: { $ne: 'Folder' },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
ExpiryDate: {
|
||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||
},
|
||||
Placeholders: { $ne: null },
|
||||
},
|
||||
keys: [
|
||||
'Name',
|
||||
'Note',
|
||||
'Folder.Name',
|
||||
'URL',
|
||||
'ExtUserPtr.Name',
|
||||
'Signers.Name',
|
||||
'Signers.UserId',
|
||||
'AuditTrail',
|
||||
],
|
||||
};
|
||||
// Drafts report show on dashboard
|
||||
case 'kC5mfynCi4':
|
||||
return {
|
||||
reportName: 'Drafts',
|
||||
params: {
|
||||
Type: null,
|
||||
$or: [
|
||||
{ Signers: null, SignedUrl: null },
|
||||
{ Signers: { $exists: true }, Placeholders: null },
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
},
|
||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||
};
|
||||
// contact book report
|
||||
case '5KhaPr482K':
|
||||
return {
|
||||
reportName: 'Contactbook',
|
||||
params: {
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
IsDeleted: { $ne: true },
|
||||
},
|
||||
keys: ['Name', 'Email', 'Phone'],
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,30 @@
|
||||
import fs from 'node:fs';
|
||||
import https from 'https';
|
||||
import formData from 'form-data';
|
||||
import Mailgun from 'mailgun.js';
|
||||
import https from 'https';
|
||||
import { createTransport } from 'nodemailer';
|
||||
|
||||
const mailgun = new Mailgun(formData);
|
||||
const mailgunClient = mailgun.client({
|
||||
username: 'api',
|
||||
key: process.env.MAILGUN_API_KEY,
|
||||
});
|
||||
const mailgunDomain = process.env.MAILGUN_DOMAIN;
|
||||
let transporterSMTP;
|
||||
let mailgunClient;
|
||||
let mailgunDomain;
|
||||
if (process.env.SMTP_ENABLE) {
|
||||
transporterSMTP = createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: process.env.SMTP_PORT || 465,
|
||||
secure: process.env.SMTP_SECURE || true,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER_EMAIL,
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const mailgun = new Mailgun(formData);
|
||||
mailgunClient = mailgun.client({
|
||||
username: 'api',
|
||||
key: process.env.MAILGUN_API_KEY,
|
||||
});
|
||||
mailgunDomain = process.env.MAILGUN_DOMAIN;
|
||||
}
|
||||
|
||||
async function sendmail(req) {
|
||||
try {
|
||||
@@ -38,22 +54,67 @@ async function sendmail(req) {
|
||||
const pdfName = req.params.pdfName && `${req.params.pdfName}.pdf`;
|
||||
const file = {
|
||||
filename: pdfName || 'exported.pdf',
|
||||
data: PdfBuffer, //fs.readFileSync('./exports/exported_file_1223.pdf'),
|
||||
content: process.env.SMTP_ENABLE ? PdfBuffer : undefined, //fs.readFileSync('./exports/exported_file_1223.pdf'),
|
||||
data: process.env.SMTP_ENABLE ? undefined : PdfBuffer,
|
||||
};
|
||||
|
||||
// const html = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body style='text-align: center;'> <p style='font-weight: bolder; font-size: large;'>Hello!</p> <p>This is a html checking mail</p><p><button style='background-color: lightskyblue; cursor: pointer; border-radius: 5px; padding: 10px; border-style: solid; border-width: 2px; text-decoration: none; font-weight: bolder; color:blue'>Verify email</button></p></body></html>"
|
||||
|
||||
const from = req.params.from || '';
|
||||
const mailsender = process.env.SMTP_ENABLE
|
||||
? process.env.SMTP_USER_EMAIL
|
||||
: process.env.MAILGUN_SENDER;
|
||||
|
||||
const messageParams = {
|
||||
from: from + ' <' + process.env.MAILGUN_SENDER + '>',
|
||||
from: from + ' <' + mailsender + '>',
|
||||
to: req.params.recipient,
|
||||
subject: req.params.subject,
|
||||
text: req.params.text || 'mail',
|
||||
html: req.params.html || '',
|
||||
attachment: file,
|
||||
attachments: process.env.SMTP_ENABLE ? [file] : undefined,
|
||||
attachment: process.env.SMTP_ENABLE ? undefined : file,
|
||||
};
|
||||
if (transporterSMTP) {
|
||||
const res = await transporterSMTP.sendMail(messageParams);
|
||||
console.log('Res ', res);
|
||||
if (!res.err) {
|
||||
return {
|
||||
status: 'success',
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
|
||||
console.log('Res ', res);
|
||||
if (res.status === 200) {
|
||||
return {
|
||||
status: 'success',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const from = req.params.from || '';
|
||||
const mailsender = process.env.SMTP_ENABLE
|
||||
? process.env.SMTP_USER_EMAIL
|
||||
: process.env.MAILGUN_SENDER;
|
||||
|
||||
const messageParams = {
|
||||
from: from + ' <' + mailsender + '>',
|
||||
to: req.params.recipient,
|
||||
subject: req.params.subject,
|
||||
text: req.params.text || 'mail',
|
||||
html: req.params.html || '',
|
||||
};
|
||||
|
||||
if (transporterSMTP) {
|
||||
const res = await transporterSMTP.sendMail(messageParams);
|
||||
console.log('Res ', res);
|
||||
if (!res.err) {
|
||||
return {
|
||||
status: 'success',
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
|
||||
console.log('Res ', res);
|
||||
if (res.status === 200) {
|
||||
@@ -62,23 +123,6 @@ async function sendmail(req) {
|
||||
};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const from = req.params.from || '';
|
||||
const messageParams = {
|
||||
from: from + ' <' + process.env.MAILGUN_SENDER + '>',
|
||||
to: req.params.recipient,
|
||||
subject: req.params.subject,
|
||||
text: req.params.text || 'mail',
|
||||
html: req.params.html || '',
|
||||
};
|
||||
|
||||
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
|
||||
console.log('Res ', res);
|
||||
if (res.status === 200) {
|
||||
return {
|
||||
status: 'success',
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err ', err);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
*
|
||||
* @param {Parse} Parse
|
||||
*/
|
||||
exports.up = async Parse => {
|
||||
// TODO: set className here
|
||||
const className = 'contracts_Users';
|
||||
const schema = new Parse.Schema(className);
|
||||
// schema.addString('Name');
|
||||
// schema.addString('Phone');
|
||||
// schema.addString('JobTitle');
|
||||
// schema.addString('Email');
|
||||
// schema.addString('Company');
|
||||
// schema.addString('UserRole');
|
||||
// schema.addObject('Plan');
|
||||
// schema.addString('Customer_id');
|
||||
// schema.addString('Subscription_id');
|
||||
// schema.addString('Next_billing_date');
|
||||
// schema.addBoolean('IsContactEntry');
|
||||
// schema.addBoolean('ShareWithTeam');
|
||||
// schema.addPointer('TenantId', 'partners_Tenant');
|
||||
// schema.addPointer('UserId', '_User');
|
||||
// schema.addPointer('CreatedBy', '_User');
|
||||
schema.setCLP({
|
||||
get: {},
|
||||
find: {},
|
||||
count: {},
|
||||
create: { '*': true },
|
||||
update: { '*': true },
|
||||
delete: {},
|
||||
addField: {},
|
||||
});
|
||||
|
||||
return schema.update();
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Parse} Parse
|
||||
*/
|
||||
exports.down = async Parse => {
|
||||
// TODO: set className here
|
||||
const className = 'contracts_Users';
|
||||
const schema = new Parse.Schema(className);
|
||||
|
||||
return schema.purge().then(() => schema.delete());
|
||||
};
|
||||
@@ -0,0 +1,556 @@
|
||||
/**
|
||||
*
|
||||
* @param {Parse} Parse
|
||||
*/
|
||||
exports.up = async Parse => {
|
||||
const className = 'w_menu';
|
||||
const userMenu = new Parse.Query(className);
|
||||
const updateUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||
updateUserMenu.set('menuItems', [
|
||||
{
|
||||
icon: 'fas fa-tachometer-alt',
|
||||
title: 'Dashboard',
|
||||
target: '',
|
||||
pageType: 'dashboard',
|
||||
description: '',
|
||||
objectId: '35KBoSgoAK',
|
||||
},
|
||||
{
|
||||
icon: 'far fa-newspaper',
|
||||
title: 'New Document',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: null,
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-nib',
|
||||
title: 'Sign yourself',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: 'sHAnZphf69',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
title: 'Request signatures',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: '8mZzFxbG1z',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-folder',
|
||||
title: 'OpenSignDrive™',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-address-card',
|
||||
title: 'Reports',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-signature',
|
||||
title: 'Need your sign',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '4Hhwbp482K',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-tasks',
|
||||
title: 'In Progress',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '1MwEuxLEkF',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-check-circle',
|
||||
title: 'Completed',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'kQUoW4hUXz',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-edit',
|
||||
title: 'Drafts',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'ByHuevtCFY',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-times-circle',
|
||||
title: 'Declined',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'UPr2Fm5WY3',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-hourglass-end',
|
||||
title: 'Expired',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'zNqBHXHsYH',
|
||||
},
|
||||
{
|
||||
icon: 'fa-solid fa-address-book',
|
||||
title: 'Contactbook',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '5KhaPr482K',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-cog',
|
||||
title: 'Settings',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-fancy',
|
||||
title: 'My Signature',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const AdminMenu = new Parse.Query(className);
|
||||
const updateAdminMenu = await AdminMenu.get('VPh91h0ZHk');
|
||||
updateAdminMenu.set('menuItems', [
|
||||
{
|
||||
icon: 'fas fa-tachometer-alt',
|
||||
title: 'Dashboard',
|
||||
target: '',
|
||||
pageType: 'dashboard',
|
||||
description: '',
|
||||
objectId: '35KBoSgoAK',
|
||||
},
|
||||
{
|
||||
icon: 'far fa-newspaper',
|
||||
title: 'New Document',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: null,
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-nib',
|
||||
title: 'Sign yourself',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: 'sHAnZphf69',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
title: 'Request signatures',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: '8mZzFxbG1z',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-folder',
|
||||
title: 'OpenSignDrive™',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-address-card',
|
||||
title: 'Reports',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-signature',
|
||||
title: 'Need your sign',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '4Hhwbp482K',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-tasks',
|
||||
title: 'In Progress',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '1MwEuxLEkF',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-check-circle',
|
||||
title: 'Completed',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'kQUoW4hUXz',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-edit',
|
||||
title: 'Drafts',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'ByHuevtCFY',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-times-circle',
|
||||
title: 'Declined',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'UPr2Fm5WY3',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-hourglass-end',
|
||||
title: 'Expired',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'zNqBHXHsYH',
|
||||
},
|
||||
{
|
||||
icon: 'fa-solid fa-address-book',
|
||||
title: 'Contactbook',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '5KhaPr482K',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-cog',
|
||||
title: 'Settings',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-fancy',
|
||||
title: 'My Signature',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||
},
|
||||
{
|
||||
icon: 'far fa-user',
|
||||
title: 'Add User',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: 'lM0xRnM3iE',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
// TODO: Set the schema here
|
||||
// Example:
|
||||
// schema.addString('name').addNumber('cash');
|
||||
const batch = [updateUserMenu, updateAdminMenu];
|
||||
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Parse} Parse
|
||||
*/
|
||||
exports.down = async Parse => {
|
||||
// TODO: set className here
|
||||
const className = 'w_menu';
|
||||
const userMenu = new Parse.Query(className);
|
||||
const revertUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||
revertUserMenu.set('menuItems', [
|
||||
{
|
||||
icon: 'fas fa-tachometer-alt',
|
||||
title: 'Dashboard',
|
||||
target: '',
|
||||
pageType: 'dashboard',
|
||||
description: '',
|
||||
objectId: '35KBoSgoAK',
|
||||
},
|
||||
{
|
||||
icon: 'far fa-newspaper',
|
||||
title: 'New Document',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: null,
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-nib',
|
||||
title: 'Sign yourself',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: 'sHAnZphf69',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
title: 'Request signatures',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: '8mZzFxbG1z',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-folder',
|
||||
title: 'OpenSignDrive™',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-address-card',
|
||||
title: 'Reports',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-signature',
|
||||
title: 'Need your sign',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '4Hhwbp482K',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-tasks',
|
||||
title: 'In Progress',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '1MwEuxLEkF',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-check-circle',
|
||||
title: 'Completed',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'kQUoW4hUXz',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-edit',
|
||||
title: 'Drafts',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'ByHuevtCFY',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-times-circle',
|
||||
title: 'Declined',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'UPr2Fm5WY3',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-hourglass-end',
|
||||
title: 'Expired',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'zNqBHXHsYH',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-cog',
|
||||
title: 'Settings',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-fancy',
|
||||
title: 'My Signature',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const adminMenu = new Parse.Query(className);
|
||||
const revertAdminMenu = await adminMenu.get('VPh91h0ZHk');
|
||||
revertAdminMenu.set('menuItems', [
|
||||
{
|
||||
icon: 'fas fa-tachometer-alt',
|
||||
title: 'Dashboard',
|
||||
target: '',
|
||||
pageType: 'dashboard',
|
||||
description: '',
|
||||
objectId: '35KBoSgoAK',
|
||||
},
|
||||
{
|
||||
icon: 'far fa-newspaper',
|
||||
title: 'New Document',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: null,
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-nib',
|
||||
title: 'Sign yourself',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: 'sHAnZphf69',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
title: 'Request signatures',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: '8mZzFxbG1z',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-folder',
|
||||
title: 'OpenSignDrive™',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-address-card',
|
||||
title: 'Reports',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-signature',
|
||||
title: 'Need your sign',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '4Hhwbp482K',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-tasks',
|
||||
title: 'In Progress',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: '1MwEuxLEkF',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-check-circle',
|
||||
title: 'Completed',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'kQUoW4hUXz',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-edit',
|
||||
title: 'Drafts',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'ByHuevtCFY',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-times-circle',
|
||||
title: 'Declined',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'UPr2Fm5WY3',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-hourglass-end',
|
||||
title: 'Expired',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId: 'zNqBHXHsYH',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-cog',
|
||||
title: 'Settings',
|
||||
target: '_self',
|
||||
pageType: null,
|
||||
description: '',
|
||||
objectId: null,
|
||||
children: [
|
||||
{
|
||||
icon: 'fas fa-pen-fancy',
|
||||
title: 'My Signature',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||
},
|
||||
{
|
||||
icon: 'far fa-user',
|
||||
title: 'Add User',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: 'lM0xRnM3iE',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
// TODO: Set the schema here
|
||||
// Example:
|
||||
// schema.addString('name').addNumber('cash');
|
||||
const batch = [revertUserMenu, revertAdminMenu];
|
||||
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||
};
|
||||
@@ -10,7 +10,7 @@
|
||||
<br />
|
||||
<p><a href="{{{link}}}" style="background-color: lightskyblue; cursor: pointer; border-radius: 5px; padding: 10px; border-style: solid; border-width: 2px; text-decoration: none; font-weight: bolder; color:blue">Verify email</a></p>
|
||||
<br />
|
||||
<p>ExampleApp</p>
|
||||
<p><a href="https://www.opensignlabs.com">OpenSign™</a></p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -17,10 +17,12 @@ import S3Adapter from 'parse-server-s3-adapter';
|
||||
import FSFilesAdapter from 'parse-server-fs-adapter';
|
||||
import AWS from 'aws-sdk';
|
||||
import { app as customRoute } from './cloud/customRoute/customApp.js';
|
||||
import { exec } from 'child_process';
|
||||
import { createTransport } from 'nodemailer';
|
||||
|
||||
const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT);
|
||||
// console.log("configuration ", configuration);
|
||||
if (process.env.USE_LOCAL !== "TRUE") {
|
||||
if (process.env.USE_LOCAL !== 'TRUE') {
|
||||
const s3Options = {
|
||||
bucket: process.env.DO_SPACE, // globalConfig.S3FilesAdapter.bucket,
|
||||
baseUrl: process.env.DO_BASEURL,
|
||||
@@ -36,18 +38,31 @@ if (process.env.USE_LOCAL !== "TRUE") {
|
||||
var fsAdapter = new S3Adapter(s3Options);
|
||||
} else {
|
||||
var fsAdapter = new FSFilesAdapter({
|
||||
"filesSubDirectory": "files" // optional, defaults to ./files
|
||||
filesSubDirectory: 'files', // optional, defaults to ./files
|
||||
});
|
||||
}
|
||||
|
||||
let transporterMail;
|
||||
let mailgunClient;
|
||||
let mailgunDomain;
|
||||
if (process.env.MAILGUN_API_KEY) {
|
||||
|
||||
if (process.env.SMTP_ENABLE) {
|
||||
transporterMail = createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: process.env.SMTP_PORT || 465,
|
||||
secure: process.env.SMTP_SECURE || true,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER_EMAIL,
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
});
|
||||
} else if (process.env.MAILGUN_API_KEY) {
|
||||
const mailgun = new Mailgun(formData);
|
||||
mailgunClient = mailgun.client({
|
||||
username: 'api',
|
||||
key: process.env.MAILGUN_API_KEY,
|
||||
});
|
||||
|
||||
mailgunDomain = process.env.MAILGUN_DOMAIN;
|
||||
}
|
||||
|
||||
@@ -59,41 +74,46 @@ export const config = {
|
||||
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
|
||||
masterKeyIps: ['0.0.0.0/0', '::1'], // '::1'
|
||||
serverURL: process.env.SERVER_URL || 'http://localhost:8080/app', // Don't forget to change to https if needed
|
||||
// verifyUserEmails: true,
|
||||
verifyUserEmails: true,
|
||||
publicServerURL: process.env.SERVER_URL || 'http://localhost:8080/app',
|
||||
// Your apps name. This will appear in the subject and body of the emails that are sent.
|
||||
appName: 'Open Sign',
|
||||
allowClientClassCreation: false,
|
||||
emailAdapter: process.env.MAILGUN_API_KEY
|
||||
? {
|
||||
module: 'parse-server-api-mail-adapter',
|
||||
options: {
|
||||
// The email address from which emails are sent.
|
||||
sender: process.env.MAILGUN_SENDER,
|
||||
// The email templates.
|
||||
templates: {
|
||||
// The template used by Parse Server to send an email for password
|
||||
// reset; this is a reserved template name.
|
||||
passwordResetEmail: {
|
||||
subjectPath: './files/password_reset_email_subject.txt',
|
||||
textPath: './files/password_reset_email.txt',
|
||||
htmlPath: './files/password_reset_email.html',
|
||||
emailAdapter:
|
||||
process.env.SMTP_ENABLE || process.env.MAILGUN_API_KEY
|
||||
? {
|
||||
module: 'parse-server-api-mail-adapter',
|
||||
options: {
|
||||
// The email address from which emails are sent.
|
||||
sender: process.env.SMTP_ENABLE
|
||||
? process.env.SMTP_USER_EMAIL
|
||||
: process.env.MAILGUN_SENDER,
|
||||
// The email templates.
|
||||
templates: {
|
||||
// The template used by Parse Server to send an email for password
|
||||
// reset; this is a reserved template name.
|
||||
passwordResetEmail: {
|
||||
subjectPath: './files/password_reset_email_subject.txt',
|
||||
textPath: './files/password_reset_email.txt',
|
||||
htmlPath: './files/password_reset_email.html',
|
||||
},
|
||||
// The template used by Parse Server to send an email for email
|
||||
// address verification; this is a reserved template name.
|
||||
verificationEmail: {
|
||||
subjectPath: './files/verification_email_subject.txt',
|
||||
textPath: './files/verification_email.txt',
|
||||
htmlPath: './files/verification_email.html',
|
||||
},
|
||||
},
|
||||
// The template used by Parse Server to send an email for email
|
||||
// address verification; this is a reserved template name.
|
||||
verificationEmail: {
|
||||
subjectPath: './files/verification_email_subject.txt',
|
||||
textPath: './files/verification_email.txt',
|
||||
htmlPath: './files/verification_email.html',
|
||||
apiCallback: async ({ payload, locale }) => {
|
||||
if (mailgunClient) {
|
||||
const mailgunPayload = ApiPayloadConverter.mailgun(payload);
|
||||
await mailgunClient.messages.create(mailgunDomain, mailgunPayload);
|
||||
} else if (transporterMail) await transporterMail.sendMail(payload);
|
||||
},
|
||||
},
|
||||
apiCallback: async ({ payload, locale }) => {
|
||||
const mailgunPayload = ApiPayloadConverter.mailgun(payload);
|
||||
await mailgunClient.messages.create(mailgunDomain, mailgunPayload);
|
||||
},
|
||||
},
|
||||
}
|
||||
: null,
|
||||
}
|
||||
: null,
|
||||
filesAdapter: fsAdapter,
|
||||
auth: {
|
||||
google: {
|
||||
@@ -164,6 +184,20 @@ if (!process.env.TESTING) {
|
||||
httpServer.headersTimeout = 100000; // in milliseconds
|
||||
httpServer.listen(port, function () {
|
||||
console.log('parse-server-example running on port ' + port + '.');
|
||||
const migrate = `APPLICATION_ID=${process.env.APP_ID} SERVER_URL=http://localhost:8080/app MASTER_KEY=${process.env.MASTER_KEY} npx parse-dbtool migrate`;
|
||||
|
||||
exec(migrate, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`Error: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
console.error(`Error: ${stderr}`);
|
||||
return;
|
||||
}
|
||||
console.log(`Command output: ${stdout}`);
|
||||
});
|
||||
});
|
||||
// This will enable the Live Query real-time server
|
||||
await ParseServer.createLiveQueryServer(httpServer);
|
||||
|
||||
Generated
+334
-11
@@ -18,16 +18,19 @@
|
||||
"express-sse": "^0.5.3",
|
||||
"form-data": "^4.0.0",
|
||||
"jsonschema": "^1.4.1",
|
||||
"mailgun.js": "^9.0.1",
|
||||
"mailgun.js": "^9.3.0",
|
||||
"mongoose": "^7.2.1",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"multer-s3": "^2.10.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-signpdf": "^1.5.1",
|
||||
"nodemailer": "^6.9.7",
|
||||
"openai": "^4.8.0",
|
||||
"parse": "4.1.0",
|
||||
"parse-dbtool": "^1.2.0",
|
||||
"parse-server": "6.3.1",
|
||||
"parse-server-api-mail-adapter": "^3.0.0",
|
||||
"parse-server-fs-adapter": "1.0.1",
|
||||
"parse-server-s3-adapter": "^1.2.0",
|
||||
"pdf-lib": "^1.16.0",
|
||||
"pdfkit": "^0.13.0",
|
||||
@@ -2145,7 +2148,6 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
@@ -2794,6 +2796,37 @@
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "2.30.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
|
||||
"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.11"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/date-fns"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns/node_modules/@babel/runtime": {
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
|
||||
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns/node_modules/regenerator-runtime": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
||||
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
@@ -3900,6 +3933,32 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.2",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-glob/node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
@@ -3999,7 +4058,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@@ -4335,7 +4393,6 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
@@ -5091,7 +5148,6 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@@ -6016,9 +6072,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mailgun.js": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.0.1.tgz",
|
||||
"integrity": "sha512-bVZ1zGh5UfQcChqIwIAil99hzoTeB3aHqAUbqmIBLMLcKfx+FF2qvhbc00WtwrFhe5dBQqQw6zPj0QBlqV4nXg==",
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.3.0.tgz",
|
||||
"integrity": "sha512-iRqCglCdi+Q5anFpeRKHiytT/i34E14p/WtTE57VSeq5bATK+zQ8UnpFgPRaqGGTJqyGjqcO9m5YDRRB4/qirw==",
|
||||
"dependencies": {
|
||||
"axios": "^1.3.3",
|
||||
"base-64": "^1.0.0",
|
||||
@@ -6087,6 +6143,14 @@
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
@@ -6095,6 +6159,18 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
|
||||
@@ -6799,6 +6875,14 @@
|
||||
"node-forge": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemailer": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz",
|
||||
"integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemon": {
|
||||
"version": "2.0.22",
|
||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
|
||||
@@ -7328,6 +7412,234 @@
|
||||
"crypto-js": "4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-dbtool/-/parse-dbtool-1.2.0.tgz",
|
||||
"integrity": "sha512-APRMPdQ2jyJ7SBouPYZsCD4BjB0zIrSEgALgeYZsVSDrrtoqXhUHJHi42tF/0ocTA/nolteUMzlHT+msrqPvjQ==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.1",
|
||||
"date-fns": "^2.21.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"fast-glob": "^3.2.5",
|
||||
"parse": "^3.2.0",
|
||||
"ts-dedent": "^2.1.1",
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"parse-dbtool": "src/parse-dbtool.js"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/@babel/runtime": {
|
||||
"version": "7.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.0.tgz",
|
||||
"integrity": "sha512-YMQvx/6nKEaucl0MY56mwIG483xk8SDNdlUwb2Ts6FUpr7fm85DxEmsY18LXBNhcTz6tO6JwZV8w1W06v8UKeg==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/@babel/runtime-corejs3": {
|
||||
"version": "7.17.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz",
|
||||
"integrity": "sha512-ZbYSUvoSF6dXZmMl/CYTMOvzIFnbGfv4W3SEHYgMvNsFTeLaF2gkGAF4K2ddmtSK4Emej+0aYcnSC6N5dPCXUQ==",
|
||||
"dependencies": {
|
||||
"core-js-pure": "^3.20.2",
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/dotenv": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
||||
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/idb-keyval": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.0.3.tgz",
|
||||
"integrity": "sha512-yh8V7CnE6EQMu9YDwQXhRxwZh4nv+8xm/HV4ZqK4IiYFJBWYGjJuykADJbSP+F/GDXUBwCSSNn/14IpGL81TuA==",
|
||||
"dependencies": {
|
||||
"safari-14-idb-fix": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/parse": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/parse/-/parse-3.5.1.tgz",
|
||||
"integrity": "sha512-uxkLVNfbqgZ/pStg/jIQGh09tOUkPZorzDIqz9vSFjZ3iIZzgvNk6VBbjXjcMWsR8LyFPOR1ROR6/y9Dedn3/w==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.18.0",
|
||||
"@babel/runtime-corejs3": "7.17.8",
|
||||
"idb-keyval": "6.0.3",
|
||||
"react-native-crypto-js": "1.0.0",
|
||||
"uuid": "3.4.0",
|
||||
"ws": "8.6.0",
|
||||
"xmlhttprequest": "1.8.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"crypto-js": "4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
||||
"bin": {
|
||||
"uuid": "bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/ws": {
|
||||
"version": "8.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
|
||||
"integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-dbtool/node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-server": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-server/-/parse-server-6.3.1.tgz",
|
||||
@@ -7403,6 +7715,12 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-server-fs-adapter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-server-fs-adapter/-/parse-server-fs-adapter-1.0.1.tgz",
|
||||
"integrity": "sha512-5IRKAT2QkzHrYrBESY4E8jsV1sl+XVBTKGyUvBPgBR2QzsTTqiyU/lFZD8PAJavA+TH1BLyLTUMZbhZhswNVbQ==",
|
||||
"deprecated": "use @parse/fs-files-adapter"
|
||||
},
|
||||
"node_modules/parse-server-s3-adapter": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-server-s3-adapter/-/parse-server-s3-adapter-1.2.0.tgz",
|
||||
@@ -7881,7 +8199,6 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
@@ -8455,7 +8772,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -9221,7 +9537,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
@@ -9283,6 +9598,14 @@
|
||||
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
|
||||
},
|
||||
"node_modules/ts-dedent": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
|
||||
"integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
|
||||
"engines": {
|
||||
"node": ">=6.10"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
|
||||
|
||||
@@ -27,18 +27,20 @@
|
||||
"express-sse": "^0.5.3",
|
||||
"form-data": "^4.0.0",
|
||||
"jsonschema": "^1.4.1",
|
||||
"mailgun.js": "^9.0.1",
|
||||
"mailgun.js": "^9.3.0",
|
||||
"mongoose": "^7.2.1",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"multer-s3": "^2.10.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-signpdf": "^1.5.1",
|
||||
"nodemailer": "^6.9.7",
|
||||
"openai": "^4.8.0",
|
||||
"parse": "4.1.0",
|
||||
"parse-dbtool": "^1.2.0",
|
||||
"parse-server": "6.3.1",
|
||||
"parse-server-api-mail-adapter": "^3.0.0",
|
||||
"parse-server-s3-adapter": "^1.2.0",
|
||||
"parse-server-fs-adapter": "1.0.1",
|
||||
"parse-server-s3-adapter": "^1.2.0",
|
||||
"pdf-lib": "^1.16.0",
|
||||
"pdfkit": "^0.13.0",
|
||||
"razorpay": "^2.8.6",
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// const { exec } = require('child_process');
|
||||
import { exec } from 'child_process';
|
||||
|
||||
const migrate =
|
||||
'APPLICATION_ID=legadranaxn SERVER_URL=http://localhost:8080/app MASTER_KEY=XnAwPDRQQyMr npx parse-dbtool migrate';
|
||||
// `APPLICATION_ID=${process.env.APP_ID} SERVER_URL=${process.env.SERVER_URL} MASTER_KEY=${process.env.MASTER_KEY} npx parse-dbtool migrate`;
|
||||
|
||||
exec(migrate, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`Error: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
console.error(`Error: ${stderr}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Command output: ${stdout}`);
|
||||
});
|
||||
|
||||
// const seeder =
|
||||
// 'APPLICATION_ID=legadranaxn SERVER_URL=http://localhost:8080/app MASTER_KEY=XnAwPDRQQyMr npx parse-dbtool seed';
|
||||
|
||||
// exec(seeder, (error, stdout, stderr) => {
|
||||
// if (error) {
|
||||
// console.error(`Error: ${error.message}`);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (stderr) {
|
||||
// console.error(`Error: ${stderr}`);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// console.log(`Command output: ${stdout}`);
|
||||
// });
|
||||
@@ -40,7 +40,7 @@
|
||||
"id": "c1935cc0-28d4-3d73-b72a-8c1e3d18a17f",
|
||||
"queryType": "",
|
||||
"class": "contracts_Document",
|
||||
"query": "where={\"CreatedBy\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"#UserId.objectId#\"},\"IsCompleted\":{\"$ne\":true},\"IsDeclined\":{\"$ne\":true},\"Type\":{\"$ne\":\"Folder\"},\"Placeholders\":{\"$ne\":null},\"ExpiryDate\":{\"#*gt\":{\"__type\":\"#Date#\",\"iso\":\"#today#\"}}}&count=1",
|
||||
"query": "where={\"IsDeclined\":{\"$ne\":true},\"IsCompleted\":{\"$ne\":true},\"Type\":{\"$ne\":\"Folder\"},\"Placeholders\":{\"$ne\":null},\"ExpiryDate\":{\"#*gt\":{\"__type\":\"#Date#\",\"iso\":\"#today#\"}}}&include=Signers,AuditTrail.UserPtr",
|
||||
"key": "count",
|
||||
"Redirect_type": "Report",
|
||||
"Redirect_id": "1MwEuxLEkF",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
[{
|
||||
[
|
||||
{
|
||||
"_id": "H9vRfEYKhT",
|
||||
"_created_at": {
|
||||
"$date": "2023-09-04T14:04:00.669Z"
|
||||
@@ -105,6 +106,14 @@
|
||||
"pageType": "report",
|
||||
"description": "",
|
||||
"objectId": "zNqBHXHsYH"
|
||||
},
|
||||
{
|
||||
"icon": "fa-solid fa-address-book",
|
||||
"title": "Contactbook",
|
||||
"target": "_self",
|
||||
"pageType": "report",
|
||||
"description": "",
|
||||
"objectId": "5KhaPr482K"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -237,6 +246,14 @@
|
||||
"pageType": "report",
|
||||
"description": "",
|
||||
"objectId": "zNqBHXHsYH"
|
||||
},
|
||||
{
|
||||
"icon": "fa-solid fa-address-book",
|
||||
"title": "Contactbook",
|
||||
"target": "_self",
|
||||
"pageType": "report",
|
||||
"description": "",
|
||||
"objectId": "5KhaPr482K"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -269,4 +286,5 @@
|
||||
],
|
||||
"menuTitle": "Admin Menu",
|
||||
"menuType": "Side Menu"
|
||||
}]
|
||||
}
|
||||
]
|
||||
+54
-55
@@ -1,55 +1,54 @@
|
||||
MIIKLwIBAzCCCeUGCSqGSIb3DQEHAaCCCdYEggnSMIIJzjCCBEIGCSqGSIb3DQEH
|
||||
BqCCBDMwggQvAgEAMIIEKAYJKoZIhvcNAQcBMFcGCSqGSIb3DQEFDTBKMCkGCSqG
|
||||
SIb3DQEFDDAcBAh6cQqVpHfTzAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQME
|
||||
ASoEEFKEIGJTTRo3voO/FvsXs7yAggPAI7rMCboTFFBfdMuuV3Y9/xfphAgdGD7P
|
||||
0xAN10CcmXlMtedc8cRxOaD9n3Q7zJx5iIbqEGDTc0dgp5EtdWsGl7MP76iHkSfB
|
||||
ZUPc13nbnRU4Nq4hNFcSj1m6NVa0lT9UobbTsG+wUkJn8aLfijzZ1OY82KLlKUoJ
|
||||
lqLsQ1yZkeLiLKI0aEew/2vzfiLUX9A99qnCRoryo8ZbLiWl0Vu/FEKM5mqIRFEp
|
||||
BKeSUsRxBfJCMZ2Ks5t4/MTCV+yrcsuhLPF/AJpzKfIinEFDhm7MxP4RXtk2LWNe
|
||||
+EO2GuFRjZCfsMO0oNWybFmDeNDMCHZj5TeoqL1JwAV5e1lEeqR38v4Wcr4OVefY
|
||||
DfdrJ2xdvm7XbBZ8Lgx8L4fwugw7oDyTpR2jJqHMlpOsQrxipN6UKkN6EVYeCC5K
|
||||
4dF5LHdCcIa7L/OI/feD5g/zz8SGCTc91husVN7zi+CVO0lQLRkAj02+VbiXPPDD
|
||||
eQm/QBieG2yVe5IRfcnIs2aszulbQbgHdguSYSQa/7DEvN/9/uxUIRFbItwrreRI
|
||||
VAUUNS02L680Zok9xzDed1I/WJoPr2+5n2eV1jc5zoH7mAni0+Z1d5qLoYV6pNaN
|
||||
P9okvBf75LLNoJKsb/eWlkk73rmlH6/Qz+hudgnlkxUJuU/b79AMQpd0EWEWhcim
|
||||
ZeB4d9lPLLwyvY/FN4aCGWzsoAW69RK9E1DyGZAZRYRwCKHSWXmCaenR1ilxcPFx
|
||||
TDavpybObIISPtylv5Z/IGBjE19Lw0UHc6Waln/jx0YXXGGDWs1F/MrdJ/8mkVXf
|
||||
tHB/5ds4u5md+CmXpaCITO3Cg9GltGSWyDoEJsz1u/Wzq4X4FYmolXiqQvMPQrxu
|
||||
iThTnPDGbz9VqFSyNKPKswIQ8CUbvZ209A5vjERPzE0Lp1pO39K51fnHD9oD968t
|
||||
tGbGmNiQ0++Orze79cH0UVwDa6NLGCmnE0oBgke1JDPlaU3kkx7+R9SAS0Zytsmj
|
||||
aLxW5Z1cOFaqqBLjwgHUxOqRO+cl6P9ORox34wJjiwZKy1L+0ppw22Na/unwi2Rk
|
||||
a8jvK7+ycOLaiSmI77T0l7VCWgKsRsWLvBA3cjX5XAGtatFXrY/7Imoxl0nWGLjG
|
||||
n5Sv5XuDek4e4QAPeJmhpURMnzLDsSXAYOSYZvS/kgENYhYSnQLQp50TxrzquA2c
|
||||
lAeFIEqqAJy9tAMfp5UAqMeOC60Ttn6ySsdOle003F2NrRilhPynNDZ3h1ZQknur
|
||||
Y9zWUm9qBmXCjhPzdmzHz3Ozj2Bi6kd4MIIFhAYJKoZIhvcNAQcBoIIFdQSCBXEw
|
||||
ggVtMIIFaQYLKoZIhvcNAQwKAQKgggUxMIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkq
|
||||
hkiG9w0BBQwwHAQIZenzippqfSQCAggAMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUD
|
||||
BAEqBBCddSIj/wfxowZAO1j3W9FwBIIE0C/guzeZtV/vPsaIDAtWEkmepCvhm9Rg
|
||||
aUgOoR66wjyYx7upeuZJ+pYJdsEqUmTgGYN+ClBpsU0bqCM7PI0mepvIT9kLD6ZL
|
||||
UkprtNAYP87NBA/e5dpXlGAf9ibDRT0F2Y+lCSF83rCIYKG8n7h5834F6Saf+dU7
|
||||
6y5bgorbf2Fnxy123XfUSg5qdCraZZM+DwE1gpQdBGrFyq8cwlQ8hJpKHDWup7WA
|
||||
f2HcT/X0Wjb24L6JWjC1FvTbTNdS/lzTOcqLYUc31iuU9rF6O4qtX9PK/yGWc+YE
|
||||
qakuV+HrsF4je/YdVZRYHtkbbcYXW9PjtMv+4D1ut5X2SPeHwpj3WmGAb7Zno6SD
|
||||
SfohMihXvDbIjVSMDBpW97bhgk0h7iS4ISIYoQJUGJv3QQ3XJq91LoIP3zpiO/Cq
|
||||
ZuuHuGvZmO6lb0PGShRT7mFg3k3rswTfFyKdtY76zAVJIR2bz/6bRf4uQI48SOLR
|
||||
NX1Z6lavUNiE4nPNlnfBp480C+YANKs/bdev0wkRVmFxPMyb5FFLXwLSqcfdSQag
|
||||
RayrKd8xPOm6lor3cTvrkO3XH2Hf9TgFHjeIAQ3VZ1Cncb9jfra3V4zvIocek4dC
|
||||
GREirPbEyL/js5O0aAa0mg9EontMWKRqncomKhUOckheP2dYiQOazDFDFP9OQCYV
|
||||
MBb0RDwm3+hiMU0lPeO+NAjAv2SfFK7G4maMb2SL7inT7An7ZPPpnDNXLDt+nOgo
|
||||
IKuaJpy8JX/OKB4ntYsdnQG4E0J3vpHWjYPKif7j1njIYFd76bIgNVlqWuQFArBy
|
||||
U9BuPyF+eYouJc+TpX9R5ybPvabRR4NUjnrttr2E5AzQfIgNGrSFiewjvYZHQOKd
|
||||
WyVR9YV0cUv591xyUDdXMoHh+J0v0xK1WCHe/9enY5y/C8YohL8h5tEvInAQconj
|
||||
lJ2r9qX8iBmIupJij5M5Ebza8HQ4aVMdHu/s05Vj9BC6K0ok3h+DFTj2gUBD24sp
|
||||
APHic0DmNnciUQuHuuoW/1SVb6I1HJswsgcC8CekvoXF26ygwWhJPyqw+5djip2w
|
||||
I/l3uOnPPUWZQHKhnBH4noZydrzBBJN1po9dkxb8LKuKZDEcnKo+tQrTnZJaFRXK
|
||||
pQDsAjQ0HcYi8ZqN/GPezXOqzRgvObevXeDYTJrNejr46B1HqjPw8doai+AEf//1
|
||||
iiM9EK4y3bGbX837oebTByRi112AOctISHTWbF0zdFMiBO9X9PML4n3i14ToqLH1
|
||||
EUp0WtCdKLJmrRnO9PKJUMpce3yNu6oRSBzB4EkgUMOTVx9tM66h/gcR3wr+qKJP
|
||||
1EABMbbCsJeYYLujhQHVh0JluqLBXYuCmr5n6o8qmonj5tEfTn9zs2gi0OvKTliH
|
||||
wRXWsar004alt8D8o4M/Oqu3qyVV1O8BlVEofUC1CfAMIh/T1NJBeKG/FPfAFoEz
|
||||
9liLLkoDvGvFVJ4Ezy4BaPtg+G3yU/SeiruwsCB3unHRD7G6VvS4jY2B8vEYl0yM
|
||||
Z1mLFbKK8CIEvg8+v/vbc0noYUOzd6bkwh6Y6cziR/u78y2nALYZpQK+3XiVVH/v
|
||||
SaVoDckZgUwAX+dMd1P4U3a487MPXBZZmLVFMHTuv3NvW6NIQCMd4l35ViRd7YcS
|
||||
V2QDKTnUtPN2MSUwIwYJKoZIhvcNAQkVMRYEFMSz7PlBO5VzTDqC/foidPWrMjkw
|
||||
MEEwMTANBglghkgBZQMEAgEFAAQgPlLuG+67SxPOEPbgFuEnVgewvY6LUzFmrprx
|
||||
c6yryFgECIld0S5kDk7JAgIIAA==
|
||||
MIIKCQIBAzCCCc8GCSqGSIb3DQEHAaCCCcAEggm8MIIJuDCCBG8GCSqGSIb3DQEH
|
||||
BqCCBGAwggRcAgEAMIIEVQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIpumu
|
||||
bFabBWACAggAgIIEKDqHS7Icd5MzIBk1dBokGK2s+5a2fA4308WA1QzEWmczqVYI
|
||||
z6lYmW8qsiZIw4PFkRzdIx1+zCmP8jgWiiqh5RKnbHYmh1JPNyx9SqmUDILDXmjg
|
||||
KxO9agRw9LXge4hgRL7YW0TxYZYw4EeXV9Yr7kcOq9DoO2MoRikJ+2Tuvvq/hfuV
|
||||
9zFHsz4jpf7W95k1IeH6bZ92klz5R1e/EK8JuHy592i/u+BxxW1vTkiPpTaHD6s9
|
||||
1lDSkT1j0LIDU6l9gVvJvFBV8j88vet/Z4QkTbHPMYvBnKNRstKuOvDasEJE4RkA
|
||||
PV4TfBwFF6uvREZI1vBboM/18pzeyjoRX+mlJNfcH3kh1tkck+Jg+M2bLXAH1EdD
|
||||
GRwENvnTNW1CFIn37VVja7SFBQNXA+E6rejmqtUmZ5XktSINDBUyjow9XuYTUtI/
|
||||
sgcRSC0aB0EKKpphbFPp1niKCLm1ef33e+bWyWbtR2L2Kc3ETmhjNADpyapAGmzc
|
||||
LP2BafGaKj18KiLAG4GL6+kXk0GUz7Fw5q8H8RY1T33o+xjWvC0+aJgvr65qWdKw
|
||||
+ug6wuu4Cr2kFEuXxPKsnYqmE5NT/x+lfunlZ5iEQN3w2XO5J2u2eMXVRUsPH2T6
|
||||
0sJKomjY0RB1JsqZBnyleWm+tYo0RpVAyJ3NGBp9dVb7a3Qw6jNZBG/xMW+gvtUJ
|
||||
q6hfK/cD3cagD0NQFVD5STMOuGOSqq/bbwAKjZ/lrPmCCYATKwkjAFybYfHJVrrW
|
||||
Y2tQgCQ/zrZLIxQjp7F17hU0+gT54x0MpF6AoqIM/qqNnHrQ0fi50ECmLvx3SqYa
|
||||
nvjvt/HZhMZfqRXiXjeicIwpnNoG7+uQknySk+7cc9GNhHZR7cfPfkTpgvuuebrQ
|
||||
l5YW+k9tG+xrX8g72nvtFMnammlBixlFwECJaEszEQk5tc2ti8uG2z+kGnFoDoBV
|
||||
M6ZVMpKDJzXPxLdzT6ChIPyatjIkqOKe6vDpnmzcoEhbBhmtkVjWFA2dfX846ugV
|
||||
y1QiecWgk8pMNWhh3IDd05v/wzbFwNcq+Gi+1dZsPmFH+egIcrQKZu2r3jCJtGHh
|
||||
DNG/nyf/anqvKXF90bi4hRT3vdDXXuWgY7EUwfn9h5jYabCO6HsQxQOBjFYNmBrh
|
||||
MfaiBZe72E8fzNAfIlwDcJ4AWY1SOM7hi8bqfRWw1NtNxuMUiRFoR31O6XkQauye
|
||||
9hAmpdlZHZXtJ6LM0QaWkPJmG3058GMtIn/qS60V9nINh+zXhwza/1pnFB+e9MWc
|
||||
hAPgo0nn55FusM//g1nM31PKe+nOm3Jyp0nEQ4m8aDtJS63o2fvp3e2KJbPWQMHE
|
||||
a83W975diWg4NTdevV9lFpNllHclVoPoavUHIzHd7HF9TcPpjbXJSUZ7cITHHefr
|
||||
kQTa/2G9cWuRhN9GKIHBdr13nfEvMIIFQQYJKoZIhvcNAQcBoIIFMgSCBS4wggUq
|
||||
MIIFJgYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECDgnjfOf
|
||||
AjArAgIIAASCBMgkbVuptroBdyMY5gl/eBQj5+iAV02YSaF969ihStLSWI4x5FAf
|
||||
HuDgqCyEMSl4RHG8ZvNaO9JoNfIpMK/TPQBoQRCzE2Vjf66VTERaQtU6h7tZrbQt
|
||||
K96n9eqvohm/vXbXe08fsodYp2s79kAvKgpuGG5iX77qYVzJHBPed87cvczo4ToP
|
||||
CpurDpByt8fGEmjtcikal8o+H9uoHjcFwqMigX1Q7IEjuKXrb5e6wTvxMRob8yfv
|
||||
LVl6ahteKSkWCMb6rLZ5f12jDoCGX/YXRrSsU9t/lXe0Nxv5i7c8flb2EsNtwygD
|
||||
fexVvn5u6ble6RDYNpuQkPgF41HyZh+JvGAF6i1r4tJPL9Pf4HnjEB8Y8IHgon+w
|
||||
T5I+8LTgcrWyhptzblXMjKySTEp9OEa2cCVwZkl4z43PWJ5oIAQ2IDTOQ603/5o/
|
||||
d9KA76/zMPQ5O0gv17OA7kwFv98v6sTcR4vgkQZqnyDpJSEPHyNxhw2MSBqS3jq3
|
||||
YPhRz+3Ei1oFp9uYFhzn39f9gzNi++X9pOjSrDb8v3mcDXZKNrxQLuoRMSf0eQNI
|
||||
dgJRqj/fuqNZ5ac3kd4P5BALCsnA1tM27zYrgUdpOnrc2D9FBthEjpRlQKMMzhQf
|
||||
cNMFWmoNjakDilvvLcsQeQ3P6cXbN1ODoNnjgK3VzcmeKyzW2PrTXEPHARUM3j4V
|
||||
sZzGaUOVKLqaaDrXWQKC0vrTvxP2WMfjQ1dTdXQP/kSZTXRC5rtB9tky38flBor0
|
||||
N9rhUDIGMs5qBvyrkV2hKXiW39G69p1KWY+Cw28AzY+CNSjePRi60TsnUxgcOS7i
|
||||
0AT25Gx3A4YqxmTY38MPB4wPcBPcw4hjNoQamaC9mqs+KVHcP5YHUlqykMeH0YVi
|
||||
J+ehytJE9xuDcfBOjxjadxp3/q/Lku4rky89gdJGFQWuuz75VulDywPRZRwmQTel
|
||||
sjEGMHR1zTOlPJdTDWhqaKmWvL4GhbCgEPIKwmqd1QKRTl/3Baa1nYllJeYVwiTT
|
||||
qLCkbA6qXrLGj1ENZxrKn9yqr8HwOoApjwhARu4LF/BRMgdkzelK2kOXHnZ26sZ2
|
||||
NY/MMtVmq4c59y6iQwmsbHr9tWGz3ahyXcZZufjNXU/AVnO1c92g7umAWZF4RohL
|
||||
gMmh57cAhN9PEbEv6j/6BT3XXp8jB0ywcRriYxfxwidviCKH/76Q4sytYJQaDFI1
|
||||
fnzmv0aDotbG2BdpWSiYPDOPm+3cmfjlULsn1FYWL4NDCX1f+C4lNtKVX9LU8c5M
|
||||
m8dA1DUlDfnuNO5/BShuoGXG2z4O/XwxIaRFizMxWS2sWurbAEFJ6oNw3kC7WSah
|
||||
NIe8aUC1umpc1Gk3X2f4Ytzj9OEqn0y55qoqLINJuejXMffF/gjopxHWadLVaVaj
|
||||
Q1SewrECuEXdSbBR/a10po24wmRtkmlvRJXJl7sG95xE5ZCqp+m6sRPWGdf1yKbV
|
||||
vyWNUe4Qvkxe4a0VAJpTyIGr980CKz/jkvtNQMobGl7AfhxKJ450wg454WcexMct
|
||||
BYXvZMSdUDCgMLlh0nHJHl5btrFWqE0Z/fqWmIknZL2jZ4J+2hdVl/xB/sUt6kcu
|
||||
txw+RfL+vNE8PxhTNaOdJFwD8yeN1mJ3yMUA8HHYpw9yljgxJTAjBgkqhkiG9w0B
|
||||
CRUxFgQUDYlgGVxSxuOknhQc256x3++7BDwwMTAhMAkGBSsOAwIaBQAEFFjASdYl
|
||||
3pXAXxZuvVvv9tsb4bdrBAhyb+KCIjp/gAICCAA=
|
||||
|
||||
+21
-19
@@ -1,21 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIUdpdDPiNqilWn26oMvcpT9qmMtoswDQYJKoZIhvcNAQEL
|
||||
BQAwPjELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAk5JMQowCAYDVQQHDAFOMQowCAYD
|
||||
VQQKDAFTMQowCAYDVQQLDAFTMB4XDTIzMTEwNTEzMDg1OFoXDTI0MTEwNDEzMDg1
|
||||
OFowPjELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAk5JMQowCAYDVQQHDAFOMQowCAYD
|
||||
VQQKDAFTMQowCAYDVQQLDAFTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAzT30t7Adb6XdXWywzC4RF03r3piTt5MF4MZClvorsl8bySNKrYkl7i5+igpz
|
||||
36SfLp090Dal0cUZ7it9QCxaxrWv3m8OFAwfwK5ePuzUryF6/QJcoF560Sq4k3Pb
|
||||
640PJ5UlFwvUqsXQN8A/pAA6S96MqpwCrPQE0u5OcRQuVIsZxBL2s17lv5eROjX+
|
||||
Ufx/6qtmuZscn9xKDP6GNO8aa6X0YZMoVXlll14iEn4bg0yagiY7QhvVCzK8q7nB
|
||||
9yKCLvw/28eSoD08yJnHnUZnIOoNrn+cZKTkl8VcyKW55IeOiUilb5h3a07JD6bj
|
||||
Q/VroPQE5UtveajB9CBa3eUCiwIDAQABo1MwUTAdBgNVHQ4EFgQUIQGrIwhvSNkG
|
||||
L3ATZra96d4cDE4wHwYDVR0jBBgwFoAUIQGrIwhvSNkGL3ATZra96d4cDE4wDwYD
|
||||
VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAp2mCfhRf6Jft6lSgL4hi
|
||||
I8xHfqcUjG+XnDM1Pi7gKVxxclwVQ67vVtfO0rU1SBPWUO3nIaaLN9Wyzcx+LXPV
|
||||
4e3pyHlq2T6Z6ENuozOsMhHeY9+ows6wPBcxq57KLLHnBpx3lJiKHKOp0ueiAbkz
|
||||
LaI+Mm+VQo0MbzhCw7KXs8VPFt8YO+S3XircVMWaa007VgGY/NjYF62hlG35fD/v
|
||||
CTHccRj5Y3coQ2MjosTUQTd4u3N5VhgxdRbyMdpjpwDxu0u9BE7ISXKMBhnBLV/w
|
||||
+/mxoF2bqExBuPiZS8vT6yW9rehdi/KR9c26GUreTsKLtjXyveeP6VLoTJ60T3D9
|
||||
Jg==
|
||||
MIIDxTCCAq2gAwIBAgIUAZQ9QST2eBZz5k9pCa//mHQVm1QwDQYJKoZIhvcNAQEL
|
||||
BQAwcjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQKDA1P
|
||||
cGVuU2lnbiBMYWJzMREwDwYDVQQDDAhPcGVuU2lnbjElMCMGCSqGSIb3DQEJARYW
|
||||
aGVsbG9Ab3BlbnNpZ25sYWJzLmNvbTAeFw0yMzExMTcxOTQ0MzZaFw0yNDExMTYx
|
||||
OTQ0MzZaMHIxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEWMBQGA1UE
|
||||
CgwNT3BlblNpZ24gTGFiczERMA8GA1UEAwwIT3BlblNpZ24xJTAjBgkqhkiG9w0B
|
||||
CQEWFmhlbGxvQG9wZW5zaWdubGFicy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQDLRKLjCSrvV1zAY2leWxCvdKTUaThpQO8nWPE/4v5ilMU2aRON
|
||||
krAnli0LUfQ/tIRWNurxwVjJ7HrW3ICLn05GBLjm2AUCfuMbJCvOEEdmFJqRY04n
|
||||
12fBZWz2KtzbZEIBVxLhc4E4g+Rz68hQA2fqwNuFdyGkkIbhVXpZIePEppqRmw+2
|
||||
uuDvIzJ77rdDaLqwwPoHWenZ2uZTedKXx7PGYs98psg35GvcpssqAJGAIAi9Rzg/
|
||||
ZV4oSpGXCjn/TJy61zTDbmPFCS/rC1XBWzBQfwDeBPDI18W6gPVX6N4dp0Ao+n8Q
|
||||
txeI6g4FzMH91KPbdbZXxm8rZqXj87VQs9trAgMBAAGjUzBRMB0GA1UdDgQWBBRN
|
||||
NtRPagnqovdmbrdhSUON9Rwd3TAfBgNVHSMEGDAWgBRNNtRPagnqovdmbrdhSUON
|
||||
9Rwd3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBrcPyA7GHq
|
||||
+ol9qjy9HijpoU5MaEiV9v9H8/0v7KoXUND3rMl37yFyjxGN8uda8WxpEhE2eFnk
|
||||
Xjtm2NgPrv8qeYHor/A3y5RfQhnlCY4kE1bREZGhcuKihR4rOtmComwFjx4Ibwwj
|
||||
4nKsflj6rXcWKSfSNHLkXFXHPYwyqRsKdtClrD/8YJn6LeeMlMjIYGGP4qyi2WwS
|
||||
Z8hExWGEMaMWiA9rxTMX6iu/parGH/pWU/55Os3WlcHPhlvqchBkQFJ+f8b+NYz0
|
||||
vIHQgwn4K5WMsZVLxoiUcU7cSqE/qhnP+pzBf8lRaYwd+zUznDvzpKKz6nFgeHok
|
||||
s8BK7JAKkIsl
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
+30
-30
@@ -1,30 +1,30 @@
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIJvntFBuTIWACAggA
|
||||
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECEE+1CDDu5XvBIIEyEwR/61HhjJ0
|
||||
P6oGr1E+uDTKVcUqK++fbsrhqxYq+oEoj+w5C1KOgUxQYQTm2he6PhfGkPh56V9w
|
||||
OaArJ+QrGrSFRUdTtLZG+qBbfyWKQyah9VxwYhmG9Ptf6RyQXDJnup4WtgJWI2sw
|
||||
fAcJ6QqPQkSFUq/0cn0s/RLNCy6P8qKfUjdVugEv0K9dsc7dFNWZQEQlpyKeZdbY
|
||||
rJfKjf85qSmDpFfRnP1B0n//vzlPWK03fNH2be4EnBTFW7l1sDnju6iwasLSP7P+
|
||||
EuGq8Bw9YGlf3I/STWGgfxWWLZACCjgVDiRjLakstkodLqC1tZAWawOKcDQGPyKG
|
||||
nRrF/yF4H0ChmcMBA9Ur4zxBd4uayWujwqIPehfWU+ODYYaVDluSVrxiTaSHGAP2
|
||||
XnT6vrOnR5sg/uzgsbuApHTbHCW+lplof/R0swvwyt15fKaD8HsngNMN6R75e0ar
|
||||
6+ltI/BLgcSbu0f7Fe8qMumBNrJiU5j09EdvDKaIEe3+Ko2HWCV/zLgxvL8BwGyB
|
||||
K9RSMw1YzivO/CahWE3cQcS4GQSX84+y8VXF43CxpmTRf3Hmdpj4JBGB0fOvGHzA
|
||||
hv+st5E+hhSOOv2ZZ00XtEaUi3d2uQFYApxEoXubz2QG481M7ulNXaVd74DZf/Fr
|
||||
J+R7BmCa633rEw34sXFKUcfdfVOzUfMnMGvO5danSrov6k/cFfLPH56ORb9Ep30a
|
||||
U1fXHP+pcFQohR/kjAk5gjDUr8pjkOJ0/JHv106rptT4SNCznvJa8BvWtP9wDXDv
|
||||
UZDA/UCLlnl20mJUjLtb0iM5vtqhi7XOxDoS8AauOimSEh+M0uLEZ7HOQvtGchLl
|
||||
tDLd/DVew/WzPBhL4eNTmhwwno9JL21nPBEaFAa58djoiZXgzUdLQbBDbo/7nsRA
|
||||
UJ9imt0HmhDU+xrimnMZJD051KcbohHjPvTnTb4qvd0Rt7u/dpL9NT07rQlVIe3u
|
||||
qGl4sEe+1vEueRdHt5QCSGbxnwPPHdE9XMsK8et3M/DOYN+ToB9QmDm72lLsJNkm
|
||||
0nxdYVpfXHUiPmMorkJgb9YXfY+j0UEWuT0l4bl7a5+mzGm/Zy9FCoLaW7MTWNJd
|
||||
fyDSYsVotOhRdCBi0Osho21GldKmfX6XoqHYENVqsh7x9bgvjNwvLNgpCWXYh7/Q
|
||||
K6N3iDQ3G3A6x9nOgeKpXYREd8fx8byM6u7FAttVTtcV71QaWU3TSn7Oice1Bklg
|
||||
osIhUJydHny856D/WCD6EmnPBuukx9Tht8NKtJVS0XoXqbz69mx4xfq987HGkJJa
|
||||
nvCgkZOr/LhcVylmRjg9ZVfiUrwim4Gp42gV3JtsZpOGE1m+1twSXShtr/PQ2FdF
|
||||
jD41LOEG1OGdZ5XIDLxAI4085jwVD/WIRo/AZELENog1XKtjeXSqJ/H7njauB30w
|
||||
MeNv0VRTIItVA0eXRDwoqjpqyGSdn9YF2SQ/qDR6WU+Y2bVD38m6ZJlsy/zHx9uc
|
||||
sH1DK7hbbRRSuZ9Sx/TjD19DWJ4qNPTpUZTd0+dxsG/HGQKpkbpXI5f3aQ6nTWWM
|
||||
MjlWF6mUI06iLIRhLyNwBrtEjJHL1k8fIOvO/MUKtj72VBGt/fnoutS0WifZLvfn
|
||||
mFXB4iaMX0hGcgzpK4iNcg==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,5932FA9F02938D1B
|
||||
|
||||
6gkkZP80WrVnR3dVwkimtfirSeYNXZlrXXBv+Ddjyq7FScqca7svJFd8ObC0xXjg
|
||||
nbxChDKS8SXcSjsNCTzixG0QReO5vaqovrpQoYbkSQ9GRMIVV8WuWNzlyMnypNJ4
|
||||
Z6hdpd5nkc1hIP8A6WcY3lA8msyHceU9IidEEb75CE743qsvUMko+XvqntZx/LNe
|
||||
0uK8Bs+cXeDzolpNX8ORKBTAOMii+WPlN2l+9ldsWTECEk4GmWa51QfpKouLxz5E
|
||||
u7fuGuku/nPKGb4Yj7sCgaD91UabRksDLS9UGDBqeNL+mogG3gY/Iu0/q2cUs6XR
|
||||
x1W6KW1eJHnOf1pAp7+G/zNqzdsxI3pnoR+nsV6/G0glBLar+Xqc99B568lnUWWv
|
||||
5NGN3Buz1axx1jPKIknDcT4Skmvt6TcmgrjoCQ9XvmNKVClpExQ+dKPmJI/EVNoU
|
||||
jjDZyfghcJ6BEMcTgoOBDiUrPM0273sb89u/AzyUA1tTciW2KARz6cOUTPWVRSRn
|
||||
4yXpkA4BJDpxRmK68BXorZLNxtvHk+on80c9tu5e+IVa3Gu1K7gc269TPmlIolAM
|
||||
v//i+jpwJ4Pe2IGVYdojMr15useUv7JC6/Kconnkx4q9rkMriguuXoQt8qW3kvEs
|
||||
Ur8KuibtDqhz2zGbsKboQFMOd6cdd+63dJCGAUqk4hFrSikTw3LhkXNcg9GZHq1z
|
||||
WFAfaA3x2jd+kJJ5xg8xMVEHax5IAOXDL2ektyPFpI1UZOuTc2i7FK6Y0NnXPkSN
|
||||
G/+DsKdLWT943mPfZj01mTRi3MgseDXsHMHGmmPxW9J4jv+WW4OdpHvd474QzJ8b
|
||||
vQmyiKq4XPHsuQUkzHVPbTrGe1B9z4p97YQKdEfXP2ChGFsUHCYQdpHyXwie2+pq
|
||||
E2rc7Bai0OuL0anYMSIvDrJ0DE8mVVaFur1b2Uz6ieCDlrOXnzD1BrcleiZem7og
|
||||
on/3oCUK+qxibCCcd5Hg2HtPusa43U0/UbCrqb2sww9iN36DLdtef/jlozKNiBx9
|
||||
e8ZztF6GtAKhIdgGW/M9TXMUZOYr7aaXO71MsqhwpVWZ5dNqagOBzhmd7Etokf1H
|
||||
O0WxJZ5XPDsnlKwYq86ssK+2RCNYAuvZoM3dRCysPvXoBFmsmHDzKdbKcckd8Vxr
|
||||
6P1yaCkB/iX55dUqwKfIuqxY3m4MA2Us9DD0BRxZOSUqHhzHHSogsLhqLQEQENA4
|
||||
U9N/v/za81UaU8nfkAswsGlTdTKjWH6Fzc0NeagbEFtpUaG/WIHPesUzU7ZNvMzR
|
||||
SQACVWl62Dley2g2eAgcrsIn78MbwNJI2YN5eXIw0K2MiMlGXWOEvkjIIVfjc0/d
|
||||
QxLFJwqShZBVO+jnAJ8jti7mP6PgskjtfHNAIphRJ4fm9h/Ns1YMpipBRVBDhbwY
|
||||
AOVT4bRw9Q3O5I0pe10ZdViAhexegQ8yGt3pUlKaUf9GRwIFEknjZ5Pc98V/R/wC
|
||||
INSIOZzDHj2uyZ3p7ToF1Z6kVVbbyfqDOnxUiV2ykR8ZqQMXNWcEJKH8qRqI+VHf
|
||||
oszD2BQvXgkWdrJtHuHjJCdDl03Y+daS5yP8IKTDucHvRv4ZSMghZ34SJTw5MaBP
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
Binary file not shown.
+20
@@ -36,6 +36,7 @@
|
||||
"react-scrollbars-custom": "^4.1.1",
|
||||
"react-signature-canvas": "^1.0.6",
|
||||
"reactour": "^1.19.1",
|
||||
"select-dom": "^9.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
}
|
||||
},
|
||||
@@ -18702,6 +18703,20 @@
|
||||
"resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz",
|
||||
"integrity": "sha512-HSdN78VMvFCSGCkh0oYX/tY4R3P1DW61f8+TeZZ4j2VLgfwvw0bpRSOv4PCVKisktIwbzHCfZsx+rLbbDBqIBA=="
|
||||
},
|
||||
"node_modules/select-dom": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-dom/-/select-dom-9.0.0.tgz",
|
||||
"integrity": "sha512-AD1NfASSwJQc1Sy713R1vT9CMmUSUo2tg0j1FtkRGIxllTphDrkuH2pYYvhRlGaoq3pS6tcKkKS/diEZLy+7BQ==",
|
||||
"dependencies": {
|
||||
"typed-query-selector": "^2.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/fregante"
|
||||
}
|
||||
},
|
||||
"node_modules/select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
@@ -20203,6 +20218,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-query-selector": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.11.0.tgz",
|
||||
"integrity": "sha512-qBs4sfmnLlPOyo2oSdvHbIFHe2CPgU54/1UGfSNceb7LARpIEVxUaeRX0Doje6oKpuySS2stqy90R3YrynR8Kg=="
|
||||
},
|
||||
"node_modules/typedarray-to-buffer": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"react-scrollbars-custom": "^4.1.1",
|
||||
"react-signature-canvas": "^1.0.6",
|
||||
"reactour": "^1.19.1",
|
||||
"select-dom": "^9.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "./certificate.css";
|
||||
import opensignLogo from "../../assests/open-sign-logo.png";
|
||||
|
||||
import { Page, Text, View, Document, StyleSheet } from "@react-pdf/renderer";
|
||||
import {
|
||||
Page,
|
||||
Text,
|
||||
View,
|
||||
Document,
|
||||
StyleSheet,
|
||||
Image
|
||||
} from "@react-pdf/renderer";
|
||||
|
||||
function Certificate({ pdfData }) {
|
||||
const [isMultiSigners, setIsMultiSigners] = useState();
|
||||
@@ -49,70 +57,34 @@ function Certificate({ pdfData }) {
|
||||
fontSize: "11px",
|
||||
marginBottom: "10px",
|
||||
color: "gray"
|
||||
},
|
||||
image: {
|
||||
width: "71px",
|
||||
height: "17px"
|
||||
}
|
||||
});
|
||||
|
||||
const generatedDate = () => {
|
||||
const newDate = new Date();
|
||||
const localExpireDate = newDate.toLocaleDateString("en-US", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
|
||||
var currentOffset = newDate.getTimezoneOffset();
|
||||
|
||||
var ISTOffset = 330; // IST offset UTC +5:30
|
||||
|
||||
var ISTTime = new Date(
|
||||
newDate.getTime() + (ISTOffset + currentOffset) * 60000
|
||||
);
|
||||
|
||||
// ISTTime now represents the time in IST coordinates
|
||||
|
||||
var hoursIST = ISTTime.getHours();
|
||||
var minutesIST = ISTTime.getMinutes();
|
||||
const utcTime = newDate.toUTCString();
|
||||
|
||||
return (
|
||||
<Text
|
||||
style={{
|
||||
textAlign: "right",
|
||||
color: "gray",
|
||||
fontSize: "10px",
|
||||
marginBottom: "30px"
|
||||
fontSize: "10px"
|
||||
}}
|
||||
>
|
||||
Generated On {localExpireDate} {hoursIST}:{minutesIST} IST
|
||||
Generated On {utcTime}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
const changeCompletedDate = () => {
|
||||
const completedOn = pdfData[0].updatedAt;
|
||||
const newDate = new Date(completedOn);
|
||||
const localExpireDate = newDate.toLocaleDateString("en-US", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric"
|
||||
});
|
||||
const utcTime = newDate.toUTCString();
|
||||
|
||||
var currentOffset = newDate.getTimezoneOffset();
|
||||
|
||||
var ISTOffset = 330; // IST offset UTC +5:30
|
||||
|
||||
var ISTTime = new Date(
|
||||
newDate.getTime() + (ISTOffset + currentOffset) * 60000
|
||||
);
|
||||
|
||||
// ISTTime now represents the time in IST coordinates
|
||||
|
||||
var hoursIST = ISTTime.getHours();
|
||||
var minutesIST = ISTTime.getMinutes();
|
||||
|
||||
return (
|
||||
<Text style={styles.textStyle2}>
|
||||
{localExpireDate} {hoursIST}:{minutesIST} IST
|
||||
</Text>
|
||||
);
|
||||
return <Text style={styles.textStyle2}>{utcTime}</Text>;
|
||||
};
|
||||
|
||||
const signerName = (data) => {
|
||||
@@ -143,7 +115,19 @@ function Certificate({ pdfData }) {
|
||||
{/** Page defines a single page of content. */}
|
||||
<Page size="A4" style={styles.page}>
|
||||
<View style={styles.section1}>
|
||||
{generatedDate()}
|
||||
<View
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
marginBottom: "30px"
|
||||
}}
|
||||
>
|
||||
<Image src={opensignLogo} style={styles.image} />
|
||||
{generatedDate()}
|
||||
</View>
|
||||
|
||||
<View style={{ justifyContent: "center" }}>
|
||||
<Text
|
||||
style={{
|
||||
@@ -182,7 +166,9 @@ function Certificate({ pdfData }) {
|
||||
</Text>
|
||||
<Text style={styles.textStyle}>
|
||||
Organization :
|
||||
<Text style={styles.textStyle2}>__</Text>
|
||||
<Text style={styles.textStyle2}>
|
||||
{pdfData[0].ExtUserPtr.Company}
|
||||
</Text>
|
||||
</Text>
|
||||
<Text style={styles.textStyle}>
|
||||
Completed on : {changeCompletedDate()}
|
||||
@@ -260,6 +246,12 @@ function Certificate({ pdfData }) {
|
||||
{pdfData[0].ExtUserPtr.Name}
|
||||
</Text>
|
||||
</Text>
|
||||
<Text style={styles.textStyle}>
|
||||
Email :
|
||||
<Text style={styles.textStyle2}>
|
||||
{pdfData[0].ExtUserPtr.Email}
|
||||
</Text>
|
||||
</Text>
|
||||
<Text style={styles.textStyle}>
|
||||
Accessed from :
|
||||
<Text style={styles.textStyle2}>
|
||||
|
||||
@@ -1,61 +1,47 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import axios from "axios";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Loader from "./component/loader";
|
||||
import { getHostUrl } from "../utils/Utils";
|
||||
import { contractDocument, getHostUrl } from "../utils/Utils";
|
||||
function DraftDocument() {
|
||||
const navigate = useNavigate();
|
||||
const [pdfDetails, setPdfDetails] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState({
|
||||
isLoad: true,
|
||||
message: "This might take some time",
|
||||
message: "This might take some time"
|
||||
});
|
||||
|
||||
const rowLevel =
|
||||
localStorage.getItem("rowlevel") &&
|
||||
JSON.parse(localStorage.getItem("rowlevel"));
|
||||
const signObjId =
|
||||
const docId =
|
||||
rowLevel && rowLevel?.id
|
||||
? rowLevel.id
|
||||
: rowLevel?.objectId && rowLevel.objectId;
|
||||
|
||||
useEffect(() => {
|
||||
if (signObjId) {
|
||||
if (docId) {
|
||||
getDocumentDetails();
|
||||
}
|
||||
}, []);
|
||||
|
||||
//get document details
|
||||
const getDocumentDetails = async () => {
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document?where={"objectId":"${signObjId}"}&include=ExtUserPtr,Signers`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
||||
},
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
|
||||
if (res[0] && res.length > 0) {
|
||||
setPdfDetails(res);
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
alert("No data found!");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("axois err ", err);
|
||||
});
|
||||
//getting document details
|
||||
const documentData = await contractDocument(docId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
setPdfDetails(documentData);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
} else if (
|
||||
documentData === "Error: Something went wrong!" ||
|
||||
(documentData.result && documentData.result.error)
|
||||
) {
|
||||
alert("Error: Something went wrong!");
|
||||
} else {
|
||||
alert("No data found!");
|
||||
}
|
||||
};
|
||||
|
||||
//check document type and render on signyour self and placeholder route
|
||||
@@ -63,24 +49,25 @@ function DraftDocument() {
|
||||
const data = pdfDetails[0];
|
||||
const checkSignerExist =
|
||||
pdfDetails[0] && pdfDetails[0].Signers && pdfDetails[0].Signers;
|
||||
const isPlaceholder =
|
||||
const isPlaceholder =
|
||||
pdfDetails[0].Placeholders && pdfDetails[0].Placeholders;
|
||||
const isDecline = data.IsDeclined && data.IsDeclined;
|
||||
const signUrl = data.SignedUrl && data.SignedUrl;
|
||||
const expireDate = pdfDetails[0] && pdfDetails[0].ExpiryDate.iso && pdfDetails[0].ExpiryDate.iso;
|
||||
const expireDate =
|
||||
pdfDetails[0] &&
|
||||
pdfDetails[0].ExpiryDate.iso &&
|
||||
pdfDetails[0].ExpiryDate.iso;
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
const currDate = new Date().getTime();
|
||||
const hostUrl = getHostUrl();
|
||||
|
||||
//checking document is completed and signer exist then navigate to pdfRequestFiles file
|
||||
if (data.IsCompleted && checkSignerExist) {
|
||||
navigate(`${hostUrl}pdfRequestFiles`);
|
||||
navigate(`${hostUrl}pdfRequestFiles`);
|
||||
}
|
||||
//checking document is completed and signer does not exist then navigate to recipientSignPdf file
|
||||
else if (data.IsCompleted && !checkSignerExist) {
|
||||
navigate(
|
||||
`${hostUrl}signaturePdf`
|
||||
);
|
||||
navigate(`${hostUrl}signaturePdf`);
|
||||
}
|
||||
//checking document is declined by someone then navigate to pdfRequestFiles file
|
||||
else if (isDecline) {
|
||||
|
||||
+8
-2
@@ -99,7 +99,7 @@ function PdfFileComponent({
|
||||
|
||||
//function for navigate user to microapp-signature component
|
||||
const checkPdfStatus = async (data) => {
|
||||
|
||||
|
||||
const hostUrl = getHostUrl();
|
||||
const expireDate = data.ExpiryDate.iso;
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
@@ -221,13 +221,19 @@ function PdfFileComponent({
|
||||
// console.log("download")
|
||||
const pdfName = data && data.Name;
|
||||
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
|
||||
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`);
|
||||
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||
} else if (selectType === "Rename") {
|
||||
// console.log("rename")
|
||||
setRenameValue(data.Name);
|
||||
setRename(data.objectId);
|
||||
}
|
||||
};
|
||||
|
||||
const sanitizeFileName = (pdfName) => {
|
||||
// Replace spaces with underscore
|
||||
return pdfName.replace(/ /g, '_');
|
||||
}
|
||||
|
||||
const handleEnterPress = (e, data) => {
|
||||
if (e.key === "Enter") {
|
||||
handledRenameDoc(data);
|
||||
|
||||
@@ -6,6 +6,7 @@ import PdfFileComponent from "./FolderDrive/legaDriveComponent";
|
||||
import Modal from "react-bootstrap/Modal";
|
||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
||||
import { themeColor, iconColor } from "../../utils/ThemeColor/backColor";
|
||||
import { getDrive } from "../../utils/Utils";
|
||||
|
||||
function PdfFile() {
|
||||
const scrollRef = useRef(null);
|
||||
@@ -15,28 +16,24 @@ function PdfFile() {
|
||||
const [pdfData, setPdfData] = useState([]);
|
||||
const [isFolder, setIsFolder] = useState(false);
|
||||
const [newFolderName, setNewFolderName] = useState();
|
||||
// const [parentFolderName, setParentFolderName] = useState();
|
||||
// const [parentFolder, setParentFolder] = useState([]);
|
||||
const [error, setError] = useState();
|
||||
const [folderLoader, setIsFolderLoader] = useState(false);
|
||||
const [isShowSort, setIsShowSort] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState({
|
||||
isLoad: true,
|
||||
message: "This might take some time",
|
||||
message: "This might take some time"
|
||||
});
|
||||
const [docId, setDocId] = useState();
|
||||
const [handleError, setHandleError] = useState();
|
||||
|
||||
const [folderName, setFolderName] = useState([]);
|
||||
|
||||
const senderUser =
|
||||
const currentUser =
|
||||
localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
) &&
|
||||
localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
);
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
const jsonCurrentUser = JSON.parse(currentUser);
|
||||
|
||||
useEffect(() => {
|
||||
if (docId) {
|
||||
@@ -50,104 +47,59 @@ function PdfFile() {
|
||||
const getPdfDocumentList = async () => {
|
||||
const load = {
|
||||
isLoad: true,
|
||||
message: "This might take some time",
|
||||
message: "This might take some time"
|
||||
};
|
||||
setIsLoading(load);
|
||||
//?where={"Type":"Folder" }&include=ExtUserPtr,Signers
|
||||
//?where={"$or":[{"Type":{"$exists":true}},{"Folder":{"$exists":false}}]}&include=ExtUserPtr,Signers
|
||||
// "CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${jsonSender.objectId}"}
|
||||
// where={"Folder":{"$exists":false} }&include=ExtUserPtr,Signers`,
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document?where={"Folder":{"$exists":false},"$or":[{"CreatedBy":{"$exists":false}},{"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${
|
||||
jsonSender.objectId
|
||||
}"}}]}&include=ExtUserPtr,Signers`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
||||
},
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
// console.log("result", res);
|
||||
if (res[0] && res.length > 0) {
|
||||
setPdfData(res);
|
||||
}
|
||||
const driveDetails = await getDrive();
|
||||
|
||||
const data = [
|
||||
{
|
||||
name: "OpenSignDrive™",
|
||||
objectId: "",
|
||||
},
|
||||
];
|
||||
setFolderName(data);
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
})
|
||||
.catch((err) => {
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
});
|
||||
if (driveDetails) {
|
||||
if (driveDetails.length > 0) {
|
||||
setPdfData(driveDetails);
|
||||
}
|
||||
const data = [
|
||||
{
|
||||
name: "OpenSignDrive™",
|
||||
objectId: ""
|
||||
}
|
||||
];
|
||||
setFolderName(data);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
} else if (driveDetails === "Error: Something went wrong!") {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
};
|
||||
//function for get parent folder document list
|
||||
const getPdfFolderDocumentList = async () => {
|
||||
const load = {
|
||||
isLoad: true,
|
||||
message: "This might take some time",
|
||||
message: "This might take some time"
|
||||
};
|
||||
setIsLoading(load);
|
||||
//{"$inQuery":{"where":{"objectId":"${docId}"},"className":"${appName}_Document"}}
|
||||
//"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${jsonSender.objectId}"}
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document?where={"Folder":{"__type":"Pointer","className":"${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document","objectId":"${docId}"},"$or":[{"CreatedBy":{"$exists":false}},{"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${
|
||||
jsonSender.objectId
|
||||
}"}}]}&include=ExtUserPtr,Signers,Folder`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
||||
},
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
|
||||
if (res[0] && res.length > 0) {
|
||||
setPdfData(res);
|
||||
} else {
|
||||
setPdfData([]);
|
||||
}
|
||||
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
})
|
||||
.catch((err) => {
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
});
|
||||
const driveDetails = await getDrive(docId);
|
||||
if (driveDetails) {
|
||||
if (driveDetails.length > 0) {
|
||||
setPdfData(driveDetails);
|
||||
} else {
|
||||
setPdfData([]);
|
||||
}
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
} else if (driveDetails === "Error: Something went wrong!") {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
};
|
||||
|
||||
//function for get all pdf document list
|
||||
@@ -158,7 +110,7 @@ function PdfFile() {
|
||||
const handleRoute = (data) => {
|
||||
let loadObj = {
|
||||
isLoad: true,
|
||||
message: "This might take some time",
|
||||
message: "This might take some time"
|
||||
};
|
||||
if (data.name === "LegaDrive™") {
|
||||
setIsLoading(loadObj);
|
||||
@@ -167,7 +119,7 @@ function PdfFile() {
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}, 1000);
|
||||
@@ -176,12 +128,11 @@ function PdfFile() {
|
||||
setIsLoading(loadObj);
|
||||
setTimeout(() => {
|
||||
const loadObj = {
|
||||
isLoad: false,
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}, 1000);
|
||||
} else {
|
||||
// console.log("go here1",data.objectId)
|
||||
const findIndex = folderName.findIndex(
|
||||
(fold) => fold.objectId === data.objectId
|
||||
);
|
||||
@@ -207,22 +158,32 @@ function PdfFile() {
|
||||
setIsFolderLoader(true);
|
||||
|
||||
const getParentObjId = folderName[folderName.length - 1];
|
||||
const isParentId = getParentObjId && getParentObjId.objectId;
|
||||
const parentId = getParentObjId && getParentObjId.objectId;
|
||||
let data;
|
||||
if (isParentId) {
|
||||
if (parentId) {
|
||||
data = {
|
||||
Name: newFolderName,
|
||||
Type: "Folder",
|
||||
Folder: {
|
||||
__type: "Pointer",
|
||||
className: `${localStorage.getItem("_appName")}_Document`,
|
||||
objectId: isParentId,
|
||||
objectId: parentId
|
||||
},
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: jsonCurrentUser.objectId
|
||||
}
|
||||
};
|
||||
} else {
|
||||
data = {
|
||||
Name: newFolderName,
|
||||
Type: "Folder",
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: jsonCurrentUser.objectId
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -237,8 +198,8 @@ function PdfFile() {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken"),
|
||||
},
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -388,7 +349,7 @@ function PdfFile() {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
@@ -406,7 +367,7 @@ function PdfFile() {
|
||||
style={{
|
||||
margin: "10px 0px 10px 0px",
|
||||
fontSize: "15px",
|
||||
fontWeight: "400",
|
||||
fontWeight: "400"
|
||||
}}
|
||||
>
|
||||
Name*
|
||||
@@ -428,7 +389,7 @@ function PdfFile() {
|
||||
display: "flex",
|
||||
alignItems: "flex-end",
|
||||
justifyContent: "flex-end",
|
||||
alignContent: "flex-end",
|
||||
alignContent: "flex-end"
|
||||
}}
|
||||
>
|
||||
<button
|
||||
@@ -437,7 +398,7 @@ function PdfFile() {
|
||||
borderRadius: "0px",
|
||||
border: "1.5px solid #e3e2e1",
|
||||
fontWeight: "600",
|
||||
color: "black",
|
||||
color: "black"
|
||||
}}
|
||||
className="finishBtn"
|
||||
onClick={() => setIsFolder(false)}
|
||||
@@ -448,7 +409,7 @@ function PdfFile() {
|
||||
<button
|
||||
onClick={() => handleAddFolder()}
|
||||
style={{
|
||||
background: themeColor(),
|
||||
background: themeColor()
|
||||
}}
|
||||
type="button"
|
||||
className="finishBtn"
|
||||
@@ -469,7 +430,7 @@ function PdfFile() {
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
width: "100%",
|
||||
flexDirection: "column",
|
||||
flexDirection: "column"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
@@ -488,7 +449,7 @@ function PdfFile() {
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
width: "100%",
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: "20px", color: "gray" }}>
|
||||
@@ -502,7 +463,7 @@ function PdfFile() {
|
||||
onMouseEnter={(e) => handleMouseEnter(e)}
|
||||
ref={scrollRef}
|
||||
style={{
|
||||
width: "100%",
|
||||
width: "100%"
|
||||
}}
|
||||
className="folderPath"
|
||||
>
|
||||
@@ -514,7 +475,7 @@ function PdfFile() {
|
||||
style={{
|
||||
color: "#a64b4e",
|
||||
fontWeight: "400",
|
||||
cursor: "pointer",
|
||||
cursor: "pointer"
|
||||
}}
|
||||
>
|
||||
{data.name}
|
||||
@@ -523,7 +484,7 @@ function PdfFile() {
|
||||
color: "#a64b4e",
|
||||
fontWeight: "200",
|
||||
cursor: "pointer",
|
||||
margin: "0 4px",
|
||||
margin: "0 4px"
|
||||
}}
|
||||
>
|
||||
>
|
||||
@@ -545,13 +506,13 @@ function PdfFile() {
|
||||
style={{
|
||||
marginRight: "5px",
|
||||
fontSize: "14px",
|
||||
color: `${iconColor()}`,
|
||||
color: `${iconColor()}`
|
||||
}}
|
||||
></i>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "15px",
|
||||
color: `${iconColor()}`,
|
||||
color: `${iconColor()}`
|
||||
}}
|
||||
>
|
||||
{selectedSort}
|
||||
@@ -694,7 +655,7 @@ function PdfFile() {
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "50vh",
|
||||
width: "100%",
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<span style={{ fontWeight: "bold" }}>No Data Found!</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||
import { PDFDocument, rgb } from "pdf-lib";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import "../css/signature.css";
|
||||
import axios from "axios";
|
||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
||||
@@ -11,7 +11,16 @@ import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { useParams } from "react-router-dom";
|
||||
import SignPad from "./component/signPad";
|
||||
import RenderAllPdfPage from "./component/renderAllPdfPage";
|
||||
import { getBase64FromIMG, getBase64FromUrl } from "../utils/Utils";
|
||||
import {
|
||||
convertPNGtoJPEG,
|
||||
contractDocument,
|
||||
getBase64FromIMG,
|
||||
getBase64FromUrl,
|
||||
urlValidator,
|
||||
multiSignEmbed,
|
||||
embedDocId,
|
||||
pdfNewWidthFun
|
||||
} from "../utils/Utils";
|
||||
import Loader from "./component/loader";
|
||||
import HandleError from "./component/HandleError";
|
||||
import Nodata from "./component/Nodata";
|
||||
@@ -84,19 +93,14 @@ function PdfRequestFiles() {
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
|
||||
useEffect(() => {
|
||||
const clientWidth = window.innerWidth;
|
||||
const value = docId ? 80 : 30;
|
||||
const pdfWidth = clientWidth - 160 - 200 - value;
|
||||
|
||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
||||
//pdf from left and right component
|
||||
setPdfNewWidth(pdfWidth);
|
||||
if (documentId) {
|
||||
getDocumentDetails();
|
||||
}
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (divRef.current) {
|
||||
const pdfWidth = pdfNewWidthFun(divRef);
|
||||
setPdfNewWidth(pdfWidth);
|
||||
setContainerWH({
|
||||
width: divRef.current.offsetWidth,
|
||||
height: divRef.current.offsetHeight
|
||||
@@ -106,153 +110,135 @@ function PdfRequestFiles() {
|
||||
|
||||
//function for get document details for perticular signer with signer'object id
|
||||
const getDocumentDetails = async () => {
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document?where={"objectId":"${documentId}"}&include=ExtUserPtr,Signers,UserPtr`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
//getting document details
|
||||
const documentData = await contractDocument(documentId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
const isCompleted =
|
||||
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
||||
const expireDate = documentData[0].ExpiryDate.iso;
|
||||
const declined = documentData[0].IsDeclined && documentData[0].IsDeclined;
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
const currDate = new Date().getTime();
|
||||
const getSigners = documentData[0].Signers;
|
||||
const getCurrentSigner =
|
||||
getSigners &&
|
||||
getSigners.filter(
|
||||
(data) => data.UserId.objectId === jsonSender.objectId
|
||||
);
|
||||
|
||||
if (res[0] && res.length > 0) {
|
||||
const isCompleted = res[0].IsCompleted && res[0].IsCompleted;
|
||||
const expireDate = res[0].ExpiryDate.iso;
|
||||
const declined = res[0].IsDeclined && res[0].IsDeclined;
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
const currDate = new Date().getTime();
|
||||
const getSigners = res[0].Signers;
|
||||
const getCurrentSigner =
|
||||
getSigners &&
|
||||
getSigners.filter(
|
||||
(data) => data.UserId.objectId === jsonSender.objectId
|
||||
);
|
||||
|
||||
const currUserId = getCurrentSigner[0]
|
||||
? getCurrentSigner[0].objectId
|
||||
: "";
|
||||
setSignerObjectId(currUserId);
|
||||
if (res[0].SignedUrl) {
|
||||
setPdfUrl(res[0].SignedUrl);
|
||||
} else {
|
||||
setPdfUrl(res[0].URL);
|
||||
}
|
||||
if (isCompleted) {
|
||||
setIsSigned(true);
|
||||
const data = {
|
||||
isCertificate: true,
|
||||
isModal: true
|
||||
};
|
||||
setAlreadySign(true);
|
||||
setIsCompleted(data);
|
||||
} else if (declined) {
|
||||
const currentDecline = {
|
||||
currnt: "another",
|
||||
isDeclined: true
|
||||
};
|
||||
setIsDecline(currentDecline);
|
||||
} else if (currDate > expireUpdateDate) {
|
||||
setIsExpired(true);
|
||||
}
|
||||
|
||||
if (res.length > 0) {
|
||||
const checkDocIdExist =
|
||||
json.results[0].AuditTrail &&
|
||||
json.results[0].AuditTrail.length > 0 &&
|
||||
json.results[0].AuditTrail.filter(
|
||||
(data) => data.Activity === "Signed"
|
||||
);
|
||||
|
||||
const checkAlreadySign =
|
||||
json.results[0].AuditTrail &&
|
||||
json.results[0].AuditTrail.length > 0 &&
|
||||
json.results[0].AuditTrail.filter(
|
||||
(data) =>
|
||||
data.UserPtr.objectId === currUserId &&
|
||||
data.Activity === "Signed"
|
||||
);
|
||||
if (
|
||||
checkAlreadySign &&
|
||||
checkAlreadySign[0] &&
|
||||
checkAlreadySign.length > 0
|
||||
) {
|
||||
setAlreadySign(true);
|
||||
}
|
||||
|
||||
let signers = [];
|
||||
let unSignedSigner = [];
|
||||
|
||||
//check document is signed or not
|
||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
||||
setAlreadySign(true);
|
||||
setIsDocId(true);
|
||||
const signerRes = res[0].Signers;
|
||||
//comparison auditTrail user details with signers user details
|
||||
for (let i = 0; i < signerRes.length; i++) {
|
||||
const signerId = signerRes[i].objectId;
|
||||
|
||||
let isSigned = false;
|
||||
for (let j = 0; j < checkDocIdExist.length; j++) {
|
||||
const signedExist =
|
||||
checkDocIdExist[j] && checkDocIdExist[j].UserPtr.objectId;
|
||||
//checking signerObjId and auditTrail User objId
|
||||
// if match then add signed data in signer array and break loop
|
||||
|
||||
if (signerId === signedExist) {
|
||||
signers.push({ ...signerRes[i], ...signerRes[i] });
|
||||
isSigned = true;
|
||||
break;
|
||||
}
|
||||
// if does not match then add unsigned data in unSignedSigner array
|
||||
}
|
||||
if (!isSigned) {
|
||||
unSignedSigner.push({ ...signerRes[i], ...signerRes[i] });
|
||||
}
|
||||
}
|
||||
setSignedSigners(signers);
|
||||
setUnSignedSigners(unSignedSigner);
|
||||
|
||||
setSignerPos(res[0].Placeholders);
|
||||
} else {
|
||||
let unsigned = [];
|
||||
for (let i = 0; i < res.length; i++) {
|
||||
unsigned.push(res[i].Signers);
|
||||
}
|
||||
setUnSignedSigners(unsigned[0]);
|
||||
setSignerPos(res[0].Placeholders);
|
||||
}
|
||||
|
||||
setPdfDetails(res);
|
||||
|
||||
setIsUiLoading(false);
|
||||
} else {
|
||||
alert("No data found!");
|
||||
}
|
||||
} else {
|
||||
setNoData(true);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
setIsUiLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("err", err);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
const currUserId = getCurrentSigner[0]
|
||||
? getCurrentSigner[0].objectId
|
||||
: "";
|
||||
setSignerObjectId(currUserId);
|
||||
if (documentData[0].SignedUrl) {
|
||||
setPdfUrl(documentData[0].SignedUrl);
|
||||
} else {
|
||||
setPdfUrl(documentData[0].URL);
|
||||
}
|
||||
if (isCompleted) {
|
||||
setIsSigned(true);
|
||||
const data = {
|
||||
isCertificate: true,
|
||||
isModal: true
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
});
|
||||
setAlreadySign(true);
|
||||
setIsCompleted(data);
|
||||
} else if (declined) {
|
||||
const currentDecline = {
|
||||
currnt: "another",
|
||||
isDeclined: true
|
||||
};
|
||||
setIsDecline(currentDecline);
|
||||
} else if (currDate > expireUpdateDate) {
|
||||
setIsExpired(true);
|
||||
}
|
||||
|
||||
if (documentData.length > 0) {
|
||||
const checkDocIdExist =
|
||||
documentData[0].AuditTrail &&
|
||||
documentData[0].AuditTrail.length > 0 &&
|
||||
documentData[0].AuditTrail.filter(
|
||||
(data) => data.Activity === "Signed"
|
||||
);
|
||||
|
||||
const checkAlreadySign =
|
||||
documentData[0].AuditTrail &&
|
||||
documentData[0].AuditTrail.length > 0 &&
|
||||
documentData[0].AuditTrail.filter(
|
||||
(data) =>
|
||||
data.UserPtr.objectId === currUserId && data.Activity === "Signed"
|
||||
);
|
||||
if (
|
||||
checkAlreadySign &&
|
||||
checkAlreadySign[0] &&
|
||||
checkAlreadySign.length > 0
|
||||
) {
|
||||
setAlreadySign(true);
|
||||
}
|
||||
|
||||
let signers = [];
|
||||
let unSignedSigner = [];
|
||||
|
||||
//check document is signed or not
|
||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
||||
setIsDocId(true);
|
||||
const signerRes = documentData[0].Signers;
|
||||
//comparison auditTrail user details with signers user details
|
||||
for (let i = 0; i < signerRes.length; i++) {
|
||||
const signerId = signerRes[i].objectId;
|
||||
|
||||
let isSigned = false;
|
||||
for (let j = 0; j < checkDocIdExist.length; j++) {
|
||||
const signedExist =
|
||||
checkDocIdExist[j] && checkDocIdExist[j].UserPtr.objectId;
|
||||
//checking signerObjId and auditTrail User objId
|
||||
// if match then add signed data in signer array and break loop
|
||||
|
||||
if (signerId === signedExist) {
|
||||
signers.push({ ...signerRes[i], ...signerRes[i] });
|
||||
isSigned = true;
|
||||
break;
|
||||
}
|
||||
// if does not match then add unsigned data in unSignedSigner array
|
||||
}
|
||||
if (!isSigned) {
|
||||
unSignedSigner.push({ ...signerRes[i], ...signerRes[i] });
|
||||
}
|
||||
}
|
||||
setSignedSigners(signers);
|
||||
setUnSignedSigners(unSignedSigner);
|
||||
|
||||
setSignerPos(documentData[0].Placeholders);
|
||||
} else {
|
||||
let unsigned = [];
|
||||
for (let i = 0; i < documentData.length; i++) {
|
||||
unsigned.push(documentData[i].Signers);
|
||||
}
|
||||
setUnSignedSigners(unsigned[0]);
|
||||
setSignerPos(documentData[0].Placeholders);
|
||||
}
|
||||
setPdfDetails(documentData);
|
||||
setIsUiLoading(false);
|
||||
} else {
|
||||
alert("No data found!");
|
||||
}
|
||||
} else if (
|
||||
documentData === "Error: Something went wrong!" ||
|
||||
(documentData.result && documentData.result.error)
|
||||
) {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
setNoData(true);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
setIsUiLoading(false);
|
||||
}
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
@@ -294,7 +280,6 @@ function PdfRequestFiles() {
|
||||
const checkUser = signerPos.filter(
|
||||
(data) => data.signerObjId === signerObjectId
|
||||
);
|
||||
|
||||
if (checkUser && checkUser.length > 0) {
|
||||
let checkSignUrl = [];
|
||||
const checkSign = checkUser[0].placeHolder.filter(
|
||||
@@ -332,67 +317,25 @@ function PdfRequestFiles() {
|
||||
if (isDocId) {
|
||||
pdfBase64 = await getBase64FromUrl(url);
|
||||
} else {
|
||||
for (let i = 0; i < allPages; i++) {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
|
||||
const fontSize = 10;
|
||||
const textContent =
|
||||
documentId && `OpenSign™ DocumentId: ${documentId}`;
|
||||
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[i];
|
||||
|
||||
page.drawText(textContent, {
|
||||
x: 10,
|
||||
y: page.getHeight() - 10,
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0.5, 0.5, 0.5)
|
||||
});
|
||||
}
|
||||
//embed document's object id to all pages in pdf document
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
pdfBase64 = await pdfDoc.saveAsBase64({
|
||||
useObjectStreams: false
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < pngUrl.length; i++) {
|
||||
const imgUrlList = pngUrl[i].pos;
|
||||
const pageNo = pngUrl[i].pageNumber;
|
||||
imgUrlList.map(async (data) => {
|
||||
//cheking signUrl is defau;t signature url of custom url
|
||||
let ImgUrl = data.SignUrl;
|
||||
const checkUrl = ImgUrl.includes("https:");
|
||||
const checkUrl = urlValidator(ImgUrl);
|
||||
|
||||
//if default signature url then convert it in base 64
|
||||
if (checkUrl) {
|
||||
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
||||
}
|
||||
//function for called convert png signatre to jpeg in base 64
|
||||
const convertPNGtoJPEG = (base64Data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const img = new Image();
|
||||
img.src = base64Data;
|
||||
|
||||
img.onload = () => {
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// Convert to JPEG by using the canvas.toDataURL() method
|
||||
const jpegBase64Data = canvas.toDataURL("image/jpeg");
|
||||
|
||||
resolve(jpegBase64Data);
|
||||
};
|
||||
|
||||
img.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
convertPNGtoJPEG(ImgUrl)
|
||||
.then((jpegBase64Data) => {
|
||||
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
||||
@@ -419,123 +362,15 @@ function PdfRequestFiles() {
|
||||
}
|
||||
//else if signature is more than one then embed all sign with the use of pdf-lib
|
||||
else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) {
|
||||
for (let i = 0; i < allPages; i++) {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
|
||||
const fontSize = 10;
|
||||
const textContent =
|
||||
documentId && `OpenSign™ DocumentId: ${documentId} `;
|
||||
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[i];
|
||||
|
||||
page.drawText(textContent, {
|
||||
x: 10,
|
||||
y: page.getHeight() - 10,
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0.5, 0.5, 0.5)
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < pngUrl.length; i++) {
|
||||
const pageNo = pngUrl[i].pageNumber;
|
||||
|
||||
const imgUrlList = pngUrl[i].pos;
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[pageNo - 1];
|
||||
|
||||
const images = await Promise.all(
|
||||
imgUrlList.map(async (url) => {
|
||||
let signUrl = url.SignUrl;
|
||||
|
||||
const checkUrl = url.SignUrl.includes("https:");
|
||||
if (checkUrl) {
|
||||
signUrl = signUrl + "?get";
|
||||
}
|
||||
const res = await fetch(signUrl);
|
||||
|
||||
return res.arrayBuffer();
|
||||
})
|
||||
);
|
||||
images.forEach(async (imgData, id) => {
|
||||
let img;
|
||||
if (
|
||||
imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/jpeg"
|
||||
) {
|
||||
img = await pdfDoc.embedJpg(imgData);
|
||||
} else if (
|
||||
imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/png"
|
||||
) {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
} else {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
}
|
||||
|
||||
const imgHeight = imgUrlList[id].Height
|
||||
? imgUrlList[id].Height
|
||||
: 60;
|
||||
const imgWidth = imgUrlList[id].Width
|
||||
? imgUrlList[id].Width
|
||||
: 150;
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = window.innerWidth;
|
||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||
const xPos = (pos) => {
|
||||
//checking both condition mobile and desktop view
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (pos.isMobile) {
|
||||
const x = pos.xPosition * (pos.scale / scale);
|
||||
return x * scale + 50;
|
||||
} else {
|
||||
const x = pos.xPosition / scale;
|
||||
return x * scale;
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
if (pos.isMobile) {
|
||||
const x = pos.xPosition * pos.scale + 50;
|
||||
return x;
|
||||
} else {
|
||||
return pos.xPosition;
|
||||
}
|
||||
}
|
||||
};
|
||||
const yPos = (pos) => {
|
||||
//checking both condition mobile and desktop view
|
||||
const y = pos.yPosition / scale;
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (pos.isMobile) {
|
||||
const y = pos.yPosition * (pos.scale / scale);
|
||||
return page.getHeight() - y * scale - imgHeight;
|
||||
} else {
|
||||
return page.getHeight() - y * scale - imgHeight;
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
if (pos.isMobile) {
|
||||
const y = pos.yPosition * pos.scale;
|
||||
return page.getHeight() - y - imgHeight;
|
||||
} else {
|
||||
return page.getHeight() - pos.yPosition - imgHeight;
|
||||
}
|
||||
}
|
||||
};
|
||||
page.drawImage(img, {
|
||||
x: xPos(imgUrlList[id]),
|
||||
y: yPos(imgUrlList[id]),
|
||||
width: imgWidth,
|
||||
height: imgHeight
|
||||
});
|
||||
});
|
||||
}
|
||||
const pdfBytes = await pdfDoc.saveAsBase64({
|
||||
useObjectStreams: false
|
||||
});
|
||||
//embed document's object id to all pages in pdf document
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
//embed multi signature in pdf
|
||||
const pdfBytes = await multiSignEmbed(
|
||||
pngUrl,
|
||||
pdfDoc,
|
||||
pdfOriginalWidth,
|
||||
false
|
||||
);
|
||||
|
||||
signPdfFun(pdfBytes, documentId, pngUrl);
|
||||
}
|
||||
@@ -597,12 +432,12 @@ function PdfRequestFiles() {
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (pos.isMobile) {
|
||||
const y = pos.yPosition * (pos.scale / scale);
|
||||
const y = pos.yBottom * (pos.scale / scale);
|
||||
yPosition = pos.isDrag
|
||||
? y * scale - height
|
||||
: pos.firstYPos
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
return yPosition;
|
||||
} else {
|
||||
const y = pos.yBottom / scale;
|
||||
@@ -610,8 +445,8 @@ function PdfRequestFiles() {
|
||||
yPosition = pos.isDrag
|
||||
? y * scale - height
|
||||
: pos.firstYPos
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
return yPosition;
|
||||
}
|
||||
} else {
|
||||
@@ -622,15 +457,15 @@ function PdfRequestFiles() {
|
||||
yPosition = pos.isDrag
|
||||
? y - height
|
||||
: pos.firstYPos
|
||||
? y - height + pos.firstYPos
|
||||
: y - height;
|
||||
? y - height + pos.firstYPos
|
||||
: y - height;
|
||||
return yPosition;
|
||||
} else {
|
||||
yPosition = pos.isDrag
|
||||
? pos.yBottom - height
|
||||
: pos.firstYPos
|
||||
? pos.yBottom - height + pos.firstYPos
|
||||
: pos.yBottom - height;
|
||||
? pos.yBottom - height + pos.firstYPos
|
||||
: pos.yBottom - height;
|
||||
return yPosition;
|
||||
}
|
||||
}
|
||||
@@ -1048,7 +883,7 @@ function PdfRequestFiles() {
|
||||
|
||||
<Modal.Body>
|
||||
<p className="pTagBody">
|
||||
This document has been signed by all Sigers.
|
||||
This document has been signed by all Signers.
|
||||
</p>
|
||||
</Modal.Body>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { PDFDocument, rgb } from "pdf-lib";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import "../css/./signature.css";
|
||||
import sign from "../assests/sign3.png";
|
||||
import stamp from "../assests/stamp2.png";
|
||||
@@ -15,7 +15,14 @@ import EmailComponent from "./component/emailComponent";
|
||||
import FieldsComponent from "./component/fieldsComponent";
|
||||
import Modal from "react-bootstrap/Modal";
|
||||
import ModalHeader from "react-bootstrap/esm/ModalHeader";
|
||||
import { getBase64FromIMG } from "../utils/Utils";
|
||||
import {
|
||||
convertPNGtoJPEG,
|
||||
contractDocument,
|
||||
getBase64FromIMG,
|
||||
embedDocId,
|
||||
multiSignEmbed,
|
||||
pdfNewWidthFun
|
||||
} from "../utils/Utils";
|
||||
import { useParams } from "react-router-dom";
|
||||
import Tour from "reactour";
|
||||
import { onSaveImage, onSaveSign } from "../utils/Utils";
|
||||
@@ -24,7 +31,9 @@ import HandleError from "./component/HandleError";
|
||||
import Nodata from "./component/Nodata";
|
||||
import Header from "./component/header";
|
||||
import RenderPdf from "./component/renderPdf";
|
||||
import { contractUsers, contactBook } from "../utils/Utils";
|
||||
import { contractUsers, contactBook, urlValidator } from "../utils/Utils";
|
||||
import { modalAlign } from "../utils/Utils";
|
||||
|
||||
//For signYourself inProgress section signer can add sign and complete doc sign.
|
||||
function SignYourSelf() {
|
||||
const [pdfDetails, setPdfDetails] = useState([]);
|
||||
@@ -73,7 +82,7 @@ function SignYourSelf() {
|
||||
status: false,
|
||||
type: "load"
|
||||
});
|
||||
|
||||
const divRef = useRef(null);
|
||||
const nodeRef = useRef(null);
|
||||
const [{ isOver }, drop] = useDrop({
|
||||
accept: "BOX",
|
||||
@@ -160,68 +169,57 @@ function SignYourSelf() {
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
|
||||
useEffect(() => {
|
||||
const clientWidth = window.innerWidth;
|
||||
const value = docId ? 80 : 80;
|
||||
const pdfWidth = clientWidth - 160 - 200 - value;
|
||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
||||
//pdf from left and right component
|
||||
setPdfNewWidth(pdfWidth);
|
||||
if (documentId) {
|
||||
getDocumentDetails();
|
||||
getDocumentDetails(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (divRef.current) {
|
||||
const pdfWidth = pdfNewWidthFun(divRef);
|
||||
setPdfNewWidth(pdfWidth);
|
||||
}
|
||||
}, [divRef.current]);
|
||||
|
||||
//function for get document details for perticular signer with signer'object id
|
||||
const getDocumentDetails = async () => {
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document?where={"objectId":"${documentId}"}&include=ExtUserPtr,Signers`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
const getDocumentDetails = async (showComplete) => {
|
||||
//getting document details
|
||||
const documentData = await contractDocument(documentId);
|
||||
|
||||
if (res[0] && res.length > 0) {
|
||||
setPdfDetails(res);
|
||||
const isCompleted = res[0].IsCompleted && res[0].IsCompleted;
|
||||
if (isCompleted) {
|
||||
const docStatus = {
|
||||
isCompleted: isCompleted
|
||||
};
|
||||
|
||||
setDocumentStatus(docStatus);
|
||||
const alreadySign = {
|
||||
status: true,
|
||||
mssg: "You have successfully signed the document!"
|
||||
};
|
||||
setShowAlreadySignDoc(alreadySign);
|
||||
setPdfUrl(res[0].SignedUrl);
|
||||
}
|
||||
} else {
|
||||
setNoData(true);
|
||||
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
if (documentData && documentData.length > 0) {
|
||||
setPdfDetails(documentData);
|
||||
const isCompleted =
|
||||
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
||||
if (isCompleted) {
|
||||
const docStatus = {
|
||||
isCompleted: isCompleted
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
});
|
||||
setDocumentStatus(docStatus);
|
||||
setPdfUrl(documentData[0].SignedUrl);
|
||||
const alreadySign = {
|
||||
status: true,
|
||||
mssg: "You have successfully signed the document!"
|
||||
};
|
||||
if (showComplete) {
|
||||
setShowAlreadySignDoc(alreadySign);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
documentData === "Error: Something went wrong!" ||
|
||||
(documentData.result && documentData.result.error)
|
||||
) {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
setNoData(true);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
@@ -252,13 +250,10 @@ function SignYourSelf() {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
});
|
||||
const contractUsersRes = await contractUsers(jsonSender.objectId);
|
||||
|
||||
if (
|
||||
contractUsersRes !== "Error: Something went wrong!" &&
|
||||
contractUsersRes &&
|
||||
contractUsersRes[0]
|
||||
) {
|
||||
const contractUsersRes = await contractUsers(jsonSender.email);
|
||||
|
||||
if (contractUsersRes[0] && contractUsersRes.length > 0) {
|
||||
setContractName("_Users");
|
||||
setSignerUserId(contractUsersRes[0].objectId);
|
||||
const tourstatuss =
|
||||
@@ -285,14 +280,12 @@ function SignYourSelf() {
|
||||
setIsLoading(loadObj);
|
||||
} else if (contractUsersRes.length === 0) {
|
||||
const contractContactBook = await contactBook(jsonSender.objectId);
|
||||
if (contractContactBook && contractContactBook[0]) {
|
||||
if (contractContactBook && contractContactBook.length > 0) {
|
||||
setContractName("_Contactbook");
|
||||
|
||||
setSignerUserId(contractContactBook[0].objectId);
|
||||
const tourstatuss =
|
||||
contractContactBook[0].TourStatus &&
|
||||
contractContactBook[0].TourStatus;
|
||||
|
||||
if (tourstatuss && tourstatuss.length > 0) {
|
||||
setTourStatus(tourstatuss);
|
||||
const checkTourRecipients = tourstatuss.filter(
|
||||
@@ -302,6 +295,8 @@ function SignYourSelf() {
|
||||
setCheckTourStatus(checkTourRecipients[0].signyourself);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setNoData(true);
|
||||
}
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
@@ -432,24 +427,7 @@ function SignYourSelf() {
|
||||
//checking if signature is only one then send image url in jpeg formate to server
|
||||
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
||||
//embed document's object id to all pages in pdf document
|
||||
for (let i = 0; i < allPages; i++) {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
|
||||
const fontSize = 10;
|
||||
const textContent =
|
||||
documentId && `OpenSign™ DocumentId: ${documentId}`;
|
||||
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[i];
|
||||
|
||||
page.drawText(textContent, {
|
||||
x: 10,
|
||||
y: page.getHeight() - 10,
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0.5, 0.5, 0.5)
|
||||
});
|
||||
}
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
const pdfBase64 = await pdfDoc.saveAsBase64({
|
||||
useObjectStreams: false
|
||||
});
|
||||
@@ -460,39 +438,13 @@ function SignYourSelf() {
|
||||
imgUrlList.map(async (data) => {
|
||||
let ImgUrl = data.SignUrl;
|
||||
//cheking signUrl is defau;t signature url of custom url
|
||||
const checkUrl = ImgUrl.includes("https:");
|
||||
const checkUrl = urlValidator(ImgUrl);
|
||||
|
||||
//if default signature url then convert it in base 64
|
||||
if (checkUrl) {
|
||||
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
||||
}
|
||||
|
||||
//function for convert signature png base64 url to jpeg base64
|
||||
const convertPNGtoJPEG = (base64Data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const img = new Image();
|
||||
img.src = base64Data;
|
||||
|
||||
img.onload = () => {
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// Convert to JPEG by using the canvas.toDataURL() method
|
||||
const jpegBase64Data = canvas.toDataURL("image/jpeg");
|
||||
|
||||
resolve(jpegBase64Data);
|
||||
};
|
||||
|
||||
img.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
convertPNGtoJPEG(ImgUrl)
|
||||
.then((jpegBase64Data) => {
|
||||
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
||||
@@ -500,7 +452,6 @@ function SignYourSelf() {
|
||||
removeBase64Fromjpeg,
|
||||
""
|
||||
);
|
||||
|
||||
//function for call to embed signature in pdf and get digital signature pdf
|
||||
signPdfFun(newImgUrl, documentId, data, pdfBase64, pageNo);
|
||||
})
|
||||
@@ -512,91 +463,15 @@ function SignYourSelf() {
|
||||
}
|
||||
//else if signature is more than one then embed all sign with the use of pdf-lib
|
||||
else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
||||
for (let i = 0; i < allPages; i++) {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
|
||||
const fontSize = 10;
|
||||
const textContent =
|
||||
documentId && `OpenSign™ DocumentId: ${documentId} `;
|
||||
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[i];
|
||||
|
||||
page.drawText(textContent, {
|
||||
x: 10,
|
||||
y: page.getHeight() - 10,
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0.5, 0.5, 0.5)
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < pngUrl.length; i++) {
|
||||
const pageNo = pngUrl[i].pageNumber;
|
||||
|
||||
const imgUrlList = pngUrl[i].pos;
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[pageNo - 1];
|
||||
|
||||
const images = await Promise.all(
|
||||
imgUrlList.map(async (url) => {
|
||||
let signUrl = url.SignUrl;
|
||||
|
||||
const checkUrl = url.SignUrl.includes("https:");
|
||||
if (checkUrl) {
|
||||
signUrl = signUrl + "?get";
|
||||
}
|
||||
const res = await fetch(signUrl);
|
||||
|
||||
return res.arrayBuffer();
|
||||
})
|
||||
);
|
||||
images.forEach(async (imgData, id) => {
|
||||
let img;
|
||||
if (
|
||||
imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/jpeg"
|
||||
) {
|
||||
img = await pdfDoc.embedJpg(imgData);
|
||||
} else if (
|
||||
imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/png"
|
||||
) {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
} else {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
}
|
||||
|
||||
const imgHeight = imgUrlList[id].Height
|
||||
? imgUrlList[id].Height
|
||||
: 60;
|
||||
const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150;
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = window.innerWidth;
|
||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||
|
||||
const posY = () => {
|
||||
if (id === 0) {
|
||||
return (
|
||||
page.getHeight() -
|
||||
imgUrlList[id].yPosition * scale -
|
||||
imgHeight
|
||||
);
|
||||
} else if (id > 0) {
|
||||
return page.getHeight() - imgUrlList[id].yPosition * scale;
|
||||
}
|
||||
};
|
||||
page.drawImage(img, {
|
||||
x: isMobile
|
||||
? imgUrlList[id].xPosition * scale + imgWidth / 2
|
||||
: imgUrlList[id].xPosition,
|
||||
y: posY(),
|
||||
width: imgWidth,
|
||||
height: imgHeight
|
||||
});
|
||||
});
|
||||
}
|
||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||
|
||||
//embed document's object id to all pages in pdf document
|
||||
await embedDocId(pdfDoc, documentId, allPages);
|
||||
//embed multi signature in pdf
|
||||
const pdfBytes = await multiSignEmbed(
|
||||
pngUrl,
|
||||
pdfDoc,
|
||||
pdfOriginalWidth,
|
||||
true
|
||||
);
|
||||
signPdfFun(pdfBytes, documentId);
|
||||
}
|
||||
setIsSignPad(false);
|
||||
@@ -615,17 +490,18 @@ function SignYourSelf() {
|
||||
pageNo
|
||||
) => {
|
||||
let singleSign;
|
||||
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = window.innerWidth;
|
||||
const newWidth = window.innerWidth - 32;
|
||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||
const imgWidth = xyPosData.Width.Width ? xyPosData.Width.Width : 150;
|
||||
const imgWidth = xyPosData ? xyPosData.Width : 150;
|
||||
if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) {
|
||||
const height = xyPosData.Height ? xyPosData.Height : 60;
|
||||
const bottomY = xyPosData.isDrag
|
||||
? xyPosData.yBottom * scale - height
|
||||
? xyPosData.yBottom * scale - height * scale
|
||||
: xyPosData.firstYPos
|
||||
? xyPosData.yBottom * scale - height + xyPosData.firstYPos
|
||||
: xyPosData.yBottom * scale - height;
|
||||
? xyPosData.yBottom * scale - height * scale + xyPosData.firstYPos
|
||||
: xyPosData.yBottom * scale - height * scale;
|
||||
|
||||
singleSign = {
|
||||
pdfFile: pdfBase64Url,
|
||||
@@ -633,11 +509,11 @@ function SignYourSelf() {
|
||||
sign: {
|
||||
Base64: base64Url,
|
||||
Left: isMobile
|
||||
? xyPosData.xPosition * scale + imgWidth / 2
|
||||
? xyPosData.xPosition * scale + 43
|
||||
: xyPosData.xPosition,
|
||||
Bottom: bottomY,
|
||||
Width: xyPosData.Width ? xyPosData.Width : 150,
|
||||
Height: height,
|
||||
Width: xyPosData.Width ? xyPosData.Width * scale : 150 * scale,
|
||||
Height: height * scale,
|
||||
Page: pageNo
|
||||
}
|
||||
};
|
||||
@@ -661,15 +537,7 @@ function SignYourSelf() {
|
||||
// console.log("json ", json);
|
||||
setPdfUrl(json.result.data);
|
||||
if (json.result.data) {
|
||||
const docStatus = {
|
||||
isCompleted: true
|
||||
};
|
||||
|
||||
setDocumentStatus(docStatus);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
getDocumentDetails(false);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -1009,7 +877,7 @@ function SignYourSelf() {
|
||||
) : noData ? (
|
||||
<Nodata />
|
||||
) : (
|
||||
<div className="signatureContainer">
|
||||
<div className="signatureContainer" ref={divRef}>
|
||||
{/* this component used for UI interaction and show their functionality */}
|
||||
{pdfLoadFail && !checkTourStatus && (
|
||||
<Tour
|
||||
@@ -1041,7 +909,11 @@ function SignYourSelf() {
|
||||
>
|
||||
{/* this modal is used show this document is already sign */}
|
||||
|
||||
<Modal show={showAlreadySignDoc.status}>
|
||||
<Modal
|
||||
show={showAlreadySignDoc.status}
|
||||
onShow={() => modalAlign()}
|
||||
backdropClassName="signature-backdrop"
|
||||
>
|
||||
<ModalHeader style={{ background: themeColor() }}>
|
||||
<span style={{ color: "white" }}> Sign Documents</span>
|
||||
</ModalHeader>
|
||||
@@ -1115,6 +987,8 @@ function SignYourSelf() {
|
||||
pdfDetails={pdfDetails}
|
||||
isShowHeader={true}
|
||||
currentSigner={true}
|
||||
alreadySign={pdfUrl ? true : false}
|
||||
isSignYourself={true}
|
||||
/>
|
||||
|
||||
{/* className="hidePdf" */}
|
||||
|
||||
@@ -28,9 +28,7 @@ function EmailComponent({
|
||||
setIsLoading(true);
|
||||
let sendMail;
|
||||
for (let i = 0; i < emailCount.length; i++) {
|
||||
|
||||
try {
|
||||
|
||||
const imgPng =
|
||||
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
||||
// "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png";
|
||||
@@ -41,7 +39,7 @@ function EmailComponent({
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
|
||||
|
||||
const themeBGcolor = themeColor();
|
||||
let params = {
|
||||
pdfName: pdfName,
|
||||
@@ -111,26 +109,36 @@ function EmailComponent({
|
||||
|
||||
const pdf = await getBase64FromUrl(pdfUrl);
|
||||
const isAndroidDevice = navigator.userAgent.match(/Android/i);
|
||||
const isAppleDevice = (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) && !window.MSStream
|
||||
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 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');
|
||||
window.open(blobUrl, "_blank");
|
||||
} else {
|
||||
printModule({ printable: pdf, type: "pdf", base64: true });
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//handle download signed pdf
|
||||
const handleDownloadPdf = () => {
|
||||
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`);
|
||||
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||
};
|
||||
|
||||
const sanitizeFileName = (pdfName) => {
|
||||
// Replace spaces with underscore
|
||||
return pdfName.replace(/ /g, "_");
|
||||
};
|
||||
|
||||
const isAndroid = /Android/i.test(navigator.userAgent);
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* isEmail */}
|
||||
@@ -162,7 +170,7 @@ function EmailComponent({
|
||||
)}
|
||||
|
||||
<ModalHeader style={{ background: themeColor() }}>
|
||||
<span style={{ color: "white" }}>Email Documents</span>
|
||||
<span style={{ color: "white" }}>Successfully signed!</span>
|
||||
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
<div></div>
|
||||
@@ -248,20 +256,25 @@ function EmailComponent({
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
|
||||
|
||||
flexWrap: "wrap"
|
||||
}}
|
||||
>
|
||||
{emailCount.map((data, ind) => {
|
||||
return (
|
||||
<div className="emailChip"
|
||||
style={{display:"flex", flexDirection:"row", alignItems:"center"}}
|
||||
key={ind}>
|
||||
<div
|
||||
className="emailChip"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
key={ind}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "13px",
|
||||
marginRight: "20px"
|
||||
fontSize: "13px"
|
||||
}}
|
||||
>
|
||||
{data}
|
||||
@@ -273,7 +286,8 @@ function EmailComponent({
|
||||
src={close}
|
||||
width={10}
|
||||
height={10}
|
||||
style={{ fontWeight: "600" }}
|
||||
style={{ fontWeight: "600", marginLeft: "7px" }}
|
||||
className="emailChipClose"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -27,13 +27,13 @@ function Header({
|
||||
signersdata,
|
||||
isMailSend,
|
||||
alertSendEmail,
|
||||
isSigned,
|
||||
isCompleted,
|
||||
isShowHeader,
|
||||
decline,
|
||||
currentSigner,
|
||||
dataTut4,
|
||||
alreadySign
|
||||
alreadySign,
|
||||
isSignYourself
|
||||
}) {
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const navigate = useNavigate();
|
||||
@@ -61,12 +61,19 @@ function Header({
|
||||
|
||||
const pdf = await getBase64FromUrl(pdfUrl);
|
||||
const isAndroidDevice = navigator.userAgent.match(/Android/i);
|
||||
const isAppleDevice = (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) && !window.MSStream
|
||||
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 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');
|
||||
window.open(blobUrl, "_blank");
|
||||
} else {
|
||||
printModule({ printable: pdf, type: "pdf", base64: true });
|
||||
}
|
||||
@@ -75,13 +82,148 @@ function Header({
|
||||
//handle download signed pdf
|
||||
const handleDownloadPdf = () => {
|
||||
const pdfName = pdfDetails[0] && pdfDetails[0].Name;
|
||||
|
||||
saveAs(pdfUrl, `${pdfName}_signed_by_OpenSign™.pdf`);
|
||||
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
||||
};
|
||||
|
||||
const sanitizeFileName = (pdfName) => {
|
||||
// Replace spaces with underscore
|
||||
return pdfName.replace(/ /g, "_");
|
||||
};
|
||||
//certificate generate and download component in mobile view
|
||||
const CertificateDropDown = () => {
|
||||
//after generate download certifcate pdf
|
||||
const handleDownload = (pdfBlob, fileName) => {
|
||||
if (pdfBlob) {
|
||||
const url = window.URL.createObjectURL(pdfBlob);
|
||||
// Create a temporary anchor element
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = fileName;
|
||||
// Append the anchor to the body
|
||||
document.body.appendChild(link);
|
||||
// Programmatically click the anchor to trigger the download
|
||||
link.click();
|
||||
// Remove the anchor from the body
|
||||
document.body.removeChild(link);
|
||||
// Release the object URL to free up resources
|
||||
window.URL.revokeObjectURL(url);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PDFDownloadLink
|
||||
onClick={(e) => e.preventDefault()}
|
||||
style={{ textDecoration: "none", zIndex: "35" }}
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
>
|
||||
{({ blob, url, loading, error }) => (
|
||||
<>
|
||||
{loading ? (
|
||||
<div
|
||||
style={{
|
||||
border: "none",
|
||||
backgroundColor: "#fff"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
marginRight: "2px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
border: "none",
|
||||
backgroundColor: "#fff"
|
||||
}}
|
||||
onClick={() =>
|
||||
handleDownload(
|
||||
blob,
|
||||
`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`
|
||||
)
|
||||
}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
marginRight: "2px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</PDFDownloadLink>
|
||||
);
|
||||
};
|
||||
const CertificateComponent = () => {
|
||||
return (
|
||||
<PDFDownloadLink
|
||||
style={{ textDecoration: "none" }}
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div
|
||||
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
|
||||
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
|
||||
className="mobileHead"
|
||||
>
|
||||
{isMobile && isShowHeader ? (
|
||||
@@ -89,7 +231,9 @@ function Header({
|
||||
id="navbar"
|
||||
className={isGuestSigner ? "stickySignerHead" : "stickyHead"}
|
||||
style={{
|
||||
width: isGuestSigner ? window.innerWidth : window.innerWidth - 30 + "px"
|
||||
width: isGuestSigner
|
||||
? window.innerWidth
|
||||
: window.innerWidth - 30 + "px"
|
||||
}}
|
||||
>
|
||||
<div className="preBtn2">
|
||||
@@ -134,16 +278,16 @@ function Header({
|
||||
style={{ color: "gray", cursor: "pointer" }}
|
||||
></i>
|
||||
</div>
|
||||
{pdfUrl ? (
|
||||
{pdfUrl && alreadySign ? (
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<div
|
||||
// onClick={() => handleDownloadPdf()}
|
||||
style={{
|
||||
color: themeColor(),
|
||||
border: "none",
|
||||
fontWeight: "650",
|
||||
fontSize: "16px"
|
||||
fontSize: "16px",
|
||||
padding: "0px 3px 0px 5px"
|
||||
}}
|
||||
>
|
||||
<i className="fa fa-ellipsis-v" aria-hidden="true"></i>
|
||||
@@ -173,44 +317,41 @@ function Header({
|
||||
Download
|
||||
</div>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item className="DropdownMenuItem">
|
||||
<PDFDownloadLink
|
||||
style={{ textDecoration: "none" }}
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
{recipient && pdfDetails[0] && pdfDetails.length > 0 ? (
|
||||
<DropdownMenu.Item className="DropdownMenuItem">
|
||||
<CertificateDropDown />
|
||||
</DropdownMenu.Item>
|
||||
) : isPdfRequestFiles &&
|
||||
alreadySign &&
|
||||
isCompleted.isCertificate ? (
|
||||
<DropdownMenu.Item className="DropdownMenuItem">
|
||||
<CertificateDropDown />
|
||||
</DropdownMenu.Item>
|
||||
) : (
|
||||
isSignYourself && (
|
||||
<DropdownMenu.Item className="DropdownMenuItem">
|
||||
<CertificateDropDown />
|
||||
</DropdownMenu.Item>
|
||||
)
|
||||
)}
|
||||
<DropdownMenu.Item
|
||||
className="DropdownMenuItem"
|
||||
onClick={handleToPrint}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row"
|
||||
}}
|
||||
>
|
||||
{({ blob, url, loading, error }) => (
|
||||
<>
|
||||
{console.log("error", error)}
|
||||
{loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</PDFDownloadLink>
|
||||
{" "}
|
||||
<i
|
||||
className="fa fa-print"
|
||||
aria-hidden="true"
|
||||
style={{ marginRight: "2px" }}
|
||||
></i>
|
||||
Print
|
||||
</div>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
@@ -261,6 +402,8 @@ function Header({
|
||||
onClick={() => {
|
||||
if (!pdfUrl) {
|
||||
embedImages();
|
||||
} else if (isPdfRequestFiles) {
|
||||
embedImages();
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
@@ -291,40 +434,7 @@ function Header({
|
||||
pdfUrl || isAlreadySign.mssg ? (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
{pdfDetails[0] && pdfDetails.length > 0 && (
|
||||
<PDFDownloadLink
|
||||
style={{ textDecoration: "none" }}
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
<CertificateComponent />
|
||||
)}
|
||||
<button
|
||||
onClick={handleToPrint}
|
||||
@@ -449,42 +559,7 @@ function Header({
|
||||
) : isPdfRequestFiles ? (
|
||||
alreadySign ? (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
{isCompleted.isCertificate && (
|
||||
<PDFDownloadLink
|
||||
style={{ textDecoration: "none" }}
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="defaultBtn certificateBtn"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
)}
|
||||
{isCompleted.isCertificate && <CertificateComponent />}
|
||||
<button
|
||||
onClick={handleToPrint}
|
||||
type="button"
|
||||
@@ -571,40 +646,7 @@ function Header({
|
||||
)
|
||||
) : pdfUrl || (documentStatus && documentStatus.isCompleted) ? (
|
||||
<div style={{ display: "flex", flexDirection: "row" }}>
|
||||
<PDFDownloadLink
|
||||
style={{ textDecoration: "none" }}
|
||||
document={<Certificate pdfData={pdfDetails} />}
|
||||
fileName={`completion certificate-${
|
||||
pdfDetails[0] && pdfDetails[0].Name
|
||||
}.pdf`}
|
||||
>
|
||||
{({ blob, url, loading, error }) =>
|
||||
loading ? (
|
||||
"Loading document..."
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
className="defaultBtn certificateBtn"
|
||||
>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
marginRight: "3px"
|
||||
}}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
Certificate
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</PDFDownloadLink>
|
||||
<CertificateComponent />
|
||||
<button
|
||||
onClick={handleToPrint}
|
||||
type="button"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,12 @@ import HandleError from "./component/HandleError";
|
||||
import Nodata from "./component/Nodata";
|
||||
import SignerListPlace from "./component/signerListPlace";
|
||||
import Header from "./component/header";
|
||||
import { contactBook, contractUsers, getHostUrl } from "../utils/Utils";
|
||||
import {
|
||||
pdfNewWidthFun,
|
||||
contractDocument,
|
||||
contractUsers,
|
||||
getHostUrl
|
||||
} from "../utils/Utils";
|
||||
import RenderPdf from "./component/renderPdf";
|
||||
import ModalComponent from "./component/modalComponent";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -31,13 +36,10 @@ function PlaceHolderSign() {
|
||||
const [pageNumber, setPageNumber] = useState(1);
|
||||
const [signBtnPosition, setSignBtnPosition] = useState([]);
|
||||
const [xySignature, setXYSignature] = useState({});
|
||||
const signRef = useRef(null);
|
||||
const dragRef = useRef(null);
|
||||
const [dragKey, setDragKey] = useState();
|
||||
const [signersdata, setSignersData] = useState();
|
||||
const [signerObjId, setSignerObjId] = useState();
|
||||
const [signerPos, setSignerPos] = useState([]);
|
||||
|
||||
const [isSelectListId, setIsSelectId] = useState();
|
||||
const [isSendAlert, setIsSendAlert] = useState({});
|
||||
const [isSend, setIsSend] = useState(false);
|
||||
@@ -56,6 +58,9 @@ function PlaceHolderSign() {
|
||||
const [pdfOriginalWidth, setPdfOriginalWidth] = useState();
|
||||
const [contractName, setContractName] = useState("");
|
||||
const { docId } = useParams();
|
||||
const signRef = useRef(null);
|
||||
const dragRef = useRef(null);
|
||||
const divRef = useRef(null);
|
||||
const [isShowEmail, setIsShowEmail] = useState(false);
|
||||
const [selectedEmail, setSelectedEmail] = useState(false);
|
||||
const [pdfLoadFail, setPdfLoadFail] = useState({
|
||||
@@ -156,69 +161,53 @@ function PlaceHolderSign() {
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
|
||||
useEffect(() => {
|
||||
const clientWidth = window.innerWidth;
|
||||
const value = docId ? 80 : 30;
|
||||
const pdfWidth = clientWidth - 160 - 200 - value;
|
||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
||||
//pdf from left and right component
|
||||
setPdfNewWidth(pdfWidth);
|
||||
if (documentId) {
|
||||
getDocumentDetails();
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (divRef.current) {
|
||||
const pdfWidth = pdfNewWidthFun(divRef);
|
||||
setPdfNewWidth(pdfWidth);
|
||||
}
|
||||
}, [divRef.current]);
|
||||
//function for get document details
|
||||
const getDocumentDetails = async () => {
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document?where={"objectId":"${documentId}"}&include=ExtUserPtr,Signers`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
//getting document details
|
||||
const documentData = await contractDocument(documentId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
setPdfDetails(documentData);
|
||||
|
||||
if (res[0] && res.length > 0) {
|
||||
setPdfDetails(res);
|
||||
const currEmail = documentData[0].ExtUserPtr.Email;
|
||||
const filterCurrEmail = documentData[0].Signers.filter(
|
||||
(data) => data.Email === currEmail
|
||||
);
|
||||
|
||||
const currEmail = res[0].ExtUserPtr.Email;
|
||||
const filterCurrEmail = res[0].Signers.filter(
|
||||
(data) => data.Email === currEmail
|
||||
);
|
||||
setCurrentEmail(filterCurrEmail);
|
||||
setSignersData(documentData[0]);
|
||||
|
||||
setCurrentEmail(filterCurrEmail);
|
||||
setSignersData(res[0]);
|
||||
|
||||
setSignerObjId(res[0].Signers[0].objectId);
|
||||
setContractName(res[0].Signers[0].className);
|
||||
setIsSelectId(0);
|
||||
} else {
|
||||
setNoData(true);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("axois err ", err);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
});
|
||||
|
||||
const res = await contractUsers(jsonSender.objectId);
|
||||
setSignerObjId(documentData[0].Signers[0].objectId);
|
||||
setContractName(documentData[0].Signers[0].className);
|
||||
setIsSelectId(0);
|
||||
} else if (
|
||||
documentData === "Error: Something went wrong!" ||
|
||||
(documentData.result && documentData.result.error)
|
||||
) {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
setNoData(true);
|
||||
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
const res = await contractUsers(jsonSender.email);
|
||||
if (res[0] && res.length) {
|
||||
setSignerUserId(res[0].objectId);
|
||||
const tourstatus = res[0].TourStatus && res[0].TourStatus;
|
||||
@@ -242,24 +231,12 @@ function PlaceHolderSign() {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else if (res.length === 0) {
|
||||
const res = await contactBook(jsonSender.objectId);
|
||||
if (res[0] && res.length) {
|
||||
setSignerUserId(res[0].objectId);
|
||||
const tourstatus = res[0].TourStatus && res[0].TourStatus;
|
||||
if (tourstatus && tourstatus.length > 0) {
|
||||
setTourStatus(tourstatus);
|
||||
const checkTourRecipients = tourstatus.filter(
|
||||
(data) => data.placeholder
|
||||
);
|
||||
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
||||
setCheckTourStatus(checkTourRecipients[0].placeholder);
|
||||
}
|
||||
}
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
setNoData(true);
|
||||
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -856,7 +833,7 @@ function PlaceHolderSign() {
|
||||
) : noData ? (
|
||||
<Nodata />
|
||||
) : (
|
||||
<div className="signatureContainer">
|
||||
<div className="signatureContainer" ref={divRef}>
|
||||
{/* this component used for UI interaction and show their functionality */}
|
||||
{!checkTourStatus && (
|
||||
//this tour component used in your html component where you want to put
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { PDFDocument, rgb } from "pdf-lib";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import "../css/./signature.css";
|
||||
import axios from "axios";
|
||||
import Modal from "react-bootstrap/Modal";
|
||||
@@ -14,7 +14,14 @@ import DefaultSignature from "./component/defaultSignature";
|
||||
import {
|
||||
getBase64FromUrl,
|
||||
getBase64FromIMG,
|
||||
contactBookName
|
||||
pdfNewWidthFun,
|
||||
convertPNGtoJPEG,
|
||||
contractUsers,
|
||||
contactBook,
|
||||
contractDocument,
|
||||
urlValidator,
|
||||
multiSignEmbed,
|
||||
embedDocId
|
||||
} from "../utils/Utils";
|
||||
import Tour from "reactour";
|
||||
import Signedby from "./component/signedby";
|
||||
@@ -25,6 +32,7 @@ import Nodata from "./component/Nodata";
|
||||
import Header from "./component/header";
|
||||
import RenderPdf from "./component/renderPdf";
|
||||
import CustomModal from "./component/CustomModal";
|
||||
import { modalAlign } from "../utils/Utils";
|
||||
function EmbedPdfImage() {
|
||||
const { id, contactBookId } = useParams();
|
||||
const [isSignPad, setIsSignPad] = useState(false);
|
||||
@@ -74,18 +82,24 @@ function EmbedPdfImage() {
|
||||
return object.pageNumber === pageNumber;
|
||||
});
|
||||
const divRef = useRef(null);
|
||||
const senderUser = localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
)
|
||||
? localStorage.getItem(
|
||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||
)
|
||||
: `${localStorage.getItem("UserInformation")}` &&
|
||||
`${localStorage.getItem("UserInformation")}`;
|
||||
const jsonSender = JSON.parse(senderUser);
|
||||
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
|
||||
const isGuestSigner = localStorage.getItem("isGuestSigner");
|
||||
useEffect(() => {
|
||||
const clientWidth = window.innerWidth;
|
||||
const pdfWidth = clientWidth - 160 - 220 - 30;
|
||||
//160 is width of left side, 200 is width of right side component and 50 is space of middle compoent
|
||||
//pdf from left and right component
|
||||
setPdfNewWidth(pdfWidth);
|
||||
getDocumentDetails();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (divRef.current) {
|
||||
const pdfWidth = pdfNewWidthFun(divRef);
|
||||
setPdfNewWidth(pdfWidth);
|
||||
setContainerWH({
|
||||
width: divRef.current.offsetWidth,
|
||||
height: divRef.current.offsetHeight
|
||||
@@ -96,33 +110,26 @@ function EmbedPdfImage() {
|
||||
//function for get document details for perticular signer with signer'object id
|
||||
const getDocumentDetails = async () => {
|
||||
let currUserId, userObjectId;
|
||||
const json = await contactBookName(contactBookId, "_Contactbook");
|
||||
if (json !== "Error: Something went wrong!" && json && json.results[0]) {
|
||||
//getting contracts_contactBook details
|
||||
const json = await contactBook(contactBookId);
|
||||
if (json && json.length > 0) {
|
||||
setContractName("_Contactbook");
|
||||
if (json.results[0]) {
|
||||
userObjectId = json.results[0].UserId.objectId;
|
||||
setUserObjectID(userObjectId);
|
||||
currUserId = json.results[0].objectId;
|
||||
|
||||
setSignerUserId(currUserId);
|
||||
const tourstatus =
|
||||
json.results[0].TourStatus && json.results[0].TourStatus;
|
||||
userObjectId = json[0].UserId.objectId;
|
||||
setUserObjectID(userObjectId);
|
||||
currUserId = json[0].objectId;
|
||||
|
||||
if (tourstatus && tourstatus.length > 0) {
|
||||
setTourStatus(tourstatus);
|
||||
const checkTourRecipients = tourstatus.filter(
|
||||
(data) => data.recipientssign
|
||||
);
|
||||
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
||||
setCheckTourStatus(checkTourRecipients[0].recipientssign);
|
||||
}
|
||||
setSignerUserId(currUserId);
|
||||
const tourstatus = json[0].TourStatus && json[0].TourStatus;
|
||||
|
||||
if (tourstatus && tourstatus.length > 0) {
|
||||
setTourStatus(tourstatus);
|
||||
const checkTourRecipients = tourstatus.filter(
|
||||
(data) => data.recipientssign
|
||||
);
|
||||
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
||||
setCheckTourStatus(checkTourRecipients[0].recipientssign);
|
||||
}
|
||||
} else {
|
||||
setNoData(true);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
} else if (json === "Error: Something went wrong!") {
|
||||
const loadObj = {
|
||||
@@ -131,18 +138,16 @@ function EmbedPdfImage() {
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
const json = await contactBookName(contactBookId, "_Users");
|
||||
|
||||
if (json !== "Error: Something went wrong!" && json && json.results[0]) {
|
||||
const json = await contractUsers(jsonSender.email);
|
||||
if (json && json.length > 0) {
|
||||
setContractName("_Users");
|
||||
if (json.results[0]) {
|
||||
userObjectId = json.results[0].UserId.objectId;
|
||||
if (json[0]) {
|
||||
userObjectId = json[0].UserId.objectId;
|
||||
setUserObjectID(userObjectId);
|
||||
currUserId = json.results[0].objectId;
|
||||
currUserId = json[0].objectId;
|
||||
|
||||
setSignerUserId(currUserId);
|
||||
const tourstatus =
|
||||
json.results[0].TourStatus && json.results[0].TourStatus;
|
||||
const tourstatus = json[0].TourStatus && json[0].TourStatus;
|
||||
|
||||
if (tourstatus && tourstatus.length > 0) {
|
||||
setTourStatus(tourstatus);
|
||||
@@ -166,171 +171,170 @@ function EmbedPdfImage() {
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setNoData(true);
|
||||
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Document?where={"objectId":"${docId}"}&include=ExtUserPtr,Signers,AuditTrail
|
||||
,`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
if (res[0] && res.length > 0) {
|
||||
const declined = res[0].IsDeclined && res[0].IsDeclined;
|
||||
const isCompleted = res[0].IsCompleted && res[0].IsCompleted;
|
||||
const expireDate = res[0].ExpiryDate.iso;
|
||||
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
const currDate = new Date().getTime();
|
||||
if (isCompleted) {
|
||||
//checking document is completed (signed by all requested signers) than isCompleted true
|
||||
//then show alert with completed message
|
||||
const alreadySign = {
|
||||
status: true,
|
||||
mssg: "This document has been successfully signed!"
|
||||
};
|
||||
setIsAlreadySign(alreadySign);
|
||||
setPdfUrl(res[0].SignedUrl);
|
||||
setSignedPdfData(json.results);
|
||||
setCompletePdfData(res);
|
||||
} else if (declined) {
|
||||
const currentDecline = {
|
||||
currnt: "another",
|
||||
isDeclined: true
|
||||
};
|
||||
setIsDecline(currentDecline);
|
||||
|
||||
setSignedPdfData(json.results);
|
||||
} else if (currDate > expireUpdateDate) {
|
||||
setIsExpired(true);
|
||||
const checkDocIdExist =
|
||||
json.results[0].AuditTrail &&
|
||||
json.results[0].AuditTrail.length > 0 &&
|
||||
json.results[0].AuditTrail.filter(
|
||||
(data) => data.Activity === "Signed"
|
||||
);
|
||||
|
||||
//if signed by someone than go to in if condition
|
||||
// and second signer could not be add documentId
|
||||
//for that setIsDocId true
|
||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
||||
setIsDocId(true);
|
||||
const currUser =
|
||||
json.results[0].Placeholders &&
|
||||
json.results[0].Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(json.results);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
//for show current requested signer's placeholder
|
||||
else {
|
||||
const currUser =
|
||||
json.results[0].Placeholders &&
|
||||
json.results[0].Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(json.results);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
} else {
|
||||
//checking document has signed by someone or not
|
||||
|
||||
const checkDocIdExist =
|
||||
json.results[0].AuditTrail &&
|
||||
json.results[0].AuditTrail.length > 0 &&
|
||||
json.results[0].AuditTrail.filter(
|
||||
(data) => data.Activity === "Signed"
|
||||
);
|
||||
|
||||
//if signed by someone than go to in if condition
|
||||
// and second signer could not be add documentId
|
||||
//for that setIsDocId true
|
||||
|
||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
||||
setIsDocId(true);
|
||||
|
||||
//condition for checking document signed by current requested user or not
|
||||
const checkAlreadyBySigner = json.results[0].AuditTrail.filter(
|
||||
(data) =>
|
||||
data.UserPtr.objectId === currUserId &&
|
||||
data.Activity === "Signed"
|
||||
);
|
||||
|
||||
// if checkAlreadyBySigner has some data that current user already sign this document
|
||||
// then show alert with message
|
||||
if (checkAlreadyBySigner && checkAlreadyBySigner.length > 0) {
|
||||
const alreadySign = {
|
||||
status: true,
|
||||
mssg: "You have successfully signed the document!"
|
||||
};
|
||||
setIsAlreadySign(alreadySign);
|
||||
setPdfUrl(res[0].SignedUrl);
|
||||
setSignedPdfData(json.results);
|
||||
}
|
||||
//else show placeholder of current requested signer
|
||||
else {
|
||||
const currUser =
|
||||
json.results[0].Placeholders &&
|
||||
json.results[0].Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(json.results);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
}
|
||||
//for show current requested signer's placeholder
|
||||
else {
|
||||
const currUser =
|
||||
json.results[0].Placeholders &&
|
||||
json.results[0].Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(json.results);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
console.log("err", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//getting document details
|
||||
const documentData = await contractDocument(docId);
|
||||
if (documentData && documentData.length > 0) {
|
||||
const declined = documentData[0].IsDeclined && documentData[0].IsDeclined;
|
||||
const isCompleted =
|
||||
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
||||
const expireDate = documentData[0].ExpiryDate.iso;
|
||||
|
||||
const expireUpdateDate = new Date(expireDate).getTime();
|
||||
const currDate = new Date().getTime();
|
||||
if (isCompleted) {
|
||||
//checking document is completed (signed by all requested signers) than isCompleted true
|
||||
//then show alert with completed message
|
||||
const alreadySign = {
|
||||
status: true,
|
||||
mssg: "This document has been successfully signed!"
|
||||
};
|
||||
setIsAlreadySign(alreadySign);
|
||||
setPdfUrl(documentData[0].SignedUrl);
|
||||
setSignedPdfData(documentData);
|
||||
setCompletePdfData(documentData);
|
||||
} else if (declined) {
|
||||
const currentDecline = {
|
||||
currnt: "another",
|
||||
isDeclined: true
|
||||
};
|
||||
setIsDecline(currentDecline);
|
||||
|
||||
setSignedPdfData(documentData);
|
||||
} else if (currDate > expireUpdateDate) {
|
||||
setIsExpired(true);
|
||||
const checkDocIdExist =
|
||||
documentData[0].AuditTrail &&
|
||||
documentData[0].AuditTrail.length > 0 &&
|
||||
documentData[0].AuditTrail.filter(
|
||||
(data) => data.Activity === "Signed"
|
||||
);
|
||||
|
||||
//if signed by someone than go to in if condition
|
||||
// and second signer could not be add documentId
|
||||
//for that setIsDocId true
|
||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
||||
setIsDocId(true);
|
||||
const currUser =
|
||||
documentData.Placeholders &&
|
||||
documentData.Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(documentData);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
//for show current requested signer's placeholder
|
||||
else {
|
||||
const currUser =
|
||||
documentData[0].Placeholders &&
|
||||
documentData[0].Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(documentData);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
} else {
|
||||
//checking document has signed by someone or not
|
||||
|
||||
const checkDocIdExist =
|
||||
documentData[0].AuditTrail &&
|
||||
documentData[0].AuditTrail.length > 0 &&
|
||||
documentData[0].AuditTrail.filter(
|
||||
(data) => data.Activity === "Signed"
|
||||
);
|
||||
|
||||
//if signed by someone than go to in if condition
|
||||
// and second signer could not be add documentId
|
||||
//for that setIsDocId true
|
||||
|
||||
if (checkDocIdExist && checkDocIdExist.length > 0) {
|
||||
setIsDocId(true);
|
||||
|
||||
//condition for checking document signed by current requested user or not
|
||||
const checkAlreadyBySigner = documentData[0].AuditTrail.filter(
|
||||
(data) =>
|
||||
data.UserPtr.objectId === currUserId && data.Activity === "Signed"
|
||||
);
|
||||
|
||||
// if checkAlreadyBySigner has some data that current user already sign this document
|
||||
// then show alert with message
|
||||
if (checkAlreadyBySigner && checkAlreadyBySigner.length > 0) {
|
||||
const alreadySign = {
|
||||
status: true,
|
||||
mssg: "You have successfully signed the document!"
|
||||
};
|
||||
setIsAlreadySign(alreadySign);
|
||||
setPdfUrl(documentData[0].SignedUrl);
|
||||
setSignedPdfData(documentData);
|
||||
}
|
||||
//else show placeholder of current requested signer
|
||||
else {
|
||||
const currUser =
|
||||
documentData[0].Placeholders &&
|
||||
documentData[0].Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(documentData);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
}
|
||||
//for show current requested signer's placeholder
|
||||
else {
|
||||
const currUser =
|
||||
documentData[0].Placeholders &&
|
||||
documentData[0].Placeholders.filter(
|
||||
(data) => data.signerObjId === currUserId
|
||||
);
|
||||
|
||||
setSignedPdfData(documentData);
|
||||
|
||||
setXyPostion(currUser[0].placeHolder);
|
||||
|
||||
const key = currUser[0].placeHolder[0].pos[0].key;
|
||||
setSignKey(key);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
documentData === "Error: Something went wrong!" ||
|
||||
(documentData.result && documentData.result.error)
|
||||
) {
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setHandleError("Error: Something went wrong!");
|
||||
setIsLoading(loadObj);
|
||||
} else {
|
||||
setNoData(true);
|
||||
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
}
|
||||
await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
@@ -419,23 +423,8 @@ function EmbedPdfImage() {
|
||||
if (isDocId) {
|
||||
pdfBase64 = await getBase64FromUrl(url);
|
||||
} else {
|
||||
for (let i = 0; i < allPages; i++) {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
|
||||
const fontSize = 10;
|
||||
const textContent = docId && `OpenSign™ DocumentId: ${docId} `;
|
||||
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[i];
|
||||
|
||||
page.drawText(textContent, {
|
||||
x: 10,
|
||||
y: page.getHeight() - 10,
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0.5, 0.5, 0.5)
|
||||
});
|
||||
}
|
||||
//embed document's object id to all pages in pdf document
|
||||
await embedDocId(pdfDoc, docId, allPages);
|
||||
pdfBase64 = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||
}
|
||||
for (let i = 0; i < xyPostion.length; i++) {
|
||||
@@ -444,38 +433,13 @@ function EmbedPdfImage() {
|
||||
imgUrlList.map(async (data) => {
|
||||
//cheking signUrl is defau;t signature url of custom url
|
||||
let ImgUrl = data.SignUrl;
|
||||
const checkUrl = ImgUrl.includes("https:");
|
||||
const checkUrl = urlValidator(ImgUrl);
|
||||
|
||||
//if default signature url then convert it in base 64
|
||||
if (checkUrl) {
|
||||
ImgUrl = await getBase64FromIMG(ImgUrl + "?get");
|
||||
}
|
||||
//function for called convert png signatre to jpeg in base 64
|
||||
const convertPNGtoJPEG = (base64Data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const img = new Image();
|
||||
img.src = base64Data;
|
||||
|
||||
img.onload = () => {
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// Convert to JPEG by using the canvas.toDataURL() method
|
||||
const jpegBase64Data = canvas.toDataURL("image/jpeg");
|
||||
|
||||
resolve(jpegBase64Data);
|
||||
};
|
||||
|
||||
img.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
//function for convert signature png base64 url to jpeg base64
|
||||
convertPNGtoJPEG(ImgUrl)
|
||||
.then((jpegBase64Data) => {
|
||||
const removeBase64Fromjpeg = "data:image/jpeg;base64,";
|
||||
@@ -495,123 +459,18 @@ function EmbedPdfImage() {
|
||||
}
|
||||
//else if signature is more than one then embed all sign with the use of pdf-lib
|
||||
else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) {
|
||||
for (let i = 0; i < allPages; i++) {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
|
||||
const fontSize = 10;
|
||||
const textContent = docId && `OpenSign™ DocumentId: ${docId} `;
|
||||
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[i];
|
||||
|
||||
page.drawText(textContent, {
|
||||
x: 10,
|
||||
y: page.getHeight() - 10,
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0.5, 0.5, 0.5)
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < pngUrl.length; i++) {
|
||||
const pageNo = pngUrl[i].pageNumber;
|
||||
|
||||
const imgUrlList = pngUrl[i].pos;
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[pageNo - 1];
|
||||
|
||||
const images = await Promise.all(
|
||||
imgUrlList.map(async (url) => {
|
||||
let signUrl = url.SignUrl;
|
||||
const checkUrl = url.SignUrl.includes("https:");
|
||||
if (checkUrl) {
|
||||
signUrl = signUrl + "?get";
|
||||
}
|
||||
const res = await fetch(signUrl);
|
||||
|
||||
return res.arrayBuffer();
|
||||
})
|
||||
);
|
||||
images.forEach(async (imgData, id) => {
|
||||
let img;
|
||||
if (
|
||||
imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/jpeg"
|
||||
) {
|
||||
img = await pdfDoc.embedJpg(imgData);
|
||||
} else if (
|
||||
imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/png"
|
||||
) {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
} else {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
}
|
||||
|
||||
const imgHeight = imgUrlList[id].Height
|
||||
? imgUrlList[id].Height
|
||||
: 60;
|
||||
const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150;
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = window.innerWidth;
|
||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||
const xPos = (pos) => {
|
||||
//checking both condition mobile and desktop view
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (pos.isMobile) {
|
||||
const x = pos.xPosition * (pos.scale / scale);
|
||||
return x * scale + 50;
|
||||
} else {
|
||||
const x = pos.xPosition / scale;
|
||||
return x * scale;
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
if (pos.isMobile) {
|
||||
const x = pos.xPosition * pos.scale + 50;
|
||||
return x;
|
||||
} else {
|
||||
return pos.xPosition;
|
||||
}
|
||||
}
|
||||
};
|
||||
const yPos = (pos) => {
|
||||
//checking both condition mobile and desktop view
|
||||
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (pos.isMobile) {
|
||||
const y = pos.yPosition * (pos.scale / scale);
|
||||
return page.getHeight() - y * scale - imgHeight;
|
||||
} else {
|
||||
const y = pos.yPosition / scale;
|
||||
return page.getHeight() - y * scale - imgHeight;
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
if (pos.isMobile) {
|
||||
const y = pos.yPosition * pos.scale;
|
||||
return page.getHeight() - y - imgHeight;
|
||||
} else {
|
||||
return page.getHeight() - pos.yPosition - imgHeight;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
page.drawImage(img, {
|
||||
x: xPos(imgUrlList[id]),
|
||||
y: yPos(imgUrlList[id]),
|
||||
width: imgWidth,
|
||||
height: imgHeight
|
||||
});
|
||||
});
|
||||
}
|
||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||
//embed document's object id to all pages in pdf document
|
||||
await embedDocId(pdfDoc, docId, allPages);
|
||||
//embed multi signature in pdf
|
||||
const pdfBytes = await multiSignEmbed(
|
||||
pngUrl,
|
||||
pdfDoc,
|
||||
pdfOriginalWidth,
|
||||
false
|
||||
);
|
||||
signPdfFun(pdfBytes, docId);
|
||||
}
|
||||
|
||||
setIsSignPad(false);
|
||||
|
||||
setXyPostion([]);
|
||||
}
|
||||
}
|
||||
@@ -662,8 +521,8 @@ function EmbedPdfImage() {
|
||||
yPosition = pos.isDrag
|
||||
? y * scale - height
|
||||
: pos.firstYPos
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
return yPosition;
|
||||
} else {
|
||||
const y = pos.yBottom / scale;
|
||||
@@ -671,8 +530,8 @@ function EmbedPdfImage() {
|
||||
yPosition = pos.isDrag
|
||||
? y * scale - height
|
||||
: pos.firstYPos
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
? y * scale - height + pos.firstYPos
|
||||
: y * scale - height;
|
||||
return yPosition;
|
||||
}
|
||||
} else {
|
||||
@@ -683,15 +542,15 @@ function EmbedPdfImage() {
|
||||
yPosition = pos.isDrag
|
||||
? y - height
|
||||
: pos.firstYPos
|
||||
? y - height + pos.firstYPos
|
||||
: y - height;
|
||||
? y - height + pos.firstYPos
|
||||
: y - height;
|
||||
return yPosition;
|
||||
} else {
|
||||
yPosition = pos.isDrag
|
||||
? pos.yBottom - height
|
||||
: pos.firstYPos
|
||||
? pos.yBottom - height + pos.firstYPos
|
||||
: pos.yBottom - height;
|
||||
? pos.yBottom - height + pos.firstYPos
|
||||
: pos.yBottom - height;
|
||||
return yPosition;
|
||||
}
|
||||
}
|
||||
@@ -1016,7 +875,11 @@ function EmbedPdfImage() {
|
||||
}}
|
||||
>
|
||||
{/* this modal is used show this document is already sign */}
|
||||
<Modal show={isAlreadySign.status}>
|
||||
<Modal
|
||||
show={isAlreadySign.status}
|
||||
onShow={() => modalAlign()}
|
||||
backdropClassName="signature-backdrop"
|
||||
>
|
||||
<ModalHeader style={{ background: themeColor() }}>
|
||||
<span style={{ color: "white" }}> Sign Documents</span>
|
||||
</ModalHeader>
|
||||
@@ -1072,7 +935,7 @@ function EmbedPdfImage() {
|
||||
{/* pdf header which contain finish back button */}
|
||||
<Header
|
||||
recipient={true}
|
||||
pdfDetails={completePdfData}
|
||||
pdfDetails={signedPdfData}
|
||||
isAlreadySign={isAlreadySign}
|
||||
pageNumber={pageNumber}
|
||||
allPages={allPages}
|
||||
@@ -1083,6 +946,7 @@ function EmbedPdfImage() {
|
||||
isShowHeader={true}
|
||||
currentSigner={true}
|
||||
decline={true}
|
||||
alreadySign={pdfUrl ? true : false}
|
||||
/>
|
||||
|
||||
<RenderPdf
|
||||
@@ -1127,9 +991,8 @@ function EmbedPdfImage() {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
</DndProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default EmbedPdfImage;
|
||||
export default EmbedPdfImage;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
@@ -80,6 +80,10 @@
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.emailChipClose:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.addEmailInput {
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
@@ -374,15 +378,13 @@
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.DropdownMenuContent,
|
||||
.DropdownMenuSubContent {
|
||||
min-width: 130px;
|
||||
background-color: #887abf;
|
||||
border: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, .15);
|
||||
border-radius: 0.25rem;
|
||||
padding: 5px;
|
||||
|
||||
animation-duration: 400ms;
|
||||
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
will-change: transform, opacity;
|
||||
@@ -413,13 +415,13 @@
|
||||
font-size: 13px;
|
||||
line-height: 1;
|
||||
color: black;
|
||||
background-color: #887abf;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 25px;
|
||||
padding: 0 5px;
|
||||
position: relative;
|
||||
padding-left: 25px;
|
||||
padding-left: 20px;
|
||||
user-select: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
@@ -565,13 +567,13 @@ option {
|
||||
color: var(--violet-11);
|
||||
cursor: default;
|
||||
}
|
||||
.fontOptionContainer{
|
||||
border: 1px solid #d6d3d3;
|
||||
margin: 10px 5px 5px 5px;
|
||||
|
||||
.fontOptionContainer {
|
||||
border: 1px solid #d6d3d3;
|
||||
margin: 10px 5px 5px 5px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width:766px) {
|
||||
|
||||
.showPages {
|
||||
@@ -628,25 +630,27 @@ option {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
/* The sticky class is added to the navbar
|
||||
/* The sticky class is added to the navbar
|
||||
with JS when it reaches its scroll position */
|
||||
.stickyHead {
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 0.9rem;
|
||||
}
|
||||
.stickySignerHead{
|
||||
position: fixed;
|
||||
}
|
||||
.stickyfooter {
|
||||
}
|
||||
|
||||
.stickySignerHead {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.stickyfooter {
|
||||
position: fixed;
|
||||
z-index: 32 !important;
|
||||
bottom: 0px;
|
||||
right: 0rem;
|
||||
}
|
||||
|
||||
/* Add some top padding to the page content
|
||||
to prevent sudden quick movement (as the
|
||||
navigation bar gets a new position at the top of the
|
||||
/* Add some top padding to the page content
|
||||
to prevent sudden quick movement (as the
|
||||
navigation bar gets a new position at the top of the
|
||||
page (position:fixed and top:0) */
|
||||
.stickyHead+.content {
|
||||
padding-top: 60px;
|
||||
@@ -776,4 +780,14 @@ option {
|
||||
.mobileHead {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.signature-backdrop {
|
||||
position: fixed;
|
||||
top: 0; bottom: 0; left: 0; right: 0;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.signature-backdrop.fade.in {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import axios from "axios";
|
||||
|
||||
import { $ } from "select-dom";
|
||||
import { rgb } from "pdf-lib";
|
||||
export async function getBase64FromUrl(url) {
|
||||
const data = await fetch(url);
|
||||
const blob = await data.blob();
|
||||
@@ -28,13 +29,35 @@ export async function getBase64FromIMG(url) {
|
||||
};
|
||||
});
|
||||
}
|
||||
//function for convert signature png base64 url to jpeg base64
|
||||
export const convertPNGtoJPEG = (base64Data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const img = new Image();
|
||||
img.src = base64Data;
|
||||
|
||||
img.onload = () => {
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = "#ffffff"; // white color
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(img, 0, 0);
|
||||
// Convert to JPEG by using the canvas.toDataURL() method
|
||||
const jpegBase64Data = canvas.toDataURL("image/jpeg");
|
||||
|
||||
resolve(jpegBase64Data);
|
||||
};
|
||||
|
||||
img.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export function getHostUrl() {
|
||||
const hostUrl = window.location.href;
|
||||
/// const hostUrl = "https://contracts-defaultssty.qik.ai/#/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive";
|
||||
// const hostUrl = "https://contracts-defaultssty.qik.ai/#/"
|
||||
// const hostUrl = "https://lionfish-app-75ly7.ondigitalocean.app/mf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive"
|
||||
//const hostUrl = "https://app.opensignlabs.com/rpmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument";
|
||||
|
||||
if (hostUrl) {
|
||||
const urlSplit = hostUrl.split("/");
|
||||
@@ -57,7 +80,6 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
||||
(data, ind) =>
|
||||
data.key === signKey && data.Width && data.Height && data.SignUrl
|
||||
);
|
||||
|
||||
|
||||
if (updateFilter.length > 0) {
|
||||
let newWidth, newHeight;
|
||||
@@ -139,7 +161,7 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
||||
...url,
|
||||
Width: getPosData[0].Width ? getPosData[0].Width : newWidth,
|
||||
Height: getPosData[0].Height ? getPosData[0].Height : newHeight,
|
||||
SignUrl: image.src,
|
||||
SignUrl: image.src,
|
||||
ImageType: image.imgType
|
||||
};
|
||||
}
|
||||
@@ -153,7 +175,6 @@ export function onSaveImage(xyPostion, index, signKey, imgWH, image) {
|
||||
return obj;
|
||||
});
|
||||
return newUpdateUrl;
|
||||
// setXyPostion(newUpdateUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,40 +204,105 @@ export function onSaveSign(xyPostion, index, signKey, signatureImg) {
|
||||
return newUpdateUrl;
|
||||
}
|
||||
|
||||
//function for getting contract_User details
|
||||
export const contractUsers = async (objectId) => {
|
||||
const result = await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Users?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${objectId}"}}`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
//function for getting document details from contract_Documents class
|
||||
export const contractDocument = async (documentId) => {
|
||||
const data = {
|
||||
docId: documentId
|
||||
};
|
||||
const documentDeatils = 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")
|
||||
}
|
||||
)
|
||||
})
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
const res = json.results;
|
||||
return res;
|
||||
let data = [];
|
||||
if (json && json.result.error) {
|
||||
return json;
|
||||
} else if (json && json.result) {
|
||||
data.push(json.result);
|
||||
return data;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
return "Error: Something went wrong!";
|
||||
});
|
||||
|
||||
return result;
|
||||
return documentDeatils;
|
||||
};
|
||||
|
||||
//function for getting contrscts_contactbook details
|
||||
//function for getting document details for getDrive
|
||||
export const getDrive = async (documentId) => {
|
||||
const data = {
|
||||
docId: documentId && documentId
|
||||
};
|
||||
const driveDeatils = await axios
|
||||
.post(`${localStorage.getItem("baseUrl")}functions/getDrive`, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessiontoken: localStorage.getItem("accesstoken")
|
||||
}
|
||||
})
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
|
||||
if (json && json.result.error) {
|
||||
return json;
|
||||
} else if (json && json.result) {
|
||||
const data = json.result;
|
||||
return data;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
return "Error: Something went wrong!";
|
||||
});
|
||||
|
||||
return driveDeatils;
|
||||
};
|
||||
//function for getting contract_User details
|
||||
export const contractUsers = async (email) => {
|
||||
const data = {
|
||||
email: email
|
||||
};
|
||||
const userDetails = await axios
|
||||
.post(`${localStorage.getItem("baseUrl")}functions/getUserDetails`, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
}
|
||||
})
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
let data = [];
|
||||
|
||||
if (json && json.result) {
|
||||
data.push(json.result);
|
||||
return data;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
return "Error: Something went wrong!";
|
||||
});
|
||||
|
||||
return userDetails;
|
||||
};
|
||||
|
||||
//function for getting contracts_contactbook details
|
||||
export const contactBook = async (objectId) => {
|
||||
const result = await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}_Contactbook?where={"UserId": {"__type": "Pointer","className": "_User", "objectId":"${objectId}"}}`,
|
||||
)}_Contactbook?where={"objectId":"${objectId}"}`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -237,26 +323,166 @@ export const contactBook = async (objectId) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
export const contactBookName = async (objectId, className) => {
|
||||
const result = await axios
|
||||
.get(
|
||||
`${localStorage.getItem("baseUrl")}classes/${localStorage.getItem(
|
||||
"_appName"
|
||||
)}${className}?where={"objectId":"${objectId}"}`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
// function for validating URLs
|
||||
export function urlValidator(url) {
|
||||
try {
|
||||
const newUrl = new URL(url);
|
||||
return newUrl.protocol === "http:" || newUrl.protocol === "https:";
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export function modalAlign() {
|
||||
let modalDialog = $(".modal-dialog").getBoundingClientRect();
|
||||
let mobileHead = $(".mobileHead").getBoundingClientRect();
|
||||
let modal = $(".modal-dialog");
|
||||
if (modalDialog.left < mobileHead.left) {
|
||||
let leftOffset = mobileHead.left - modalDialog.left;
|
||||
modal.style.left = leftOffset + "px";
|
||||
modal.style.top = window.innerHeight / 3 + "px";
|
||||
}
|
||||
}
|
||||
|
||||
//function for embed multiple signature using pdf-lib
|
||||
export const multiSignEmbed = async (
|
||||
pngUrl,
|
||||
pdfDoc,
|
||||
pdfOriginalWidth,
|
||||
signyourself
|
||||
) => {
|
||||
for (let i = 0; i < pngUrl.length; i++) {
|
||||
const pageNo = pngUrl[i].pageNumber;
|
||||
const imgUrlList = pngUrl[i].pos;
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[pageNo - 1];
|
||||
const images = await Promise.all(
|
||||
imgUrlList.map(async (url) => {
|
||||
let signUrl = url.SignUrl;
|
||||
if (url.ImageType === "image/png") {
|
||||
//function for convert signature png base64 url to jpeg base64
|
||||
const newUrl = await convertPNGtoJPEG(signUrl);
|
||||
signUrl = newUrl;
|
||||
}
|
||||
const checkUrl = urlValidator(signUrl);
|
||||
if (checkUrl) {
|
||||
signUrl = signUrl + "?get";
|
||||
}
|
||||
const res = await fetch(signUrl);
|
||||
return res.arrayBuffer();
|
||||
})
|
||||
);
|
||||
images.forEach(async (imgData, id) => {
|
||||
let img;
|
||||
if (
|
||||
(imgUrlList[id].ImageType &&
|
||||
imgUrlList[id].ImageType === "image/png") ||
|
||||
imgUrlList[id].ImageType === "image/jpeg"
|
||||
) {
|
||||
img = await pdfDoc.embedJpg(imgData);
|
||||
} else {
|
||||
img = await pdfDoc.embedPng(imgData);
|
||||
}
|
||||
)
|
||||
.then((Listdata) => {
|
||||
const json = Listdata.data;
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
return "Error: Something went wrong!";
|
||||
const imgHeight = imgUrlList[id].Height ? imgUrlList[id].Height : 60;
|
||||
const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150;
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = window.innerWidth - 32;
|
||||
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
|
||||
const xPos = (pos) => {
|
||||
if (signyourself) {
|
||||
if (isMobile) {
|
||||
return imgUrlList[id].xPosition * scale + 43;
|
||||
} else {
|
||||
return imgUrlList[id].xPosition;
|
||||
}
|
||||
} else {
|
||||
//checking both condition mobile and desktop view
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (pos.isMobile) {
|
||||
const x = pos.xPosition * (pos.scale / scale);
|
||||
return x * scale + 50;
|
||||
} else {
|
||||
const x = pos.xPosition / scale;
|
||||
return x * scale;
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
if (pos.isMobile) {
|
||||
const x = pos.xPosition * pos.scale + 50;
|
||||
return x;
|
||||
} else {
|
||||
return pos.xPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const yPos = (pos) => {
|
||||
if (signyourself) {
|
||||
if (isMobile) {
|
||||
return (
|
||||
page.getHeight() -
|
||||
imgUrlList[id].yPosition * scale -
|
||||
imgHeight * scale
|
||||
);
|
||||
} else {
|
||||
return page.getHeight() - imgUrlList[id].yPosition - imgHeight;
|
||||
}
|
||||
} else {
|
||||
//checking both condition mobile and desktop view
|
||||
const y = pos.yPosition / scale;
|
||||
if (isMobile) {
|
||||
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
|
||||
if (pos.isMobile) {
|
||||
const y = pos.yPosition * (pos.scale / scale);
|
||||
return page.getHeight() - y * scale - imgHeight;
|
||||
} else {
|
||||
return page.getHeight() - y * scale - imgHeight;
|
||||
}
|
||||
} else {
|
||||
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
|
||||
if (pos.isMobile) {
|
||||
const y = pos.yPosition * pos.scale;
|
||||
return page.getHeight() - y - imgHeight;
|
||||
} else {
|
||||
return page.getHeight() - pos.yPosition - imgHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
page.drawImage(img, {
|
||||
x: xPos(imgUrlList[id]),
|
||||
y: yPos(imgUrlList[id]),
|
||||
width: signyourself ? imgWidth * scale : imgWidth,
|
||||
height: signyourself ? imgHeight * scale : imgHeight
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false });
|
||||
return pdfBytes;
|
||||
};
|
||||
//function for embed document id
|
||||
export const embedDocId = async (pdfDoc, documentId, allPages) => {
|
||||
for (let i = 0; i < allPages; i++) {
|
||||
const font = await pdfDoc.embedFont("Helvetica");
|
||||
const fontSize = 10;
|
||||
const textContent = documentId && `OpenSign™ DocumentId: ${documentId} `;
|
||||
const pages = pdfDoc.getPages();
|
||||
const page = pages[i];
|
||||
page.drawText(textContent, {
|
||||
x: 10,
|
||||
y: page.getHeight() - 10,
|
||||
size: fontSize,
|
||||
font,
|
||||
color: rgb(0.5, 0.5, 0.5)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const pdfNewWidthFun = (divRef) => {
|
||||
const clientWidth = divRef.current.offsetWidth;
|
||||
const pdfWidth = clientWidth - 160 - 200;
|
||||
//160 is width of left side, 200 is width of right side component
|
||||
return pdfWidth;
|
||||
};
|
||||
|
||||
Generated
+704
@@ -0,0 +1,704 @@
|
||||
{
|
||||
"name": "opensign",
|
||||
"version": "1.0.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "opensign",
|
||||
"version": "1.0.6",
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"husky": "^8.0.0",
|
||||
"lint-staged": "^15.1.0",
|
||||
"prettier": "3.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-escapes": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz",
|
||||
"integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
|
||||
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"restore-cursor": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-truncate": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz",
|
||||
"integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"slice-ansi": "^5.0.0",
|
||||
"string-width": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/colorette": {
|
||||
"version": "2.0.20",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
||||
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/execa": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
|
||||
"integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"get-stream": "^8.0.1",
|
||||
"human-signals": "^5.0.0",
|
||||
"is-stream": "^3.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^5.1.0",
|
||||
"onetime": "^6.0.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"strip-final-newline": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
||||
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/husky": {
|
||||
"version": "8.0.3",
|
||||
"resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz",
|
||||
"integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"husky": "lib/bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/typicode"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
|
||||
"integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
|
||||
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
||||
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged": {
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.1.0.tgz",
|
||||
"integrity": "sha512-ZPKXWHVlL7uwVpy8OZ7YQjYDAuO5X4kMh0XgZvPNxLcCCngd0PO5jKQyy3+s4TL2EnHoIXIzP1422f/l3nZKMw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "5.3.0",
|
||||
"commander": "11.1.0",
|
||||
"debug": "4.3.4",
|
||||
"execa": "8.0.1",
|
||||
"lilconfig": "2.1.0",
|
||||
"listr2": "7.0.2",
|
||||
"micromatch": "4.0.5",
|
||||
"pidtree": "0.6.0",
|
||||
"string-argv": "0.3.2",
|
||||
"yaml": "2.3.4"
|
||||
},
|
||||
"bin": {
|
||||
"lint-staged": "bin/lint-staged.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/lint-staged"
|
||||
}
|
||||
},
|
||||
"node_modules/listr2": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz",
|
||||
"integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cli-truncate": "^3.1.0",
|
||||
"colorette": "^2.0.20",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"log-update": "^5.0.1",
|
||||
"rfdc": "^1.3.0",
|
||||
"wrap-ansi": "^8.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/log-update": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz",
|
||||
"integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-escapes": "^5.0.0",
|
||||
"cli-cursor": "^4.0.0",
|
||||
"slice-ansi": "^5.0.0",
|
||||
"strip-ansi": "^7.0.1",
|
||||
"wrap-ansi": "^8.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-fn": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
|
||||
"integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path/node_modules/path-key": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
|
||||
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/onetime": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pidtree": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
|
||||
"integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"pidtree": "bin/pidtree.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz",
|
||||
"integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/rfdc": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
|
||||
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/slice-ansi": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
|
||||
"integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.0.0",
|
||||
"is-fullwidth-code-point": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/string-argv": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
|
||||
"integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.6.19"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-final-newline": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
|
||||
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
|
||||
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
|
||||
"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "opensign",
|
||||
"version": "1.0.6",
|
||||
"description": "Free and open source alternative to DocuSign",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"prepare": "husky install",
|
||||
"lint-staged-changes": "lint-staged"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "github.com/opensignlabs/opensign"
|
||||
},
|
||||
"keywords": [
|
||||
"digital",
|
||||
"signature",
|
||||
"e-signature",
|
||||
"docusign",
|
||||
"electronic",
|
||||
"signature"
|
||||
],
|
||||
"author": "OpenSignLabs",
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"husky": "^8.0.0",
|
||||
"lint-staged": "^15.1.0",
|
||||
"prettier": "3.1.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user