Compare commits
454 Commits
Kartik_Bug
...
main
Author | SHA1 | Date | |
---|---|---|---|
12b632f087 | |||
6ee4fb6d04 | |||
67bb685d4b | |||
8fd4e7f3f1 | |||
aca2decb00 | |||
f7f4b68997 | |||
f839613066 | |||
b58bd33774 | |||
136bc94c5b | |||
281a956ac8 | |||
31882c3d12 | |||
a64635cd37 | |||
9b8c8c34ab | |||
704ba79289 | |||
3440467107 | |||
f4edcfd2f3 | |||
62e5c6899a | |||
00a23b3de9 | |||
79161a8ede | |||
860779d096 | |||
a2067e150d | |||
edce5ef614 | |||
dd944b3414 | |||
13d3572cf6 | |||
0dd7c19457 | |||
3cc4f0b416 | |||
f8095ac9bf | |||
6280abf95e | |||
1200937097 | |||
5d1ccb9572 | |||
91ffc5a0e0 | |||
1c4804fed2 | |||
0e5e716df2 | |||
aecaee7116 | |||
97dca1a10b | |||
c35eacca5a | |||
5e27ed36fa | |||
8bcfcc5718 | |||
ad1bef4f7b | |||
9886fac03e | |||
a28a7fb444 | |||
470421b730 | |||
7505b790a7 | |||
8fd13247c7 | |||
0fec257354 | |||
638c033705 | |||
7872e21477 | |||
6928bbd309 | |||
3693af3d00 | |||
d5df200ede | |||
9c6450496e | |||
cfd3986479 | |||
764b145ad9 | |||
20c7cf7f37 | |||
6d74940c0c | |||
02dcd8611f | |||
02600308e8 | |||
d1c72291a3 | |||
fdbd81c5e7 | |||
28d5ef653d | |||
550b142d74 | |||
68335f0695 | |||
4ea20981fc | |||
965e1e4808 | |||
1c376fe91f | |||
61835cb189 | |||
375c482b61 | |||
72424eee53 | |||
22514b1fa0 | |||
61b209a082 | |||
198e31290c | |||
482f8a9bcb | |||
2489095b0b | |||
eb8d269662 | |||
bbd8ed12f6 | |||
1e7b4ba21e | |||
4de3987a37 | |||
7455d8a221 | |||
3f4b7d08d4 | |||
7ac3268514 | |||
f8740472de | |||
be72ca9a58 | |||
c71c00c0f7 | |||
112e0ff798 | |||
96eb030457 | |||
a873ace109 | |||
fb164bd2f2 | |||
0d6708619f | |||
edba191a2e | |||
ddfe09b570 | |||
acb899dd2e | |||
ae66cb3705 | |||
d52fa00de0 | |||
ca8a41bb63 | |||
265c74f079 | |||
2ef1fcfd1d | |||
3233043cf2 | |||
3fddb686d3 | |||
4fd6e5cc1a | |||
1fb8eb9ef1 | |||
1a3890e837 | |||
2dbf08e330 | |||
b044b88c49 | |||
db815ba038 | |||
53fa013c39 | |||
22a1ad45e7 | |||
91dcd7c132 | |||
7d18edfa9b | |||
fb08e48edd | |||
69c225ac72 | |||
182280e91d | |||
38bd8d36c0 | |||
a4bccc9bf6 | |||
0e6dd93260 | |||
245219ad71 | |||
978a497f28 | |||
451d0a785f | |||
84f9cb2e29 | |||
9d9ca28bad | |||
1d218056ac | |||
58837cef0c | |||
1cd3bf6c7f | |||
d2b10495bd | |||
ae9c4833b3 | |||
e69efe61cb | |||
92b1531b75 | |||
57edd92dce | |||
49eaf857ad | |||
ccdfc193c6 | |||
817b31379e | |||
b36120f73d | |||
e2ae2e5fbd | |||
521e6690cb | |||
1f4a7e5e9c | |||
1d3fcff859 | |||
1286184e1f | |||
4e315aafcf | |||
52e12426af | |||
d975664023 | |||
d87dae4799 | |||
4683eff749 | |||
772a3e2829 | |||
ca7b0cda13 | |||
a380a7ab29 | |||
c609387924 | |||
69cc3b9383 | |||
6ebbc853bc | |||
71dd35adc2 | |||
533b40d1bf | |||
42a80bbd68 | |||
397020ccb4 | |||
71932ea6dc | |||
693cabf63d | |||
4afe43d116 | |||
b9b3788dda | |||
5e1ccc9b05 | |||
aee510f527 | |||
7e6020e3db | |||
cf78d17cf5 | |||
72dbdb0fe0 | |||
afcd1934f9 | |||
![]() |
3e5afe0bc6 | ||
![]() |
070fa93fca | ||
53a9cbc30b | |||
70acf57266 | |||
b2d7349fc9 | |||
a0f7e5c57b | |||
fa7dc2860c | |||
a1a935b0d5 | |||
![]() |
e610cc08c1 | ||
9711144236 | |||
1a88f5fec5 | |||
ce73cfad21 | |||
7dafd4a45f | |||
2e3e3aa6ca | |||
158c934a9f | |||
f6d864d42e | |||
90b96864be | |||
5a048f7066 | |||
731d2dbed7 | |||
25de45b31b | |||
58b5da1793 | |||
0746e5c349 | |||
83143dff0a | |||
994f22e8c0 | |||
84a5be52f8 | |||
b39df5f665 | |||
9bdcc74486 | |||
005fdb3490 | |||
9223f7a176 | |||
27b62c858d | |||
00d6774e06 | |||
1ef82ad0b2 | |||
1da587d010 | |||
164b82e1c7 | |||
e9d8b6daea | |||
9b37288901 | |||
54e609883d | |||
7d17422681 | |||
d67121c150 | |||
e154bac64a | |||
ea350db98b | |||
133024bc5c | |||
ea219b7176 | |||
af5519fd60 | |||
08194dd8ef | |||
1452e77bc5 | |||
7fa2ca9227 | |||
0d9ef7f248 | |||
9a3488c92b | |||
1b144aab8a | |||
2e65007f26 | |||
3c4c25b449 | |||
979293ad90 | |||
99eaf92e3f | |||
28b0541894 | |||
a48fc1d989 | |||
78a0ecebf1 | |||
8eb8e27f89 | |||
012a89b3ea | |||
18698a67e3 | |||
701d1adc0b | |||
b2c68824dd | |||
b3b7297bc3 | |||
9311f41f56 | |||
9ba2ecfb1f | |||
a27b8571b5 | |||
fd36298543 | |||
09bb58e50e | |||
01a5766074 | |||
0348f6da8e | |||
1c0e8655c4 | |||
6211f52e3a | |||
df9107f0d8 | |||
eea7252b96 | |||
442ecff926 | |||
0abd77dab7 | |||
4b0ea3a0db | |||
d3218eb77a | |||
4ad87af7f4 | |||
7b15309dbf | |||
834ce62e67 | |||
889b477dd0 | |||
19f8189fc3 | |||
970c195ca5 | |||
d944d3a389 | |||
e0c7eee1fd | |||
6baa2896c2 | |||
a835e75f66 | |||
cc7ef47055 | |||
95fbac4760 | |||
a86c815ca2 | |||
daa1a29e8a | |||
794429821b | |||
7d94c17c71 | |||
fb6a8255c9 | |||
7ef10e3e5b | |||
0a489be675 | |||
c014d6c929 | |||
2c378745fa | |||
080d2307ca | |||
d2288ea967 | |||
42086d7f3a | |||
020020056e | |||
9b3ffdb33d | |||
d70c8e5995 | |||
e6e90c7d4e | |||
19241cc556 | |||
7c2744058d | |||
a963176c95 | |||
6bc8c65c81 | |||
45bd5a7f66 | |||
e179a267aa | |||
9c51378963 | |||
4927680fe3 | |||
9af7a5ceb2 | |||
94eb283b2d | |||
0e3a634205 | |||
2ef56e7f83 | |||
d80fa27906 | |||
70110192f4 | |||
548597ed4f | |||
75ca3d1504 | |||
f20ff7eb73 | |||
ce59869827 | |||
d77e3c5f03 | |||
2f2ddb0576 | |||
2e14fc862d | |||
84500f6913 | |||
2790f50275 | |||
8c48b83581 | |||
f992dbeaf1 | |||
d1098e64a7 | |||
212e969258 | |||
9de1613bd9 | |||
9676d45710 | |||
7e5b6952f5 | |||
0484de498c | |||
a7ccaa2812 | |||
5fb7e89cb2 | |||
2027bd3d17 | |||
ee9698f665 | |||
25ec5a354c | |||
8335c42935 | |||
3963002a2d | |||
717264c9f9 | |||
1a04dd51fc | |||
c83de16466 | |||
b51b3db9ec | |||
79553cab4e | |||
7a74084841 | |||
7638f8bdaa | |||
78f304a490 | |||
0b38436dfe | |||
15581f3f26 | |||
8dc064340b | |||
285b853026 | |||
81e5456e1d | |||
4741025dcb | |||
aec6bd64ff | |||
eea36a2722 | |||
1a7e77c814 | |||
b1a2250c48 | |||
f20c3a64f6 | |||
ebab03dc9f | |||
d6de8cbfc1 | |||
44cc6c6e81 | |||
6604a4db13 | |||
b66106c301 | |||
691fd9208f | |||
45b21d3e73 | |||
3db6cc2100 | |||
b934527cf5 | |||
bac62e1fa7 | |||
5ec5218dd6 | |||
47d0e332f1 | |||
b02893fd98 | |||
c9ccd46385 | |||
aa45731d8c | |||
614d61e6e9 | |||
0e35194a82 | |||
20077a137f | |||
1ff1bc9269 | |||
b50b6bc454 | |||
d87defbf9a | |||
e454917763 | |||
b113675cc2 | |||
025b13ea64 | |||
755eb94ae3 | |||
1138bdf009 | |||
2642532b60 | |||
67d399e3d3 | |||
fdc377cc3a | |||
1bd951636a | |||
13a517f998 | |||
d5b3c25b45 | |||
f8466e5f4a | |||
6998714fea | |||
98546afc1a | |||
49b89f74ff | |||
7a5fc509fb | |||
8d44606b0b | |||
b91487712d | |||
6ca6ec31f7 | |||
849709ad05 | |||
1abed1de3a | |||
1b98c60120 | |||
4295e7d8d6 | |||
f72b7c62c8 | |||
01a3f5809a | |||
bb7e488bb0 | |||
da8d63ce62 | |||
ef0eff98f8 | |||
2a833196f8 | |||
97a4a4593e | |||
a112886897 | |||
63a5f7b902 | |||
ace507232a | |||
f9876c6d52 | |||
6d86362e9e | |||
698c1b7b16 | |||
e216ac16ef | |||
0194c4427a | |||
ea022d37c8 | |||
957f790fce | |||
6a472b39ef | |||
768f810465 | |||
7ed6a7e5b9 | |||
5c59ac3115 | |||
7e81649841 | |||
e39355c6fd | |||
f9fe987a94 | |||
87221965de | |||
6caad7850d | |||
8f8cbf27ef | |||
0db0edec1a | |||
f56fd23cbf | |||
2b5fc9aaac | |||
1eaf4a080c | |||
fe3d356c2e | |||
f3913c2824 | |||
e66ce11cd5 | |||
a8239d5c31 | |||
97a32b8f42 | |||
a52cf0bc39 | |||
e007c0e8da | |||
e2de5eba40 | |||
fd14328562 | |||
e8459d3671 | |||
528d3b756c | |||
11be36b67a | |||
ef00f83c44 | |||
809f2ef726 | |||
a95e365087 | |||
2ee9c8ecbd | |||
7eb22bb785 | |||
cd32f743ce | |||
acd642c935 | |||
06503ac4d3 | |||
ee1887de8f | |||
2f24d4a7ff | |||
518928e439 | |||
cec16ded3e | |||
b70d03af8a | |||
daf7f11310 | |||
b93eaf6b95 | |||
d42790628c | |||
1c9df57c74 | |||
d4804e4c3f | |||
386b61d978 | |||
14fba75d19 | |||
65b90bc9ac | |||
7268971275 | |||
1ad9b782a4 | |||
5dfaa6d44c | |||
4b988109f9 | |||
83c2f7fb0c | |||
ead8901d1e | |||
8b2529013f | |||
bbd137a334 | |||
8b11bd952d | |||
d729054065 | |||
585199a2a1 | |||
ac0d17ca6d | |||
61fb797db4 | |||
86187eaf8a | |||
67bf293bef | |||
25945366d6 | |||
a602bebc5e | |||
ee2c973d01 | |||
4d66ebeb50 | |||
38332c0a0d | |||
7ad65ece78 | |||
34cf3a0913 |
0
.scannerwork/.sonar_lock
Normal file
6
.scannerwork/report-task.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
projectKey=pms-react
|
||||||
|
serverUrl=https://sonar.marcoaiot.com
|
||||||
|
serverVersion=25.5.0.107428
|
||||||
|
dashboardUrl=https://sonar.marcoaiot.com/dashboard?id=pms-react
|
||||||
|
ceTaskId=ad6ba36a-08cb-400b-903e-94f173cac03f
|
||||||
|
ceTaskUrl=https://sonar.marcoaiot.com/api/ce/task?id=ad6ba36a-08cb-400b-903e-94f173cac03f
|
138
package-lock.json
generated
@ -37,6 +37,7 @@
|
|||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"react-toastify": "^11.0.2",
|
"react-toastify": "^11.0.2",
|
||||||
"sort-by": "^1.2.0",
|
"sort-by": "^1.2.0",
|
||||||
|
"swiper": "^11.2.10",
|
||||||
"xlsx": "^0.18.5",
|
"xlsx": "^0.18.5",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
},
|
},
|
||||||
@ -808,9 +809,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/source-map": {
|
"node_modules/@jridgewell/source-map": {
|
||||||
"version": "0.3.6",
|
"version": "0.3.11",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
|
||||||
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
|
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -1551,13 +1552,13 @@
|
|||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.13.13",
|
"version": "24.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.13.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz",
|
||||||
"integrity": "sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ==",
|
"integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.20.0"
|
"undici-types": "~7.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
@ -1834,9 +1835,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.14.0",
|
"version": "8.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@ -1844,6 +1846,19 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/acorn-import-phases": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"acorn": "^8.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn-jsx": {
|
"node_modules/acorn-jsx": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||||
@ -2624,9 +2639,9 @@
|
|||||||
"integrity": "sha512-ZpSAUOZ2Izby7qnZluSrAlGgGQzucmFbN0n64dYzocYxnxV5ufurpj3VgEe4cUp7ir9LmeLxNYo8bVnlM8bQHw=="
|
"integrity": "sha512-ZpSAUOZ2Izby7qnZluSrAlGgGQzucmFbN0n64dYzocYxnxV5ufurpj3VgEe4cUp7ir9LmeLxNYo8bVnlM8bQHw=="
|
||||||
},
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.18.1",
|
"version": "5.18.3",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
|
||||||
"integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
|
"integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2740,9 +2755,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/es-module-lexer": {
|
"node_modules/es-module-lexer": {
|
||||||
"version": "1.6.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
|
||||||
"integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
|
"integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
@ -3137,9 +3152,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/fast-uri": {
|
"node_modules/fast-uri": {
|
||||||
"version": "3.0.6",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
|
||||||
"integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
|
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@ -5162,9 +5177,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/schema-utils": {
|
"node_modules/schema-utils": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
|
||||||
"integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
|
"integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5547,25 +5562,47 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/swiper": {
|
||||||
|
"version": "11.2.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz",
|
||||||
|
"integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/swiperjs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "open_collective",
|
||||||
|
"url": "http://opencollective.com/swiper"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tapable": {
|
"node_modules/tapable": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz",
|
||||||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
"integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/webpack"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.39.0",
|
"version": "5.44.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz",
|
||||||
"integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
|
"integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
"acorn": "^8.8.2",
|
"acorn": "^8.15.0",
|
||||||
"commander": "^2.20.0",
|
"commander": "^2.20.0",
|
||||||
"source-map-support": "~0.5.20"
|
"source-map-support": "~0.5.20"
|
||||||
},
|
},
|
||||||
@ -5758,9 +5795,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "6.20.0",
|
"version": "7.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz",
|
||||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
"integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
@ -5888,9 +5925,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
|
||||||
"integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
|
"integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5908,21 +5945,23 @@
|
|||||||
"license": "BSD-2-Clause"
|
"license": "BSD-2-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.98.0",
|
"version": "5.101.3",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz",
|
||||||
"integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
|
"integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.7",
|
"@types/eslint-scope": "^3.7.7",
|
||||||
"@types/estree": "^1.0.6",
|
"@types/estree": "^1.0.8",
|
||||||
|
"@types/json-schema": "^7.0.15",
|
||||||
"@webassemblyjs/ast": "^1.14.1",
|
"@webassemblyjs/ast": "^1.14.1",
|
||||||
"@webassemblyjs/wasm-edit": "^1.14.1",
|
"@webassemblyjs/wasm-edit": "^1.14.1",
|
||||||
"@webassemblyjs/wasm-parser": "^1.14.1",
|
"@webassemblyjs/wasm-parser": "^1.14.1",
|
||||||
"acorn": "^8.14.0",
|
"acorn": "^8.15.0",
|
||||||
|
"acorn-import-phases": "^1.0.3",
|
||||||
"browserslist": "^4.24.0",
|
"browserslist": "^4.24.0",
|
||||||
"chrome-trace-event": "^1.0.2",
|
"chrome-trace-event": "^1.0.2",
|
||||||
"enhanced-resolve": "^5.17.1",
|
"enhanced-resolve": "^5.17.3",
|
||||||
"es-module-lexer": "^1.2.1",
|
"es-module-lexer": "^1.2.1",
|
||||||
"eslint-scope": "5.1.1",
|
"eslint-scope": "5.1.1",
|
||||||
"events": "^3.2.0",
|
"events": "^3.2.0",
|
||||||
@ -5932,11 +5971,11 @@
|
|||||||
"loader-runner": "^4.2.0",
|
"loader-runner": "^4.2.0",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"neo-async": "^2.6.2",
|
"neo-async": "^2.6.2",
|
||||||
"schema-utils": "^4.3.0",
|
"schema-utils": "^4.3.2",
|
||||||
"tapable": "^2.1.1",
|
"tapable": "^2.1.1",
|
||||||
"terser-webpack-plugin": "^5.3.11",
|
"terser-webpack-plugin": "^5.3.11",
|
||||||
"watchpack": "^2.4.1",
|
"watchpack": "^2.4.1",
|
||||||
"webpack-sources": "^3.2.3"
|
"webpack-sources": "^3.3.3"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"webpack": "bin/webpack.js"
|
"webpack": "bin/webpack.js"
|
||||||
@ -5955,15 +5994,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webpack-sources": {
|
"node_modules/webpack-sources": {
|
||||||
"version": "3.2.3",
|
"version": "3.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
|
||||||
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
|
"integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/webpack/node_modules/@types/estree": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/webpack/node_modules/eslint-scope": {
|
"node_modules/webpack/node_modules/eslint-scope": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"react-toastify": "^11.0.2",
|
"react-toastify": "^11.0.2",
|
||||||
"sort-by": "^1.2.0",
|
"sort-by": "^1.2.0",
|
||||||
|
"swiper": "^11.2.10",
|
||||||
"xlsx": "^0.18.5",
|
"xlsx": "^0.18.5",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
},
|
},
|
||||||
|
@ -1,8 +1,282 @@
|
|||||||
:root,
|
:root,
|
||||||
[data-bs-theme="light"] {
|
[data-bs-theme="light"] {
|
||||||
--bs-nav-link-font-size: 0.7375rem;
|
--bs-nav-link-font-size: 0.7375rem;
|
||||||
|
--bg-border-color :#f8f6f6
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header {
|
.card-header {
|
||||||
padding: 0.5rem var(--bs-card-cap-padding-x);
|
padding: 0.5rem var(--bs-card-cap-padding-x);
|
||||||
}
|
}
|
||||||
|
.table_header_border {
|
||||||
|
border-bottom:2px solid var(--bs-table-border-color) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.text-xxs { font-size: 0.55rem; } /* 8px */
|
||||||
|
.text-xs { font-size: 0.75rem; } /* 12px */
|
||||||
|
.text-sm { font-size: 0.875rem; } /* 14px */
|
||||||
|
.text-base { font-size: 1rem; } /* 16px */
|
||||||
|
.text-lg { font-size: 1.125rem; } /* 18px */
|
||||||
|
.text-xl { font-size: 1.25rem; } /* 20px */
|
||||||
|
.text-2xl { font-size: 1.5rem; } /* 24px */
|
||||||
|
.text-3xl { font-size: 1.875rem; } /* 30px */
|
||||||
|
.text-4xl { font-size: 2.25rem; } /* 36px */
|
||||||
|
.text-5xl { font-size: 3rem; } /* 48px */
|
||||||
|
.text-6xl { font-size: 3.75rem; } /* 60px */
|
||||||
|
.text-7xl { font-size: 4.5rem; } /* 72px */
|
||||||
|
.text-8xl { font-size: 6rem; } /* 96px */
|
||||||
|
.text-9xl { font-size: 8rem; } /* 128px */
|
||||||
|
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
.w-0 { width: 0px; }
|
||||||
|
.w-px { width: 1px; }
|
||||||
|
.w-1 { width: 0.25rem; } /* 4px */
|
||||||
|
.w-2 { width: 0.5rem; } /* 8px */
|
||||||
|
.w-3 { width: 0.75rem; } /* 12px */
|
||||||
|
.w-4 { width: 1rem; } /* 16px */
|
||||||
|
.w-5 { width: 1.25rem; } /* 20px */
|
||||||
|
.w-6 { width: 1.5rem; } /* 24px */
|
||||||
|
.w-8 { width: 2rem; } /* 32px */
|
||||||
|
.w-10 { width: 2.5rem; } /* 40px */
|
||||||
|
.w-12 { width: 3rem; } /* 48px */
|
||||||
|
.w-16 { width: 4rem; } /* 64px */
|
||||||
|
.w-20 { width: 5rem; } /* 80px */
|
||||||
|
.w-24 { width: 6rem; } /* 96px */
|
||||||
|
.w-32 { width: 8rem; } /* 128px */
|
||||||
|
.w-40 { width: 10rem; } /* 160px */
|
||||||
|
.w-48 { width: 12rem; } /* 192px */
|
||||||
|
.w-56 { width: 14rem; } /* 224px */
|
||||||
|
.w-64 { width: 16rem; } /* 256px */
|
||||||
|
.w-auto { width: auto; }
|
||||||
|
.w-full { width: 100%; }
|
||||||
|
.w-screen{ width: 100vw; }
|
||||||
|
.w-min { width: min-content; }
|
||||||
|
.w-max { width: max-content; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.h-0 { height: 0px; }
|
||||||
|
.h-px { height: 1px; }
|
||||||
|
.h-1 { height: 0.25rem; } /* 4px */
|
||||||
|
.h-2 { height: 0.5rem; } /* 8px */
|
||||||
|
.h-3 { height: 0.75rem; } /* 12px */
|
||||||
|
.h-4 { height: 1rem; } /* 16px */
|
||||||
|
.h-5 { height: 1.25rem; } /* 20px */
|
||||||
|
.h-6 { height: 1.5rem; } /* 24px */
|
||||||
|
.h-8 { height: 2rem; } /* 32px */
|
||||||
|
.h-10 { height: 2.5rem; } /* 40px */
|
||||||
|
.h-12 { height: 3rem; } /* 48px */
|
||||||
|
.h-16 { height: 4rem; } /* 64px */
|
||||||
|
.h-20 { height: 5rem; } /* 80px */
|
||||||
|
.h-24 { height: 6rem; } /* 96px */
|
||||||
|
.h-32 { height: 8rem; } /* 128px */
|
||||||
|
.h-40 { height: 10rem; } /* 160px */
|
||||||
|
.h-48 { height: 12rem; } /* 192px */
|
||||||
|
.h-56 { height: 14rem; } /* 224px */
|
||||||
|
.h-64 { height: 16rem; } /* 256px */
|
||||||
|
.h-auto { height: auto; }
|
||||||
|
.h-full { height: 100%; }
|
||||||
|
.h-screen{ height: 100vh; }
|
||||||
|
.h-min { height: min-content; }
|
||||||
|
.h-max { height: max-content; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ==========================
|
||||||
|
Base Font Sizes (mobile first)
|
||||||
|
========================== */
|
||||||
|
.text-xxs { font-size: 0.55rem; } /* 8px */
|
||||||
|
.text-xs { font-size: 0.75rem; } /* 12px */
|
||||||
|
.text-sm { font-size: 0.875rem; } /* 14px */
|
||||||
|
.text-base{ font-size: 1rem; } /* 16px */
|
||||||
|
.text-lg { font-size: 1.125rem; } /* 18px */
|
||||||
|
.text-xl { font-size: 1.25rem; } /* 20px */
|
||||||
|
.text-2xl { font-size: 1.5rem; } /* 24px */
|
||||||
|
.text-3xl { font-size: 1.875rem; } /* 30px */
|
||||||
|
.text-4xl { font-size: 2.25rem; } /* 36px */
|
||||||
|
.text-5xl { font-size: 3rem; } /* 48px */
|
||||||
|
.text-6xl { font-size: 3.75rem; } /* 60px */
|
||||||
|
.text-7xl { font-size: 4.5rem; } /* 72px */
|
||||||
|
.text-8xl { font-size: 6rem; } /* 96px */
|
||||||
|
.text-9xl { font-size: 8rem; } /* 128px */
|
||||||
|
|
||||||
|
/* ==========================
|
||||||
|
Base Heights
|
||||||
|
========================== */
|
||||||
|
.h-0 { height: 0; }
|
||||||
|
.h-px { height: 1px; }
|
||||||
|
.h-1 { height: 0.25rem; } /* 4px */
|
||||||
|
.h-2 { height: 0.5rem; } /* 8px */
|
||||||
|
.h-3 { height: 0.75rem; } /* 12px */
|
||||||
|
.h-4 { height: 1rem; } /* 16px */
|
||||||
|
.h-5 { height: 1.25rem; } /* 20px */
|
||||||
|
.h-6 { height: 1.5rem; } /* 24px */
|
||||||
|
.h-8 { height: 2rem; } /* 32px */
|
||||||
|
.h-10 { height: 2.5rem; } /* 40px */
|
||||||
|
.h-12 { height: 3rem; } /* 48px */
|
||||||
|
.h-16 { height: 4rem; } /* 64px */
|
||||||
|
.h-20 { height: 5rem; } /* 80px */
|
||||||
|
.h-24 { height: 6rem; } /* 96px */
|
||||||
|
.h-32 { height: 8rem; } /* 128px */
|
||||||
|
.h-40 { height: 10rem; } /* 160px */
|
||||||
|
.h-48 { height: 12rem; } /* 192px */
|
||||||
|
.h-56 { height: 14rem; } /* 224px */
|
||||||
|
.h-64 { height: 16rem; } /* 256px */
|
||||||
|
.h-full { height: 100%; }
|
||||||
|
.h-screen{ height: 100vh; }
|
||||||
|
|
||||||
|
/* ==========================
|
||||||
|
Base Widths
|
||||||
|
========================== */
|
||||||
|
.w-0 { width: 0; }
|
||||||
|
.w-px { width: 1px; }
|
||||||
|
.w-1 { width: 0.25rem; }
|
||||||
|
.w-2 { width: 0.5rem; }
|
||||||
|
.w-3 { width: 0.75rem; }
|
||||||
|
.w-4 { width: 1rem; }
|
||||||
|
.w-5 { width: 1.25rem; }
|
||||||
|
.w-6 { width: 1.5rem; }
|
||||||
|
.w-8 { width: 2rem; }
|
||||||
|
.w-10 { width: 2.5rem; }
|
||||||
|
.w-12 { width: 3rem; }
|
||||||
|
.w-16 { width: 4rem; }
|
||||||
|
.w-20 { width: 5rem; }
|
||||||
|
.w-24 { width: 6rem; }
|
||||||
|
.w-32 { width: 8rem; }
|
||||||
|
.w-40 { width: 10rem; }
|
||||||
|
.w-48 { width: 12rem; }
|
||||||
|
.w-56 { width: 14rem; }
|
||||||
|
.w-64 { width: 16rem; }
|
||||||
|
.w-full { width: 100%; }
|
||||||
|
.w-screen{ width: 100vw; }
|
||||||
|
|
||||||
|
/* ==========================
|
||||||
|
Responsive Variants
|
||||||
|
========================== */
|
||||||
|
@media (min-width: 576px) { /* sm */
|
||||||
|
/* Font */
|
||||||
|
.text-xxs-sm { font-size: 0.55rem; }
|
||||||
|
.text-xs-sm { font-size: 0.75rem; }
|
||||||
|
.text-sm-sm { font-size: 0.875rem; }
|
||||||
|
.text-base-sm{ font-size: 1rem; }
|
||||||
|
.text-lg-sm { font-size: 1.125rem; }
|
||||||
|
.text-xl-sm { font-size: 1.25rem; }
|
||||||
|
.text-2xl-sm{ font-size: 1.5rem; }
|
||||||
|
|
||||||
|
/* Height */
|
||||||
|
.h-1-sm{ height: 0.25rem; }
|
||||||
|
.h-2-sm{ height: 0.5rem; }
|
||||||
|
.h-3-sm{ height: 0.75rem; }
|
||||||
|
.h-4-sm{ height: 1rem; }
|
||||||
|
.h-5-sm{ height: 1.25rem; }
|
||||||
|
.h-6-sm{ height: 1.5rem; }
|
||||||
|
.h-8-sm{ height: 2rem; }
|
||||||
|
.h-10-sm{ height: 2.5rem; }
|
||||||
|
|
||||||
|
/* Width */
|
||||||
|
.w-1-sm{ width: 0.25rem; }
|
||||||
|
.w-2-sm{ width: 0.5rem; }
|
||||||
|
.w-3-sm{ width: 0.75rem; }
|
||||||
|
.w-4-sm{ width: 1rem; }
|
||||||
|
.w-5-sm{ width: 1.25rem; }
|
||||||
|
.w-6-sm{ width: 1.5rem; }
|
||||||
|
.w-8-sm{ width: 2rem; }
|
||||||
|
.w-10-sm{ width: 2.5rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) { /* md */
|
||||||
|
/* Font */
|
||||||
|
.text-xxs-md { font-size: 0.55rem; }
|
||||||
|
.text-xs-md { font-size: 0.75rem; }
|
||||||
|
.text-sm-md { font-size: 0.875rem; }
|
||||||
|
.text-base-md{ font-size: 1rem; }
|
||||||
|
.text-lg-md { font-size: 1.125rem; }
|
||||||
|
.text-xl-md { font-size: 1.25rem; }
|
||||||
|
.text-2xl-md{ font-size: 1.5rem; }
|
||||||
|
|
||||||
|
/* Height */
|
||||||
|
.h-1-md{ height: 0.25rem; }
|
||||||
|
.h-2-md{ height: 0.5rem; }
|
||||||
|
.h-3-md{ height: 0.75rem; }
|
||||||
|
.h-4-md{ height: 1rem; }
|
||||||
|
.h-5-md{ height: 1.25rem; }
|
||||||
|
.h-6-md{ height: 1.5rem; }
|
||||||
|
.h-8-md{ height: 2rem; }
|
||||||
|
.h-10-md{ height: 2.5rem; }
|
||||||
|
|
||||||
|
/* Width */
|
||||||
|
.w-1-md{ width: 0.25rem; }
|
||||||
|
.w-2-md{ width: 0.5rem; }
|
||||||
|
.w-3-md{ width: 0.75rem; }
|
||||||
|
.w-4-md{ width: 1rem; }
|
||||||
|
.w-5-md{ width: 1.25rem; }
|
||||||
|
.w-6-md{ width: 1.5rem; }
|
||||||
|
.w-8-md{ width: 2rem; }
|
||||||
|
.w-10-md{ width: 2.5rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) { /* lg */
|
||||||
|
/* Font */
|
||||||
|
.text-xxs-lg { font-size: 0.55rem; }
|
||||||
|
.text-xs-lg { font-size: 0.75rem; }
|
||||||
|
.text-sm-lg { font-size: 0.875rem; }
|
||||||
|
.text-base-lg{ font-size: 1rem; }
|
||||||
|
.text-lg-lg { font-size: 1.125rem; }
|
||||||
|
.text-xl-lg { font-size: 1.25rem; }
|
||||||
|
.text-2xl-lg{ font-size: 1.5rem; }
|
||||||
|
|
||||||
|
/* Height */
|
||||||
|
.h-1-lg{ height: 0.25rem; }
|
||||||
|
.h-2-lg{ height: 0.5rem; }
|
||||||
|
.h-3-lg{ height: 0.75rem; }
|
||||||
|
.h-4-lg{ height: 1rem; }
|
||||||
|
.h-5-lg{ height: 1.25rem; }
|
||||||
|
.h-6-lg{ height: 1.5rem; }
|
||||||
|
.h-8-lg{ height: 2rem; }
|
||||||
|
.h-10-lg{ height: 2.5rem; }
|
||||||
|
|
||||||
|
/* Width */
|
||||||
|
.w-1-lg{ width: 0.25rem; }
|
||||||
|
.w-2-lg{ width: 0.5rem; }
|
||||||
|
.w-3-lg{ width: 0.75rem; }
|
||||||
|
.w-4-lg{ width: 1rem; }
|
||||||
|
.w-5-lg{ width: 1.25rem; }
|
||||||
|
.w-6-lg{ width: 1.5rem; }
|
||||||
|
.w-8-lg{ width: 2rem; }
|
||||||
|
.w-10-lg{ width: 2.5rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) { /* xl */
|
||||||
|
/* Font */
|
||||||
|
.text-xxs-xl { font-size: 0.55rem; }
|
||||||
|
.text-xs-xl { font-size: 0.75rem; }
|
||||||
|
.text-sm-xl { font-size: 0.875rem; }
|
||||||
|
.text-base-xl{ font-size: 1rem; }
|
||||||
|
.text-lg-xl { font-size: 1.125rem; }
|
||||||
|
.text-xl-xl { font-size: 1.25rem; }
|
||||||
|
.text-2xl-xl{ font-size: 1.5rem; }
|
||||||
|
|
||||||
|
/* Height */
|
||||||
|
.h-1-xl{ height: 0.25rem; }
|
||||||
|
.h-2-xl{ height: 0.5rem; }
|
||||||
|
.h-3-xl{ height: 0.75rem; }
|
||||||
|
.h-4-xl{ height: 1rem; }
|
||||||
|
.h-5-xl{ height: 1.25rem; }
|
||||||
|
.h-6-xl{ height: 1.5rem; }
|
||||||
|
.h-8-xl{ height: 2rem; }
|
||||||
|
.h-10-xl{ height: 2.5rem; }
|
||||||
|
|
||||||
|
/* Width */
|
||||||
|
.w-1-xl{ width: 0.25rem; }
|
||||||
|
.w-2-xl{ width: 0.5rem; }
|
||||||
|
.w-3-xl{ width: 0.75rem; }
|
||||||
|
.w-4-xl{ width: 1rem; }
|
||||||
|
.w-5-xl{ width: 1.25rem; }
|
||||||
|
.w-6-xl{ width: 1.5rem; }
|
||||||
|
.w-8-xl{ width: 2rem; }
|
||||||
|
.w-10-xl{ width: 2.5rem; }
|
||||||
|
}
|
||||||
|
@ -30,9 +30,7 @@
|
|||||||
width: 45px;
|
width: 45px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-brand-logo-login {
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-brand-logo-border {
|
.app-brand-logo-border {
|
||||||
border: 1px solid #d5d5d5;
|
border: 1px solid #d5d5d5;
|
||||||
@ -164,3 +162,24 @@
|
|||||||
thead tr {
|
thead tr {
|
||||||
border-top: 1px solid white;
|
border-top: 1px solid white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-brand-logo-login {
|
||||||
|
max-width: 50px; /* default for mobile */
|
||||||
|
height: auto; /* keep aspect ratio */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Tablet and up (≥768px) */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.app-brand-logo-login {
|
||||||
|
max-width: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktop and up (≥1200px) */
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.app-brand-logo-login {
|
||||||
|
max-width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
5
public/assets/img/SP-Placeholdeer.svg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="120" height="120" fill="#EFF1F3"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.2503 38.4816C33.2603 37.0472 34.4199 35.8864 35.8543 35.875H83.1463C84.5848 35.875 85.7503 37.0431 85.7503 38.4816V80.5184C85.7403 81.9528 84.5807 83.1136 83.1463 83.125H35.8543C34.4158 83.1236 33.2503 81.957 33.2503 80.5184V38.4816ZM80.5006 41.1251H38.5006V77.8751L62.8921 53.4783C63.9172 52.4536 65.5788 52.4536 66.6039 53.4783L80.5006 67.4013V41.1251ZM43.75 51.6249C43.75 54.5244 46.1005 56.8749 49 56.8749C51.8995 56.8749 54.25 54.5244 54.25 51.6249C54.25 48.7254 51.8995 46.3749 49 46.3749C46.1005 46.3749 43.75 48.7254 43.75 51.6249Z" fill="#687787"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 888 B |
BIN
public/assets/img/orglogo.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
30
public/assets/vendor/css/core.css
vendored
@ -18613,6 +18613,10 @@ li:not(:first-child) .dropdown-item,
|
|||||||
min-height: 70vh !important;
|
min-height: 70vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-min-h{
|
||||||
|
min-height: 60vh !important;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-fill {
|
.flex-fill {
|
||||||
flex: 1 1 auto !important;
|
flex: 1 1 auto !important;
|
||||||
}
|
}
|
||||||
@ -32544,3 +32548,29 @@ body:not(.modal-open) .layout-content-navbar .layout-navbar {
|
|||||||
var(--bs-dark-contrast)
|
var(--bs-dark-contrast)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* App colors classes */
|
||||||
|
.bg-gray-60{
|
||||||
|
background-color:var(--bs-gray-60)
|
||||||
|
}
|
||||||
|
.text-gray-60{
|
||||||
|
color:var(--bs-gray-60)
|
||||||
|
}
|
||||||
|
.bg-blue {
|
||||||
|
background-color:var(--bs-blue)
|
||||||
|
}
|
||||||
|
.text-blue{
|
||||||
|
color:var(--bs-blue)
|
||||||
|
}
|
||||||
|
.bg-indigo {
|
||||||
|
background-color:var(--bs-indigo)
|
||||||
|
}
|
||||||
|
.text-indigo{
|
||||||
|
color:var(--bs-indigo)
|
||||||
|
}
|
||||||
|
.bg-red {
|
||||||
|
background-color:var(--bs-red)
|
||||||
|
}
|
||||||
|
.text-red{
|
||||||
|
color:var(--bs-red)
|
||||||
|
}
|
BIN
public/img/app/dashboard-light-01.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
public/img/app/dashboard-light-02.png
Normal file
After Width: | Height: | Size: 222 KiB |
BIN
public/img/app/dashboard-light-03.png
Normal file
After Width: | Height: | Size: 308 KiB |
BIN
public/img/app/dashboard-light-04.png
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
public/img/app/dashboard-light-05.png
Normal file
After Width: | Height: | Size: 217 KiB |
BIN
public/img/app/dashboard-light-06.png
Normal file
After Width: | Height: | Size: 278 KiB |
BIN
public/img/app/dashboard-light-07.png
Normal file
After Width: | Height: | Size: 202 KiB |
BIN
public/img/app/dashboard-light-08.png
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
public/img/backgrounds/cta-bg-dark.png
Normal file
After Width: | Height: | Size: 411 KiB |
BIN
public/img/backgrounds/cta-bg-light.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
public/img/backgrounds/footer-bg-dark.png
Normal file
After Width: | Height: | Size: 787 KiB |
BIN
public/img/backgrounds/footer-bg-light.png
Normal file
After Width: | Height: | Size: 786 KiB |
BIN
public/img/backgrounds/footer-bg.png
Normal file
After Width: | Height: | Size: 237 KiB |
BIN
public/img/backgrounds/hero-bg.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
public/img/brand/logo-1.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
public/img/brand/logo-2.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
public/img/brand/logo-3.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
public/img/brand/logo-4.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/img/brand/logo-5.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
public/img/brand/logo-6.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
public/img/brand/logo_1-dark.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
public/img/brand/logo_1-light.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
public/img/brand/logo_2-dark.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
public/img/brand/logo_2-light.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/img/brand/logo_3-dark.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
public/img/brand/logo_3-light.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
public/img/brand/logo_4-dark.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
public/img/brand/logo_4-light.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/img/brand/logo_5-dark.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
public/img/brand/logo_5-light.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 37 KiB |
BIN
public/img/icons/Join-community-arrow.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/img/icons/apple-icon.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
4
public/img/icons/check-warning.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="65" height="65" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" d="M14.125 50.9038C11.825 48.6038 13.35 43.7788 12.175 40.9538C11 38.1288 6.5 35.6538 6.5 32.5288C6.5 29.4038 10.95 27.0288 12.175 24.1038C13.4 21.1788 11.825 16.4538 14.125 14.1538C16.425 11.8538 21.25 13.3788 24.075 12.2038C26.9 11.0288 29.375 6.52881 32.5 6.52881C35.625 6.52881 38 10.9788 40.925 12.2038C43.85 13.4288 48.575 11.8538 50.875 14.1538C53.175 16.4538 51.65 21.2788 52.825 24.1038C54 26.9288 58.5 29.4038 58.5 32.5288C58.5 35.6538 54.05 38.0288 52.825 40.9538C51.6 43.8788 53.175 48.6038 50.875 50.9038C48.575 53.2038 43.75 51.6788 40.925 52.8538C38.1 54.0288 35.625 58.5288 32.5 58.5288C29.375 58.5288 27 54.0788 24.075 52.8538C21.15 51.6288 16.425 53.2038 14.125 50.9038Z" fill="#FFAB00"/>
|
||||||
|
<path d="M43.5 26.5288L28.825 40.5288L21.5 33.5288M14.125 50.9038C11.825 48.6038 13.35 43.7788 12.175 40.9538C11 38.1288 6.5 35.6538 6.5 32.5288C6.5 29.4038 10.95 27.0288 12.175 24.1038C13.4 21.1788 11.825 16.4538 14.125 14.1538C16.425 11.8538 21.25 13.3788 24.075 12.2038C26.9 11.0288 29.375 6.52881 32.5 6.52881C35.625 6.52881 38 10.9788 40.925 12.2038C43.85 13.4288 48.575 11.8538 50.875 14.1538C53.175 16.4538 51.65 21.2788 52.825 24.1038C54 26.9288 58.5 29.4038 58.5 32.5288C58.5 35.6538 54.05 38.0288 52.825 40.9538C51.6 43.8788 53.175 48.6038 50.875 50.9038C48.575 53.2038 43.75 51.6788 40.925 52.8538C38.1 54.0288 35.625 58.5288 32.5 58.5288C29.375 58.5288 27 54.0788 24.075 52.8538C21.15 51.6288 16.425 53.2038 14.125 50.9038Z" stroke="#FFAB00" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
4
public/img/icons/check.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" d="M13.625 50.8413C11.325 48.5413 12.85 43.7163 11.675 40.8913C10.5 38.0663 6 35.5913 6 32.4663C6 29.3413 10.45 26.9663 11.675 24.0413C12.9 21.1163 11.325 16.3913 13.625 14.0913C15.925 11.7913 20.75 13.3163 23.575 12.1413C26.4 10.9663 28.875 6.46631 32 6.46631C35.125 6.46631 37.5 10.9163 40.425 12.1413C43.35 13.3663 48.075 11.7913 50.375 14.0913C52.675 16.3913 51.15 21.2163 52.325 24.0413C53.5 26.8663 58 29.3413 58 32.4663C58 35.5913 53.55 37.9663 52.325 40.8913C51.1 43.8163 52.675 48.5413 50.375 50.8413C48.075 53.1413 43.25 51.6163 40.425 52.7913C37.6 53.9663 35.125 58.4663 32 58.4663C28.875 58.4663 26.5 54.0163 23.575 52.7913C20.65 51.5663 15.925 53.1413 13.625 50.8413Z" fill="#696CFF"/>
|
||||||
|
<path d="M43 26.4663L28.325 40.4663L21 33.4663M13.625 50.8413C11.325 48.5413 12.85 43.7163 11.675 40.8913C10.5 38.0663 6 35.5913 6 32.4663C6 29.3413 10.45 26.9663 11.675 24.0413C12.9 21.1163 11.325 16.3913 13.625 14.0913C15.925 11.7913 20.75 13.3163 23.575 12.1413C26.4 10.9663 28.875 6.46631 32 6.46631C35.125 6.46631 37.5 10.9163 40.425 12.1413C43.35 13.3663 48.075 11.7913 50.375 14.0913C52.675 16.3913 51.15 21.2163 52.325 24.0413C53.5 26.8663 58 29.3413 58 32.4663C58 35.5913 53.55 37.9663 52.325 40.8913C51.1 43.8163 52.675 48.5413 50.375 50.8413C48.075 53.1413 43.25 51.6163 40.425 52.7913C37.6 53.9663 35.125 58.4663 32 58.4663C28.875 58.4663 26.5 54.0163 23.575 52.7913C20.65 51.5663 15.925 53.1413 13.625 50.8413Z" stroke="#696CFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
BIN
public/img/icons/contact-border.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
5
public/img/icons/diamond-info.svg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<svg width="65" height="65" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" d="M46.5001 10.5288H32.5001L20.2251 26.5288L32.5001 56.5288L60.5001 26.5288L46.5001 10.5288Z" fill="#03C3EC"/>
|
||||||
|
<path d="M18.5 10.5288H46.5L60.5 26.5288L32.5 56.5288L4.5 26.5288L18.5 10.5288Z" stroke="#03C3EC" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.2934 9.92012C33.1042 9.67343 32.8109 9.52881 32.5 9.52881C32.1891 9.52881 31.8958 9.67343 31.7066 9.92012L19.7318 25.5288H4.5C3.94772 25.5288 3.5 25.9765 3.5 26.5288C3.5 27.0811 3.94772 27.5288 4.5 27.5288H19.5537L31.5745 56.9075C31.7282 57.2833 32.094 57.5288 32.5 57.5288C32.906 57.5288 33.2718 57.2833 33.4255 56.9075L45.4463 27.5288H60.5C61.0523 27.5288 61.5 27.0811 61.5 26.5288C61.5 25.9765 61.0523 25.5288 60.5 25.5288H45.2682L33.2934 9.92012ZM42.7474 25.5288L32.5 12.1717L22.2526 25.5288H42.7474ZM21.7146 27.5288L32.5 53.8881L43.2854 27.5288H21.7146Z" fill="#03C3EC"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
3
public/img/icons/facebook.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.8609 18.0262V11.1962H14.1651L14.5076 8.52204H11.8609V6.81871C11.8609 6.04704 12.0759 5.51871 13.1834 5.51871H14.5868V3.13454C13.904 3.06136 13.2176 3.02603 12.5309 3.02871C10.4943 3.02871 9.09593 4.27204 9.09593 6.55454V8.51704H6.80676V11.1912H9.10093V18.0262H11.8609Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 401 B |
3
public/img/icons/github.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.7184 2.19556C6.12757 2.19556 2.40674 5.91639 2.40674 10.5072C2.40674 14.1789 4.78757 17.2947 8.0909 18.3947C8.50674 18.4697 8.65674 18.2139 8.65674 17.9939C8.65674 17.7964 8.65007 17.2731 8.64757 16.5806C6.33507 17.0822 5.84674 15.4656 5.84674 15.4656C5.47007 14.5056 4.92424 14.2497 4.92424 14.2497C4.17007 13.7339 4.98174 13.7456 4.98174 13.7456C5.81674 13.8039 6.25424 14.6022 6.25424 14.6022C6.9959 15.8722 8.2009 15.5056 8.67257 15.2931C8.7484 14.7556 8.96507 14.3889 9.20174 14.1814C7.35674 13.9722 5.41674 13.2589 5.41674 10.0731C5.41674 9.16722 5.74091 8.42389 6.27007 7.84389C6.1859 7.63306 5.89841 6.78722 6.35257 5.64389C6.35257 5.64389 7.05007 5.41972 8.63757 6.49472C9.31557 6.31028 10.0149 6.21614 10.7176 6.21472C11.4202 6.21586 12.1196 6.31001 12.7976 6.49472C14.3859 5.41889 15.0826 5.64389 15.0826 5.64389C15.5367 6.78722 15.2517 7.63306 15.1651 7.84389C15.6984 8.42389 16.0184 9.16639 16.0184 10.0731C16.0184 13.2672 14.0767 13.9689 12.2251 14.1747C12.5209 14.4314 12.7876 14.9381 12.7876 15.7131C12.7876 16.8247 12.7776 17.7214 12.7776 17.9939C12.7776 18.2164 12.9259 18.4747 13.3501 18.3931C16.6517 17.2914 19.0301 14.1781 19.0301 10.5072C19.0301 5.91639 15.3092 2.19556 10.7184 2.19556Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/img/icons/google-play-icon.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
11
public/img/icons/instagram.svg
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<svg width="18" height="19" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1833_185630)">
|
||||||
|
<path d="M17.5869 6.33973C17.5774 5.62706 17.444 4.9215 17.1926 4.25456C16.9747 3.69202 16.6418 3.18112 16.2152 2.75453C15.7886 2.32793 15.2776 1.995 14.7151 1.77703C14.0568 1.5299 13.3613 1.39627 12.6582 1.38183C11.753 1.34137 11.466 1.33008 9.16819 1.33008C6.87039 1.33008 6.57586 1.33008 5.67725 1.38183C4.97451 1.39637 4.27932 1.53 3.62127 1.77703C3.05863 1.99485 2.54765 2.32772 2.12103 2.75434C1.69442 3.18096 1.36155 3.69193 1.14373 4.25456C0.896101 4.91242 0.76276 5.60776 0.749471 6.31056C0.70901 7.2167 0.696777 7.50368 0.696777 9.8015C0.696777 12.0993 0.696777 12.3928 0.749471 13.2924C0.763585 13.9963 0.89626 14.6907 1.14373 15.3503C1.36192 15.9128 1.69503 16.4236 2.1218 16.85C2.54855 17.2765 3.05957 17.6091 3.6222 17.8269C4.27846 18.084 4.97377 18.2272 5.67819 18.2504C6.58433 18.2908 6.87133 18.303 9.16913 18.303C11.4669 18.303 11.7615 18.303 12.6601 18.2504C13.3632 18.2365 14.0587 18.1032 14.717 17.8561C15.2794 17.6378 15.7902 17.3048 16.2167 16.8782C16.6433 16.4517 16.9763 15.941 17.1945 15.3785C17.442 14.7198 17.5746 14.0254 17.5888 13.3207C17.6293 12.4155 17.6414 12.1285 17.6414 9.82973C17.6396 7.53191 17.6396 7.24021 17.5869 6.33973ZM9.16255 14.1468C6.75935 14.1468 4.81251 12.2 4.81251 9.79679C4.81251 7.39359 6.75935 5.44676 9.16255 5.44676C10.3163 5.44676 11.4227 5.90506 12.2385 6.72085C13.0543 7.53664 13.5126 8.64309 13.5126 9.79679C13.5126 10.9505 13.0543 12.057 12.2385 12.8727C11.4227 13.6885 10.3163 14.1468 9.16255 14.1468ZM13.6857 6.3002C13.5525 6.30033 13.4206 6.27417 13.2974 6.22325C13.1743 6.17231 13.0624 6.09759 12.9682 6.00338C12.874 5.90917 12.7992 5.79729 12.7483 5.67417C12.6974 5.55105 12.6712 5.41909 12.6713 5.28585C12.6713 5.15271 12.6976 5.02087 12.7485 4.89786C12.7994 4.77485 12.8742 4.66308 12.9683 4.56893C13.0625 4.47479 13.1743 4.4001 13.2973 4.34915C13.4202 4.2982 13.5521 4.27197 13.6853 4.27197C13.8184 4.27197 13.9503 4.2982 14.0732 4.34915C14.1962 4.4001 14.3081 4.47479 14.4022 4.56893C14.4963 4.66308 14.571 4.77485 14.622 4.89786C14.6729 5.02087 14.6991 5.15271 14.6991 5.28585C14.6991 5.84666 14.2456 6.3002 13.6857 6.3002Z" fill="white"/>
|
||||||
|
<path d="M9.16296 12.6226C10.7236 12.6226 11.9887 11.3575 11.9887 9.79688C11.9887 8.23629 10.7236 6.97119 9.16296 6.97119C7.60238 6.97119 6.33728 8.23629 6.33728 9.79688C6.33728 11.3575 7.60238 12.6226 9.16296 12.6226Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_1833_185630">
|
||||||
|
<rect width="16.9412" height="18" fill="white" transform="translate(0.696777 0.528809)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
1
public/img/icons/inventory.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg idth="64" height="64" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path opacity="0.2" fill-rule="evenodd" clip-rule="evenodd" d="M0 142.1L0 480c0 17.7 14.3 32 32 32s32-14.3 32-32l0-240c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32l0 240c0 17.7 14.3 32 32 32s32-14.3 32-32l0-337.9c0-27.5-17.6-52-43.8-60.7L303.2 5.1c-9.9-3.3-20.5-3.3-30.4 0L43.8 81.4C17.6 90.1 0 114.6 0 142.1zM464 256l-352 0 0 64 352 0 0-64zM112 416l352 0 0-64-352 0 0 64zm352 32l-352 0 0 64 352 0 0-64z"/></svg>
|
After Width: | Height: | Size: 500 B |
4
public/img/icons/keyboard.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" d="M55.875 14.4663H8.125C6.95139 14.4663 6 15.4177 6 16.5913V48.3413C6 49.5149 6.95139 50.4663 8.125 50.4663H55.875C57.0486 50.4663 58 49.5149 58 48.3413V16.5913C58 15.4177 57.0486 14.4663 55.875 14.4663Z" fill="#696CFF"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 16.5913C7 15.97 7.50368 15.4663 8.125 15.4663H55.875C56.4963 15.4663 57 15.97 57 16.5913V48.3413C57 48.9626 56.4963 49.4663 55.875 49.4663H8.125C7.50368 49.4663 7 48.9626 7 48.3413V16.5913ZM8.125 13.4663C6.39911 13.4663 5 14.8654 5 16.5913V48.3413C5 50.0672 6.39911 51.4663 8.125 51.4663H55.875C57.6009 51.4663 59 50.0672 59 48.3413V16.5913C59 14.8654 57.6009 13.4663 55.875 13.4663H8.125ZM14 23.4663C13.4477 23.4663 13 23.914 13 24.4663C13 25.0186 13.4477 25.4663 14 25.4663H50C50.5523 25.4663 51 25.0186 51 24.4663C51 23.914 50.5523 23.4663 50 23.4663H14ZM14 31.4663C13.4477 31.4663 13 31.914 13 32.4663C13 33.0186 13.4477 33.4663 14 33.4663H50C50.5523 33.4663 51 33.0186 51 32.4663C51 31.914 50.5523 31.4663 50 31.4663H14ZM13 40.4663C13 39.914 13.4477 39.4663 14 39.4663H16C16.5523 39.4663 17 39.914 17 40.4663C17 41.0186 16.5523 41.4663 16 41.4663H14C13.4477 41.4663 13 41.0186 13 40.4663ZM24 39.4663C23.4477 39.4663 23 39.914 23 40.4663C23 41.0186 23.4477 41.4663 24 41.4663H40C40.5523 41.4663 41 41.0186 41 40.4663C41 39.914 40.5523 39.4663 40 39.4663H24ZM47 40.4663C47 39.914 47.4477 39.4663 48 39.4663H50C50.5523 39.4663 51 39.914 51 40.4663C51 41.0186 50.5523 41.4663 50 41.4663H48C47.4477 41.4663 47 41.0186 47 40.4663Z" fill="#696CFF"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
4
public/img/icons/laptop.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" d="M10 44.4663V18.4663C10 17.4054 10.4214 16.388 11.1716 15.6379C11.9217 14.8877 12.9391 14.4663 14 14.4663H50C51.0609 14.4663 52.0783 14.8877 52.8284 15.6379C53.5786 16.388 54 17.4054 54 18.4663V44.4663H10Z" fill="#696CFF"/>
|
||||||
|
<path d="M10 44.4663V18.4663C10 17.4054 10.4214 16.388 11.1716 15.6379C11.9217 14.8877 12.9391 14.4663 14 14.4663H50C51.0609 14.4663 52.0783 14.8877 52.8284 15.6379C53.5786 16.388 54 17.4054 54 18.4663V44.4663M36 22.4663H28M6 44.4663H58V48.4663C58 49.5272 57.5786 50.5446 56.8284 51.2947C56.0783 52.0449 55.0609 52.4663 54 52.4663H10C8.93913 52.4663 7.92172 52.0449 7.17157 51.2947C6.42143 50.5446 6 49.5272 6 48.4663V44.4663Z" stroke="#696CFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 860 B |
BIN
public/img/icons/paper-airplane.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
4
public/img/icons/paper.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" d="M52.575 9.44123L5.97499 22.5662C5.57831 22.6747 5.2247 22.9028 4.96234 23.2195C4.69997 23.5361 4.54161 23.926 4.50881 24.3359C4.47602 24.7459 4.57039 25.1559 4.77907 25.5103C4.98775 25.8647 5.3006 26.1461 5.67499 26.3162L27.075 36.4412C27.4942 36.6354 27.8309 36.972 28.025 37.3912L38.15 58.7912C38.3201 59.1656 38.6016 59.4785 38.9559 59.6872C39.3103 59.8958 39.7204 59.9902 40.1303 59.9574C40.5402 59.9246 40.9301 59.7662 41.2468 59.5039C41.5634 59.2415 41.7915 58.8879 41.9 58.4912L55.025 11.8912C55.1245 11.5512 55.1306 11.1906 55.0428 10.8474C54.955 10.5041 54.7765 10.1908 54.5259 9.94028C54.2754 9.68975 53.9621 9.51123 53.6189 9.42342C53.2756 9.33562 52.9151 9.34177 52.575 9.44123Z" fill="#696CFF"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M53.8666 8.45462C53.3513 8.32282 52.8102 8.33156 52.2995 8.47988L52.2942 8.48144L5.71115 21.6016L5.70701 21.6028C5.11366 21.7659 4.5848 22.1076 4.19216 22.5815C3.79862 23.0565 3.56107 23.6413 3.51188 24.2562C3.46268 24.8711 3.60424 25.4862 3.91726 26.0177C4.22884 26.5468 4.69522 26.9675 5.25338 27.2231L26.6472 37.3452L26.6472 37.3452L26.6546 37.3486C26.8589 37.4432 27.0229 37.6072 27.1175 37.8115L27.1174 37.8115L27.1209 37.8189L37.243 59.2126C37.4985 59.7708 37.9192 60.2372 38.4484 60.5488C38.9799 60.8619 39.595 61.0034 40.2099 60.9542C40.8248 60.905 41.4096 60.6675 41.8846 60.2739C42.3586 59.8813 42.7002 59.3524 42.8634 58.759L42.8645 58.755L55.9847 12.1719L55.9862 12.1668C56.1346 11.656 56.1433 11.1149 56.0115 10.5996C55.8792 10.0825 55.6103 9.61055 55.2329 9.23317C54.8556 8.85579 54.3836 8.58688 53.8666 8.45462ZM52.846 10.4038L52.5749 9.44123L52.8556 10.401C53.0235 10.3519 53.2015 10.3489 53.3709 10.3922C53.5404 10.4356 53.695 10.5237 53.8187 10.6474C53.9424 10.7711 54.0305 10.9257 54.0739 11.0952C54.1172 11.2646 54.1142 11.4426 54.0651 11.6105L54.065 11.6105L54.0623 11.6201L40.9373 58.2201L40.9353 58.2275C40.8811 58.4258 40.767 58.6026 40.6087 58.7338C40.4503 58.865 40.2554 58.9442 40.0504 58.9606C39.8455 58.977 39.6404 58.9298 39.4632 58.8255C39.2861 58.7211 39.1454 58.5647 39.0603 58.3775L39.0538 58.3635L28.9323 36.971L28.9303 36.9667C28.9285 36.9629 28.9268 36.9591 28.925 36.9553L39.732 26.1483C40.1225 25.7578 40.1225 25.1246 39.732 24.7341C39.3415 24.3436 38.7083 24.3436 38.3178 24.7341L27.5108 35.5411C27.5069 35.5393 27.503 35.5375 27.4991 35.5357L6.10255 25.4123L6.0886 25.4058C5.9014 25.3208 5.74498 25.18 5.64064 25.0029C5.53629 24.8257 5.48911 24.6206 5.50551 24.4157C5.5219 24.2107 5.60109 24.0158 5.73227 23.8574C5.86345 23.6991 6.04025 23.5851 6.2386 23.5308L6.2386 23.5309L6.24598 23.5288L52.846 10.4038Z" fill="#696CFF"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
BIN
public/img/icons/plane.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
public/img/icons/pricing-plans-arrow.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
4
public/img/icons/rocket.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" fill-rule="evenodd" clip-rule="evenodd" d="M52.8934 36.9867L45.1661 27.709C45.4614 33.3937 44.0587 40.0137 39.7274 47.5687L47.1102 53.475C47.3728 53.6835 47.6842 53.8215 48.0149 53.8759C48.3457 53.9303 48.6849 53.8994 49.0004 53.786C49.3159 53.6726 49.5972 53.4806 49.8177 53.228C50.0381 52.9755 50.1905 52.6709 50.2602 52.343L53.2872 38.6602C53.3602 38.3701 53.3625 38.0667 53.294 37.7755C53.2255 37.4843 53.0881 37.2138 52.8934 36.9867ZM10.959 37.1344L18.6864 27.8813C18.3911 33.566 19.7938 40.1859 24.1251 47.7164L16.7422 53.6227C16.4814 53.8311 16.1718 53.9698 15.8426 54.0256C15.5134 54.0814 15.1754 54.0526 14.8604 53.9419C14.5453 53.8311 14.2637 53.6421 14.0418 53.3925C13.82 53.143 13.6653 52.8411 13.5922 52.5152L10.5653 38.8078C10.4923 38.5177 10.49 38.2144 10.5585 37.9232C10.627 37.632 10.7644 37.3615 10.959 37.1344Z" fill="#696CFF"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.1373 4.56417C30.661 4.13034 31.3197 3.89282 31.9999 3.89282C32.6817 3.89282 33.3419 4.1314 33.8661 4.56708C36.2461 6.5048 41.3981 11.3124 44.2413 18.7028C45.231 21.2754 45.9359 24.1485 46.1526 27.3062L53.8054 36.4894C54.1015 36.8368 54.3105 37.2498 54.4151 37.6941C54.519 38.1357 54.5167 38.5956 54.4085 39.0361L51.3844 52.7309L51.3837 52.734C51.2735 53.2253 51.0402 53.6805 50.7057 54.0569C50.3712 54.4332 49.9465 54.7183 49.4715 54.8853C48.9964 55.0523 48.4867 55.0957 47.9903 55.0115C47.4939 54.9273 47.027 54.7182 46.6337 54.4039L46.6332 54.4035L39.5243 48.7164H24.4758L17.3669 54.4035L17.3665 54.4039C16.9731 54.7182 16.5062 54.9273 16.0098 55.0115C15.5134 55.0957 15.0037 55.0523 14.5287 54.8853C14.0537 54.7183 13.6289 54.4332 13.2944 54.0569C12.9599 53.6805 12.7266 53.2253 12.6165 52.734L12.6158 52.7309L9.59162 39.0361C9.48345 38.5957 9.48117 38.1358 9.58509 37.6941C9.68969 37.2496 9.89886 36.8364 10.1952 36.489L17.7037 27.4979C17.9004 24.2604 18.619 21.3188 19.6398 18.6906C22.5111 11.2981 27.7301 6.49122 30.1373 4.56417ZM44.1834 27.8703C44.1674 27.7856 44.1625 27.6995 44.1686 27.6142C43.9794 24.5834 43.3088 21.8491 42.3746 19.4209C39.7071 12.4872 34.8477 7.94455 32.5992 6.11468L32.5893 6.10666L32.5894 6.1066C32.424 5.96848 32.2154 5.89282 31.9999 5.89282C31.7845 5.89282 31.5759 5.96848 31.4105 6.1066L31.3942 6.11994C29.1222 7.93749 24.1977 12.4799 21.5041 19.4147C20.5347 21.9107 19.8484 24.7306 19.6863 27.8638C19.6871 27.9087 19.6849 27.9536 19.6796 27.9984C19.4292 33.348 20.7083 39.6051 24.7062 46.7164H39.2879C43.2365 39.5474 44.4691 33.2477 44.1834 27.8703ZM52.2729 37.7746L46.2018 30.4892C46.0153 35.5301 44.567 41.2065 41.1592 47.4631L47.8821 52.8414C48.0105 52.944 48.1628 53.0122 48.3248 53.0397C48.4868 53.0672 48.6531 53.053 48.8081 52.9985C48.9631 52.944 49.1017 52.851 49.2109 52.7282C49.3197 52.6057 49.3957 52.4576 49.4318 52.2978L49.4321 52.2965L52.4584 38.5922C52.4605 38.5827 52.4627 38.5733 52.4651 38.5639C52.499 38.4289 52.5001 38.2877 52.4682 38.1522C52.4363 38.0167 52.3724 37.8908 52.2818 37.7852L52.2728 37.7746L52.2729 37.7746ZM17.6801 30.6463L11.7266 37.7754L11.7184 37.7852L11.7183 37.7852C11.6277 37.8908 11.5638 38.0167 11.5319 38.1522C11.5 38.2877 11.5011 38.4289 11.5351 38.5639C11.5374 38.5733 11.5397 38.5827 11.5418 38.5922L14.568 52.2965L14.5683 52.2978C14.6044 52.4576 14.6804 52.6057 14.7893 52.7282C14.8984 52.851 15.037 52.944 15.192 52.9985C15.347 53.053 15.5133 53.0672 15.6753 53.0397C15.8373 53.0122 15.9897 52.944 16.118 52.8414L22.835 47.4678C19.3947 41.2766 17.9053 35.6511 17.6801 30.6463ZM27.0626 55.5914C27.0626 55.0391 27.5103 54.5914 28.0626 54.5914H35.9376C36.4899 54.5914 36.9376 55.0391 36.9376 55.5914C36.9376 56.1437 36.4899 56.5914 35.9376 56.5914H28.0626C27.5103 56.5914 27.0626 56.1437 27.0626 55.5914ZM34.9532 24.0914C34.9532 25.7224 33.631 27.0445 32.0001 27.0445C30.3691 27.0445 29.047 25.7224 29.047 24.0914C29.047 22.4604 30.3691 21.1383 32.0001 21.1383C33.631 21.1383 34.9532 22.4604 34.9532 24.0914Z" fill="#696CFF"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
BIN
public/img/icons/section-title-icon.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
public/img/icons/shuttle-rocket.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
3
public/img/icons/twitter.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M17.0576 7.19293C17.0684 7.33876 17.0684 7.48376 17.0684 7.62876C17.0684 12.0663 13.6909 17.1796 7.5184 17.1796C5.61674 17.1796 3.85007 16.6288 2.3634 15.6721C2.6334 15.7029 2.8934 15.7138 3.17424 15.7138C4.68506 15.7174 6.15311 15.2122 7.34174 14.2796C6.64125 14.2669 5.96222 14.0358 5.39943 13.6185C4.83665 13.2013 4.41822 12.6187 4.20257 11.9521C4.41007 11.9829 4.6184 12.0038 4.83674 12.0038C5.13757 12.0038 5.44007 11.9621 5.7209 11.8896C4.9607 11.7361 4.27713 11.3241 3.78642 10.7235C3.29571 10.1229 3.02815 9.37097 3.02924 8.59543V8.55376C3.47674 8.80293 3.9959 8.95876 4.5459 8.9796C4.08514 8.67342 3.70734 8.25795 3.44619 7.77026C3.18504 7.28256 3.04866 6.73781 3.04924 6.1846C3.04924 5.56126 3.21507 4.9896 3.5059 4.49126C4.34935 5.52878 5.40132 6.37756 6.59368 6.98265C7.78604 7.58773 9.0922 7.93561 10.4276 8.00376C10.3759 7.75376 10.3442 7.4946 10.3442 7.2346C10.344 6.79373 10.4307 6.35715 10.5993 5.9498C10.7679 5.54245 11.0152 5.17233 11.3269 4.86059C11.6386 4.54885 12.0088 4.30161 12.4161 4.133C12.8235 3.96438 13.26 3.87771 13.7009 3.87793C14.6676 3.87793 15.5401 4.28293 16.1534 4.93793C16.9049 4.79261 17.6255 4.51828 18.2834 4.1271C18.0329 4.90278 17.5082 5.56052 16.8076 5.9771C17.4741 5.90108 18.1254 5.72581 18.7401 5.4571C18.281 6.12635 17.7122 6.71322 17.0576 7.19293Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
6
public/img/icons/user-success.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="65" height="65" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="User">
|
||||||
|
<path id="Vector" opacity="0.2" d="M32.4999 8.52881C27.6437 8.52739 22.9012 9.99922 18.899 12.7499C14.8969 15.5005 11.8233 19.4006 10.0844 23.9348C8.34542 28.4691 8.02291 33.4242 9.15945 38.1456C10.296 42.867 12.8381 47.1326 16.4499 50.3788C17.9549 47.4151 20.2511 44.9261 23.0841 43.1875C25.917 41.4489 29.176 40.5287 32.4999 40.5288C30.5221 40.5288 28.5887 39.9423 26.9442 38.8435C25.2997 37.7447 24.018 36.1829 23.2611 34.3556C22.5043 32.5284 22.3062 30.5177 22.6921 28.5779C23.0779 26.6381 24.0303 24.8563 25.4289 23.4577C26.8274 22.0592 28.6092 21.1068 30.549 20.721C32.4888 20.3351 34.4995 20.5331 36.3268 21.29C38.154 22.0469 39.7158 23.3286 40.8146 24.9731C41.9135 26.6176 42.4999 28.551 42.4999 30.5288C42.4999 33.181 41.4464 35.7245 39.571 37.5999C37.6956 39.4752 35.1521 40.5288 32.4999 40.5288C35.8238 40.5287 39.0829 41.4489 41.9158 43.1875C44.7487 44.9261 47.045 47.4151 48.5499 50.3788C52.1618 47.1326 54.7039 42.867 55.8404 38.1456C56.977 33.4242 56.6545 28.4691 54.9155 23.9348C53.1766 19.4006 50.103 15.5005 46.1008 12.7499C42.0987 9.99922 37.3562 8.52739 32.4999 8.52881Z" fill="#71DD37"/>
|
||||||
|
<path id="Vector_2" d="M32.5 40.5288C38.0228 40.5288 42.5 36.0517 42.5 30.5288C42.5 25.006 38.0228 20.5288 32.5 20.5288C26.9772 20.5288 22.5 25.006 22.5 30.5288C22.5 36.0517 26.9772 40.5288 32.5 40.5288ZM32.5 40.5288C29.1759 40.5288 25.9168 41.4477 23.0839 43.1866C20.2509 44.9255 17.9548 47.4149 16.45 50.3788M32.5 40.5288C35.8241 40.5288 39.0832 41.4477 41.9161 43.1866C44.7491 44.9255 47.0452 47.4149 48.55 50.3788M56.5 32.5288C56.5 45.7836 45.7548 56.5288 32.5 56.5288C19.2452 56.5288 8.5 45.7836 8.5 32.5288C8.5 19.274 19.2452 8.52881 32.5 8.52881C45.7548 8.52881 56.5 19.274 56.5 32.5288Z" stroke="#71DD37" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
4
public/img/icons/user.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.2" d="M31.9999 8.46631C27.1437 8.46489 22.4012 9.93672 18.399 12.6874C14.3969 15.438 11.3233 19.3381 9.58436 23.8723C7.84542 28.4066 7.52291 33.3617 8.65945 38.0831C9.79598 42.8045 12.3381 47.0701 15.9499 50.3163C17.4549 47.3526 19.7511 44.8636 22.5841 43.125C25.417 41.3864 28.676 40.4662 31.9999 40.4663C30.0221 40.4663 28.0887 39.8798 26.4442 38.781C24.7997 37.6822 23.518 36.1204 22.7611 34.2931C22.0043 32.4659 21.8062 30.4552 22.1921 28.5154C22.5779 26.5756 23.5303 24.7938 24.9289 23.3952C26.3274 21.9967 28.1092 21.0443 30.049 20.6585C31.9888 20.2726 33.9995 20.4706 35.8268 21.2275C37.654 21.9844 39.2158 23.2661 40.3146 24.9106C41.4135 26.5551 41.9999 28.4885 41.9999 30.4663C41.9999 33.1185 40.9464 35.662 39.071 37.5374C37.1956 39.4127 34.6521 40.4663 31.9999 40.4663C35.3238 40.4662 38.5829 41.3864 41.4158 43.125C44.2487 44.8636 46.545 47.3526 48.0499 50.3163C51.6618 47.0701 54.2039 42.8045 55.3404 38.0831C56.477 33.3617 56.1545 28.4066 54.4155 23.8723C52.6766 19.3381 49.603 15.438 45.6008 12.6874C41.5987 9.93672 36.8562 8.46489 31.9999 8.46631Z" fill="#696CFF"/>
|
||||||
|
<path d="M32 40.4663C37.5228 40.4663 42 35.9892 42 30.4663C42 24.9435 37.5228 20.4663 32 20.4663C26.4772 20.4663 22 24.9435 22 30.4663C22 35.9892 26.4772 40.4663 32 40.4663ZM32 40.4663C28.6759 40.4663 25.4168 41.3852 22.5839 43.1241C19.7509 44.863 17.4548 47.3524 15.95 50.3163M32 40.4663C35.3241 40.4663 38.5832 41.3852 41.4161 43.1241C44.2491 44.863 46.5452 47.3524 48.05 50.3163M56 32.4663C56 45.7211 45.2548 56.4663 32 56.4663C18.7452 56.4663 8 45.7211 8 32.4663C8 19.2115 18.7452 8.46631 32 8.46631C45.2548 8.46631 56 19.2115 56 32.4663Z" stroke="#696CFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/img/illustrations/faq-boy-with-logos.png
Normal file
After Width: | Height: | Size: 224 KiB |
BIN
public/img/illustrations/girl-unlock-password-light.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
public/img/illustrations/registration.jpg
Normal file
After Width: | Height: | Size: 2.2 MiB |
4955
public/img/illustrations/worker_01.svg
Normal file
After Width: | Height: | Size: 395 KiB |
BIN
public/img/illustrations/worker_02.jpg
Normal file
After Width: | Height: | Size: 267 KiB |
1117
public/img/illustrations/worker_02.svg
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
public/img/illustrations/worker_03.jpg
Normal file
After Width: | Height: | Size: 252 KiB |
BIN
public/img/illustrations/worker_03.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
383
public/img/illustrations/worker_03.svg
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 660.738 500" style="enable-background:new 0 0 660.738 500;" xml:space="preserve">
|
||||||
|
<g id="BACKGROUND">
|
||||||
|
<rect style="fill:#FFFFFF;" width="660.738" height="500"/>
|
||||||
|
</g>
|
||||||
|
<g id="OBJECTS">
|
||||||
|
<g>
|
||||||
|
<ellipse style="fill:#F5DDB8;" cx="346.299" cy="252.054" rx="212.469" ry="204.073"/>
|
||||||
|
<ellipse style="fill:#F5DDB8;" cx="500.166" cy="136.609" rx="111.561" ry="107.153"/>
|
||||||
|
<ellipse style="fill:#F5DDB8;" cx="200.771" cy="377.989" rx="111.561" ry="107.153"/>
|
||||||
|
<ellipse style="fill:#F5DDB8;" cx="478.13" cy="332.91" rx="152.023" ry="146.016"/>
|
||||||
|
<ellipse style="fill:#F5DDB8;" cx="187.093" cy="164.392" rx="131.136" ry="125.954"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<path id="SVGID_1_" d="M616.694,272.218c-17.05-35.776-20.273-76.723-7.291-114.167c3.691-10.647,5.69-22.036,5.69-33.875
|
||||||
|
c0-59.179-49.947-107.153-111.561-107.153c-36.006,0-68.023,16.388-88.421,41.818c-21.509-7.038-44.566-10.861-68.555-10.861
|
||||||
|
c-28.126,0-54.969,5.261-79.539,14.796c-23.928-24.539-57.959-39.879-95.725-39.879c-72.424,0-131.136,56.392-131.136,125.955
|
||||||
|
c0,57.435,40.469,110.084,95.19,125.234c0.606,6.721,1.107,9.152,2.375,15.672c-29.148,19.331-48.253,51.636-48.253,88.232
|
||||||
|
c0,59.179,49.947,107.152,111.561,107.152c33.924,0,64.307-14.547,84.768-37.497c19.253,5.509,39.643,8.483,60.76,8.483
|
||||||
|
c14.941,0,29.519-1.489,43.59-4.307c24.88,17.064,55.339,27.106,88.241,27.106c83.96,0,152.023-65.373,152.023-146.016
|
||||||
|
C630.412,311.254,625.502,290.7,616.694,272.218z"/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_00000034081970537545137950000001927858695121682357_">
|
||||||
|
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<g style="clip-path:url(#SVGID_00000034081970537545137950000001927858695121682357_);">
|
||||||
|
<line style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" x1="543.39" y1="347.122" x2="543.39" y2="377.424"/>
|
||||||
|
<line style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" x1="572.915" y1="295.842" x2="572.915" y2="326.144"/>
|
||||||
|
<line style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" x1="562.815" y1="294.64" x2="562.815" y2="323.813"/>
|
||||||
|
<line style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" x1="568.253" y1="283.41" x2="568.253" y2="331.583"/>
|
||||||
|
<line style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" x1="548.829" y1="351.784" x2="548.829" y2="382.086"/>
|
||||||
|
<rect x="537.041" y="363.267" style="fill:#D9AC88;" width="31.941" height="131.863"/>
|
||||||
|
<rect x="557.242" y="308.101" style="fill:#D9AC88;" width="25.47" height="131.863"/>
|
||||||
|
<g style="opacity:0.76;">
|
||||||
|
<polyline style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" points="443.982,216.684 419.604,178.441 415.851,178.027
|
||||||
|
386.42,210.634 "/>
|
||||||
|
<line style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" x1="161.296" y1="151.887" x2="161.296" y2="531.322"/>
|
||||||
|
<line style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" x1="181.74" y1="151.887" x2="181.74" y2="531.322"/>
|
||||||
|
<line style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" x1="180.104" y1="151.887" x2="180.104" y2="531.322"/>
|
||||||
|
<line style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" x1="196.459" y1="151.887" x2="196.459" y2="531.322"/>
|
||||||
|
<line style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" x1="182.161" y1="126.476" x2="424.378" y2="153.223"/>
|
||||||
|
<line style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" x1="180.905" y1="137.855" x2="423.121" y2="164.603"/>
|
||||||
|
<polyline style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" points="417.944,164.305 406.496,151.249 391.452,160.831
|
||||||
|
378.861,148.197 365.201,157.658 353.965,145.173 340.516,155.206 329.821,142.782 313.121,152.456 302.999,139.82
|
||||||
|
285.757,149.434 275.062,137.009 259.145,147.043 249.353,133.895 231.269,143.691 218.467,130.485 203.121,140.308
|
||||||
|
194.112,127.521 "/>
|
||||||
|
<polyline style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" points="162.172,153.702 181.051,175.781 161.914,198.678
|
||||||
|
181.826,218.85 162.431,236.022 182.085,257.556 161.914,276.91 182.085,296.808 161.914,318.887 181.568,338.513 "/>
|
||||||
|
<polyline style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" points="181.397,153.357 195.482,175.436 181.204,198.333
|
||||||
|
196.061,218.504 181.589,235.677 196.254,257.211 181.204,276.564 196.254,296.463 181.204,318.542 195.868,338.168 "/>
|
||||||
|
<polyline style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" points="88.253,121.605 182.27,67.404 422.301,153.405
|
||||||
|
"/>
|
||||||
|
|
||||||
|
<rect x="349.63" y="145.277" transform="matrix(-0.994 -0.1098 0.1098 -0.994 752.7931 334.7805)" style="fill:#C79E7D;" width="71.962" height="2.787"/>
|
||||||
|
|
||||||
|
<rect x="257.42" y="107.318" transform="matrix(0.1098 -0.994 0.994 0.1098 98.5395 375.3563)" style="fill:#C79E7D;" width="2.787" height="50.7"/>
|
||||||
|
|
||||||
|
<rect x="415.398" y="148.232" transform="matrix(-0.994 -0.1098 0.1098 -0.994 818.0342 372.9768)" style="fill:#C79E7D;" width="7.769" height="31.483"/>
|
||||||
|
<polygon style="fill:none;stroke:#BD997F;stroke-miterlimit:10;" points="73.978,130.161 171.921,140.976 173.133,130.003
|
||||||
|
81.497,120.659 "/>
|
||||||
|
<polygon style="fill:#C79E7D;" points="155.287,153.901 203.743,153.852 204.036,123.188 189.052,113.391 155.673,113.424
|
||||||
|
"/>
|
||||||
|
|
||||||
|
<rect x="392.337" y="223.501" transform="matrix(-0.994 -0.1098 0.1098 -0.994 796.2745 511.3983)" style="fill:#C79E7D;" width="39.751" height="20.564"/>
|
||||||
|
|
||||||
|
<rect x="381.993" y="211.561" transform="matrix(-0.994 -0.1098 0.1098 -0.994 801.0934 482.4521)" style="fill:#C79E7D;" width="63.665" height="15.231"/>
|
||||||
|
<rect x="176.936" y="63.332" style="fill:#C79E7D;" width="3.15" height="64.256"/>
|
||||||
|
</g>
|
||||||
|
<rect x="182.74" y="246.202" style="fill:#3A6A6B;" width="38.527" height="236.494"/>
|
||||||
|
<rect x="174.452" y="246.202" style="fill:#479E88;" width="38.527" height="236.494"/>
|
||||||
|
<g>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="579.296" y1="120.027" x2="579.296" y2="338.645"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="599.792" y1="120.027" x2="599.792" y2="338.645"/>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill:none;stroke:#19303B;stroke-miterlimit:10;" points="234.517,168.001 262.854,132.779 266.617,132.779
|
||||||
|
292.208,168.305 "/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="522.533" y1="123.575" x2="522.533" y2="501.786"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="502.155" y1="123.575" x2="502.155" y2="501.786"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="503.786" y1="123.575" x2="503.786" y2="501.786"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="487.484" y1="123.575" x2="487.484" y2="501.786"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="503.786" y1="107.272" x2="260.883" y2="107.272"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="503.786" y1="118.684" x2="260.883" y2="118.684"/>
|
||||||
|
<polyline style="fill:none;stroke:#19303B;stroke-miterlimit:10;" points="266.045,118.955 278.815,107.272 292.672,118.412
|
||||||
|
306.529,107.272 319.027,118.14 331.526,107.001 343.752,118.412 355.707,107.272 371.194,118.684 382.606,107.272
|
||||||
|
398.637,118.684 410.591,107.544 425.263,119.227 436.403,107.272 453.249,118.955 467.378,107.272 481.506,118.684
|
||||||
|
491.831,107.001 "/>
|
||||||
|
<polyline style="fill:none;stroke:#19303B;stroke-miterlimit:10;" points="522.004,137.431 503.187,159.439 522.262,182.262
|
||||||
|
502.413,202.368 521.746,219.486 502.155,240.95 522.262,260.241 502.155,280.076 522.262,302.084 502.671,321.646 "/>
|
||||||
|
<polyline style="fill:none;stroke:#19303B;stroke-miterlimit:10;" points="503.174,137.431 488.299,159.439 503.378,182.262
|
||||||
|
487.687,202.368 502.971,219.486 487.484,240.95 503.378,260.241 487.484,280.076 503.378,302.084 487.891,321.646 "/>
|
||||||
|
<polyline style="fill:none;stroke:#19303B;stroke-miterlimit:10;" points="600.376,115.423 513.159,51.437 262.921,107.68
|
||||||
|
"/>
|
||||||
|
<rect x="264.143" y="103.632" style="fill:#BD4F4F;" width="71.73" height="2.778"/>
|
||||||
|
<rect x="401.897" y="103.632" style="fill:#BD4F4F;" width="50.537" height="2.778"/>
|
||||||
|
<rect x="260.883" y="102.789" style="fill:#BD4F4F;" width="7.744" height="31.382"/>
|
||||||
|
<rect x="512.344" y="111.755" style="fill:#BD4F4F;" width="98.221" height="11.004"/>
|
||||||
|
<rect x="571.032" y="125.205" style="fill:#325578;" width="37.087" height="6.113"/>
|
||||||
|
<rect x="571.032" y="134.986" style="fill:#325578;" width="37.087" height="6.113"/>
|
||||||
|
<rect x="571.032" y="144.767" style="fill:#325578;" width="37.087" height="6.113"/>
|
||||||
|
<rect x="509.899" y="44.101" style="fill:#325578;" width="3.668" height="53.797"/>
|
||||||
|
<polygon style="fill:#325578;" points="529.462,135.801 478.925,135.801 478.925,105.234 494.65,95.453 529.462,95.453
|
||||||
|
"/>
|
||||||
|
<polygon style="fill:none;stroke:#BF5068;stroke-miterlimit:10;" points="523.846,131.318 484.54,131.318 484.54,107.544
|
||||||
|
496.771,99.936 523.846,99.936 "/>
|
||||||
|
<rect x="228.674" y="178.169" style="fill:#325578;" width="70.894" height="6.216"/>
|
||||||
|
<rect x="232.392" y="166.179" style="fill:#479E88;" width="63.46" height="15.182"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="230.968" y1="171.949" x2="296.731" y2="171.949"/>
|
||||||
|
</g>
|
||||||
|
<path style="fill:#BD4F4F;" d="M589.315,347.297L589.315,347.297c-8.504,0-15.397-6.894-15.397-15.397v-5.552h30.795v5.552
|
||||||
|
C604.713,340.403,597.819,347.297,589.315,347.297z"/>
|
||||||
|
<circle style="fill:#325578;" cx="580.207" cy="291.278" r="6.149"/>
|
||||||
|
<path style="fill:#325578;" d="M606.396,290.822c0,3.396-2.753,6.149-6.149,6.149s-6.149-2.753-6.149-6.149
|
||||||
|
c0-3.396,2.753-6.149,6.149-6.149S606.396,287.426,606.396,290.822z"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="600.247" y1="290.822" x2="578.385" y2="290.822"/>
|
||||||
|
<path style="fill:#479E88;" d="M602.98,290.822c0,1.509-1.223,2.733-2.733,2.733c-1.509,0-2.733-1.224-2.733-2.733
|
||||||
|
c0-1.509,1.223-2.733,2.733-2.733C601.756,288.089,602.98,289.313,602.98,290.822z"/>
|
||||||
|
<path style="fill:#479E88;" d="M582.516,290.822c0,1.509-1.224,2.733-2.733,2.733c-1.509,0-2.733-1.224-2.733-2.733
|
||||||
|
c0-1.509,1.224-2.733,2.733-2.733C581.293,288.089,582.516,289.313,582.516,290.822z"/>
|
||||||
|
</g>
|
||||||
|
<rect x="116.053" y="430.259" style="fill:#D9AC88;" width="496.488" height="78.475"/>
|
||||||
|
<rect x="320.725" y="189.035" style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" width="166.015" height="236.494"/>
|
||||||
|
<rect x="274.423" y="203.209" style="fill:none;stroke:#C79E7D;stroke-miterlimit:10;" width="92.756" height="236.494"/>
|
||||||
|
<rect x="84.841" y="210.884" style="fill:#D9AC88;" width="50.109" height="211.726"/>
|
||||||
|
<rect x="83.262" y="184.467" style="fill:#D9AC88;" width="12.862" height="211.726"/>
|
||||||
|
<g>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="229.099" y1="356.612" x2="526.25" y2="356.612"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="229.099" y1="374.605" x2="526.25" y2="374.605"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="458.935" y1="223.77" x2="458.935" y2="278.584"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="468.551" y1="220.057" x2="468.551" y2="274.871"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="337.766" y1="237.233" x2="337.766" y2="292.047"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="347.383" y1="233.52" x2="347.383" y2="288.334"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="478.168" y1="229.673" x2="478.168" y2="274.871"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="251.217" y1="201.785" x2="251.217" y2="256.599"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="262.757" y1="197.939" x2="262.757" y2="252.753"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="275.259" y1="208.517" x2="275.259" y2="253.714"/>
|
||||||
|
<rect x="243.524" y="224.865" style="fill:#3A6A6B;" width="46.16" height="224.066"/>
|
||||||
|
<rect x="468.487" y="265.085" style="fill:#19303B;" width="38.53" height="183.845"/>
|
||||||
|
<rect x="452.139" y="248.463" style="fill:#19303B;" width="38.53" height="200.467"/>
|
||||||
|
<rect x="404.43" y="259.685" style="fill:#3A6A6B;" width="27.922" height="190.207"/>
|
||||||
|
<rect x="379.2" y="252.753" style="fill:#19303B;" width="15.076" height="196.297"/>
|
||||||
|
<rect x="335.925" y="252.753" style="fill:#19303B;" width="20.112" height="196.297"/>
|
||||||
|
<rect x="240.639" y="224.865" style="fill:#479E88;" width="46.159" height="224.066"/>
|
||||||
|
<rect x="465.602" y="265.085" style="fill:#479E88;" width="38.53" height="183.845"/>
|
||||||
|
<rect x="449.254" y="248.463" style="fill:#479E88;" width="38.53" height="200.467"/>
|
||||||
|
<rect x="401.545" y="271.22" style="fill:#479E88;" width="15.076" height="178.673"/>
|
||||||
|
<rect x="376.315" y="252.753" style="fill:#479E88;" width="15.076" height="196.297"/>
|
||||||
|
<rect x="333.04" y="252.753" style="fill:#479E88;" width="20.112" height="196.297"/>
|
||||||
|
<rect x="227.176" y="290.257" style="opacity:0.56;fill:#19303B;" width="286.573" height="11.54"/>
|
||||||
|
<rect x="227.176" y="285.449" style="fill:#479E88;" width="286.573" height="11.54"/>
|
||||||
|
<rect x="468.487" y="303.348" style="fill:#F5DDB8;" width="8.851" height="145.583"/>
|
||||||
|
<rect x="453.101" y="247.945" style="fill:#1FBFA7;" width="4.872" height="200.986"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="302.185" y1="337.379" x2="302.185" y2="447.007"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="318.533" y1="337.379" x2="318.533" y2="447.007"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="426.238" y1="337.379" x2="426.238" y2="447.007"/>
|
||||||
|
<line style="fill:none;stroke:#19303B;stroke-miterlimit:10;" x1="442.586" y1="337.379" x2="442.586" y2="447.007"/>
|
||||||
|
</g>
|
||||||
|
<rect x="251.299" y="434.695" style="fill:#BD4F4F;" width="238.099" height="29.057"/>
|
||||||
|
<path style="fill:#19303B;" d="M494.097,449.443c0,8.033-1.574,14.545-3.515,14.545s-3.515-6.512-3.515-14.545
|
||||||
|
s1.574-14.545,3.515-14.545S494.097,441.41,494.097,449.443z"/>
|
||||||
|
<path style="fill:#C9A369;" d="M56.567,491.13c14.865-19.063,31.052-37.094,48.4-53.929
|
||||||
|
c14.764-14.326,33.631-31.545,56.014-27.963c11.418,1.827,21.057,9.199,30.161,16.329c26.424,20.695,42.479,42.806,55.564,73.643
|
||||||
|
"/>
|
||||||
|
<g>
|
||||||
|
<rect x="294.057" y="415.207" style="fill:#E06767;" width="238.099" height="22.747"/>
|
||||||
|
<path style="fill:none;stroke:#19303B;stroke-width:0.5;stroke-miterlimit:10;" d="M513.828,437.92
|
||||||
|
c-1.631,0-2.953-5.077-2.953-11.339c0-6.263,1.322-11.339,2.953-11.339"/>
|
||||||
|
<path style="fill:none;stroke:#19303B;stroke-width:0.5;stroke-miterlimit:10;" d="M469.416,437.92
|
||||||
|
c-1.631,0-2.953-5.077-2.953-11.339c0-6.263,1.322-11.339,2.953-11.339"/>
|
||||||
|
<path style="fill:none;stroke:#19303B;stroke-width:0.5;stroke-miterlimit:10;" d="M425.004,437.92
|
||||||
|
c-1.631,0-2.953-5.077-2.953-11.339c0-6.263,1.322-11.339,2.953-11.339"/>
|
||||||
|
<path style="fill:none;stroke:#19303B;stroke-width:0.5;stroke-miterlimit:10;" d="M380.591,437.92
|
||||||
|
c-1.631,0-2.953-5.077-2.953-11.339c0-6.263,1.322-11.339,2.953-11.339"/>
|
||||||
|
<path style="fill:none;stroke:#19303B;stroke-width:0.5;stroke-miterlimit:10;" d="M336.179,437.92
|
||||||
|
c-1.631,0-2.953-5.077-2.953-11.339c0-6.263,1.322-11.339,2.953-11.339"/>
|
||||||
|
<path style="fill:#BF5068;" d="M294.503,437.92c-1.631,0-2.953-5.077-2.953-11.339c0-6.263,1.322-11.339,2.953-11.339"/>
|
||||||
|
<path style="fill:#19303B;" d="M535.181,426.58c0,6.263-1.322,11.339-2.953,11.339c-1.631,0-2.953-5.077-2.953-11.339
|
||||||
|
c0-6.263,1.322-11.339,2.953-11.339C533.859,415.241,535.181,420.318,535.181,426.58z"/>
|
||||||
|
</g>
|
||||||
|
<path style="fill:#FFCF85;" d="M147.473,491.13c14.865-19.063,31.052-37.094,48.4-53.929
|
||||||
|
c14.764-14.326,33.631-31.545,56.014-27.963c11.418,1.827,21.057,9.199,30.161,16.329c26.424,20.695,42.479,42.806,55.564,73.643
|
||||||
|
"/>
|
||||||
|
<path style="fill:#E6BA78;" d="M246.926,517.547c14.865-19.063,31.052-37.094,48.4-53.929
|
||||||
|
c14.764-14.326,33.631-31.545,56.014-27.963c11.418,1.827,21.057,9.199,30.161,16.329c26.423,20.695,42.479,42.806,55.564,73.643
|
||||||
|
"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<rect id="SVGID_00000003788632383088003210000006058380616871777177_" width="660.738" height="500"/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_00000134218526486784863960000000169376898782754693_">
|
||||||
|
<use xlink:href="#SVGID_00000003788632383088003210000006058380616871777177_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<g style="clip-path:url(#SVGID_00000134218526486784863960000000169376898782754693_);">
|
||||||
|
<path style="fill:#F0806C;" d="M258.789,317.704c2.625-3.164,5.538-6.132,8.211-9.214c0.622-0.717,1.285-1.463,2.179-1.785
|
||||||
|
c0.894-0.321,2.081-0.039,2.435,0.843c0.286,0.712-0.049,1.508-0.38,2.202c-1.207,2.532-2.402,5.069-3.62,7.595
|
||||||
|
c-0.932,1.934-2.303,3.609-3.379,5.493c-2.042,3.573-6.243,11.528-11.399,8.525c-0.356-0.208-0.7-0.472-0.878-0.844
|
||||||
|
c-0.283-0.594-0.076-1.297,0.153-1.914C253.622,324.524,256.048,321.008,258.789,317.704z"/>
|
||||||
|
<path style="fill:#BF6D5E;" d="M246.028,453.269c-5.808-0.139-11.579-0.492-17.259-1.156c-1.997-0.234-3.643-1.677-4.108-3.633
|
||||||
|
c-0.395-1.659-1.09-3.3-1.624-4.917c-5.379-16.285-10.757-32.569-16.136-48.854c-6.686-20.243-14.01-39.608-14.063-61.301
|
||||||
|
c-0.016-6.382,0.554-13.073,3.986-18.454c6.714-10.53,18.625-7.685,25.687,0.656c7.134,8.426,9.177,19.908,10.959,30.804
|
||||||
|
c4.642,28.384,10.293,56.768,11.943,85.313c0.029,0.494,0.1,1.016,0.412,1.4c0.328,0.404,0.856,0.577,1.354,0.731
|
||||||
|
c7.89,2.43,15.78,4.86,23.671,7.291c5.116,1.576,10.234,3.152,15.278,4.943c1.393,0.494,2.987,1.22,3.042,2.845
|
||||||
|
c0.025,0.743-0.34,1.455-0.893,1.953c-1.183,1.065-2.758,1.178-4.262,1.264C271.548,452.858,258.7,453.572,246.028,453.269z"/>
|
||||||
|
<g>
|
||||||
|
<path style="fill:#FFFFFF;" d="M301.262,258.703c-12.34,11.127-21.704,25.475-28.658,40.641
|
||||||
|
c-9.589,20.912-16.423,44.389-22.017,66.565c-0.66,2.617-8.663,40.873-10.306,40.873c0.05,0,112.779,0,112.779,0
|
||||||
|
c4.184-16.594,7.032-49.299,19.362-86.426c3.811-11.476,10.014-24.28,16.831-33.91c6.764-9.555,14.371-18.479,21.527-27.744
|
||||||
|
H301.262z"/>
|
||||||
|
<path style="fill:none;stroke:#3A6A6B;stroke-miterlimit:10;stroke-dasharray:4;" d="M309.279,264.364
|
||||||
|
c-36.147,40.974-47.883,82.94-55.14,127.305"/>
|
||||||
|
<path style="fill:none;stroke:#3A6A6B;stroke-width:0.5;stroke-miterlimit:10;stroke-dasharray:4;" d="M315.495,264.019
|
||||||
|
c-36.147,40.974-47.883,82.94-55.14,127.305"/>
|
||||||
|
<polygon style="fill:none;stroke:#3A6A6B;stroke-width:0.5;stroke-miterlimit:10;" points="303.693,354.892 293.057,391.151
|
||||||
|
274.686,390.872 285.322,355.171 "/>
|
||||||
|
<path style="opacity:0.39;fill:#3A6A6B;" d="M326.14,311.773c-4.762-0.249-17.295-0.331-18.799-0.294
|
||||||
|
c-9.654,20.526-16.996,49.158-23.85,79.499h46.36c0,0,11.655-50.245,23.568-78.475
|
||||||
|
C344.518,312.177,335.034,312.238,326.14,311.773z"/>
|
||||||
|
|
||||||
|
<line style="opacity:0.39;fill:none;stroke:#3A6A6B;stroke-miterlimit:10;" x1="343.837" y1="269.943" x2="386.57" y2="269.943"/>
|
||||||
|
|
||||||
|
<line style="opacity:0.39;fill:none;stroke:#3A6A6B;stroke-miterlimit:10;" x1="339.952" y1="274.863" x2="381.391" y2="274.863"/>
|
||||||
|
|
||||||
|
<line style="opacity:0.39;fill:none;stroke:#3A6A6B;stroke-miterlimit:10;" x1="337.017" y1="279.612" x2="375.175" y2="279.525"/>
|
||||||
|
<path style="opacity:0.39;fill:#3A6A6B;" d="M333.136,274.46c-1.532,3.842-5.862,6.741-9.671,6.475
|
||||||
|
c-3.809-0.266-5.654-3.596-4.122-7.438c1.532-3.842,5.862-6.741,9.671-6.475C332.823,267.288,334.669,270.618,333.136,274.46z"
|
||||||
|
/>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<line style="fill:none;stroke:#3A6A6B;stroke-width:0.5;stroke-miterlimit:10;" x1="309.391" y1="303.957" x2="356.355" y2="304.993"/>
|
||||||
|
<polygon style="fill:#3A6A6B;" points="313.88,300.849 307.664,303.957 310.772,308.101 "/>
|
||||||
|
<polygon style="fill:#3A6A6B;" points="356.657,301.798 360.052,305.783 354.455,309.18 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path style="fill:none;stroke:#3A6A6B;stroke-width:0.5;stroke-miterlimit:10;" d="M270.888,388.529
|
||||||
|
c7.252-26.676,10.99-45.313,21.927-75.334"/>
|
||||||
|
<polygon style="fill:#3A6A6B;" points="274.582,387.515 269.465,392.218 266.699,387.839 "/>
|
||||||
|
<polygon style="fill:#3A6A6B;" points="295.908,314.048 293.393,309.457 288.226,313.479 "/>
|
||||||
|
</g>
|
||||||
|
<polyline style="opacity:0.39;fill:#3A6A6B;" points="298.513,334.69 329.851,390.978 284.268,390.892 "/>
|
||||||
|
<path style="fill:#E06767;" d="M315.824,390.952l14.027,0.027l-7.634-13.711c-2.547,2.533-4.26,5.918-5.334,9.407
|
||||||
|
C316.451,388.078,316.103,389.507,315.824,390.952z"/>
|
||||||
|
<polygon style="fill:none;stroke:#3A6A6B;stroke-miterlimit:10;stroke-dasharray:4;" points="362.484,321.482 351.606,364.475
|
||||||
|
322.081,363.957 "/>
|
||||||
|
</g>
|
||||||
|
<path style="fill:#ED5151;" d="M197.733,516.234c-14.823,0.8-29.699,0.63-44.501-0.508
|
||||||
|
c-4.314-12.714-12.062-40.834-16.376-53.548c-2.848-8.393-5.706-16.827-7.237-25.557c-2.582-14.729-1.262-30.123,3.79-44.197
|
||||||
|
c3.065-8.538,7.647-16.789,14.692-22.504c7.045-5.715,16.862-8.524,25.462-5.639c9.937,3.334,13.296,11.696,12.419,21.023
|
||||||
|
c-1.079,11.473,0.953,23.003,2.112,34.601C190.789,446.827,196.291,489.217,197.733,516.234z"/>
|
||||||
|
<path style="fill:#ED5151;" d="M50.672,514.172c2.66-28.794,21.908-86.576,28.489-114.734
|
||||||
|
c6.581-28.158,17.781-36.754,43.694-49.587c18.676,9.584,34.122,19.018,49.584,33.216c1.065,0.978,2.185,2.084,2.38,3.517
|
||||||
|
c0.189,1.387-0.54,2.716-1.243,3.926c-21.893,37.677-74.083,130.615-75.767,131.69c-2.585,1.651-2.93,3.346-5.957,2.849
|
||||||
|
C82.875,523.576,59.649,515.646,50.672,514.172z"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:10;" d="M112.694,383.743
|
||||||
|
c-25.718,56.559-50.777,113.418-75.171,170.561"/>
|
||||||
|
<path style="fill:#44204D;" d="M101.098,265.935c2.595-7.035,6.253-13.496,12.181-17.922c8.724-6.513,20.368-7.103,31.25-7.438
|
||||||
|
c28.145-0.867,61.599,8.69,73.468,37.583c8.374,20.384-7.42,40.312-14.068,59.306c-7.087,20.249-9.691,39.051-17.252,59.128
|
||||||
|
c-0.362,0.96-0.767,1.978-1.603,2.573c-0.851,0.606-1.97,0.646-3.014,0.624c-6.522-0.135-12.905-1.786-19.218-3.428
|
||||||
|
c-28.333-7.366-56.667-14.732-85-22.099c-0.487-0.127,17.548-87.451,19.388-95.027
|
||||||
|
C98.306,274.811,99.501,270.264,101.098,265.935z"/>
|
||||||
|
<path style="fill:#44204D;" d="M231.785,284.869c0.945,4.532,1.449,9.175,1.993,13.235c1.712,12.779,3.424,25.558,5.136,38.336
|
||||||
|
c-10.963,5.548-22.993,7.712-34.84,10.811c-4.773,1.249-11.93,2.032-16.031,5.007c-0.242,0.175-0.813,0.395-0.8,0.775
|
||||||
|
c-0.868-25.189-1.736-50.378-2.604-75.568c-0.275-7.993-2.088-22.672,8.574-24.377c4.249-0.679,5.395,2.178,9.263,4.065
|
||||||
|
c7.431,3.624,18.644,6.976,23.771,13.845C229.104,274.825,230.723,279.777,231.785,284.869z"/>
|
||||||
|
<path style="fill:#CADE33;" d="M191.67,386.732c4.227-21.542,7.731-43.213,11.207-64.887c-0.489-3.101-0.619-6.297-0.593-9.424
|
||||||
|
c0.148-17.72,4.225-35.396,11.852-51.391c-4.008-1.482-8.016-2.963-12.023-4.445c-3.148,11.637-13.872,26.934-27.813,20.199
|
||||||
|
c-6.439-3.11-11.451-6.689-13.43-14.016c-1.918-7.1-0.414-14.718,2.251-21.572c-4.786-0.917-9.611-1.616-14.456-2.13
|
||||||
|
c-0.361,2.905-0.709,5.812-1.084,8.714c-1.682,13.021-3.945,26.369-10.443,37.969c-2.829,5.05-6.242,9.839-10.45,13.837
|
||||||
|
c-3.542,3.365-7.778,6.31-12.595,7.344c-3.428,1.83-7.163,3.031-11.037,3.156c-3.362,0.108-6.617-0.734-9.525-2.417
|
||||||
|
c-0.713-0.413-1.4-0.862-2.07-1.336c-5.869,28.19-17.549,72.561-17.221,72.646c28.333,7.366,60.269,10.017,88.602,17.383
|
||||||
|
c4.371,1.136,8.758,2.281,13.236,2.917c0.609,0.087,5.753,0.634,8.903,0.609c0.697-0.005,2.427,0.093,3.963,0.149
|
||||||
|
C189.883,395.607,190.798,391.174,191.67,386.732z"/>
|
||||||
|
|
||||||
|
<rect x="140.806" y="306.727" transform="matrix(0.9784 0.2067 -0.2067 0.9784 68.3245 -27.6007)" style="fill:#FFFFFF;" width="50.868" height="12.851"/>
|
||||||
|
<path style="fill:#ECB061;" d="M222.811,543.533c-0.286,0-0.572,0-0.858,0"/>
|
||||||
|
<path style="fill:#F0806C;" d="M279.992,327.767c0.162-0.237,0.409-0.32,0.91-0.586c1.763-0.936,3.481-1.802,5.327-2.54
|
||||||
|
c3.137-1.264,6.252-2.583,9.343-3.957c0.989-0.439,1.222-1.881,0.719-2.741c-0.596-1.019-1.748-1.16-2.741-0.719
|
||||||
|
c-4.586,2.038-9.233,3.932-13.923,5.714c0.001-0.236,0.011-0.472,0.009-0.708c-0.004-0.439-0.019-0.884-0.054-1.327
|
||||||
|
c5.083-1.927,10.143-3.915,15.175-5.97c1.001-0.409,1.71-1.332,1.399-2.464c-0.261-0.948-1.457-1.811-2.464-1.399
|
||||||
|
c-5.159,2.107-10.346,4.145-15.559,6.117c-0.258-0.258-0.536-0.494-0.846-0.69c4.542-2.038,9.31-3.636,14.032-5.083
|
||||||
|
c2.458-0.753,1.41-4.622-1.065-3.863c-5.32,1.631-10.607,3.432-15.652,5.797c-2.557,1.198-5.049,2.54-7.424,4.07
|
||||||
|
c-2.224,1.434-4.269,3.471-6.69,4.548c-1.197,0.533-2.486,0.828-3.707,1.306c-1.22,0.478-2.415,1.182-3.108,2.295
|
||||||
|
c-1.251,2.01-1.745,2.807-3.945,3.916c-8.596,4.333-18.994,4.558-28.307,6.279c-9.089,1.68-18.242,2.766-27.4,3.842
|
||||||
|
c-4.547,0.535-9.089,1.104-13.628,1.722c-3.977,0.542-7.077-1.863-10.715-3.753c-1.484-0.771-2.992-1.55-4.607-1.834
|
||||||
|
c-4.374-0.768-8.556,2.192-11.91,5.438c-4.459,4.315-8.611,10.389-7.604,16.902c0.368,2.384,1.413,4.576,2.665,6.544
|
||||||
|
c3.994,6.277,11.198,13.945,17.938,16.016c3.724,1.144,7.677,0.676,11.497,0.049c2.459-0.403,4.875-0.895,7.258-1.46
|
||||||
|
c12.671-3.006,24.403-8.082,36.729-12.832c5.099-2.914,11.36-4.565,16.737-7.006c5.568-2.528,10.843-5.787,16.279-8.544
|
||||||
|
c5.274-2.675,11.136-5.052,15.925-8.548c4.124-3.01,7.43-5.869,12.056-8.28c4.079-2.126,8.507-4.017,11.549-7.599
|
||||||
|
c0.288-0.339,0.568-0.699,0.709-1.121c0.141-0.422,0.12-0.922-0.156-1.271c-0.229-0.289-0.599-0.435-0.964-0.49
|
||||||
|
c-1.045-0.156-2.081,0.339-2.938,0.956c-1.737,1.252-3.598,2.284-5.374,3.468c-1.681,1.121-3.522,1.508-5.476,2.064
|
||||||
|
c0.085-0.024-0.241-1.579-0.2-1.744C279.851,328.043,279.911,327.886,279.992,327.767z"/>
|
||||||
|
<path style="fill:#F0806C;" d="M118.845,320.447c-0.803-2.117,1.937-1.035,2.27-3.274c0.306-2.056,1.499-3.863,2.764-5.511
|
||||||
|
c5.814-7.575,13.873-13.404,22.887-16.555c1.788-0.625,3.895-1.112,5.475-0.067c0.669,0.442,0.173-8.45,0.637-7.796
|
||||||
|
c10.655,15.016,20.867,40.6,28.517,57.348c4.231,9.263,6.978,18.99,1.8,28.453c-1.02,1.864-2.289,3.639-4.003,4.893
|
||||||
|
c-4.758,3.481-17.115,2.658-21.333-1.46C140.428,359.461,126.579,340.821,118.845,320.447z"/>
|
||||||
|
<path style="fill:#44204D;" d="M100.637,295.296c2.788,5.474,6.044,10.693,9.295,15.905c3.982,6.383,7.965,12.767,11.947,19.15
|
||||||
|
c15.591-7.229,30.988-14.961,45.023-24.836c-2.848-7.227-16.028-43.891-22.436-54.567c-3.748-6.244-8.164,1.257-11.937-4.971
|
||||||
|
c-0.72-0.462-1.486-0.841-2.317-1.075c-2.576-0.726-5.347-0.022-7.8,1.048c-15.637,7.922-18.496,24.122-22.637,39.664
|
||||||
|
c-0.464,1.739-0.931,3.53-0.715,5.317C99.245,292.475,99.931,293.91,100.637,295.296z"/>
|
||||||
|
<path style="fill:#F0806C;" d="M226.398,206.308c-0.819-0.441-1.641-0.895-2.348-1.496c-2.341-1.99-3.776-4.169-6.777-5.494
|
||||||
|
c-4.754-2.1-10.227-1.935-15.103-0.344c-4.876,1.591-7.64,6.911-10.67,10.849c-6.85,8.9-13.378,18.047-19.568,27.417
|
||||||
|
c-1.149,1.739-4.467,3.878-4.845,5.947c-0.064,0.351-0.001,0.712,0.072,1.062c0.792,3.741,2.885,7.145,5.649,9.788
|
||||||
|
c2.764,2.643,6.176,4.551,9.773,5.847c2.627,0.946,5.429,1.583,8.204,1.276c1.81-0.2,3.614-0.837,5.075-1.938
|
||||||
|
c1.452-1.093,1.638-2.114,2.246-3.688c1.58-4.087,3.74-8.039,5.589-12.013c4.949,2.115,10.916,0.169,14.851-3.501
|
||||||
|
c3.936-3.67,6.208-8.761,8.044-13.819c1.386-3.817,2.583-7.704,3.585-11.639c0.327-1.283,0.634-2.621,0.374-3.919
|
||||||
|
C230.067,208.231,228.239,207.3,226.398,206.308z"/>
|
||||||
|
<path d="M194.563,215.278c-1.019,1.776-1.825,3.634-4.316,3.915c-0.445,0.05-5.037-6.696-5.445-7.483
|
||||||
|
c-1.219-2.353-1.495-5.517-0.488-7.984c2.373-5.818,9.882-11.182,16.396-11.212c5.847-0.027,11.558,1.666,16.839,3.975
|
||||||
|
c2.841,1.242,5.682,2.484,8.523,3.727c3.45,1.509,9.62,3.904,11.029,7.8c0.517,1.429,0.229,3.027-0.287,4.456
|
||||||
|
c-0.452,1.252-1.091,2.464-2.055,3.382c-2.024,1.924-5.193,2.222-7.869,1.422c-2.676-0.799-4.966-2.525-7.138-4.281
|
||||||
|
c-1.644-1.329-3.494-2.774-5.602-2.612c-2.021,0.155-3.623,1.751-5.545,2.395c-2.377,0.796-4.954,0.068-7.45-0.167
|
||||||
|
c-2.031-0.192-4.961,0.076-6.184,1.99C194.828,214.823,194.694,215.05,194.563,215.278z"/>
|
||||||
|
<path style="fill:#3A6A6B;" d="M195.522,207.788c0.186-0.073,0.37-0.135,0.555-0.202c0.8-0.463,1.579-0.921,2.326-1.25
|
||||||
|
c2.952-1.297,6.385-1.055,9.521-1.464c1.248-0.163,2.675-0.198,3.853-0.678c0.217-0.088,0.409-0.205,0.591-0.333
|
||||||
|
c0.781-0.668,1.412-1.509,1.696-2.485c0.124-0.425,1.386-3.888,1.983-5.087c0.045-0.153,0.091-0.306,0.135-0.459
|
||||||
|
c-4.796-1.784-9.742-3.163-14.77-4.116c-2.431-0.461-4.829-1.113-7.296-1.365c-1.661-0.169-3.054,0.089-4.488,0.364
|
||||||
|
c-0.879,0.169-1.774,0.344-2.755,0.431c-0.462,0.041-0.953,0.059-1.34,0.316c-0.273,0.181-0.463,0.462-0.64,0.738
|
||||||
|
c-2.682,4.182-4.562,9.446-3.58,14.477c0.096,0.493,0.241,1.007,0.607,1.352c1.541,1.449,7.642,0.871,9.659,0.777
|
||||||
|
C192.981,208.738,194.23,208.296,195.522,207.788z"/>
|
||||||
|
<path style="fill:#FF7354;" d="M238.752,194.441c-0.206-0.852-0.355-1.742-0.561-2.473c-0.435-1.54-0.869-3.08-1.304-4.62
|
||||||
|
c-0.34-1.207-0.682-2.415-1.124-3.589c-0.524-1.392-1.19-2.73-1.983-3.988c-4.408-6.99-12.8-11.169-20.846-12.165
|
||||||
|
c-1.821-0.225-3.662-0.295-5.494-0.202c-8.557,0.434-18.942,5.41-22.154,13.614c-1.581,4.038-1.505,8.519-2.752,12.668
|
||||||
|
c-0.264,0.88-7.095,4.4-3.947,6.151c0.741-0.046,1.482-0.096,2.223-0.139c3.417-0.197,6.845,0.153,10.267,0.153
|
||||||
|
c0.439,0.012,0.898,0.02,1.293-0.173c0.34-0.166,0.595-0.462,0.84-0.75c0.56-0.659,1.121-1.318,1.681-1.977
|
||||||
|
c0.111-0.131,0.232-0.268,0.396-0.321c0.12-0.039,0.25-0.027,0.376-0.016c4.448,0.424,8.872,1.09,13.247,1.995
|
||||||
|
c0.985,0.204,2.52,0.257,3.392,0.751c0.444,0.252,0.494,0.593,0.732,1.072c0.575,1.157,1.429,2.417,2.704,2.862
|
||||||
|
c7.813,2.724,16.65,5.218,24.899,6.22c1.936,0.235,3.956,0.371,5.783-0.31c2.761-1.029,4.311-3.601,3.15-6.447
|
||||||
|
c-0.648-1.589-1.568-2.509-3.083-3.242c-1.278-0.618-2.581-1.184-3.905-1.696c-0.93-0.36-2.613-0.558-3.139-1.468
|
||||||
|
C239.13,195.814,238.921,195.141,238.752,194.441z"/>
|
||||||
|
<path d="M138.894,468.144c5.57-12.455,10.665-25.139,15.541-37.859l-6.226,4.15c-5.449,9.332-8.568,15.54-12.931,23.248
|
||||||
|
C136.477,461.173,137.692,464.656,138.894,468.144z"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M207.377,233.208c2.732,0.528,5.536,0.687,8.311,0.471"/>
|
||||||
|
<g>
|
||||||
|
<defs>
|
||||||
|
<path id="SVGID_00000036974503801261075080000015928047743645168817_" d="M226.398,206.308
|
||||||
|
c-0.819-0.441-1.641-0.895-2.348-1.496c-2.341-1.99-3.776-4.169-6.777-5.494c-4.754-2.1-10.227-1.935-15.103-0.344
|
||||||
|
c-4.876,1.591-7.64,6.911-10.67,10.849c-6.85,8.9-13.378,18.047-19.568,27.417c-1.528,2.312-5.81,5.743-6.18,8.488
|
||||||
|
c-0.371,2.752,4.68,5.787,7.025,7.389c6.215,4.245,13.547,6.868,21.058,7.422c0.531,0.039,1.092,0.063,1.566-0.182
|
||||||
|
c0.585-0.302,0.9-0.94,1.178-1.537c2.372-5.1,4.745-10.2,7.117-15.3c4.949,2.115,10.916,0.169,14.851-3.501
|
||||||
|
c3.936-3.67,6.208-8.761,8.044-13.819c1.386-3.817,2.583-7.704,3.585-11.639c0.327-1.283,0.634-2.621,0.374-3.919
|
||||||
|
C230.067,208.231,228.239,207.3,226.398,206.308z"/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_00000137849380344745917640000018278194934063550639_">
|
||||||
|
<use xlink:href="#SVGID_00000036974503801261075080000015928047743645168817_" style="overflow:visible;"/>
|
||||||
|
</clipPath>
|
||||||
|
<path style="clip-path:url(#SVGID_00000137849380344745917640000018278194934063550639_);" d="M208.206,245.681
|
||||||
|
c-4.161-0.705-6.595-5.153-10.412-6.955c1.144,5.117,3.926,9.855,7.838,13.347"/>
|
||||||
|
</g>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M160.673,373.612c1.114,2.569,4.803,3.571,7.063,1.918"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M180.172,341.544c-0.821,1.173-1.479,2.461-1.95,3.814"/>
|
||||||
|
<path style="fill:#F0806C;" d="M190.383,211.7c-0.727-0.708-1.574-1.376-2.628-1.673c-0.886-0.25-1.849-0.218-2.773-0.105
|
||||||
|
c-1.17,0.142-2.338,0.416-3.325,0.965c-1.446,0.804-2.389,2.15-2.791,3.57c-0.402,1.419-0.302,2.91,0.012,4.345
|
||||||
|
c0.401,1.832,1.183,3.659,2.674,5.035c1.492,1.376,3.789,2.225,5.952,1.835c2.255-0.407,3.958-2.065,4.754-3.889
|
||||||
|
C193.818,218.209,193.361,214.603,190.383,211.7z"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M184.98,212.689c1.241-0.323,2.344,0.868,2.919,2.014
|
||||||
|
c1.008,2.01,1.431,4.309,1.204,6.546"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M201.757,170.399c-1.496,0.785-2.733,2.054-3.48,3.569"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M208.484,170.731c-1.363,1.095-2.555,2.401-3.522,3.857"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M213.854,171.179c-1.13,1.065-1.894,2.51-2.139,4.043"/>
|
||||||
|
|
||||||
|
<line style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;" x1="188.475" y1="455.751" x2="188.475" y2="549.136"/>
|
||||||
|
|
||||||
|
<line style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;" x1="199.921" y1="455.751" x2="199.921" y2="549.136"/>
|
||||||
|
|
||||||
|
<line style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;" x1="509.366" y1="455.751" x2="509.366" y2="549.136"/>
|
||||||
|
|
||||||
|
<line style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;" x1="520.811" y1="455.751" x2="520.811" y2="549.136"/>
|
||||||
|
<rect x="163.146" y="448.773" width="384.518" height="6.861"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:10;" d="M100.213,413.514
|
||||||
|
c5.837,2.541,12.739,2.513,18.555-0.074c5.816-2.588,10.458-7.696,12.479-13.732"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M183.276,194.144c0.691,0.173,9.842,1.036,9.842,1.036
|
||||||
|
l0.679-1.223c0.634-1.141,1.893-1.789,3.19-1.641l15.879,1.811c1.042,0.119,1.962,0.736,2.466,1.656l0.988,1.8
|
||||||
|
c0.615,1.121,1.672,1.935,2.911,2.249c8.828,2.237,16.778,3.041,20.677-2.753"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:10;" d="M146.24,445.021
|
||||||
|
c5.888,29.119,11.579,51.111,17.467,80.23"/>
|
||||||
|
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M109.955,309.784c-2.898-4.023-5.462-8.288-7.656-12.734"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 33 KiB |
BIN
public/img/images/contact-customer-service.png
Normal file
After Width: | Height: | Size: 860 KiB |
BIN
public/img/teams/team-member-1.png
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
public/img/teams/team-member-2.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
public/img/teams/team-member-3.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
public/img/teams/team-member-4.png
Normal file
After Width: | Height: | Size: 54 KiB |
@ -4,6 +4,7 @@ import { ToastContainer } from "react-toastify";
|
|||||||
import { QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClientProvider } from '@tanstack/react-query';
|
||||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||||
import { queryClient } from "./layouts/AuthLayout";
|
import { queryClient } from "./layouts/AuthLayout";
|
||||||
|
import ModalProvider from "./ModalProvider";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ const App = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="app">
|
<div className="app">
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<ModalProvider/>
|
||||||
<DireProvider>
|
<DireProvider>
|
||||||
<AppRoutes />
|
<AppRoutes />
|
||||||
</DireProvider>
|
</DireProvider>
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
import React, {
|
|
||||||
createContext,
|
|
||||||
useContext,
|
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
} from "react";
|
|
||||||
|
|
||||||
const ModalContext = createContext();
|
|
||||||
|
|
||||||
export const useModal = () => useContext(ModalContext);
|
|
||||||
|
|
||||||
// ModalProvider to manage modal state and expose functionality to the rest of the app
|
|
||||||
export const ModalProvider = ({ children }) => {
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const [modalContent, setModalContent] = useState(null);
|
|
||||||
const [onSubmit, setOnSubmit] = useState(null);
|
|
||||||
const [modalSize, setModalSize] = useState("lg");
|
|
||||||
|
|
||||||
// Ref to track the modal content element
|
|
||||||
const modalRef = useRef(null);
|
|
||||||
|
|
||||||
const openModal = (content, onSubmitCallback, size = "lg") => {
|
|
||||||
setModalContent(content); // Set modal content dynamically
|
|
||||||
setOnSubmit(() => onSubmitCallback); // Set the submit handler dynamically
|
|
||||||
setIsOpen(true); // Open the modal
|
|
||||||
setModalSize(size); // Set the modal size
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function to close the modal
|
|
||||||
const closeModal = () => {
|
|
||||||
setIsOpen(false); // Close the modal
|
|
||||||
setModalContent(null); // Clear modal content
|
|
||||||
setOnSubmit(null); // Clear the submit callback
|
|
||||||
setModalSize("lg"); // Reset modal size
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handleEscape = (event) => {
|
|
||||||
if (event.key === "Escape") {
|
|
||||||
closeModal();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.addEventListener("keydown", handleEscape);
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("keydown", handleEscape);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handleClickOutside = (event) => {
|
|
||||||
if (modalRef.current && !modalRef.current.contains(event.target)) {
|
|
||||||
closeModal();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.addEventListener("mousedown", handleClickOutside);
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("mousedown", handleClickOutside);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ModalContext.Provider
|
|
||||||
value={{
|
|
||||||
isOpen,
|
|
||||||
openModal,
|
|
||||||
closeModal,
|
|
||||||
modalContent,
|
|
||||||
modalSize,
|
|
||||||
onSubmit,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
|
|
||||||
{isOpen && (
|
|
||||||
<div style={overlayStyles}>
|
|
||||||
<div
|
|
||||||
ref={modalRef}
|
|
||||||
style={{
|
|
||||||
...modalStyles,
|
|
||||||
maxWidth: modalSize === "sm" ? "400px" : "800px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>{modalContent}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</ModalContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const overlayStyles = {
|
|
||||||
position: "fixed",
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
zIndex: 1050,
|
|
||||||
};
|
|
||||||
|
|
||||||
const modalStyles = {
|
|
||||||
backgroundColor: "white",
|
|
||||||
padding: "20px",
|
|
||||||
borderRadius: "5px",
|
|
||||||
boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
|
|
||||||
width: "90%",
|
|
||||||
maxWidth: "800px",
|
|
||||||
};
|
|
22
src/ModalProvider.jsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { useOrganizationModal } from "./hooks/useOrganization";
|
||||||
|
import OrganizationModal from "./components/Organization/OrganizationModal";
|
||||||
|
import { useAuthModal, useModal } from "./hooks/useAuth";
|
||||||
|
import SwitchTenant from "./pages/authentication/SwitchTenant";
|
||||||
|
import ChangePasswordPage from "./pages/authentication/ChangePassword";
|
||||||
|
|
||||||
|
const ModalProvider = () => {
|
||||||
|
const { isOpen, onClose } = useOrganizationModal();
|
||||||
|
const { isOpen: isAuthOpen } = useAuthModal();
|
||||||
|
const {isOpen:isChangePass} = useModal("ChangePassword")
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isOpen && <OrganizationModal />}
|
||||||
|
{isAuthOpen && <SwitchTenant />}
|
||||||
|
{isChangePass && <ChangePasswordPage /> }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalProvider;
|
@ -12,22 +12,19 @@ import { useQueryClient } from "@tanstack/react-query";
|
|||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import { useSelectedProject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizationId, }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [todayDate, setTodayDate] = useState(new Date());
|
const [todayDate, setTodayDate] = useState(new Date());
|
||||||
const [ShowPending, setShowPending] = useState(false);
|
const [ShowPending, setShowPending] = useState(false);
|
||||||
// const selectedProject = useSelector(
|
|
||||||
// (store) => store.localVariables.projectId
|
|
||||||
// );
|
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
const {
|
const {
|
||||||
attendance,
|
attendance,
|
||||||
loading: attLoading,
|
loading: attLoading,
|
||||||
recall: attrecall,
|
recall: attrecall,
|
||||||
isFetching
|
isFetching
|
||||||
} = useAttendance(selectedProject);
|
} = useAttendance(selectedProject, organizationId);
|
||||||
const filteredAttendance = ShowPending
|
const filteredAttendance = ShowPending
|
||||||
? attendance?.filter(
|
? attendance?.filter(
|
||||||
(att) => att?.checkInTime !== null && att?.checkOutTime === null
|
(att) => att?.checkInTime !== null && att?.checkOutTime === null
|
||||||
@ -62,12 +59,11 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
const role = item.jobRoleName?.toLowerCase() || "";
|
const role = item.jobRoleName?.toLowerCase() || "";
|
||||||
return (
|
return (
|
||||||
fullName.includes(lowercasedSearchTerm) ||
|
fullName.includes(lowercasedSearchTerm) ||
|
||||||
role.includes(lowercasedSearchTerm) // ✅ also search by role
|
role.includes(lowercasedSearchTerm) // also search by role
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}, [group1, group2, searchTerm]);
|
}, [group1, group2, searchTerm]);
|
||||||
|
|
||||||
|
|
||||||
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
||||||
finalFilteredData,
|
finalFilteredData,
|
||||||
ITEMS_PER_PAGE
|
ITEMS_PER_PAGE
|
||||||
@ -114,7 +110,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="table-responsive text-nowrap h-100" >
|
<div
|
||||||
|
className="table-responsive text-nowrap h-100"
|
||||||
|
style={{ minHeight: "200px" }} // Ensures fixed height
|
||||||
|
>
|
||||||
<div className="d-flex text-start align-items-center py-2">
|
<div className="d-flex text-start align-items-center py-2">
|
||||||
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
|
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
|
||||||
<div className="form-check form-switch text-start m-0 ms-5">
|
<div className="form-check form-switch text-start m-0 ms-5">
|
||||||
@ -139,6 +138,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
<tr className="border-top-1">
|
<tr className="border-top-1">
|
||||||
<th colSpan={2}>Name</th>
|
<th colSpan={2}>Name</th>
|
||||||
<th>Role</th>
|
<th>Role</th>
|
||||||
|
<th>Organization</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-down-arrow-alt text-success"></i>
|
<i className="bx bxs-down-arrow-alt text-success"></i>
|
||||||
Check-In
|
Check-In
|
||||||
@ -187,6 +187,8 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>{item.jobRoleName}</td>
|
<td>{item.jobRoleName}</td>
|
||||||
|
<td>{item.organizationName || "--"}</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
{item.checkInTime
|
{item.checkInTime
|
||||||
? convertShortTime(item.checkInTime)
|
? convertShortTime(item.checkInTime)
|
||||||
@ -209,11 +211,20 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
{!attendance && (
|
{!attendance && (
|
||||||
<span className="text-secondary m-4">No employees assigned to the project!</span>
|
<tr>
|
||||||
|
<td
|
||||||
|
colSpan={7}
|
||||||
|
className="text-center text-secondary"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
>
|
||||||
|
No employees assigned to the project!
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
{!loading && finalFilteredData.length > ITEMS_PER_PAGE && (
|
{!loading && finalFilteredData.length > ITEMS_PER_PAGE && (
|
||||||
<nav aria-label="Page ">
|
<nav aria-label="Page ">
|
||||||
<ul className="pagination pagination-sm justify-content-end py-1">
|
<ul className="pagination pagination-sm justify-content-end py-1">
|
||||||
@ -258,7 +269,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="text-muted my-4">
|
<div
|
||||||
|
className="d-flex justify-content-center align-items-center text-muted"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
>
|
||||||
{searchTerm
|
{searchTerm
|
||||||
? "No results found for your search."
|
? "No results found for your search."
|
||||||
: attendanceList.length === 0
|
: attendanceList.length === 0
|
||||||
|
@ -4,9 +4,12 @@ import Avatar from "../common/Avatar";
|
|||||||
import { convertShortTime } from "../../utils/dateUtils";
|
import { convertShortTime } from "../../utils/dateUtils";
|
||||||
import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
||||||
import { useSelector, useDispatch } from "react-redux";
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
|
|
||||||
import DateRangePicker from "../common/DateRangePicker";
|
import DateRangePicker from "../common/DateRangePicker";
|
||||||
import { clearCacheKey, getCachedData, useSelectedProject } from "../../slices/apiDataManager";
|
import {
|
||||||
|
clearCacheKey,
|
||||||
|
getCachedData,
|
||||||
|
useSelectedProject,
|
||||||
|
} from "../../slices/apiDataManager";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
||||||
import { useAttendancesLogs } from "../../hooks/useAttendance";
|
import { useAttendancesLogs } from "../../hooks/useAttendance";
|
||||||
@ -34,195 +37,142 @@ const usePagination = (data, itemsPerPage) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
const AttendanceLog = ({ handleModalData, searchTerm, organizationId }) => {
|
||||||
// const selectedProject = useSelector(
|
const selectedProject = useSelectedProject();
|
||||||
// (store) => store.localVariables.projectId
|
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
|
||||||
// );
|
const dispatch = useDispatch();
|
||||||
const selectedProject = useSelectedProject();
|
const [loading, setLoading] = useState(false);
|
||||||
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
|
const [showPending, setShowPending] = useState(false);
|
||||||
const dispatch = useDispatch();
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [showPending,setShowPending] = useState(false)
|
|
||||||
|
|
||||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
const today = new Date();
|
||||||
const [processedData, setProcessedData] = useState([]);
|
today.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
const today = new Date();
|
const yesterday = new Date();
|
||||||
today.setHours(0, 0, 0, 0);
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
|
||||||
const yesterday = new Date();
|
const isSameDay = (dateStr) => {
|
||||||
yesterday.setDate(yesterday.getDate() - 1);
|
if (!dateStr) return false;
|
||||||
|
const d = new Date(dateStr);
|
||||||
|
d.setHours(0, 0, 0, 0);
|
||||||
|
return d.getTime() === today.getTime();
|
||||||
|
};
|
||||||
|
|
||||||
const isSameDay = (dateStr) => {
|
const isBeforeToday = (dateStr) => {
|
||||||
if (!dateStr) return false;
|
if (!dateStr) return false;
|
||||||
const d = new Date(dateStr);
|
const d = new Date(dateStr);
|
||||||
d.setHours(0, 0, 0, 0);
|
d.setHours(0, 0, 0, 0);
|
||||||
return d.getTime() === today.getTime();
|
return d.getTime() < today.getTime();
|
||||||
};
|
};
|
||||||
|
|
||||||
const isBeforeToday = (dateStr) => {
|
const sortByName = (a, b) => {
|
||||||
if (!dateStr) return false;
|
const nameA = (a.firstName + a.lastName).toLowerCase();
|
||||||
const d = new Date(dateStr);
|
const nameB = (b.firstName + b.lastName).toLowerCase();
|
||||||
d.setHours(0, 0, 0, 0);
|
return nameA.localeCompare(nameB);
|
||||||
return d.getTime() < today.getTime();
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const sortByName = (a, b) => {
|
const { data = [], isLoading, error, refetch, isFetching } = useAttendancesLogs(
|
||||||
const nameA = a.firstName.toLowerCase() + a.lastName.toLowerCase();
|
selectedProject,
|
||||||
const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase();
|
dateRange.startDate,
|
||||||
return nameA?.localeCompare(nameB);
|
dateRange.endDate,
|
||||||
};
|
organizationId
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const processedData = useMemo(() => {
|
||||||
data = [],
|
const filteredData = showPending
|
||||||
isLoading,
|
? data.filter((item) => item.checkOutTime === null)
|
||||||
error,
|
: data;
|
||||||
refetch,
|
|
||||||
isFetching,
|
|
||||||
} = useAttendancesLogs(
|
|
||||||
selectedProject,
|
|
||||||
dateRange.startDate,
|
|
||||||
dateRange.endDate
|
|
||||||
);
|
|
||||||
const filtering = (data) => {
|
|
||||||
const filteredData = showPending
|
|
||||||
? data.filter((item) => item.checkOutTime === null)
|
|
||||||
: data;
|
|
||||||
|
|
||||||
const group1 = filteredData
|
const group1 = filteredData.filter((d) => d.activity === 1 && isSameDay(d.checkInTime)).sort(sortByName);
|
||||||
.filter((d) => d.activity === 1 && isSameDay(d.checkInTime))
|
const group2 = filteredData.filter((d) => d.activity === 4 && isSameDay(d.checkOutTime)).sort(sortByName);
|
||||||
.sort(sortByName);
|
const group3 = filteredData.filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime)).sort(sortByName);
|
||||||
const group2 = filteredData
|
const group4 = filteredData.filter((d) => d.activity === 4 && isBeforeToday(d.checkOutTime));
|
||||||
.filter((d) => d.activity === 4 && isSameDay(d.checkOutTime))
|
const group5 = filteredData.filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime)).sort(sortByName);
|
||||||
.sort(sortByName);
|
const group6 = filteredData.filter((d) => d.activity === 5).sort(sortByName);
|
||||||
const group3 = filteredData
|
|
||||||
.filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime))
|
|
||||||
.sort(sortByName);
|
|
||||||
const group4 = filteredData.filter(
|
|
||||||
(d) => d.activity === 4 && isBeforeToday(d.checkOutTime)
|
|
||||||
);
|
|
||||||
const group5 = filteredData
|
|
||||||
.filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime))
|
|
||||||
.sort(sortByName);
|
|
||||||
const group6 = filteredData
|
|
||||||
.filter((d) => d.activity === 5)
|
|
||||||
.sort(sortByName);
|
|
||||||
|
|
||||||
const sortedList = [
|
const sortedList = [...group1, ...group2, ...group3, ...group4, ...group5, ...group6];
|
||||||
...group1,
|
|
||||||
...group2,
|
|
||||||
...group3,
|
|
||||||
...group4,
|
|
||||||
...group5,
|
|
||||||
...group6,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Group by date
|
const groupedByDate = sortedList.reduce((acc, item) => {
|
||||||
const groupedByDate = sortedList.reduce((acc, item) => {
|
const date = (item.checkInTime || item.checkOutTime)?.split("T")[0];
|
||||||
const date = (item.checkInTime || item.checkOutTime)?.split("T")[0];
|
if (date) {
|
||||||
if (date) {
|
acc[date] = acc[date] || [];
|
||||||
acc[date] = acc[date] || [];
|
acc[date].push(item);
|
||||||
acc[date].push(item);
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const sortedDates = Object.keys(groupedByDate).sort(
|
|
||||||
(a, b) => new Date(b) - new Date(a)
|
|
||||||
);
|
|
||||||
|
|
||||||
const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
|
|
||||||
setProcessedData(finalData);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
filtering(data);
|
|
||||||
}, [data, showPending]);
|
|
||||||
|
|
||||||
// New useEffect to handle search filtering
|
|
||||||
const filteredSearchData = useMemo(() => {
|
|
||||||
if (!searchTerm) {
|
|
||||||
return processedData;
|
|
||||||
}
|
}
|
||||||
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
return acc;
|
||||||
return processedData.filter((item) => {
|
}, {});
|
||||||
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
|
||||||
return fullName.includes(lowercasedSearchTerm);
|
|
||||||
});
|
|
||||||
}, [processedData, searchTerm]);
|
|
||||||
|
|
||||||
const {
|
const sortedDates = Object.keys(groupedByDate).sort((a, b) => new Date(b) - new Date(a));
|
||||||
currentPage,
|
return sortedDates.flatMap((date) => groupedByDate[date]);
|
||||||
totalPages,
|
}, [data, showPending]);
|
||||||
currentItems: paginatedAttendances,
|
|
||||||
paginate,
|
|
||||||
resetPage,
|
|
||||||
} = usePagination(filteredSearchData, 20);
|
|
||||||
|
|
||||||
useEffect(() => {
|
const filteredSearchData = useMemo(() => {
|
||||||
resetPage();
|
if (!searchTerm) return processedData;
|
||||||
}, [filteredSearchData, resetPage]);
|
|
||||||
|
|
||||||
const handler = useCallback(
|
const lowercased = searchTerm.toLowerCase();
|
||||||
(msg) => {
|
return processedData.filter((item) =>
|
||||||
const { startDate, endDate } = dateRange;
|
`${item.firstName} ${item.lastName}`.toLowerCase().includes(lowercased)
|
||||||
const checkIn = msg.response.checkInTime.substring(0, 10);
|
|
||||||
if (
|
|
||||||
selectedProject === msg.projectId &&
|
|
||||||
startDate <= checkIn &&
|
|
||||||
checkIn <= endDate
|
|
||||||
) {
|
|
||||||
queryClient.setQueriesData(["attendanceLogs"], (oldData) => {
|
|
||||||
if (!oldData) {
|
|
||||||
queryClient.invalidateQueries({ queryKey: ["attendanceLogs"] });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const updatedAttendance = oldData.map((record) =>
|
|
||||||
record.id === msg.response.id
|
|
||||||
? { ...record, ...msg.response }
|
|
||||||
: record
|
|
||||||
);
|
|
||||||
filtering(updatedAttendance);
|
|
||||||
return updatedAttendance;
|
|
||||||
});
|
|
||||||
resetPage();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[selectedProject, dateRange, filtering, resetPage]
|
|
||||||
);
|
);
|
||||||
|
}, [processedData, searchTerm]);
|
||||||
|
|
||||||
useEffect(() => {
|
const {
|
||||||
eventBus.on("attendance_log", handler);
|
currentPage,
|
||||||
return () => eventBus.off("attendance_log", handler);
|
totalPages,
|
||||||
}, [handler]);
|
currentItems: paginatedAttendances,
|
||||||
|
paginate,
|
||||||
|
resetPage,
|
||||||
|
} = usePagination(filteredSearchData, 20);
|
||||||
|
|
||||||
const employeeHandler = useCallback(
|
useEffect(() => {
|
||||||
(msg) => {
|
resetPage();
|
||||||
const { startDate, endDate } = dateRange;
|
}, [filteredSearchData]);
|
||||||
if (data.some((item) => item.employeeId == msg.employeeId)) {
|
|
||||||
// dispatch(
|
const handler = useCallback(
|
||||||
// fetchAttendanceData({
|
(msg) => {
|
||||||
// ,
|
const { startDate, endDate } = dateRange;
|
||||||
// fromDate: startDate,
|
const checkIn = msg.response.checkInTime.substring(0, 10);
|
||||||
// toDate: endDate,
|
|
||||||
// })
|
if (selectedProject === msg.projectId && startDate <= checkIn && checkIn <= endDate) {
|
||||||
// );
|
queryClient.setQueriesData(["attendanceLogs"], (oldData) => {
|
||||||
|
if (!oldData) {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["attendanceLogs"] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return oldData.map((record) =>
|
||||||
|
record.id === msg.response.id ? { ...record, ...msg.response } : record
|
||||||
|
);
|
||||||
|
});
|
||||||
|
resetPage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[selectedProject, dateRange, resetPage]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("attendance_log", handler);
|
||||||
|
return () => eventBus.off("attendance_log", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
const employeeHandler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
const { startDate, endDate } = dateRange;
|
||||||
|
if (data.some((item) => item.employeeId == msg.employeeId)) {
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[data, refetch]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("employee", employeeHandler);
|
||||||
|
return () => eventBus.off("employee", employeeHandler);
|
||||||
|
}, [employeeHandler]);
|
||||||
|
|
||||||
refetch()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[selectedProject, dateRange, data, refetch]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
eventBus.on("employee", employeeHandler);
|
|
||||||
return () => eventBus.off("employee", employeeHandler);
|
|
||||||
}, [employeeHandler]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className="dataTables_length text-start py-2 d-flex justify-content-between"
|
className="dataTables_length text-start py-2 d-flex justify-content-between "
|
||||||
id="DataTables_Table_0_length"
|
id="DataTables_Table_0_length"
|
||||||
>
|
>
|
||||||
<div className="d-flex align-items-center my-0 ">
|
<div className="d-flex align-items-center my-0 ">
|
||||||
@ -230,7 +180,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
onRangeChange={setDateRange}
|
onRangeChange={setDateRange}
|
||||||
defaultStartDate={yesterday}
|
defaultStartDate={yesterday}
|
||||||
/>
|
/>
|
||||||
<div className="form-check form-switch text-start m-0 ms-5">
|
<div className="form-check form-switch text-start ms-1 ms-md-2 align-items-center mb-0">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="form-check-input"
|
className="form-check-input"
|
||||||
@ -243,19 +193,16 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
<label className="form-check-label ms-0">Show Pending</label>
|
<label className="form-check-label ms-0">Show Pending</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-2 m-0 text-end">
|
|
||||||
<i
|
|
||||||
className={`bx bx-refresh cursor-pointer fs-4 ${
|
|
||||||
isFetching ? "spin" : ""
|
|
||||||
}`}
|
|
||||||
title="Refresh"
|
|
||||||
onClick={() => refetch()}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="table-responsive text-nowrap">
|
<div
|
||||||
|
className="table-responsive text-nowrap"
|
||||||
|
style={{ minHeight: "200px" }}
|
||||||
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div>
|
<div
|
||||||
|
className="d-flex justify-content-center align-items-center"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
>
|
||||||
<p className="text-secondary">Loading...</p>
|
<p className="text-secondary">Loading...</p>
|
||||||
</div>
|
</div>
|
||||||
) : filteredSearchData?.length > 0 ? (
|
) : filteredSearchData?.length > 0 ? (
|
||||||
@ -266,6 +213,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
Name
|
Name
|
||||||
</th>
|
</th>
|
||||||
<th className="border-top-1">Date</th>
|
<th className="border-top-1">Date</th>
|
||||||
|
<th>Organization</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-down-arrow-alt text-success"></i>{" "}
|
<i className="bx bxs-down-arrow-alt text-success"></i>{" "}
|
||||||
Check-In
|
Check-In
|
||||||
@ -295,7 +243,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
key={`header-${currentDate}`}
|
key={`header-${currentDate}`}
|
||||||
className="table-row-header"
|
className="table-row-header"
|
||||||
>
|
>
|
||||||
<td colSpan={6} className="text-start">
|
<td colSpan={8} className="text-start">
|
||||||
<strong>
|
<strong>
|
||||||
{moment(currentDate).format("DD-MM-YYYY")}
|
{moment(currentDate).format("DD-MM-YYYY")}
|
||||||
</strong>
|
</strong>
|
||||||
@ -325,6 +273,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
attendance.checkInTime || attendance.checkOutTime
|
attendance.checkInTime || attendance.checkOutTime
|
||||||
).format("DD-MMM-YYYY")}
|
).format("DD-MMM-YYYY")}
|
||||||
</td>
|
</td>
|
||||||
|
<td>{attendance.organizationName || "--"}</td>
|
||||||
<td>{convertShortTime(attendance.checkInTime)}</td>
|
<td>{convertShortTime(attendance.checkInTime)}</td>
|
||||||
<td>
|
<td>
|
||||||
{attendance.checkOutTime
|
{attendance.checkOutTime
|
||||||
@ -346,12 +295,20 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
) : (
|
) : (
|
||||||
<div className="my-4"><span className="text-secondary">No Record Available !</span></div>
|
<div className="my-12">
|
||||||
|
<span className="text-secondary">
|
||||||
|
No data available for the selected date range. Please Select
|
||||||
|
another date.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
||||||
<div className="my-4">
|
<div
|
||||||
<span className="text-secondary">No Pending Record Available !</span>
|
className="d-flex justify-content-center align-items-center text-secondary"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
>
|
||||||
|
No Record Available !
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{filteredSearchData.length > ITEMS_PER_PAGE && (
|
{filteredSearchData.length > ITEMS_PER_PAGE && (
|
||||||
|
@ -5,7 +5,6 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import TimePicker from "../common/TimePicker";
|
import TimePicker from "../common/TimePicker";
|
||||||
import { usePositionTracker } from "../../hooks/usePositionTracker";
|
import { usePositionTracker } from "../../hooks/usePositionTracker";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { markAttendance } from "../../slices/apiSlice/attedanceLogsSlice";
|
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
import { checkIfCurrentDate } from "../../utils/dateUtils";
|
import { checkIfCurrentDate } from "../../utils/dateUtils";
|
||||||
import { useMarkAttendance } from "../../hooks/useAttendance";
|
import { useMarkAttendance } from "../../hooks/useAttendance";
|
||||||
@ -34,7 +33,7 @@ const createSchema = (modeldata) => {
|
|||||||
const checkOut = new Date(checkIn);
|
const checkOut = new Date(checkIn);
|
||||||
checkOut.setHours(hour, minute, 0, 0);
|
checkOut.setHours(hour, minute, 0, 0);
|
||||||
|
|
||||||
return checkOut > checkIn;
|
return checkOut >= checkIn;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}, {
|
}, {
|
||||||
@ -97,16 +96,17 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
|
<form className="row p-2" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="col-12 col-md-12">
|
<div className="col-12 d-flex justify-content-center mb-4">
|
||||||
<label className="fs-5 text-dark text-center d-flex align-items-center flex-wrap">
|
<label className="fs-5 tex-semibold text-center">
|
||||||
{modeldata?.checkInTime && !modeldata?.checkOutTime
|
{modeldata?.checkInTime && !modeldata?.checkOutTime
|
||||||
? "Check-out :"
|
? "Check-Out "
|
||||||
: "Check-in :"}
|
: "Check-In "}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-6 col-md-6 ">
|
|
||||||
|
<div className="col-6 col-md-6 text-start">
|
||||||
<label className="form-label" htmlFor="checkInDate">
|
<label className="form-label" htmlFor="checkInDate">
|
||||||
{modeldata?.checkInTime && !modeldata?.checkOutTime
|
{modeldata?.checkInTime && !modeldata?.checkOutTime
|
||||||
? "Check-out Date"
|
? "Check-out Date"
|
||||||
@ -120,12 +120,12 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
|
|||||||
modeldata?.checkInTime && !modeldata?.checkOutTime
|
modeldata?.checkInTime && !modeldata?.checkOutTime
|
||||||
? formatDate(modeldata?.checkInTime?.split("T")[0]) || ""
|
? formatDate(modeldata?.checkInTime?.split("T")[0]) || ""
|
||||||
: formatDate(today)
|
: formatDate(today)
|
||||||
}
|
}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-6 col-md-6">
|
<div className="col-6 col-md-6 text-start">
|
||||||
<TimePicker
|
<TimePicker
|
||||||
label="Choose a time"
|
label="Choose a time"
|
||||||
onChange={(e) => setValue("markTime", e)}
|
onChange={(e) => setValue("markTime", e)}
|
||||||
@ -138,7 +138,7 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 col-md-12">
|
<div className="col-12 col-md-12 text-start">
|
||||||
<label className="form-label" htmlFor="description">
|
<label className="form-label" htmlFor="description">
|
||||||
Description
|
Description
|
||||||
</label>
|
</label>
|
||||||
@ -154,19 +154,19 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-center">
|
<div className="col-12 text-end mt-4">
|
||||||
<button type="submit" className="btn btn-sm btn-primary me-3">
|
|
||||||
{isLoading ? "Please Wait..." : "Submit"}
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="reset"
|
||||||
className="btn btn-sm btn-label-secondary"
|
className="btn btn-sm btn-label-secondary me-2"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
onClick={() => closeModal()}
|
onClick={() => closeModal()}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import "../../components/Project/ProjectInfra.css";
|
import "../../components/Project/ProjectInfra.css";
|
||||||
import BuildingModel from "../Project/Infrastructure/BuildingModel";
|
import BuildingModel from "../Project/Infrastructure/BuildingModel";
|
||||||
@ -8,64 +7,75 @@ import WorkAreaModel from "../Project/Infrastructure/WorkAreaModel";
|
|||||||
import TaskModel from "../Project/Infrastructure/TaskModel";
|
import TaskModel from "../Project/Infrastructure/TaskModel";
|
||||||
import ProjectRepository from "../../repositories/ProjectRepository";
|
import ProjectRepository from "../../repositories/ProjectRepository";
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
import {useProjectDetails, useProjectInfra, useProjects} from "../../hooks/useProjects";
|
import {
|
||||||
import {useHasUserPermission} from "../../hooks/useHasUserPermission";
|
useCurrentService,
|
||||||
import {APPROVE_TASK, ASSIGN_REPORT_TASK, MANAGE_PROJECT_INFRA} from "../../utils/constants";
|
useProjectDetails,
|
||||||
import {useDispatch, useSelector} from "react-redux";
|
useProjectInfra,
|
||||||
import {useProfile} from "../../hooks/useProfile";
|
useProjects,
|
||||||
import {refreshData, setProjectId} from "../../slices/localVariablesSlice";
|
} from "../../hooks/useProjects";
|
||||||
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
|
import {
|
||||||
|
APPROVE_TASK,
|
||||||
|
ASSIGN_REPORT_TASK,
|
||||||
|
MANAGE_PROJECT_INFRA,
|
||||||
|
} from "../../utils/constants";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { useProfile } from "../../hooks/useProfile";
|
||||||
|
import { refreshData, setProjectId } from "../../slices/localVariablesSlice";
|
||||||
import InfraTable from "../Project/Infrastructure/InfraTable";
|
import InfraTable from "../Project/Infrastructure/InfraTable";
|
||||||
import { useSelectedProject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import Loader from "../common/Loader";
|
import Loader from "../common/Loader";
|
||||||
|
|
||||||
|
const InfraPlanning = () => {
|
||||||
const InfraPlanning = () =>
|
const { profile: LoggedUser, refetch: fetchData } = useProfile();
|
||||||
{
|
const dispatch = useDispatch();
|
||||||
const {profile: LoggedUser, refetch : fetchData} = useProfile()
|
|
||||||
const dispatch = useDispatch()
|
|
||||||
// const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
const {projectInfra, isLoading, error} = useProjectInfra( selectedProject )
|
const selectedService = useCurrentService();
|
||||||
|
|
||||||
|
const { projectInfra, isLoading, isError, error, isFetched } =
|
||||||
|
useProjectInfra(selectedProject, selectedService || "" );
|
||||||
|
|
||||||
|
const canManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
|
||||||
const ManageInfra = useHasUserPermission( MANAGE_PROJECT_INFRA )
|
const canApproveTask = useHasUserPermission(APPROVE_TASK);
|
||||||
const ApprovedTaskRights = useHasUserPermission(APPROVE_TASK)
|
const canReportTask = useHasUserPermission(ASSIGN_REPORT_TASK);
|
||||||
const ReportTaskRights = useHasUserPermission(ASSIGN_REPORT_TASK)
|
|
||||||
const reloadedData = useSelector( ( store ) => store.localVariables.reload )
|
|
||||||
|
|
||||||
|
const reloadedData = useSelector((store) => store.localVariables.reload);
|
||||||
// useEffect( () =>
|
|
||||||
// {
|
|
||||||
// if (reloadedData)
|
|
||||||
// {
|
|
||||||
// refetch()
|
|
||||||
// dispatch( refreshData( false ) )
|
|
||||||
// }
|
|
||||||
|
|
||||||
// },[reloadedData])
|
const hasAccess = canManageInfra || canApproveTask || canReportTask;
|
||||||
|
|
||||||
|
if (isError) {
|
||||||
|
return <div>{error?.response?.data?.message || error?.message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAccess && !isLoading) {
|
||||||
|
return (
|
||||||
|
<div className="text-center">
|
||||||
|
<i className="fa-solid fa-triangle-exclamation fs-5"></i>
|
||||||
|
<p>Access Denied: You don't have permission to perform this action.</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <Loader />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFetched && (!projectInfra || projectInfra.length === 0)) {
|
||||||
|
return (
|
||||||
|
<div className="text-center">
|
||||||
|
<p className="my-3">No Result Found</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
|
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
|
||||||
<div className="card">
|
|
||||||
<div className="card-body" style={{ padding: "0.5rem" }}>
|
<div className="card-body" style={{ padding: "0.5rem" }}>
|
||||||
{(ApprovedTaskRights || ReportTaskRights) ? (
|
<div className="row">
|
||||||
<div className="align-items-center">
|
<InfraTable buildings={projectInfra} projectId={selectedProject} />
|
||||||
<div className="row ">
|
|
||||||
{isLoading && (<Loader/> )}
|
|
||||||
{( !isLoading && projectInfra?.length === 0 ) && ( <p>No Result Found</p> )}
|
|
||||||
{(!isLoading && projectInfra?.length > 0) && (<InfraTable buildings={projectInfra} projectId={selectedProject}/>)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
|
||||||
<div className="text-center">
|
|
||||||
<i className="fa-solid fa-triangle-exclamation fs-5"></i>
|
|
||||||
<p>Access Denied: You don't have permission to perform this action. !</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,25 +1,43 @@
|
|||||||
import React, { useCallback, useEffect, useState, useMemo } from "react";
|
import React, { useCallback, useEffect, useState, useMemo } from "react";
|
||||||
import Avatar from "../common/Avatar";
|
import Avatar from "../common/Avatar";
|
||||||
import { convertShortTime } from "../../utils/dateUtils";
|
import { convertShortTime, formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
import RegularizationActions from "./RegularizationActions";
|
import RegularizationActions from "./RegularizationActions";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useRegularizationRequests } from "../../hooks/useAttendance";
|
import { useRegularizationRequests } from "../../hooks/useAttendance";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import usePagination from "../../hooks/usePagination";
|
import usePagination from "../../hooks/usePagination";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
import {
|
||||||
|
cacheData,
|
||||||
|
clearCacheKey,
|
||||||
|
useSelectedProject,
|
||||||
|
} from "../../slices/apiDataManager";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
import Pagination from "../../components/common/Pagination";
|
||||||
|
|
||||||
const Regularization = ({ handleRequest, searchTerm }) => {
|
const Regularization = ({
|
||||||
|
handleRequest,
|
||||||
|
searchTerm,
|
||||||
|
projectId,
|
||||||
|
organizationId,
|
||||||
|
IncludeInActive,
|
||||||
|
}) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
const [regularizesList, setregularizedList] = useState([]);
|
const [regularizesList, setregularizedList] = useState([]);
|
||||||
const { regularizes, loading, error, refetch } =
|
const { regularizes, loading, error, refetch } = useRegularizationRequests(
|
||||||
useRegularizationRequests(selectedProject);
|
selectedProject,
|
||||||
|
organizationId,
|
||||||
|
IncludeInActive
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if(!regularizes) return
|
||||||
|
if(regularizes?.length) {
|
||||||
setregularizedList(regularizes);
|
setregularizedList(regularizes);
|
||||||
|
|
||||||
|
}
|
||||||
}, [regularizes]);
|
}, [regularizes]);
|
||||||
|
|
||||||
const sortByName = (a, b) => {
|
const sortByName = (a, b) => {
|
||||||
@ -54,18 +72,15 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
}
|
}
|
||||||
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
||||||
return sortedList.filter((item) => {
|
return sortedList.filter((item) => {
|
||||||
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
const fullName = `${item?.firstName} ${item?.lastName}`.toLowerCase();
|
||||||
return fullName.includes(lowercasedSearchTerm);
|
return fullName.includes(lowercasedSearchTerm);
|
||||||
});
|
});
|
||||||
}, [regularizesList, searchTerm]);
|
}, [regularizesList, searchTerm]);
|
||||||
|
|
||||||
const { currentPage, totalPages, currentItems, paginate } =
|
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
||||||
usePagination(filteredSearchData, 20);
|
filteredSearchData,
|
||||||
|
20
|
||||||
// Reset pagination when the search term or data changes
|
);
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
}, [filteredSearchData]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
eventBus.on("regularization", handler);
|
eventBus.on("regularization", handler);
|
||||||
@ -87,9 +102,15 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
}, [employeeHandler]);
|
}, [employeeHandler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="table-responsive text-nowrap pb-4">
|
<div
|
||||||
|
className="table-responsive text-nowrap pb-4"
|
||||||
|
style={{ minHeight: "200px" }}
|
||||||
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="my-2">
|
<div
|
||||||
|
className="d-flex justify-content-center align-items-center"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
>
|
||||||
<p className="text-secondary">Loading...</p>
|
<p className="text-secondary">Loading...</p>
|
||||||
</div>
|
</div>
|
||||||
) : currentItems?.length > 0 ? (
|
) : currentItems?.length > 0 ? (
|
||||||
@ -98,24 +119,28 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
<tr>
|
<tr>
|
||||||
<th colSpan={2}>Name</th>
|
<th colSpan={2}>Name</th>
|
||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
|
<th>Organization</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-down-arrow-alt text-success"></i>Check-In
|
<i className="bx bxs-down-arrow-alt text-success"></i>Check-In
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-up-arrow-alt text-danger"></i>Check-Out
|
<i className="bx bxs-up-arrow-alt text-danger"></i>Check-Out
|
||||||
</th>
|
</th>
|
||||||
|
<th colSpan={2}>
|
||||||
|
Requested By
|
||||||
|
</th>
|
||||||
|
<th >
|
||||||
|
Requested At
|
||||||
|
</th>
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{currentItems?.map((att, index) => (
|
{currentItems?.map((att, index) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td colSpan={2}>
|
<td colSpan={2}>
|
||||||
<div className="d-flex justify-content-start align-items-center">
|
<div className="d-flex justify-content-start align-items-center">
|
||||||
<Avatar
|
<Avatar firstName={att.firstName} lastName={att.lastName} />
|
||||||
firstName={att.firstName}
|
|
||||||
lastName={att.lastName}
|
|
||||||
></Avatar>
|
|
||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
<a href="#" className="text-heading text-truncate">
|
<a href="#" className="text-heading text-truncate">
|
||||||
<span className="fw-normal">
|
<span className="fw-normal">
|
||||||
@ -126,9 +151,28 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{moment(att.checkOutTime).format("DD-MMM-YYYY")}</td>
|
<td>{moment(att.checkOutTime).format("DD-MMM-YYYY")}</td>
|
||||||
|
|
||||||
|
<td>{att.organizationName || "--"}</td>
|
||||||
|
|
||||||
<td>{convertShortTime(att.checkInTime)}</td>
|
<td>{convertShortTime(att.checkInTime)}</td>
|
||||||
<td>
|
<td>
|
||||||
{att.checkOutTime ? convertShortTime(att.checkOutTime) : "--"}
|
{att.requestedAt ? convertShortTime(att.checkOutTime) : "--"}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td colSpan={2}>
|
||||||
|
{att.requestedBy ? ( <div className="d-flex justify-content-start align-items-center">
|
||||||
|
<Avatar firstName={att?.requestedBy?.firstName} lastName={att?.requestedBy?.lastName} />
|
||||||
|
<div className="d-flex flex-column">
|
||||||
|
<a href="#" className="text-heading text-truncate">
|
||||||
|
<span className="fw-normal">
|
||||||
|
{att?.requestedBy?.firstName} {att?.requestedBy?.lastName}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>):(<small>--</small>)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{att?.requestedAt ? formatUTCToLocalTime(att.requestedAt,true) : "--"}
|
||||||
</td>
|
</td>
|
||||||
<td className="text-center ">
|
<td className="text-center ">
|
||||||
<RegularizationActions
|
<RegularizationActions
|
||||||
@ -136,20 +180,24 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
handleRequest={handleRequest}
|
handleRequest={handleRequest}
|
||||||
refresh={refetch}
|
refresh={refetch}
|
||||||
/>
|
/>
|
||||||
{/* </div> */}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
) : (
|
) : (
|
||||||
<div className="my-4">
|
<div
|
||||||
|
className="d-flex justify-content-center align-items-center"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
>
|
||||||
<span className="text-secondary">
|
<span className="text-secondary">
|
||||||
{searchTerm ? "No results found for your search." : "No Requests Found !"}
|
{searchTerm
|
||||||
|
? "No results found for your search."
|
||||||
|
: "No Requests Found !"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!loading && totalPages > 1 && (
|
{/* {!loading && totalPages > 1 && (
|
||||||
<nav aria-label="Page ">
|
<nav aria-label="Page ">
|
||||||
<ul className="pagination pagination-sm justify-content-end py-1 mt-3">
|
<ul className="pagination pagination-sm justify-content-end py-1 mt-3">
|
||||||
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
||||||
@ -163,9 +211,8 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
{[...Array(totalPages)].map((_, index) => (
|
{[...Array(totalPages)].map((_, index) => (
|
||||||
<li
|
<li
|
||||||
key={index}
|
key={index}
|
||||||
className={`page-item ${
|
className={`page-item ${currentPage === index + 1 ? "active" : ""
|
||||||
currentPage === index + 1 ? "active" : ""
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="page-link "
|
className="page-link "
|
||||||
@ -176,9 +223,8 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
<li
|
<li
|
||||||
className={`page-item ${
|
className={`page-item ${currentPage === totalPages ? "disabled" : ""
|
||||||
currentPage === totalPages ? "disabled" : ""
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="page-link "
|
className="page-link "
|
||||||
@ -189,6 +235,14 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
)} */}
|
||||||
|
|
||||||
|
{totalPages > 0 && (
|
||||||
|
<Pagination
|
||||||
|
currentPage={currentPage}
|
||||||
|
totalPages={totalPages}
|
||||||
|
onPageChange={paginate}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import React, { act, useEffect, useState } from 'react'
|
import React, { act, useEffect, useState } from 'react'
|
||||||
import useAttendanceStatus, { ACTIONS } from '../../hooks/useAttendanceStatus';
|
import useAttendanceStatus, { ACTIONS } from '../../hooks/useAttendanceStatus';
|
||||||
// import AttendanceRepository from '../../repositories/AttendanceRepository';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { usePositionTracker } from '../../hooks/usePositionTracker';
|
import { usePositionTracker } from '../../hooks/usePositionTracker';
|
||||||
import {markCurrentAttendance} from '../../slices/apiSlice/attendanceAllSlice';
|
|
||||||
import {cacheData, getCachedData, useSelectedProject} from '../../slices/apiDataManager';
|
import {cacheData, getCachedData, useSelectedProject} from '../../slices/apiDataManager';
|
||||||
import showToast from '../../services/toastService';
|
import showToast from '../../services/toastService';
|
||||||
import { useMarkAttendance } from '../../hooks/useAttendance';
|
import { useMarkAttendance } from '../../hooks/useAttendance';
|
||||||
|
@ -77,7 +77,7 @@ export const ReportTask = ({ report, closeModal }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="container m-0">
|
<div className="container m-0">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="fs-6 fw-semibold">Report Task</p>
|
<p className="fs-5 fw-semibold">Report Task</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-1 row text-start">
|
<div className="mb-1 row text-start">
|
||||||
<label htmlFor="html5-text-input" className="col-md-4 col-form-label">
|
<label htmlFor="html5-text-input" className="col-md-4 col-form-label">
|
||||||
@ -101,16 +101,14 @@ export const ReportTask = ({ report, closeModal }) => {
|
|||||||
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
||||||
Wrok Area :
|
Wrok Area :
|
||||||
</label>
|
</label>
|
||||||
<div className="col-md-8 text-start text-wrap">
|
<div className="col-md-8 text-start">
|
||||||
<label className=" col-form-label">
|
<div className="text-wrap">
|
||||||
{" "}
|
{report?.workItem?.workArea?.floor?.building?.name} <i className="bx bx-chevron-right"></i>
|
||||||
{report?.workItem?.workArea?.floor?.building?.name}{" "}
|
{report?.workItem?.workArea?.floor?.floorName} <i className="bx bx-chevron-right"></i>
|
||||||
<i className="bx bx-chevron-right"></i>{" "}
|
{report?.workItem?.workArea?.areaName}
|
||||||
{report?.workItem?.workArea?.floor?.floorName}{" "}
|
</div>
|
||||||
<i className="bx bx-chevron-right"> </i>
|
</div>
|
||||||
{report?.workItem?.workArea?.areaName}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-1 row text-start">
|
<div className="mb-1 row text-start">
|
||||||
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
||||||
@ -185,21 +183,22 @@ export const ReportTask = ({ report, closeModal }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 text-center my-2">
|
<div className="col-12 text-end my-2 mt-4">
|
||||||
<button type="submit" className="btn btn-sm btn-primary me-3" disabled={isPending}>
|
|
||||||
{isPending ? "Please wait" : "Submit Report"}
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm btn-label-secondary"
|
className="btn btn-sm btn-label-secondary me-3"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary" disabled={isPending}>
|
||||||
|
{isPending ? "Please wait" : "Submit Report"}
|
||||||
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default ReportTask;
|
export default ReportTask;
|
@ -10,6 +10,7 @@ import { getBgClassFromHash } from "../../utils/projectStatus";
|
|||||||
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
||||||
import ImagePreview from "../common/ImagePreview";
|
import ImagePreview from "../common/ImagePreview";
|
||||||
import { useAuditStatus, useSubmitTaskComment } from "../../hooks/useTasks";
|
import { useAuditStatus, useSubmitTaskComment } from "../../hooks/useTasks";
|
||||||
|
import Label from "../common/Label";
|
||||||
|
|
||||||
const ReportTaskComments = ({
|
const ReportTaskComments = ({
|
||||||
commentsData,
|
commentsData,
|
||||||
@ -109,6 +110,8 @@ const ReportTaskComments = ({
|
|||||||
approvedTask: defaultCompletedTask || 0,
|
approvedTask: defaultCompletedTask || 0,
|
||||||
});
|
});
|
||||||
}, [defaultCompletedTask]);
|
}, [defaultCompletedTask]);
|
||||||
|
|
||||||
|
const completed_Task = watch("approvedTask")
|
||||||
return (
|
return (
|
||||||
<div className="p-2 p-sm-1">
|
<div className="p-2 p-sm-1">
|
||||||
<div className="modal-body p-sm-4 p-0">
|
<div className="modal-body p-sm-4 p-0">
|
||||||
@ -291,10 +294,10 @@ const ReportTaskComments = ({
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-6 col-sm-4 text-center align-items-end m-0">
|
<div className="col-6 col-sm-4 text-start align-items-end m-0">
|
||||||
<label htmlFor="workStatus" className="form-label">
|
<Label htmlFor="workStatus" className="form-label" required>
|
||||||
Audit Status
|
Audit Status
|
||||||
</label>
|
</Label>
|
||||||
<select
|
<select
|
||||||
id="workStatus"
|
id="workStatus"
|
||||||
className={`form-select form-select-sm`}
|
className={`form-select form-select-sm`}
|
||||||
@ -338,13 +341,13 @@ const ReportTaskComments = ({
|
|||||||
<div
|
<div
|
||||||
className={` ${
|
className={` ${
|
||||||
actionAllow && !commentsData.approvedBy
|
actionAllow && !commentsData.approvedBy
|
||||||
? " d-flex justify-content-between"
|
? " d-flex justify-content-between align-items-center"
|
||||||
: "text-end"
|
: "text-end"
|
||||||
} mt-2`}
|
} mt-2`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`form-check ${
|
className={`form-check ${
|
||||||
!(actionAllow && !commentsData.approvedBy) && "d-none"
|
!(actionAllow && !commentsData.approvedBy && defaultCompletedTask > completed_Task ) && "d-none"
|
||||||
} `}
|
} `}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@ -361,7 +364,7 @@ const ReportTaskComments = ({
|
|||||||
<span>
|
<span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm btn-secondary"
|
className="btn btn-sm btn-label-secondary mt-5"
|
||||||
onClick={closeModal}
|
onClick={closeModal}
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
@ -370,7 +373,7 @@ const ReportTaskComments = ({
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="btn btn-sm btn-primary ms-2"
|
className="btn btn-sm btn-primary ms-2 mt-5"
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
>
|
>
|
||||||
{isPending
|
{isPending
|
||||||
@ -382,7 +385,7 @@ const ReportTaskComments = ({
|
|||||||
: "Comment"}
|
: "Comment"}
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
|
@ -4,6 +4,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import { string, z } from "zod";
|
import { string, z } from "zod";
|
||||||
import {
|
import {
|
||||||
useActivitiesMaster,
|
useActivitiesMaster,
|
||||||
|
useServices,
|
||||||
useWorkCategoriesMaster,
|
useWorkCategoriesMaster,
|
||||||
} from "../../hooks/masterHook/useMaster";
|
} from "../../hooks/masterHook/useMaster";
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
@ -25,6 +26,8 @@ const SubTask = ({ activity, onClose }) => {
|
|||||||
const { activities, loading } = useActivitiesMaster();
|
const { activities, loading } = useActivitiesMaster();
|
||||||
const { categories, categoryLoading } = useWorkCategoriesMaster();
|
const { categories, categoryLoading } = useWorkCategoriesMaster();
|
||||||
const { Task, loading: TaskLoading } = useTaskById(activity?.id);
|
const { Task, loading: TaskLoading } = useTaskById(activity?.id);
|
||||||
|
const {data,isError,isLoading,error} = useServices();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -97,8 +100,8 @@ const SubTask = ({ activity, onClose }) => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="container-xxl my-1">
|
<div className="container-xxl my-1">
|
||||||
<p className="fw-semibold">Create Sub Task</p>
|
<p className="fw-semibold fs-5">Create Sub Task</p>
|
||||||
<form className="row g-2" onSubmit={handleSubmit(onSubmitForm)}>
|
<form className="row g-2 text-start" onSubmit={handleSubmit(onSubmitForm)}>
|
||||||
<div className="col-6">
|
<div className="col-6">
|
||||||
<label className="form-label">Building</label>
|
<label className="form-label">Building</label>
|
||||||
<input
|
<input
|
||||||
@ -128,27 +131,15 @@ const SubTask = ({ activity, onClose }) => {
|
|||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-12">
|
||||||
<div className="col-12">
|
<label className="form-label">Service</label>
|
||||||
<label className="form-label">Work Category</label>
|
<input
|
||||||
<select
|
type="text"
|
||||||
className="form-select form-select-sm"
|
className="form-control form-control-sm"
|
||||||
{...register("workCategoryId")}
|
value={activity?.workItem?.activityMaster?.activityGroup?.service?.name || ""}
|
||||||
onChange={handleCategoryChange}
|
disabled
|
||||||
>
|
/>
|
||||||
<option value="">
|
</div>
|
||||||
{categoryLoading ? "Loading..." : "-- Select Category --"}
|
|
||||||
</option>
|
|
||||||
{categoryData.map((category) => (
|
|
||||||
<option key={category.id} value={category.id}>
|
|
||||||
{category.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
{errors.workCategoryId && (
|
|
||||||
<div className="danger-text">{errors.workCategoryId.message}</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<label className="form-label">Select Activity</label>
|
<label className="form-label">Select Activity</label>
|
||||||
<select
|
<select
|
||||||
@ -172,6 +163,27 @@ const SubTask = ({ activity, onClose }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="col-12">
|
||||||
|
<label className="form-label">Work Category</label>
|
||||||
|
<select
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
{...register("workCategoryId")}
|
||||||
|
onChange={handleCategoryChange}
|
||||||
|
>
|
||||||
|
<option value="">
|
||||||
|
{categoryLoading ? "Loading..." : "-- Select Category --"}
|
||||||
|
</option>
|
||||||
|
{categoryData.map((category) => (
|
||||||
|
<option key={category.id} value={category.id}>
|
||||||
|
{category.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
{errors.workCategoryId && (
|
||||||
|
<div className="danger-text">{errors.workCategoryId.message}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="col-4">
|
<div className="col-4">
|
||||||
<label className="form-label">Planned Work</label>
|
<label className="form-label">Planned Work</label>
|
||||||
<input
|
<input
|
||||||
@ -219,7 +231,15 @@ const SubTask = ({ activity, onClose }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-center">
|
<div className="d-flex flex-row gap-3 justify-content-end py-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-sm btn-label-secondary"
|
||||||
|
onClick={() => onClose()}
|
||||||
|
disabled={isPending}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="btn btn-sm btn-primary me-2"
|
className="btn btn-sm btn-primary me-2"
|
||||||
@ -227,14 +247,7 @@ const SubTask = ({ activity, onClose }) => {
|
|||||||
>
|
>
|
||||||
{isPending ? "Please wait..." : "Submit"}
|
{isPending ? "Please wait..." : "Submit"}
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn btn-sm btn-secondary"
|
|
||||||
onClick={() => onClose()}
|
|
||||||
disabled={isPending}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
import React, { createContext, useState, useContext } from "react";
|
|
||||||
import ChangePasswordPage from "../../pages/authentication/ChangePassword";
|
|
||||||
|
|
||||||
const ChangePasswordContext = createContext();
|
|
||||||
|
|
||||||
export const ChangePasswordProvider = ({ children }) => {
|
|
||||||
const [isChangePasswordOpen, setIsChangePasswordOpen] = useState(false);
|
|
||||||
|
|
||||||
const openChangePassword = () => setIsChangePasswordOpen(true);
|
|
||||||
const closeChangePassword = () => setIsChangePasswordOpen(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ChangePasswordContext.Provider
|
|
||||||
value={{ isChangePasswordOpen, openChangePassword, closeChangePassword }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
|
|
||||||
{isChangePasswordOpen && (
|
|
||||||
<>
|
|
||||||
{/* This is the main Bootstrap modal container */}
|
|
||||||
{/* It provides the fixed positioning and high z-index */}
|
|
||||||
<div
|
|
||||||
className="modal fade show" // 'fade' for animation, 'show' to make it visible
|
|
||||||
style={{ display: 'block' }} // Explicitly set display: block for immediate visibility
|
|
||||||
tabIndex="-1" // Makes the modal focusable
|
|
||||||
role="dialog" // ARIA role for accessibility
|
|
||||||
aria-labelledby="changePasswordModalLabel" // Link to a heading for accessibility
|
|
||||||
aria-modal="true" // Indicate it's a modal dialog
|
|
||||||
>
|
|
||||||
{/* The ChangePasswordPage component itself contains the modal-dialog and modal-content */}
|
|
||||||
<ChangePasswordPage onClose={closeChangePassword} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* The modal backdrop */}
|
|
||||||
<div className="modal-backdrop fade show"></div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</ChangePasswordContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useChangePassword = () => useContext(ChangePasswordContext);
|
|
107
src/components/DailyProgressRport/TaskReportFilterPanel.jsx
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { useCurrentService } from "../../hooks/useProjects";
|
||||||
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import {
|
||||||
|
TaskReportDefaultValue,
|
||||||
|
TaskReportFilterSchema,
|
||||||
|
} from "./TaskRportScheam";
|
||||||
|
import { DateRangePicker1 } from "../common/DateRangePicker";
|
||||||
|
import SelectMultiple from "../common/SelectMultiple";
|
||||||
|
import { localToUtc } from "../../utils/appUtils";
|
||||||
|
import { useTaskFilter } from "../../hooks/useTasks";
|
||||||
|
|
||||||
|
const TaskReportFilterPanel = ({ handleFilter }) => {
|
||||||
|
const [resetKey, setResetKey] = useState(0);
|
||||||
|
const selectedProject = useSelectedProject();
|
||||||
|
const selectedService = useCurrentService();
|
||||||
|
const { data } = useTaskFilter(selectedProject);
|
||||||
|
|
||||||
|
const methods = useForm({
|
||||||
|
resolver: zodResolver(TaskReportFilterSchema),
|
||||||
|
defaultValues: TaskReportDefaultValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
reset,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
} = methods;
|
||||||
|
|
||||||
|
const onSubmit = (formData) => {
|
||||||
|
const filterPayload = {
|
||||||
|
...formData,
|
||||||
|
dateFrom: localToUtc(formData.dateFrom),
|
||||||
|
dateTo: localToUtc(formData.dateTo),
|
||||||
|
};
|
||||||
|
handleFilter(filterPayload);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClear = () => {
|
||||||
|
setResetKey((prev) => prev + 1);
|
||||||
|
handleFilter(TaskReportDefaultValue);
|
||||||
|
reset(TaskReportDefaultValue);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<FormProvider {...methods}>
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)} className="p-2 text-start">
|
||||||
|
<div className="mb-3 w-100">
|
||||||
|
<label className="fw-semibold">Choose Date Range:</label>
|
||||||
|
<DateRangePicker1
|
||||||
|
placeholder="DD-MM-YYYY To DD-MM-YYYY"
|
||||||
|
startField="dateFrom"
|
||||||
|
endField="dateTo"
|
||||||
|
resetSignal={resetKey}
|
||||||
|
defaultRange={false}
|
||||||
|
maxDate={new Date()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row mb-2">
|
||||||
|
<SelectMultiple
|
||||||
|
name="buildingIds"
|
||||||
|
label="Building"
|
||||||
|
options={data?.buildings}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="row mb-2">
|
||||||
|
<SelectMultiple
|
||||||
|
name="floorIds"
|
||||||
|
label="Floor"
|
||||||
|
options={data?.floors}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="row mb-2">
|
||||||
|
<SelectMultiple
|
||||||
|
name="activityIds"
|
||||||
|
label="Activities"
|
||||||
|
options={data?.activities}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="d-flex justify-content-end py-3 gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-label-secondary btn-sm"
|
||||||
|
onClick={onClear}
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
|
<button type="submit" className="btn btn-primary btn-sm">
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</FormProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TaskReportFilterPanel;
|
301
src/components/DailyProgressRport/TaskReportList.jsx
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
import React, { useState, useEffect, useMemo } from "react";
|
||||||
|
import { useTaskList } from "../../hooks/useTasks";
|
||||||
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
|
import DailyProgrssReport, {
|
||||||
|
useDailyProgrssContext,
|
||||||
|
} from "../../pages/DailyProgressReport/DailyProgrssReport";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||||
|
import {
|
||||||
|
APPROVE_TASK,
|
||||||
|
ASSIGN_REPORT_TASK,
|
||||||
|
ITEMS_PER_PAGE,
|
||||||
|
} from "../../utils/constants";
|
||||||
|
import { formatNumber, formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
|
import Pagination from "../common/Pagination";
|
||||||
|
import { TaskReportListSkeleton } from "./TaskRepprtListSkeleton";
|
||||||
|
import HoverPopup from "../common/HoverPopup";
|
||||||
|
|
||||||
|
const TaskReportList = () => {
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [filters, setFilters] = useState({
|
||||||
|
selectedBuilding: "",
|
||||||
|
selectedFloors: [],
|
||||||
|
selectedActivities: [],
|
||||||
|
});
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const ApprovedTaskRights = useHasUserPermission(APPROVE_TASK);
|
||||||
|
const ReportTaskRights = useHasUserPermission(ASSIGN_REPORT_TASK);
|
||||||
|
|
||||||
|
const { service, openModal, closeModal,filter } = useDailyProgrssContext();
|
||||||
|
const selectedProject = useSelectedProject();
|
||||||
|
const { projectNames } = useProjectName();
|
||||||
|
|
||||||
|
const { data, isLoading, isError, error } = useTaskList(
|
||||||
|
selectedProject,
|
||||||
|
ITEMS_PER_PAGE,
|
||||||
|
currentPage,
|
||||||
|
service,filter
|
||||||
|
);
|
||||||
|
|
||||||
|
const ProgrssReportColumn = [
|
||||||
|
{
|
||||||
|
key: "activity",
|
||||||
|
label: "Activity",
|
||||||
|
getValue: (task) => task.workItem.activityMaster?.activityName || "N/A",
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "assigned",
|
||||||
|
label: "Total Assigned",
|
||||||
|
getValue: (task) => task.plannedTask ?? "N/A",
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "completed",
|
||||||
|
label: "Completed",
|
||||||
|
getValue: (task) => task.completedTask ?? "N/A",
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "assignAt",
|
||||||
|
label: "Assign Date",
|
||||||
|
getValue: (task) =>
|
||||||
|
task.assignmentDate ? formatUTCToLocalTime(task.assignmentDate) : "N/A",
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "team",
|
||||||
|
label: "Team",
|
||||||
|
getValue: (task) =>
|
||||||
|
task.teamMembers?.map((m) => `${m.firstName} ${m.lastName}`).join(", ") ||
|
||||||
|
"N/A",
|
||||||
|
align: "text-start",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const paginate = (page) => {
|
||||||
|
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
||||||
|
setCurrentPage(page);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!selectedProject && projectNames.length > 0) {
|
||||||
|
dispatch(setProjectId(projectNames[0].id));
|
||||||
|
}
|
||||||
|
}, [selectedProject, projectNames, dispatch]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFilters({
|
||||||
|
selectedBuilding: "",
|
||||||
|
selectedFloors: [],
|
||||||
|
selectedActivities: [],
|
||||||
|
});
|
||||||
|
}, [selectedProject]);
|
||||||
|
|
||||||
|
// Filter and Group wise data
|
||||||
|
|
||||||
|
const filteredTasks = useMemo(() => {
|
||||||
|
if (!data?.data) return [];
|
||||||
|
return data?.data.filter((task) => {
|
||||||
|
const { selectedBuilding, selectedFloors, selectedActivities } = filters;
|
||||||
|
|
||||||
|
if (
|
||||||
|
selectedBuilding &&
|
||||||
|
task?.workItem?.workArea?.floor?.building?.name !== selectedBuilding
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
if (
|
||||||
|
selectedFloors.length > 0 &&
|
||||||
|
!selectedFloors.includes(task?.workItem?.workArea?.floor?.floorName)
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
if (
|
||||||
|
selectedActivities.length > 0 &&
|
||||||
|
!selectedActivities.includes(
|
||||||
|
task?.workItem?.activityMaster?.activityName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}, [data?.data, filters, currentPage]);
|
||||||
|
|
||||||
|
const groupedTasks = useMemo(() => {
|
||||||
|
const groups = {};
|
||||||
|
filteredTasks.forEach((task) => {
|
||||||
|
const date = task.assignmentDate.split("T")[0];
|
||||||
|
if (!groups[date]) groups[date] = [];
|
||||||
|
groups[date].push(task);
|
||||||
|
});
|
||||||
|
return Object.keys(groups)
|
||||||
|
.sort((a, b) => new Date(b) - new Date(a))
|
||||||
|
.map((date) => ({ date, tasks: groups[date] }));
|
||||||
|
}, [filteredTasks, paginate, currentPage, selectedProject]);
|
||||||
|
|
||||||
|
const renderTeamMembers = (task, refIndex) => (
|
||||||
|
<div
|
||||||
|
key={refIndex}
|
||||||
|
tabIndex="0"
|
||||||
|
className="d-flex align-items-center avatar-group justify-content-center"
|
||||||
|
data-bs-toggle="popover"
|
||||||
|
data-bs-trigger="focus"
|
||||||
|
data-bs-placement="left"
|
||||||
|
data-bs-html="true"
|
||||||
|
data-bs-content={`
|
||||||
|
<div class="border border-secondary rounded custom-popover p-2 px-3">
|
||||||
|
${task.teamMembers
|
||||||
|
.map(
|
||||||
|
(m) => `
|
||||||
|
<div class="d-flex align-items-center gap-2 mb-2">
|
||||||
|
<div class="avatar avatar-xs">
|
||||||
|
<span class="avatar-initial rounded-circle bg-label-primary">
|
||||||
|
${m?.firstName?.charAt(0) || ""}${m?.lastName?.charAt(0) || ""
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span>${m.firstName} ${m.lastName}</span>
|
||||||
|
</div>`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{task.teamMembers.slice(0, 3).map((m) => (
|
||||||
|
<div
|
||||||
|
key={m.id}
|
||||||
|
className="avatar avatar-xs"
|
||||||
|
title={`${m.firstName} ${m.lastName}`}
|
||||||
|
>
|
||||||
|
<span className="avatar-initial rounded-circle bg-label-primary">
|
||||||
|
{m?.firstName.slice(0, 1)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{task.teamMembers.length > 3 && (
|
||||||
|
<div
|
||||||
|
className="avatar avatar-xs"
|
||||||
|
title={`${task.teamMembers.length - 3} more`}
|
||||||
|
>
|
||||||
|
<span className="avatar-initial rounded-circle bg-label-secondary">
|
||||||
|
+{task.teamMembers.length - 3}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isLoading) return <TaskReportListSkeleton />;
|
||||||
|
if (isError) return <div>Loading....</div>;
|
||||||
|
return (
|
||||||
|
<div className="mt-2 table-responsive text-nowrap">
|
||||||
|
<table className="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start">Activity</th>
|
||||||
|
<th>
|
||||||
|
<span>
|
||||||
|
Total Pending{" "}
|
||||||
|
<HoverPopup
|
||||||
|
title="Total Pending Task"
|
||||||
|
content={<p>This shows the total pending tasks for each activity on that date.</p>}
|
||||||
|
>
|
||||||
|
<i className="bx bx-xs ms-1 bx-info-circle cursor-pointer"></i>
|
||||||
|
</HoverPopup>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<span>
|
||||||
|
Reported/Planned{" "}
|
||||||
|
<HoverPopup
|
||||||
|
title="Reported and Planned Task"
|
||||||
|
content={<p>This shows the reported versus planned tasks for each activity on that date.</p>}
|
||||||
|
>
|
||||||
|
<i className="bx bx-xs ms-1 bx-info-circle cursor-pointer"></i>
|
||||||
|
</HoverPopup>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>Assign Date</th>
|
||||||
|
<th>Team</th>
|
||||||
|
<th className="text-center">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{groupedTasks.length === 0 && (
|
||||||
|
<tr>
|
||||||
|
<td colSpan={6} className="text-center align-middle" style={{ height: "200px", borderBottom: "none" }}>
|
||||||
|
No reports available
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{groupedTasks.map(({ date, tasks }) => (
|
||||||
|
<React.Fragment key={date}>
|
||||||
|
<tr className="table-row-header text-start">
|
||||||
|
<td colSpan={6}>
|
||||||
|
<strong>{formatUTCToLocalTime(date)}</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{tasks.map((task, idx) => (
|
||||||
|
<tr key={task.id || idx}>
|
||||||
|
<td className="flex-wrap text-start">
|
||||||
|
<div>
|
||||||
|
{task.workItem.activityMaster?.activityName || "No Activity Name"}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm py-2">
|
||||||
|
{task.workItem.workArea?.floor?.building?.name} ›{" "}
|
||||||
|
{task.workItem.workArea?.floor?.floorName} ›{" "}
|
||||||
|
{task.workItem.workArea?.areaName}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{formatNumber(task.workItem.plannedWork)}
|
||||||
|
</td>
|
||||||
|
<td>{`${formatNumber(task.completedTask)} / ${formatNumber(task.plannedTask)}`}</td>
|
||||||
|
<td>{formatUTCToLocalTime(task.assignmentDate)}</td>
|
||||||
|
<td className="text-center">{renderTeamMembers(task, idx)}</td>
|
||||||
|
<td className="text-center">
|
||||||
|
<div className="d-flex justify-content-end gap-2">
|
||||||
|
{ReportTaskRights && !task.reportedDate && (
|
||||||
|
<button className="btn btn-xs btn-primary" onClick={() => openModal("report", task)}>
|
||||||
|
Report
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{ApprovedTaskRights && task.reportedDate && !task.approvedBy && (
|
||||||
|
<button
|
||||||
|
className="btn btn-xs btn-warning"
|
||||||
|
onClick={() => openModal("comments", { task, isActionAllow: true })}
|
||||||
|
>
|
||||||
|
QC
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
className="btn btn-xs btn-primary"
|
||||||
|
onClick={() => openModal("comments", { task, isActionAllow: false })}
|
||||||
|
>
|
||||||
|
Comment
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{data?.data?.length > 0 && (
|
||||||
|
<Pagination
|
||||||
|
currentPage={currentPage}
|
||||||
|
totalPages={data.totalPages}
|
||||||
|
onPageChange={paginate}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TaskReportList;
|
62
src/components/DailyProgressRport/TaskRepprtListSkeleton.jsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
const SkeletonLine = ({ height = 20, width = "100%", className = "" }) => (
|
||||||
|
<div
|
||||||
|
className={`skeleton mb-2 ${className}`}
|
||||||
|
style={{
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
);
|
||||||
|
export const TaskReportListSkeleton = () => {
|
||||||
|
const skeletonRows = 8; // Number of placeholder rows
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<table className="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Activity</th>
|
||||||
|
<th>Assigned</th>
|
||||||
|
<th>Completed</th>
|
||||||
|
<th>Assign On</th>
|
||||||
|
<th>Team</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{[...Array(skeletonRows)].map((_, idx) => (
|
||||||
|
<tr key={idx}>
|
||||||
|
<td>
|
||||||
|
<SkeletonLine height={16} width="70%" />
|
||||||
|
<SkeletonLine height={12} width="50%" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<SkeletonLine height={16} width="60%" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<SkeletonLine height={16} width="60%" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<SkeletonLine height={16} width="80%" />
|
||||||
|
</td>
|
||||||
|
<td className="text-center">
|
||||||
|
<div className="d-flex justify-content-center gap-1">
|
||||||
|
{[...Array(3)].map((_, i) => (
|
||||||
|
<SkeletonLine key={i} height={24} width={24} className="rounded-circle" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-flex justify-content-end gap-2">
|
||||||
|
<SkeletonLine height={24} width="60px" />
|
||||||
|
<SkeletonLine height={24} width="60px" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
17
src/components/DailyProgressRport/TaskRportScheam.jsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const TaskReportFilterSchema = z.object({
|
||||||
|
buildingIds: z.array(z.string()).optional(),
|
||||||
|
floorIds: z.array(z.string()).optional(),
|
||||||
|
activityIds: z.array(z.string()).optional(),
|
||||||
|
dateFrom: z.string().optional(),
|
||||||
|
dateTo: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TaskReportDefaultValue = {
|
||||||
|
buildingIds:[],
|
||||||
|
floorIds:[],
|
||||||
|
activityIds:[],
|
||||||
|
dateFrom:null,
|
||||||
|
dateTo:null
|
||||||
|
}
|
@ -1,194 +1,194 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
// import React, { useState, useEffect } from "react";
|
||||||
import LineChart from "../Charts/LineChart";
|
// import LineChart from "../Charts/LineChart";
|
||||||
import { useProjects } from "../../hooks/useProjects";
|
// import { useProjects } from "../../hooks/useProjects";
|
||||||
import { useDashboard_ActivityData } from "../../hooks/useDashboard_Data";
|
// import { useDashboard_ActivityData } from "../../hooks/useDashboard_Data";
|
||||||
import ApexChart from "../Charts/Circlechart";
|
// import ApexChart from "../Charts/Circlechart";
|
||||||
|
|
||||||
const LOCAL_STORAGE_PROJECT_KEY = "selectedActivityProjectId";
|
// const LOCAL_STORAGE_PROJECT_KEY = "selectedActivityProjectId";
|
||||||
|
|
||||||
const Activity = () => {
|
// const Activity = () => {
|
||||||
const { projects } = useProjects();
|
// const { projects } = useProjects();
|
||||||
const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD
|
// const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD
|
||||||
const [selectedDate, setSelectedDate] = useState(today);
|
// const [selectedDate, setSelectedDate] = useState(today);
|
||||||
const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY);
|
// const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY);
|
||||||
const initialProjectId = storedProjectId || "all";
|
// const initialProjectId = storedProjectId || "all";
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId);
|
// const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId);
|
||||||
const [displayedProjectName, setDisplayedProjectName] = useState("Select Project");
|
// const [displayedProjectName, setDisplayedProjectName] = useState("Select Project");
|
||||||
const [activeTab, setActiveTab] = useState("all");
|
// const [activeTab, setActiveTab] = useState("all");
|
||||||
|
|
||||||
const { dashboard_Activitydata: ActivityData, isLoading, error: isError } =
|
// const { dashboard_Activitydata: ActivityData, isLoading, error: isError } =
|
||||||
useDashboard_ActivityData(selectedDate, selectedProjectId);
|
// useDashboard_ActivityData(selectedDate, selectedProjectId);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (selectedProjectId === "all") {
|
// if (selectedProjectId === "all") {
|
||||||
setDisplayedProjectName("All Projects");
|
// setDisplayedProjectName("All Projects");
|
||||||
} else if (projects) {
|
// } else if (projects) {
|
||||||
const foundProject = projects.find((p) => p.id === selectedProjectId);
|
// const foundProject = projects.find((p) => p.id === selectedProjectId);
|
||||||
setDisplayedProjectName(foundProject ? foundProject.name : "Select Project");
|
// setDisplayedProjectName(foundProject ? foundProject.name : "Select Project");
|
||||||
} else {
|
// } else {
|
||||||
setDisplayedProjectName("Select Project");
|
// setDisplayedProjectName("Select Project");
|
||||||
}
|
// }
|
||||||
|
|
||||||
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId);
|
// localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId);
|
||||||
}, [selectedProjectId, projects]);
|
// }, [selectedProjectId, projects]);
|
||||||
|
|
||||||
const handleProjectSelect = (projectId) => {
|
// const handleProjectSelect = (projectId) => {
|
||||||
setSelectedProjectId(projectId);
|
// setSelectedProjectId(projectId);
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleDateChange = (e) => {
|
// const handleDateChange = (e) => {
|
||||||
setSelectedDate(e.target.value);
|
// setSelectedDate(e.target.value);
|
||||||
};
|
// };
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<div className="card h-100">
|
// <div className="card h-100">
|
||||||
<div className="card-header">
|
// <div className="card-header">
|
||||||
<div className="d-flex flex-wrap justify-content-between align-items-center mb-0">
|
// <div className="d-flex flex-wrap justify-content-between align-items-center mb-0">
|
||||||
<div className="card-title mb-0 text-start">
|
// <div className="card-title mb-0 text-start">
|
||||||
<h5 className="mb-1">Activity</h5>
|
// <h5 className="mb-1">Activity</h5>
|
||||||
<p className="card-subtitle">Activity Progress Chart</p>
|
// <p className="card-subtitle text-primary">Activity Progress Chart</p>
|
||||||
</div>
|
// </div>
|
||||||
|
|
||||||
<div className="btn-group">
|
// <div className="btn-group">
|
||||||
<button
|
// <button
|
||||||
className="btn btn-outline-primary btn-sm dropdown-toggle"
|
// className="btn btn-outline-primary btn-sm dropdown-toggle"
|
||||||
type="button"
|
// type="button"
|
||||||
data-bs-toggle="dropdown"
|
// data-bs-toggle="dropdown"
|
||||||
aria-expanded="false"
|
// aria-expanded="false"
|
||||||
>
|
// >
|
||||||
{displayedProjectName}
|
// {displayedProjectName}
|
||||||
</button>
|
// </button>
|
||||||
<ul className="dropdown-menu">
|
// <ul className="dropdown-menu">
|
||||||
<li>
|
// <li>
|
||||||
<button className="dropdown-item" onClick={() => handleProjectSelect("all")}>
|
// <button className="dropdown-item" onClick={() => handleProjectSelect("all")}>
|
||||||
All Projects
|
// All Projects
|
||||||
</button>
|
// </button>
|
||||||
</li>
|
// </li>
|
||||||
{projects?.map((project) => (
|
// {projects?.map((project) => (
|
||||||
<li key={project.id}>
|
// <li key={project.id}>
|
||||||
<button
|
// <button
|
||||||
className="dropdown-item"
|
// className="dropdown-item"
|
||||||
onClick={() => handleProjectSelect(project.id)}
|
// onClick={() => handleProjectSelect(project.id)}
|
||||||
>
|
// >
|
||||||
{project.name}
|
// {project.name}
|
||||||
</button>
|
// </button>
|
||||||
</li>
|
// </li>
|
||||||
))}
|
// ))}
|
||||||
</ul>
|
// </ul>
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
|
|
||||||
{/* ✅ Date Picker Aligned Left with Padding */}
|
// {/* ✅ Date Picker Aligned Left with Padding */}
|
||||||
<div className="d-flex justify-content-start ps-3 mb-3">
|
// <div className="d-flex justify-content-start ps-3 mb-3">
|
||||||
<div style={{ width: "150px" }}>
|
// <div style={{ width: "150px" }}>
|
||||||
<input
|
// <input
|
||||||
type="date"
|
// type="date"
|
||||||
className="form-control"
|
// className="form-control"
|
||||||
value={selectedDate}
|
// value={selectedDate}
|
||||||
onChange={handleDateChange}
|
// onChange={handleDateChange}
|
||||||
/>
|
// />
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
|
|
||||||
{/* Tabs */}
|
// {/* Tabs */}
|
||||||
<ul className="nav nav-tabs " role="tablist">
|
// <ul className="nav nav-tabs " role="tablist">
|
||||||
<li className="nav-item">
|
// <li className="nav-item">
|
||||||
<button
|
// <button
|
||||||
type="button"
|
// type="button"
|
||||||
className={`nav-link ${activeTab === "all" ? "active" : ""}`}
|
// className={`nav-link ${activeTab === "all" ? "active" : ""}`}
|
||||||
onClick={() => setActiveTab("all")}
|
// onClick={() => setActiveTab("all")}
|
||||||
data-bs-toggle="tab"
|
// data-bs-toggle="tab"
|
||||||
>
|
// >
|
||||||
Summary
|
// Summary
|
||||||
</button>
|
// </button>
|
||||||
</li>
|
// </li>
|
||||||
<li className="nav-item">
|
// <li className="nav-item">
|
||||||
<button
|
// <button
|
||||||
type="button"
|
// type="button"
|
||||||
className={`nav-link ${activeTab === "logs" ? "active" : ""}`}
|
// className={`nav-link ${activeTab === "logs" ? "active" : ""}`}
|
||||||
onClick={() => setActiveTab("logs")}
|
// onClick={() => setActiveTab("logs")}
|
||||||
data-bs-toggle="tab"
|
// data-bs-toggle="tab"
|
||||||
>
|
// >
|
||||||
Details
|
// Details
|
||||||
</button>
|
// </button>
|
||||||
</li>
|
// </li>
|
||||||
</ul>
|
// </ul>
|
||||||
|
|
||||||
<div className="card-body">
|
// <div className="card-body">
|
||||||
{activeTab === "all" && (
|
// {activeTab === "all" && (
|
||||||
<div className="row justify-content-between">
|
// <div className="row justify-content-between">
|
||||||
<div className="col-md-6 d-flex flex-column align-items-center text-center mb-4">
|
// <div className="col-md-6 d-flex flex-column align-items-center text-center mb-4">
|
||||||
{isLoading ? (
|
// {isLoading ? (
|
||||||
<p>Loading activity data...</p>
|
// <p>Loading activity data...</p>
|
||||||
) : isError ? (
|
// ) : isError ? (
|
||||||
<p>No data available.</p>
|
// <p>No data available.</p>
|
||||||
) : (
|
// ) : (
|
||||||
ActivityData && (
|
// ActivityData && (
|
||||||
<>
|
// <>
|
||||||
<h5 className="fw-bold mb-0 text-start w-80">
|
// <h5 className="fw-bold mb-0 text-start w-80">
|
||||||
<i className="bx bx-task text-info"></i> Allocated Task
|
// <i className="bx bx-task text-info"></i> Allocated Task
|
||||||
</h5>
|
// </h5>
|
||||||
<h4 className="mb-0 fw-bold">
|
// <h4 className="mb-0 fw-bold">
|
||||||
{ActivityData.totalCompletedWork?.toLocaleString()}/
|
// {ActivityData.totalCompletedWork?.toLocaleString()}/
|
||||||
{ActivityData.totalPlannedWork?.toLocaleString()}
|
// {ActivityData.totalPlannedWork?.toLocaleString()}
|
||||||
</h4>
|
// </h4>
|
||||||
<small className="text-muted">Completed / Assigned</small>
|
// <small className="text-muted">Completed / Assigned</small>
|
||||||
<div style={{ maxWidth: "180px" }}>
|
// <div style={{ maxWidth: "180px" }}>
|
||||||
<ApexChart />
|
// <ApexChart />
|
||||||
</div>
|
// </div>
|
||||||
</>
|
// </>
|
||||||
)
|
// )
|
||||||
)}
|
// )}
|
||||||
</div>
|
// </div>
|
||||||
|
|
||||||
<div className="col-md-6 d-flex flex-column align-items-center text-center mb-4">
|
// <div className="col-md-6 d-flex flex-column align-items-center text-center mb-4">
|
||||||
{!isLoading && !isError && ActivityData && (
|
// {!isLoading && !isError && ActivityData && (
|
||||||
<>
|
// <>
|
||||||
<h5 className="fw-bold mb-0 text-start w-110">
|
// <h5 className="fw-bold mb-0 text-start w-110">
|
||||||
<i className="bx bx-task text-info"></i> Activities
|
// <i className="bx bx-task text-info"></i> Activities
|
||||||
</h5>
|
// </h5>
|
||||||
<h4 className="mb-0 fw-bold">
|
// <h4 className="mb-0 fw-bold">
|
||||||
{ActivityData.totalCompletedWork?.toLocaleString()}/
|
// {ActivityData.totalCompletedWork?.toLocaleString()}/
|
||||||
{ActivityData.totalPlannedWork?.toLocaleString()}
|
// {ActivityData.totalPlannedWork?.toLocaleString()}
|
||||||
</h4>
|
// </h4>
|
||||||
<small className="text-muted ">Pending / Assigned</small>
|
// <small className="text-muted ">Pending / Assigned</small>
|
||||||
<div style={{ maxWidth: "180px" }}>
|
// <div style={{ maxWidth: "180px" }}>
|
||||||
<ApexChart />
|
// <ApexChart />
|
||||||
</div>
|
// </div>
|
||||||
</>
|
// </>
|
||||||
)}
|
// )}
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
)}
|
// )}
|
||||||
|
|
||||||
{activeTab === "logs" && (
|
// {activeTab === "logs" && (
|
||||||
<div className="table-responsive">
|
// <div className="table-responsive">
|
||||||
<table className="table table-bordered table-hover">
|
// <table className="table table-bordered table-hover">
|
||||||
<thead>
|
// <thead>
|
||||||
<tr>
|
// <tr>
|
||||||
<th>Activity / Location</th>
|
// <th>Activity / Location</th>
|
||||||
<th>Assigned / Completed</th>
|
// <th>Assigned / Completed</th>
|
||||||
</tr>
|
// </tr>
|
||||||
</thead>
|
// </thead>
|
||||||
<tbody>
|
// <tbody>
|
||||||
{[{
|
// {[{
|
||||||
activity: "Code Review / Remote",
|
// activity: "Code Review / Remote",
|
||||||
assignedToday: 3,
|
// assignedToday: 3,
|
||||||
completed: 2
|
// completed: 2
|
||||||
}].map((log, index) => (
|
// }].map((log, index) => (
|
||||||
<tr key={index}>
|
// <tr key={index}>
|
||||||
<td>{log.activity}</td>
|
// <td>{log.activity}</td>
|
||||||
<td>{log.assignedToday} / {log.completed}</td>
|
// <td>{log.assignedToday} / {log.completed}</td>
|
||||||
</tr>
|
// </tr>
|
||||||
))}
|
// ))}
|
||||||
</tbody>
|
// </tbody>
|
||||||
</table>
|
// </table>
|
||||||
</div>
|
// </div>
|
||||||
)}
|
// )}
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
};
|
// };
|
||||||
|
|
||||||
export default Activity;
|
// export default Activity;
|
||||||
|
@ -1,21 +1,16 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useMemo } from "react";
|
||||||
import LineChart from "../Charts/LineChart";
|
import ApexChart from "../Charts/Circle";
|
||||||
import { useProjects } from "../../hooks/useProjects";
|
import { useProjects } from "../../hooks/useProjects";
|
||||||
import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data";
|
import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data";
|
||||||
import ApexChart from "../Charts/Circle";
|
import { useSelectedProject } from "../../hooks/useSelectedProject"; // ✅ your custom hook
|
||||||
|
|
||||||
const LOCAL_STORAGE_PROJECT_KEY = "selectedAttendanceProjectId";
|
|
||||||
|
|
||||||
const Attendance = () => {
|
const Attendance = () => {
|
||||||
const { projects } = useProjects();
|
const { projects } = useProjects();
|
||||||
const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD
|
const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
|
||||||
const [selectedDate, setSelectedDate] = useState(today);
|
const [selectedDate, setSelectedDate] = useState(today);
|
||||||
const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY);
|
|
||||||
const initialProjectId = storedProjectId || "all";
|
// central project selection hook
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId);
|
const selectedProjectId = useSelectedProject()
|
||||||
const [displayedProjectName, setDisplayedProjectName] =
|
|
||||||
useState("Select Project");
|
|
||||||
const [activeTab, setActiveTab] = useState("Summary");
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
dashboard_Attendancedata: AttendanceData,
|
dashboard_Attendancedata: AttendanceData,
|
||||||
@ -23,38 +18,24 @@ const Attendance = () => {
|
|||||||
error: isError,
|
error: isError,
|
||||||
} = useDashboard_AttendanceData(selectedDate, selectedProjectId);
|
} = useDashboard_AttendanceData(selectedDate, selectedProjectId);
|
||||||
|
|
||||||
useEffect(() => {
|
// project name derived once
|
||||||
if (selectedProjectId === "all") {
|
const displayedProjectName = useMemo(() => {
|
||||||
setDisplayedProjectName("All Projects");
|
if (selectedProjectId === "all") return "All Projects";
|
||||||
} else if (projects) {
|
const found = projects?.find((p) => p.id === selectedProjectId);
|
||||||
const foundProject = projects.find((p) => p.id === selectedProjectId);
|
return found?.name || "Select Project";
|
||||||
setDisplayedProjectName(
|
|
||||||
foundProject ? foundProject.name : "Select Project"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
setDisplayedProjectName("Select Project");
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId);
|
|
||||||
}, [selectedProjectId, projects]);
|
}, [selectedProjectId, projects]);
|
||||||
|
|
||||||
const handleProjectSelect = (projectId) => {
|
|
||||||
setSelectedProjectId(projectId);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDateChange = (e) => {
|
|
||||||
setSelectedDate(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card h-100">
|
<div className="card h-100">
|
||||||
<div className="card-header mb-1 pb-0 ">
|
{/* Header */}
|
||||||
<div className="d-flex flex-wrap justify-content-between align-items-center mb-0 pb-0 ">
|
<div className="card-header mb-1 pb-0">
|
||||||
|
<div className="d-flex flex-wrap justify-content-between align-items-center">
|
||||||
<div className="card-title mb-0 text-start">
|
<div className="card-title mb-0 text-start">
|
||||||
<h5 className="mb-1">Attendance</h5>
|
<h5 className="mb-1">Attendance</h5>
|
||||||
<p className="card-subtitle">Daily Attendance Data</p>
|
<p className="card-subtitle">Daily Attendance Data</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Project Dropdown */}
|
||||||
<div className="btn-group">
|
<div className="btn-group">
|
||||||
<button
|
<button
|
||||||
className="btn btn-outline-primary btn-sm dropdown-toggle"
|
className="btn btn-outline-primary btn-sm dropdown-toggle"
|
||||||
@ -68,7 +49,7 @@ const Attendance = () => {
|
|||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
className="dropdown-item"
|
className="dropdown-item"
|
||||||
onClick={() => handleProjectSelect("all")}
|
onClick={() => setSelectedProjectId("all")}
|
||||||
>
|
>
|
||||||
All Projects
|
All Projects
|
||||||
</button>
|
</button>
|
||||||
@ -77,7 +58,7 @@ const Attendance = () => {
|
|||||||
<li key={project.id}>
|
<li key={project.id}>
|
||||||
<button
|
<button
|
||||||
className="dropdown-item"
|
className="dropdown-item"
|
||||||
onClick={() => handleProjectSelect(project.id)}
|
onClick={() => setSelectedProjectId(project.id)}
|
||||||
>
|
>
|
||||||
{project.name}
|
{project.name}
|
||||||
</button>
|
</button>
|
||||||
@ -88,52 +69,43 @@ const Attendance = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="d-flex flex-wrap justify-content-between align-items-center mb-0 mt-0 me-5 ms-5">
|
{/* Tabs + Date Picker */}
|
||||||
{/* Tabs */}
|
<div className="d-flex flex-wrap justify-content-between align-items-center me-5 ms-5">
|
||||||
<div>
|
<ul className="nav nav-tabs">
|
||||||
<ul className="nav nav-tabs " role="tablist">
|
<li className="nav-item">
|
||||||
<li className="nav-item">
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
className={`nav-link ${AttendanceData?.activeTab === "Summary" ? "active" : ""}`}
|
||||||
className={`nav-link ${
|
onClick={() => (AttendanceData.activeTab = "Summary")}
|
||||||
activeTab === "Summary" ? "active" : ""
|
>
|
||||||
}`}
|
Summary
|
||||||
onClick={() => setActiveTab("Summary")}
|
</button>
|
||||||
data-bs-toggle="tab"
|
</li>
|
||||||
>
|
<li className="nav-item">
|
||||||
Summary
|
<button
|
||||||
</button>
|
type="button"
|
||||||
</li>
|
className={`nav-link ${AttendanceData?.activeTab === "Details" ? "active" : ""}`}
|
||||||
<li className="nav-item">
|
onClick={() => (AttendanceData.activeTab = "Details")}
|
||||||
<button
|
>
|
||||||
type="button"
|
Details
|
||||||
className={`nav-link ${
|
</button>
|
||||||
activeTab === "Details" ? "active" : ""
|
</li>
|
||||||
}`}
|
</ul>
|
||||||
onClick={() => setActiveTab("Details")}
|
<div className="ps-6 mb-3">
|
||||||
data-bs-toggle="tab"
|
<input
|
||||||
>
|
type="date"
|
||||||
Details
|
className="form-control p-1"
|
||||||
</button>
|
style={{ width: "120px" }}
|
||||||
</li>
|
value={selectedDate}
|
||||||
</ul>
|
onChange={(e) => setSelectedDate(e.target.value)}
|
||||||
</div>
|
/>
|
||||||
{/* ✅ Date Picker Aligned Left with Padding */}
|
|
||||||
<div className="ps-6 mb-3 mt-0">
|
|
||||||
<div style={{ width: "120px" }}>
|
|
||||||
<input
|
|
||||||
type="date"
|
|
||||||
className="form-control p-1"
|
|
||||||
// style={{ fontSize: "1rem" }}
|
|
||||||
value={selectedDate}
|
|
||||||
onChange={handleDateChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Body */}
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{activeTab === "Summary" && (
|
{/* Summary */}
|
||||||
|
{AttendanceData?.activeTab === "Summary" && (
|
||||||
<div className="row justify-content-center">
|
<div className="row justify-content-center">
|
||||||
<div className="col-12 col-md-6 d-flex flex-column align-items-center text-center mb-4">
|
<div className="col-12 col-md-6 d-flex flex-column align-items-center text-center mb-4">
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@ -143,7 +115,7 @@ const Attendance = () => {
|
|||||||
) : (
|
) : (
|
||||||
AttendanceData && (
|
AttendanceData && (
|
||||||
<>
|
<>
|
||||||
<h5 className="fw-bold mb-0 text-center w-100">
|
<h5 className="fw-bold mb-0">
|
||||||
<i className="bx bx-task text-info"></i> Attendance
|
<i className="bx bx-task text-info"></i> Attendance
|
||||||
</h5>
|
</h5>
|
||||||
<h4 className="mb-0 fw-bold">
|
<h4 className="mb-0 fw-bold">
|
||||||
@ -164,11 +136,9 @@ const Attendance = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === "Details" && (
|
{/* Details */}
|
||||||
<div
|
{AttendanceData?.activeTab === "Details" && (
|
||||||
className="table-responsive"
|
<div className="table-responsive" style={{ maxHeight: "300px" }}>
|
||||||
style={{ maxHeight: "300px", overflowY: "auto" }}
|
|
||||||
>
|
|
||||||
<table className="table table-hover mb-0 text-start">
|
<table className="table table-hover mb-0 text-start">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -178,32 +148,17 @@ const Attendance = () => {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{AttendanceData?.attendanceTable &&
|
{AttendanceData?.attendanceTable?.length ? (
|
||||||
AttendanceData.attendanceTable.length > 0 ? (
|
AttendanceData.attendanceTable.map((r, i) => (
|
||||||
AttendanceData.attendanceTable.map((record, index) => (
|
<tr key={i}>
|
||||||
<tr key={index}>
|
<td>{r.firstName} {r.lastName}</td>
|
||||||
<td>
|
<td>{r.inTime ? new Date(r.inTime).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "-"}</td>
|
||||||
{record.firstName} {record.lastName}
|
<td>{r.outTime ? new Date(r.outTime).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "-"}</td>
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{new Date(record.inTime).toLocaleTimeString([], {
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
})}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{new Date(record.outTime).toLocaleTimeString([], {
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
})}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="3" className="text-center">
|
<td colSpan="3" className="text-center">No attendance data available</td>
|
||||||
No attendance data available
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -98,42 +98,44 @@ const AttendanceOverview = () => {
|
|||||||
colors: roles.map((_, i) => flatColors[i % flatColors.length]),
|
colors: roles.map((_, i) => flatColors[i % flatColors.length]),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="bg-white p-4 rounded shadow d-flex flex-column">
|
||||||
className="bg-white p-4 rounded shadow d-flex flex-column"
|
{/* Header */}
|
||||||
>
|
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||||
{/* Header */}
|
<div className="card-title mb-0 text-start">
|
||||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
<h5 className="mb-1 fw-bold">Attendance Overview</h5>
|
||||||
<div className="card-title mb-0 text-start">
|
<p className="card-subtitle">Role-wise present count</p>
|
||||||
<h5 className="mb-1">Attendance Overview</h5>
|
</div>
|
||||||
<p className="card-subtitle">Role-wise present count</p>
|
<div className="d-flex gap-2">
|
||||||
</div>
|
<select
|
||||||
<div className="d-flex gap-2">
|
className="form-select form-select-sm"
|
||||||
<select
|
value={dayRange}
|
||||||
className="form-select form-select-sm"
|
onChange={(e) => setDayRange(Number(e.target.value))}
|
||||||
value={dayRange}
|
>
|
||||||
onChange={(e) => setDayRange(Number(e.target.value))}
|
<option value={7}>Last 7 Days</option>
|
||||||
>
|
<option value={15}>Last 15 Days</option>
|
||||||
<option value={7}>Last 7 Days</option>
|
<option value={30}>Last 30 Days</option>
|
||||||
<option value={15}>Last 15 Days</option>
|
</select>
|
||||||
<option value={30}>Last 30 Days</option>
|
<button
|
||||||
</select>
|
className={`btn btn-sm p-1 ${
|
||||||
<button
|
view === "chart" ? "btn-primary" : "btn-outline-primary"
|
||||||
className={`btn btn-sm ${view === "chart" ? "btn-primary" : "btn-outline-primary"}`}
|
}`}
|
||||||
onClick={() => setView("chart")}
|
onClick={() => setView("chart")}
|
||||||
title="Chart View"
|
title="Chart View"
|
||||||
>
|
>
|
||||||
<i className="bx bx-bar-chart-alt-2"></i>
|
<i className="bx bx-bar-chart-alt-2"></i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`btn btn-sm ${view === "table" ? "btn-primary" : "btn-outline-primary"}`}
|
className={`btn btn-sm p-1 ${
|
||||||
onClick={() => setView("table")}
|
view === "table" ? "btn-primary" : "btn-outline-primary"
|
||||||
title="Table View"
|
}`}
|
||||||
>
|
onClick={() => setView("table")}
|
||||||
<i className="bx bx-task text-success"></i>
|
title="Table View"
|
||||||
</button>
|
>
|
||||||
</div>
|
<i className="bx bx-list-ul fs-5"></i>
|
||||||
</div>
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="flex-grow-1 d-flex align-items-center justify-content-center">
|
<div className="flex-grow-1 d-flex align-items-center justify-content-center">
|
||||||
|
@ -19,7 +19,7 @@ const ProjectCompletionChart = () => {
|
|||||||
<div className="card h-100">
|
<div className="card h-100">
|
||||||
<div className="card-header d-flex align-items-start justify-content-between">
|
<div className="card-header d-flex align-items-start justify-content-between">
|
||||||
<div className="card-title mb-0 text-start">
|
<div className="card-title mb-0 text-start">
|
||||||
<h5 className="mb-1">Projects</h5>
|
<h5 className="mb-1 fw-bold ">Projects</h5>
|
||||||
<p className="card-subtitle">Projects Completion Status</p>
|
<p className="card-subtitle">Projects Completion Status</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,7 +90,7 @@ const ProjectProgressChart = ({
|
|||||||
<div className="d-flex flex-wrap justify-content-between align-items-start mb-2">
|
<div className="d-flex flex-wrap justify-content-between align-items-start mb-2">
|
||||||
{/* Left: Title */}
|
{/* Left: Title */}
|
||||||
<div className="card-title text-start">
|
<div className="card-title text-start">
|
||||||
<h5 className="mb-1">Project Progress</h5>
|
<h5 className="mb-1 fw-bold">Project Progress</h5>
|
||||||
<p className="card-subtitle">Progress Overview by Project</p>
|
<p className="card-subtitle">Progress Overview by Project</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,33 +1,28 @@
|
|||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useDashboardProjectsCardData } from "../../hooks/useDashboard_Data";
|
import { useDashboardProjectsCardData } from "../../hooks/useDashboard_Data";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import GlobalRepository from "../../repositories/GlobalRepository";
|
|
||||||
|
|
||||||
const Projects = () => {
|
const Projects = () => {
|
||||||
const { projectsCardData } = useDashboardProjectsCardData();
|
const {
|
||||||
const [projectData, setProjectsData] = useState(projectsCardData);
|
data: projectsCardData,
|
||||||
|
isLoading,
|
||||||
|
isError,
|
||||||
|
error,
|
||||||
|
refetch,
|
||||||
|
} = useDashboardProjectsCardData();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setProjectsData(projectsCardData);
|
// When "project" event happens, just refetch
|
||||||
}, [projectsCardData]);
|
const handler = () => {
|
||||||
|
refetch();
|
||||||
|
};
|
||||||
|
|
||||||
const handler = useCallback(
|
|
||||||
async (msg) => {
|
|
||||||
try {
|
|
||||||
const response =
|
|
||||||
await GlobalRepository.getDashboardProjectsCardData();
|
|
||||||
setProjectsData(response.data);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[GlobalRepository]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
eventBus.on("project", handler);
|
eventBus.on("project", handler);
|
||||||
return () => eventBus.off("project", handler);
|
return () => eventBus.off("project", handler);
|
||||||
}, [handler]);
|
}, [refetch]);
|
||||||
|
|
||||||
|
const totalProjects = projectsCardData?.totalProjects ?? 0;
|
||||||
|
const ongoingProjects = projectsCardData?.ongoingProjects ?? 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card p-3 h-100 text-center d-flex justify-content-between">
|
<div className="card p-3 h-100 text-center d-flex justify-content-between">
|
||||||
@ -37,20 +32,29 @@ const Projects = () => {
|
|||||||
Projects
|
Projects
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex justify-content-around align-items-start mt-n2">
|
|
||||||
<div>
|
{isLoading ? (
|
||||||
<h4 className="mb-0 fw-bold">
|
<div className="d-flex justify-content-center align-items-center flex-grow-1">
|
||||||
{projectData.totalProjects?.toLocaleString()}
|
<div className="spinner-border text-primary" role="status">
|
||||||
</h4>
|
<span className="visually-hidden">Loading...</span>
|
||||||
<small className="text-muted">Total</small>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
) : isError ? (
|
||||||
<h4 className="mb-0 fw-bold">
|
<div className="text-danger flex-grow-1 d-flex justify-content-center align-items-center">
|
||||||
{projectData.ongoingProjects?.toLocaleString()}
|
{error?.message || "Error loading data"}
|
||||||
</h4>
|
|
||||||
<small className="text-muted">Ongoing</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
) : (
|
||||||
|
<div className="d-flex justify-content-around align-items-start mt-n2">
|
||||||
|
<div>
|
||||||
|
<h4 className="mb-0 fw-bold">{totalProjects.toLocaleString()}</h4>
|
||||||
|
<small className="text-muted">Total</small>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="mb-0 fw-bold">{ongoingProjects.toLocaleString()}</h4>
|
||||||
|
<small className="text-muted">Ongoing</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|