Compare commits

..

207 Commits

Author SHA1 Message Date
victorAnumudu 07a443d082 file upload size validation initiated 2023-08-09 20:28:19 +01:00
victorAnumudu 59a370d763 enforces user upload supported file before proceeding to upload 2023-08-09 19:34:35 +01:00
victorAnumudu 68e709f34b list of supported uploads add 2023-08-09 18:19:34 +01:00
victorAnumudu b1bb730c7d made file name in upload not to have spaces 2023-08-09 17:01:38 +01:00
ameye 20a86f4802 Merge branch 'upload-action' of WrenchBoard/Users-Wrench into master 2023-08-09 14:28:05 +00:00
victorAnumudu 2d918517f8 upload action implemented 2023-08-09 12:52:46 +01:00
tolik a0c0cbdc98 Merge branch 'master' of ssh://gitlab.chiefsoft.net:10222/WrenchBoard/Users-Wrench 2023-08-09 10:39:47 +08:00
tolik ed309007e5 Implemented Facebook login 2023-08-09 10:39:37 +08:00
ameye 594c072806 Merge branch 'add-item-btn-moved' of WrenchBoard/Users-Wrench into master 2023-08-09 01:13:02 +00:00
victorAnumudu 4b9289cb8e bug fix 2023-08-08 22:15:09 +01:00
victorAnumudu 5b39e75119 Add item button moved down 2023-08-08 22:06:44 +01:00
CHIEFSOFT\ameye e61b2c8f43 my files page 2023-08-08 08:55:12 -04:00
CHIEFSOFT\ameye 4c6952c4b3 Page format 2023-08-08 08:23:48 -04:00
CHIEFSOFT\ameye 6a5cebed5b Upload new item 2023-08-08 08:16:32 -04:00
CHIEFSOFT\ameye 663e3e8bb7 fix text 2023-08-08 08:15:26 -04:00
CHIEFSOFT\ameye aaa5b9e8ff Resource Upload My Files 2023-08-08 06:38:03 -04:00
ameye 90ec033b34 Merge branch 'wallet-styles' of WrenchBoard/Users-Wrench into master 2023-08-07 16:22:27 +00:00
Ebube c3c359cfc8 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into wallet-styles 2023-08-07 16:27:26 +01:00
Ebube 68b4031752 added online_name 2023-08-07 16:26:25 +01:00
ameye 8a2559571f Merge branch 'wallet-styles' of WrenchBoard/Users-Wrench into master 2023-08-07 08:50:16 +00:00
ameye ccae5000ee Merge branch 'reset-pwd-validation' of WrenchBoard/Users-Wrench into master 2023-08-07 08:50:12 +00:00
Ebube 5f01cb14f9 updated payload 2023-08-07 08:10:51 +01:00
Ebube 9f62345a2e Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into wallet-styles 2023-08-06 23:46:26 +01:00
Ebube b9096117bc updateprofile payload updated 2023-08-06 23:46:03 +01:00
victorAnumudu f70659901c valid pwd text added 2023-08-06 21:15:18 +01:00
tolik 451e4624b1 Merge branch 'master' of ssh://gitlab.chiefsoft.net:10222/WrenchBoard/Users-Wrench 2023-08-06 10:14:17 +08:00
tolik 1557ba1040 Fix crash 2023-08-06 10:13:15 +08:00
ameye 7133ad8de3 Merge branch 'reset-pwd-icon' of WrenchBoard/Users-Wrench into master 2023-08-05 16:33:25 +00:00
victorAnumudu 9fd8944987 pwd validation msg changed 2023-08-05 16:52:20 +01:00
victorAnumudu 874276dcba reset pwd icons added 2023-08-05 16:35:23 +01:00
ameye be1454f1b8 Merge branch 'reset-pwd-second-phase' of WrenchBoard/Users-Wrench into master 2023-08-05 14:16:16 +00:00
victorAnumudu 6a34ca6c18 reser pwd second phase implemented 2023-08-05 15:12:46 +01:00
ameye fc09771b8d Merge branch 'password-reset-first-stage' of WrenchBoard/Users-Wrench into master 2023-08-05 07:16:30 +00:00
victorAnumudu cab5ed0ece password reset first phase done 2023-08-05 05:41:46 +01:00
ameye 8d3dca96b4 Merge branch 'logo-sizing-and-alignment' of WrenchBoard/Users-Wrench into master 2023-08-04 14:26:23 +00:00
ameye e71a25630d Merge branch 'wallet-styles' of WrenchBoard/Users-Wrench into master 2023-08-04 14:26:14 +00:00
Ebube cf79a15837 size in dollar acc 2023-08-04 13:53:49 +01:00
victorAnumudu 042e8c2c17 site logo size reduced and aligned 2023-08-04 13:50:59 +01:00
Ebube 46d286e8f3 size again 2023-08-04 13:49:11 +01:00
Ebube c2bfcc81ea adjusted size 2023-08-04 13:46:43 +01:00
Ebube 654ed3741c added cancel btn style in withdraw 2023-08-04 13:41:53 +01:00
Ebube 6cccd1c372 changed font-color of naira withdraw cancel btn 2023-08-04 13:39:09 +01:00
Ebube 1e6be76449 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into wallet-styles 2023-08-04 13:29:39 +01:00
Ebube 476ca04f5f Added profile img 2023-08-04 13:29:14 +01:00
ameye ce41db474d Merge branch 'wallet-styles' of WrenchBoard/Users-Wrench into master 2023-08-04 02:32:07 +00:00
Ebube 7ace7e5b5d Added btn styles the of the credit and withdraw popup 2023-08-04 03:18:51 +01:00
ameye 51e829f7b4 Merge branch 'wallet-styles' of WrenchBoard/Users-Wrench into master 2023-08-01 19:53:51 +00:00
Ebube 173b2adc66 css fixes for uniform btn 2023-08-01 19:50:52 +01:00
ameye 31cb7a521d Merge branch 'pending-job-refresh' of WrenchBoard/Users-Wrench into master 2023-08-01 18:40:10 +00:00
ameye ad4f68b252 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-08-01 18:39:53 +00:00
victorAnumudu 10abf35d4f refreshes pending Job when expiry date is extended 2023-08-01 18:42:18 +01:00
Ebube ce767086fd BUG - Flutter wave key 2023-08-01 18:36:47 +01:00
ameye 0f44616767 Merge branch 'request-message-changed' of WrenchBoard/Users-Wrench into master 2023-08-01 15:18:07 +00:00
victorAnumudu bce00b5c0e request message changed 2023-08-01 16:10:56 +01:00
ameye 312cd54f87 Merge branch 'pending-wrong-assign' of WrenchBoard/Users-Wrench into master 2023-08-01 14:47:44 +00:00
victorAnumudu a0c3437eae pending assign value changed 2023-08-01 15:42:28 +01:00
ameye 711226f913 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-08-01 11:07:16 +00:00
Ebube f46c6232b0 updated error scenario for the modal header 2023-08-01 12:05:27 +01:00
Ebube 172f0ccbce cleanup 2 2023-08-01 11:46:33 +01:00
Ebube a2047cc2de clean up 2023-08-01 11:41:57 +01:00
Ebube 6ea52e6481 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-08-01 11:38:26 +01:00
Ebube a7bbcfdc1b complete popup fixed 2023-08-01 11:37:56 +01:00
ameye ff28be3e70 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-08-01 09:24:46 +00:00
Ebube e91b4a4424 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-31 23:58:36 +01:00
Ebube 9960033b72 debounced success payment and and fixed credit refresh 2023-07-31 23:55:23 +01:00
ameye ef135f1a9b Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-31 17:56:15 +00:00
Ebube 1df6380c4a Correct Drop Down Style for naira withdrawal 2023-07-31 15:09:12 +01:00
Ebube fc8cf551e5 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-31 14:47:15 +01:00
Ebube b1feb0438a still testing 2023-07-31 14:46:29 +01:00
ameye a89649f774 Merge branch 'amount-alignment' of WrenchBoard/Users-Wrench into master 2023-07-31 13:36:56 +00:00
victorAnumudu b96e8a3ed5 Merged master into amount-alignment 2023-07-31 14:23:57 +01:00
victorAnumudu f3226a6cfc amount alignment changed 2023-07-31 14:22:55 +01:00
ameye ff4c503100 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-31 12:04:22 +00:00
Ebube f543a2d893 testing topupResult 2023-07-31 13:02:31 +01:00
ameye 41badd52be Merge branch 'list-alignment-fix' of WrenchBoard/Users-Wrench into master 2023-07-30 16:29:28 +00:00
victorAnumudu eeddd4e0a5 list alignment fixed 2023-07-30 06:10:44 +01:00
tokslaw ee4d136834 wrenchboard-logo-text + image added 2023-07-29 19:04:08 -04:00
tokslaw 283efa42b3 social comment added 2023-07-29 12:16:57 -04:00
tokslaw 5cbab4933c Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench 2023-07-29 12:13:14 -04:00
ameye 4de2181c18 Merge branch 'family-login-no-captcha' of WrenchBoard/Users-Wrench into master 2023-07-29 15:45:31 +00:00
ameye c8f0161a29 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-29 15:45:26 +00:00
tokslaw 60222b6d88 text error correction 2023-07-29 11:11:23 -04:00
victorAnumudu 9ea3963239 family login captcha removed 2023-07-29 12:25:25 +01:00
Ebube a87592623b Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-29 07:01:22 +01:00
Ebube bfcf53f763 Not selected should appear not selected 2023-07-29 07:00:50 +01:00
CHIEFSOFT\ameye df4489c6f2 removed start top up 2023-07-29 00:09:59 -04:00
CHIEFSOFT\ameye 37185812b4 Result added 2023-07-28 16:55:45 -04:00
ameye eb3e78244d Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-28 13:25:00 +00:00
Ebube b302d7ba57 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-28 14:22:18 +01:00
ameye d6c16169d9 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-28 13:18:31 +00:00
Ebube 57129da0bd changed tx_ref number 2023-07-28 13:58:10 +01:00
Ebube 9eaf7123d4 reverse 2023-07-28 13:56:23 +01:00
Ebube 096da29149 Changed tx_ref no 2023-07-28 13:51:48 +01:00
CHIEFSOFT\ameye c8331c51cf removed debugger 2023-07-28 08:20:04 -04:00
tokslaw 3b7618702b env text-spell error 2023-07-27 17:04:57 -04:00
Ebube 84968b4435 balance refresh bug for withdraw 2023-07-27 16:28:21 +01:00
Ebube 98f11a3d80 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into Family-Tabs-Size-Fix 2023-07-27 16:18:29 +01:00
CHIEFSOFT\ameye 98d734e869 Post data 2023-07-27 11:17:15 -04:00
Ebube 47004fec8c Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into Family-Tabs-Size-Fix 2023-07-27 16:05:17 +01:00
CHIEFSOFT\ameye 48ce89489e console log 2023-07-27 11:04:01 -04:00
CHIEFSOFT\ameye 1ce05a3be3 add fund page 2023-07-27 11:01:22 -04:00
Ebube 28ab1116e9 Added Credit Limit & Pending Jobs Bug & removed reload for credit 2023-07-27 11:34:27 +01:00
ameye 994060d929 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-26 15:57:24 +00:00
Ebube a5c62564b7 Fixed tasks banner breaking 2023-07-26 16:54:31 +01:00
Ebube 22e61d2b41 Enforced send limit 2023-07-26 15:49:04 +01:00
ameye 6ab5eae0c0 Merge branch 'email-input-size' of WrenchBoard/Users-Wrench into master 2023-07-26 14:26:05 +00:00
victorAnumudu 3fbb47ee82 email input character size increased 2023-07-26 14:39:16 +01:00
ameye 3327b2b0df Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-25 20:13:46 +00:00
Ebube ec204d0389 . 2023-07-25 20:50:56 +01:00
Ebube cb1259d2c8 Added loading height 2023-07-25 20:46:46 +01:00
Ebube 706cf141e7 Add Result Page 2023-07-25 20:26:33 +01:00
ameye 2229ebb9a0 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-25 11:17:32 +00:00
Ebube 05022c29b2 Remove the cause for the login error 2023-07-25 12:12:49 +01:00
ameye 9718cfc574 Merge branch 'job-listing-bug' of WrenchBoard/Users-Wrench into master 2023-07-25 10:39:59 +00:00
ameye aef082ac60 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-25 10:39:45 +00:00
victorAnumudu 754340fcba Merged master into job-listing-bug 2023-07-25 10:14:29 +01:00
Ebube 16afd4f90c Family Tab Sizes Fixed 2023-07-25 08:53:04 +01:00
ameye b69e2ff53b Merge branch 'blog-page' of WrenchBoard/Users-Wrench into master 2023-07-24 19:29:08 +00:00
victorAnumudu 4ac799f8c9 links to blog page added 2023-07-24 20:06:25 +01:00
ameye c93d3b61a6 Merge branch 'resource-ask-question' of WrenchBoard/Users-Wrench into master 2023-07-24 16:31:16 +00:00
ameye 4fb6dbf30f Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-24 16:31:10 +00:00
victorAnumudu 11dc8fc659 resource ask question implemented 2023-07-24 15:34:29 +01:00
Ebube 4876ba80c1 Changed name to back 2023-07-24 15:07:22 +01:00
Ebube 71f799d157 Checked Errors in Wallet Page and made some tiny fixes 2023-07-24 15:01:03 +01:00
ameye 77c538ca79 Merge branch 'balance-refresh' of WrenchBoard/Users-Wrench into master 2023-07-24 11:07:41 +00:00
victorAnumudu 6b473b5dc6 wallet refresh 2023-07-24 11:58:09 +01:00
ameye 6aa11793a5 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-24 10:14:18 +00:00
victorAnumudu e098eb4626 job listing pagination bug fixed 2023-07-24 07:46:41 +01:00
Ebube 4f8edc3998 Improved solution for the credit refresh bug 2023-07-24 06:28:48 +01:00
Ebube 7dd805b804 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-24 06:15:43 +01:00
Ebube 2aa1219ea9 updated payload for new account 2023-07-24 06:15:22 +01:00
ameye c1a17949f7 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-23 23:40:59 +00:00
Ebube 24302c7435 Added New Login 2023-07-23 23:59:20 +01:00
CHIEFSOFT\ameye 27f4fda129 Added images 2023-07-23 07:47:54 -04:00
ameye 7ddef6d52d Merge branch 'notification-menu-close' of WrenchBoard/Users-Wrench into master 2023-07-23 10:20:40 +00:00
victorAnumudu 187ac61396 logged information removed 2023-07-23 07:18:56 +01:00
victorAnumudu 31297efb5b closes notification menu when see all notifications is clicked 2023-07-23 07:15:25 +01:00
ameye f8d6475ff8 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-22 23:21:04 +00:00
Ebube 22a45ac15e Added some fixes 2023-07-23 00:12:26 +01:00
ameye 0489be5e69 Merge branch 'notifications' of WrenchBoard/Users-Wrench into master 2023-07-22 22:44:03 +00:00
victorAnumudu 0f8ef167bb Merge master into notifications 2023-07-22 23:15:30 +01:00
victorAnumudu aa6e3f4b94 notification bug fixed 2023-07-22 23:12:29 +01:00
ameye 68beda891b Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-22 21:20:55 +00:00
Ebube 61bef08a24 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-22 20:53:04 +01:00
Ebube a6409a037f ConfirmNairaWithdraw layout, payload adjustment and other style fixes 2023-07-22 20:52:39 +01:00
ameye f3ab8241a3 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-22 11:27:18 +00:00
Ebube f3defdca85 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-22 12:23:41 +01:00
Ebube f3b1a42819 Bug Fixes..Notification load, Withdraw css fix 2023-07-22 12:23:14 +01:00
ameye e65d538709 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-21 10:48:59 +00:00
Ebube 98aef302de Updated Layout for Withdraw Pop UP 2023-07-21 11:45:42 +01:00
ameye b3bbf11f0a Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-20 19:43:23 +00:00
Ebube 973517215f Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-20 20:25:32 +01:00
Ebube a3782e2dfc Added Notification and Started Wallet Withdraw 2023-07-20 20:24:54 +01:00
CHIEFSOFT\ameye 25830d5bf3 Resolve conflict 2023-07-20 06:25:51 -04:00
CHIEFSOFT\ameye 1615a7ac8a Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench
# Conflicts:
#	src/middleware/AuthRoute.jsx
2023-07-20 06:24:49 -04:00
CHIEFSOFT\ameye 232211a297 home recent 2023-07-20 06:18:56 -04:00
ameye eda3d76d4c Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-20 10:17:46 +00:00
Ebube 87f1a1e3e8 Notification for header 2023-07-20 10:22:10 +01:00
ameye 5257f89acb Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-18 20:20:31 +00:00
Ebube d4cf7419bf . 2023-07-18 20:28:30 +01:00
Ebube 1ffb732bfa . 2023-07-18 19:47:23 +01:00
Ebube 9007463f6d Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-18 19:00:21 +01:00
CHIEFSOFT\ameye a4b6b9e493 notification icons 2023-07-18 11:00:40 -04:00
CHIEFSOFT\ameye ccf820da7c bank icon 2023-07-18 07:52:58 -04:00
Ebube 7c51896bbf Wallet update 2023-07-18 10:38:58 +01:00
ameye aa80bab930 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-17 23:30:44 +00:00
Ebube 1704fc60b4 removed hidden abilities for cvv 2023-07-18 00:20:15 +01:00
ameye c3e6c90c49 Merge branch 'collapse-icon' of WrenchBoard/Users-Wrench into master 2023-07-17 19:57:36 +00:00
victorAnumudu 1a65b1daa3 collapse-icon fixed, family icon fixed 2023-07-17 19:21:43 +01:00
ameye ba2c009896 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-17 17:03:29 +00:00
Ebube bc2b71ecda Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-17 17:47:31 +01:00
Ebube 1d315018a4 Added error msg for card and updated password text display 2023-07-17 17:47:03 +01:00
CHIEFSOFT\ameye 56f8b75525 wrong end point on production - Ebubes error 2023-07-17 12:12:14 -04:00
Ebube 59531df377 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-17 17:03:39 +01:00
Ebube 06a7386211 another fix 2023-07-17 17:00:59 +01:00
Ebube 4bb3a11261 correction to .env production 2023-07-17 16:22:25 +01:00
Ebube f308eeca8d Corrections made on AddFund and text variable for Header 2023-07-17 16:20:57 +01:00
ameye 8e562ed1a5 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-17 15:07:58 +00:00
Ebube 23dd7571a3 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-17 15:52:53 +01:00
Ebube 8530b2d1a0 Digits Fixed and SignOut text variable 2023-07-17 15:52:28 +01:00
ameye acdbddbc79 Merge branch 'family-icon' of WrenchBoard/Users-Wrench into master 2023-07-17 14:48:17 +00:00
victorAnumudu 15fc5f4f14 family icon added 2023-07-17 15:31:39 +01:00
ameye 2ba3b01646 Merge branch 'resource-question-page' of WrenchBoard/Users-Wrench into master 2023-07-17 12:50:09 +00:00
ameye 4e960a2f53 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-17 12:49:59 +00:00
victorAnumudu ab700edcf2 resources question page added 2023-07-17 13:42:21 +01:00
Ebube 42e80c7a11 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-17 12:59:32 +01:00
Ebube d4472a881a Fixed digits 2023-07-17 12:59:05 +01:00
Ebube 5d12ab4f62 Made a few changes 2023-07-17 11:48:03 +01:00
ameye 8b3c586456 Merge branch 'withdrwal-popup' of WrenchBoard/Users-Wrench into master 2023-07-17 10:38:48 +00:00
ameye e456b55e16 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-17 10:38:41 +00:00
Ebube 89c5936212 Some fixes 2023-07-17 11:29:50 +01:00
victorAnumudu 7bedf76945 made confirm withdrawal a pop up 2023-07-17 11:07:11 +01:00
Ebube 54bf020c55 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-17 11:04:59 +01:00
Ebube 78145eee77 Paying using new card 2023-07-17 11:04:31 +01:00
victorAnumudu d75b6ee26c made withdrawal a pop up 2023-07-17 11:03:27 +01:00
ameye bf5c9d4671 Merge branch 'profile-bug' of WrenchBoard/Users-Wrench into master 2023-07-17 08:06:43 +00:00
victorAnumudu d2db38ba21 profile bug fixed 2023-07-17 02:01:37 +01:00
ameye eecbca6b0e Merge branch 'withdraw-page' of WrenchBoard/Users-Wrench into master 2023-07-17 00:33:24 +00:00
victorAnumudu dd1430a350 confirm naira withdrawal added 2023-07-17 01:22:12 +01:00
victorAnumudu 0eca0c52ce withdraw page added 2023-07-17 01:15:16 +01:00
ameye c2c7ad7bb4 Merge branch 'family-start-task-layout' of WrenchBoard/Users-Wrench into master 2023-07-16 23:09:30 +00:00
victorAnumudu 98ccbce4c0 family start task layout changed 2023-07-16 23:38:25 +01:00
ameye 6484640e1a Merge branch 'assign-task-layout' of WrenchBoard/Users-Wrench into master 2023-07-16 22:28:28 +00:00
victorAnumudu ba3c4e1918 assign task layout btns fixed 2023-07-16 22:41:58 +01:00
ameye fa4fe35bdf Merge branch 'assign-task-bug-fixed' of WrenchBoard/Users-Wrench into master 2023-07-16 21:31:23 +00:00
Ebube fb7913c563 Another fix 2023-07-16 01:36:27 +01:00
Ebube feb301c3c0 . 2023-07-16 01:08:37 +01:00
120 changed files with 4898 additions and 3415 deletions
+3 -1
View File
@@ -46,7 +46,7 @@ REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
#developenet Account
#development Account Social
REACT_APP_FACEBOOK_CLIENT_ID=677857427521030
REACT_APP_FACEBOOK_CLIENT_SECRET=4801375f22072d8a75f64483fdd89829
@@ -68,6 +68,8 @@ REACT_APP_APPLE_REDIRECT_URL='http://localhost:9082/login/auth/apple'
REACT_APP_MAX_FILE_SIZE=1000000
REACT_APP_TOTAL_NUM_FILE=4
REACT_APP_LOGOUT_TEXT="Sign Out"
#apigate.lotus.g1.wrenchboard.com:76.209.103.227
#apigate.orion.g1.wrenchboard.com:76.209.103.227
+3 -1
View File
@@ -41,4 +41,6 @@ REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https:
REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
REACT_APP_MAX_FILE_SIZE=1000000
REACT_APP_TOTAL_NUM_FILE=4
REACT_APP_TOTAL_NUM_FILE=4
REACT_APP_LOGOUT_TEXT="Sign Out"
+3 -1
View File
@@ -48,4 +48,6 @@ REACT_APP_FACEBOOK_REDIRECT_URL="https://users.wrenchboard.com/login/auth/flogin
DISABLE_ESLINT_PLUGIN=true
REACT_APP_MAX_FILE_SIZE=1000000
REACT_APP_TOTAL_NUM_FILE=4
REACT_APP_TOTAL_NUM_FILE=4
REACT_APP_LOGOUT_TEXT="Sign Out"
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+1
View File
@@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+4 -1
View File
@@ -56,6 +56,8 @@ export default function Routers() {
<Routes>
{/* guest routes */}
<Route exact path="/login" element={<LoginPage />} />
<Route exact path="/eoffer" element={<LoginPage />} />
<Route exact path="/signup" element={<SignupPage />} />
<Route exact path="/login/auth" element={<AuthRedirect />} />
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
@@ -119,7 +121,8 @@ export default function Routers() {
<Route exact path="/sell" element={<SellPage />} />
<Route exact path="/saved" element={<SavedPage />} />
<Route exact path="/history" element={<HistoryPage />} />
<Route exact path="/upload-product" element={<UploadProductPage />} />
{/*<Route exact path="/upload-product" element={<UploadProductPage />} />*/}
<Route exact path="/my-uploads" element={<UploadProductPage />} />
<Route exact path="/profile" element={<AuthProfilePage />} />
<Route exact path="/user-profile" element={<UserProfilePage />} />
<Route exact path="/settings" element={<SettingsPage />} />
Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792" id="Bank"><path d="m896 78.526 896 358.4v119.466h-119.467q0 24.267-19.133 42-19.133 17.734-45.267 17.734H183.867q-26.134 0-45.267-17.734-19.133-17.733-19.133-42H0V436.926ZM238.933 675.859h238.934v716.8h119.466v-716.8h238.934v716.8h119.466v-716.8h238.934v716.8h119.466v-716.8h238.934v716.8h55.066q26.134 0 45.267 17.733 19.133 17.734 19.133 42v59.734H119.467v-59.734q0-24.266 19.133-42 19.133-17.733 45.267-17.733h55.066v-716.8zm1488.667 896q26.133 0 45.267 17.733 19.133 17.734 19.133 42v119.467H0v-119.467q0-24.266 19.133-42 19.134-17.733 45.267-17.733h1663.2z" fill="#4687ba" class="color000000 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 684 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" id="error"><path fill="#ff1d25" d="M29.75,25.73,18.68,3.59a3,3,0,0,0-4-1.33,3.05,3.05,0,0,0-1.33,1.33L2.25,25.73a3,3,0,0,0,2.68,4.34H27.07a3,3,0,0,0,3-3A2.88,2.88,0,0,0,29.75,25.73ZM16,25.38a.94.94,0,1,1,.94-.94A.94.94,0,0,1,16,25.38Zm.94-4.69a.94.94,0,1,1-1.88,0V11.31a.94.94,0,1,1,1.88,0Z"></path></svg>

After

Width:  |  Height:  |  Size: 365 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" id="success"><path fill="#80af52" d="M256 26c127.03 0 230 102.97 230 230S383.03 486 256 486 26 383.03 26 256 128.97 26 256 26z"></path><path fill="#fff" d="M215.999 386a9.998 9.998 0 0 1-7.525-3.415l-70-80c-3.637-4.156-3.215-10.474.941-14.11s10.475-3.217 14.111.94l60.961 69.67 142.938-238.23c2.842-4.736 8.983-6.273 13.72-3.43 4.736 2.841 6.271 8.984 3.431 13.72l-150 250a9.998 9.998 0 0 1-8.577 4.855z"></path></svg>

After

Width:  |  Height:  |  Size: 483 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 128 128" viewBox="0 0 128 128" id="Alert"><path fill="#f34093" d="M122.9,100.2L74.3,15.9c-4.6-7.9-16-7.9-20.6,0L5.1,100.2C0.5,108.1,6.2,118,15.4,118h97.3
C121.8,118,127.5,108.1,122.9,100.2z M63.9,101c-3.5-0.1-6.7-3.3-6.6-6.8c0.1-3.5,3.3-6.7,6.8-6.6c3.5,0.1,6.7,3.3,6.6,6.8
C70.6,98,67.4,101.1,63.9,101z M71.3,51.8c-0.7,7.8-1.5,15.6-2.3,23.4c-0.5,4.4-3.2,6.1-7.3,4.5c-1-0.4-2-2-2.2-3.2
C58.6,70,58,63.4,57.3,56.8c-0.3-2.8-0.5-5.6-0.8-8.5c-0.4-3.3,0.6-4.5,4-4.5c1.1,0,2.3,0,3.4,0C72,43.8,72,43.8,71.3,51.8z" class="color343433 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 621 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="Messages"><path fill="#4687ba" d="m447.372 413.112-17.544-52.629c-1-3.002-.674-6.23.775-9.043 13.184-25.615 18.629-55.858 12.925-87.736-8.746-48.868-44.53-89.475-90.943-105.048 11.976 28.924 15.628 61.084 9.645 92.984-12.155 64.837-64.074 116.246-129.191 127.924-8.429 1.512-16.945 2.248-25.396 2.463 19.776 21.336 46.173 36.503 75.619 41.784 31.682 5.682 61.784.393 87.322-12.594 2.802-1.425 6.007-1.742 8.99-.748l52.83 17.61c9.251 3.084 18.052-5.716 14.968-14.967z" class="color173042 svgShape"></path><path fill="#4687ba" d="M177.161 85.744C122.283 95.941 78.306 140.526 68.472 195.47c-5.704 31.878-.259 62.121 12.925 87.736 1.449 2.813 1.775 6.041.776 9.043l-17.545 52.629c-3.083 9.251 5.717 18.051 14.968 14.968l52.83-17.61c2.984-.994 6.19-.677 8.991.748 25.537 12.987 55.638 18.276 87.321 12.594 54.809-9.829 99.281-53.698 109.541-108.428 18.078-96.414-64.733-179.316-161.118-161.406zm34.938 177.536h-68.234c-6.73 0-12.185-5.454-12.185-12.185 0-6.73 5.455-12.185 12.185-12.185h68.234c6.731 0 12.185 5.455 12.185 12.185 0 6.731-5.454 12.185-12.185 12.185zm48.739-48.739H143.864c-6.73 0-12.185-5.454-12.185-12.185 0-6.73 5.455-12.185 12.185-12.185h116.973c6.731 0 12.185 5.455 12.185 12.185.001 6.731-5.453 12.185-12.184 12.185z" class="color173042 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="phone" x="0" y="0" version="1.1" viewBox="0 0 29 29" xml:space="preserve"><path d="M5.661 23.339c4.882 4.882 12.796 4.882 17.678 0 4.882-4.882 4.882-12.796 0-17.678s-12.796-4.882-17.678 0C.78 10.543.78 18.457 5.661 23.339zm5.545-16.613l1.86 1.86c.372.372.451.947.193 1.406l-.699 1.241a.781.781 0 0 0 .129.937l4.141 4.141a.781.781 0 0 0 .937.128l1.241-.699a1.173 1.173 0 0 1 1.406.193l1.861 1.861a1.175 1.175 0 0 1 0 1.66l-.881.881a3.135 3.135 0 0 1-3.786.493l-.084-.048a24.54 24.54 0 0 1-8.868-8.681l-.423-.706a3.128 3.128 0 0 1 .469-3.823l.844-.844a1.173 1.173 0 0 1 1.66 0z" fill="#4687ba" class="color000000 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 678 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 512 512" id="Sms"><circle cx="256" cy="256" r="256" fill="#4687ba" class="color00aebb svgShape"></circle><path fill="#ffffff" d="M256 129.3c-88.4 0-160 52-160 116.2 0 26.6 12.3 51.1 33 70.7-11.6 26.2-22.6 66.2-22.6 66.2 6.1 3.1 60.9-23.9 78.4-32.8 21.4 7.7 45.6 12.1 71.2 12.1 88.4 0 160-52 160-116.2s-71.6-116.2-160-116.2zm-59.2 148.9c-5.2 3.8-12 5.7-20.4 5.7-8.3 0-15.4-2.1-21.4-6.2-6-4.1-8.8-10.3-8.7-18.5l.1-.3h15c0 4.6 1.3 7.9 4 10.1 2.7 2.2 6.3 3.2 10.9 3.2 4.1 0 7.3-.9 9.5-2.6 2.2-1.7 3.3-4 3.3-6.9 0-3-1-5.3-3.1-7.1-2.1-1.8-5.7-3.5-10.9-5.1-8.9-2.7-15.6-5.8-20.3-9.5-4.6-3.6-6.9-8.6-6.9-14.9 0-6.3 2.6-11.5 7.8-15.5 5.2-4 11.8-6 19.9-6 8.5 0 15.4 2.2 20.6 6.5 5.2 4.3 7.7 10 7.5 16.9l-.1.3h-15c0-3.8-1.2-6.8-3.5-8.9-2.3-2.1-5.6-3.1-9.8-3.1-3.8 0-6.8.9-8.8 2.8-2.1 1.8-3.1 4.2-3.1 7 0 2.6 1.1 4.8 3.4 6.4 2.3 1.7 6.2 3.5 11.7 5.3 8.5 2.4 14.9 5.5 19.4 9.4 4.4 3.9 6.7 9 6.7 15.3-.1 6.7-2.7 11.9-7.8 15.7zm99.3 4.7h-15.5v-52.6l-.3-.1-19.1 52.7h-10.5l-19.1-52.8-.3.1v52.7h-15.5v-77.1h20.3l19.6 56.8h.3l19.8-56.8H296v77.1zm62.1-4.7c-5.2 3.8-12 5.7-20.4 5.7-8.3 0-15.4-2.1-21.4-6.2-5.9-4.1-8.8-10.3-8.7-18.5l.1-.3h15c0 4.6 1.3 7.9 4 10.1 2.7 2.2 6.3 3.2 10.9 3.2 4.1 0 7.3-.9 9.5-2.6 2.2-1.7 3.3-4 3.3-6.9 0-3-1-5.3-3.1-7.1-2.1-1.8-5.7-3.5-10.9-5.1-8.9-2.7-15.7-5.8-20.3-9.5-4.6-3.6-6.9-8.6-6.9-14.9 0-6.3 2.6-11.5 7.8-15.5 5.2-4 11.8-6 19.9-6 8.5 0 15.4 2.2 20.6 6.5 5.2 4.3 7.7 10 7.5 16.9l-.1.3h-15c0-3.8-1.2-6.8-3.5-8.9-2.3-2.1-5.6-3.1-9.8-3.1-3.8 0-6.8.9-8.8 2.8-2.1 1.8-3.1 4.2-3.1 7 0 2.6 1.1 4.8 3.4 6.4 2.3 1.7 6.2 3.5 11.7 5.3 8.5 2.4 14.9 5.5 19.4 9.4 4.4 3.9 6.7 9 6.7 15.3-.1 6.7-2.6 11.9-7.8 15.7z" class="colorffffff svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

@@ -1,8 +1,8 @@
import React, { useEffect } from 'react';
import { useDispatch } from "react-redux";
import { useLocation, useNavigate } from 'react-router-dom';
import usersService from '../../../services/UsersService';
import {updateUserDetails} from "../../../store/UserDetails";
import { useDispatch } from "react-redux";
import { updateUserDetails } from "../../../store/UserDetails";
import AuthLayout from "../AuthLayout";
function FbookRedirect() {
@@ -22,38 +22,50 @@ function FbookRedirect() {
console.log(codeResponse);
/*
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/#exchangecode
Step 1. Get access token by code
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code
GET https://graph.facebook.com/v17.0/oauth/access_token?
client_id={app-id}
&redirect_uri={redirect-uri}
&client_secret={app-secret}
&code={code-parameter}
https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-long-lived
Step 2. Get long-lived token by access token
curl -i -X GET "https://graph.facebook.com/{graph-api-version}/oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={your-access-token}"
*/
// process.env.REACT_APP_FACEBOOK_CLIENT_ID
// process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE
var reqData = {
auth_type: "FACEBOOK",
code: codeResponse,
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
redirect_uri: process.env.REACT_APP_FACEBOOK_REDIRECT_URL,
};
// userApi
// .authStart(reqData)
// .then((res) => {
// if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
// localStorage.setItem("member_id", `${res.data.member_id}`);
// localStorage.setItem("uid", `${res.data.uid}`);
// localStorage.setItem("session_token", `${res.data.session}`);
// dispatch(updateUserDetails({...res.data}));
// navigate('/', {replace: true})
// return
// }
// navigate('/login', {state: {error: true}})
// })
// .catch((error) => {
// navigate('/login', {state: {error: true}})
// console.log(error);
// });
userApi
.authStart(reqData)
.then((res) => {
if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
localStorage.setItem("member_id", `${res.data.member_id}`);
localStorage.setItem("uid", `${res.data.uid}`);
localStorage.setItem("session_token", `${res.data.session}`);
dispatch(updateUserDetails({...res.data}));
navigate('/', {replace: true})
return
}
navigate('/login', {state: {error: true}})
})
.catch((error) => {
navigate('/login', {state: {error: true}})
console.log(error);
});
},[])
return (
<AuthLayout>
@@ -0,0 +1,37 @@
import React from 'react'
import { useNavigate } from 'react-router-dom'
import localImgLoad from '../../lib/localImgLoad'
const ForgetPwdResponse = ({title, message, type}) => {
const navigate = useNavigate()
return (
<>
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<h1 className={`${type ? 'text-black' : 'text-red-500'}text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]`}>
{title}
</h1>
</div>
<div className="title-area w-[100px] h-[100px] mx-auto flex flex-col justify-center items-center relative text-center mb-7">
<img className='w-full h-full' src={`${type ? localImgLoad('images/icons/success.svg') : localImgLoad('images/icons/error.svg')}`} alt='alert-banner' />
</div>
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<p className={`${type ? 'text-sky-blue' : 'text-red-500'} font-semibold dark:text-white mb-3 leading-[27.3px] text-[18px]`}>
{message}
</p>
</div>
<div className="signin-area mb-3.5">
<div className="flex justify-center items-center gap-2">
<button
type="button"
onClick={() => navigate("/login")}
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
>
<span>Home</span>
</button>
</div>
</div>
</>
)
}
export default ForgetPwdResponse
+109 -97
View File
@@ -1,9 +1,11 @@
import React, { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout";
import EmailValidator from "../../../lib/EmailValidator";
import ForgetPwdResponse from "../ForgetPwdResponse";
export default function ForgotPassword() {
const [checked, setValue] = useState(false);
@@ -11,7 +13,7 @@ export default function ForgotPassword() {
// email
const [email, setMail] = useState("");
const [msgError, setMsgError] = useState("");
const [msgSuccess, setMsgSuccess] = useState(false);
const [msgSuccess, setMsgSuccess] = useState(null);
const navigate = useNavigate();
const userApi = new usersService();
@@ -27,12 +29,26 @@ export default function ForgotPassword() {
const resetHandler = async () => {
if (email == "") {
setMsgError("An email is required");
} else if (!checked) {
return setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
if (!checked) {
setMsgError("Check if you are human");
return setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
if(!EmailValidator(email)){ // CHECKS IF EMAIL IS VALID
setMsgError("Invalid Email");
return setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
if (email !== "" && checked) {
const reqData = { email };
const reqData = { email, action:11013 };
setResetLoading(true);
try {
const res = await userApi.StartResetPassword(reqData);
@@ -41,8 +57,11 @@ export default function ForgotPassword() {
setMail("");
setValue(false);
setResetLoading(false);
}else{
setMsgSuccess(false);
}
} catch (error) {
setMsgSuccess(false);
setResetLoading(false);
setMail("");
setMsgError("An error occurred");
@@ -53,9 +72,6 @@ export default function ForgotPassword() {
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
}
setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
};
return (
@@ -73,106 +89,102 @@ export default function ForgotPassword() {
</div>
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
<div className="flex flex-col justify-center w-full h-full px-5">
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
Forget Password
</h1>
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
Enter your email to reset your password.
</span>
</div>
<div className="input-area">
<div className="input-item mb-10">
<InputCom
fieldClass="px-6"
placeholder="Your Username/Email"
label="Email"
name="email"
type="email"
value={email}
inputHandler={handleEmail}
iconName="message"
/>
{msgSuccess == null ?
<>
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
Forget Password
</h1>
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
Enter your email to reset your password.
</span>
</div>
{/* hCaptha clone for the time being */}
<div className="mb-10">
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
{/* Checkbox */}
<div className="h-full relative inline-block">
<div className="relative table top-0 h-full">
<div className="table-cell align-middle">
<div className="relative w-[30px] h-[30px] mx-[15px]">
<input
type="checkbox"
name="human-checkbox"
id="human-checkbox"
className="w-[28px] h-[28px] border-[1px] rounded border-gray-400 checked:bg-white"
checked={checked}
onChange={humanChecker}
/>
<div className="input-area">
<div className="input-item mb-10">
<InputCom
fieldClass="px-6"
placeholder="Your Username/Email"
label="Email"
name="email"
type="email"
value={email}
inputHandler={handleEmail}
iconName="message"
/>
</div>
{/* hCaptha clone for the time being */}
<div className="mb-10">
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
{/* Checkbox */}
<div className="h-full relative inline-block">
<div className="relative table top-0 h-full">
<div className="table-cell align-middle">
<div className="relative w-[30px] h-[30px] mx-[15px]">
<input
type="checkbox"
name="human-checkbox"
id="human-checkbox"
className="w-[28px] h-[28px] border-[1px] rounded border-gray-400 checked:bg-white"
checked={checked}
onChange={humanChecker}
/>
</div>
</div>
</div>
</div>
</div>
<div className="h-full relative inline-block w-[170px]">
<label className="relative table top-0 h-full">
<label className="table-cell align-middle">
<label
className="text-800 text-sm"
htmlFor="human-checkbox"
>
I am human
<div className="h-full relative inline-block w-[170px]">
<label className="relative table top-0 h-full">
<label className="table-cell align-middle">
<label
className="text-800 text-sm"
htmlFor="human-checkbox"
>
I am human
</label>
</label>
</label>
</label>
</div>
<div className="h-full relative inline-block w-16"></div>
</div>
<div className="h-full relative inline-block w-16"></div>
</div>
</div>
{msgError && (
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
{msgError}
</div>
)}
<div className="signin-area mb-3.5">
<div className="flex justify-center items-center gap-2">
<button
type="button"
onClick={resetHandler}
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
>
{resetLoading ? (
<div className="signup btn-loader"></div>
) : (
<span>Send Code</span>
)}
</button>
<button
type="button"
onClick={() => navigate("/login")}
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
>
Cancel
</button>
</div>
</div>
</div>
{msgError && (
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
{msgError}
</div>
)}
{msgSuccess && (
<div className="relative p-4 text-[#44228c] bg-[#e3d7fb] border-[#d5c4f9] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
If we find your email, you will receive a link to reset your
password. Please use or{" "}
<Link
to="/contact"
className="text-[#4687ba] hover:text-[#009ef7]"
>
contact form
</Link>{" "}
if you did not get our message after few minutes.
</div>
)}
<div className="signin-area mb-3.5">
<div className="flex justify-center items-center gap-2">
<button
type="button"
onClick={resetHandler}
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
>
{resetLoading ? (
<div className="signup btn-loader"></div>
) : (
<span>Send Code</span>
)}
</button>
<button
type="button"
onClick={() => navigate("/login")}
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
>
Cancel
</button>
</div>
</div>
</div>
</>
:
<ForgetPwdResponse
title={'Forget Password'}
message={msgSuccess? `Check your email for the link to continue password reset. Note the reset link will expire short time` : 'We are unable to continue with your request. Please try another username or contact us for help'}
type={msgSuccess}
/>
}
</div>
</div>
</div>
+97 -91
View File
@@ -1,26 +1,25 @@
import React, { useEffect, useLayoutEffect, useState } from "react";
import { Link, useNavigate, useLocation } from "react-router-dom";
import { Link, useLocation, useNavigate } from "react-router-dom";
import linkedInLogo from "../../../assets/images/Linkedin.png";
import appleLogo from "../../../assets/images/apple-black.svg";
import facebookLogo from "../../../assets/images/facebook-4.svg";
import googleLogo from "../../../assets/images/google-logo.svg";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout";
// import { GoogleOAuthProvider } from '@react-oauth/google';
import { googleLogout, useGoogleLogin } from "@react-oauth/google";
import { useGoogleLogin } from "@react-oauth/google";
import { useDispatch } from "react-redux";
import { updateUserDetails } from "../../../store/UserDetails";
export default function Login() {
const dispatch = useDispatch();
const {state} = useLocation()
const { state } = useLocation();
let [loginType, setLoginType] = useState('');
let [loginType, setLoginType] = useState("");
const [checked, setValue] = useState(false);
const [loginLoading, setLoginLoading] = useState(false);
const [showPassword, setShowPassword] = useState(false);
@@ -30,12 +29,8 @@ export default function Login() {
// for the catch error
const [msgError, setMsgError] = useState("");
const rememberMe = () => {
setValue(!checked);
};
// To Show and Hide Password
const togglePasswordVisibility = () => {
// To Show and Hide Password
const togglePasswordVisibility = () => {
setShowPassword(!showPassword);
};
@@ -43,7 +38,7 @@ export default function Login() {
const handleLoginType = ({ target: { name } }) => {
setLoginType(name);
let currentDate = new Date();
let expirationDate = new Date(currentDate.getTime() + (24 * 60 * 60 * 1000));
let expirationDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000);
// Convert the expiration date to the appropriate format
let expirationDateString = expirationDate.toUTCString();
document.cookie = `loginType=${name}; expires=${expirationDateString}; path=/;`;
@@ -83,7 +78,9 @@ export default function Login() {
if (regEx.test(email) == false) {
setLoginLoading(false);
setMsgError("Invalid Email");
return setTimeout(()=>{setMsgError("");},3000)
return setTimeout(() => {
setMsgError("");
}, 3000);
}
// Post Data Info for normal Login
postData = {
@@ -113,7 +110,13 @@ export default function Login() {
userApi
.logInUser(postData)
.then((res) => {
if (res.status != 200 || res.data.internal_return < 0 || !res.data.member_id || !res.data.uid || !res.data.session) {
if (
res.status != 200 ||
res.data.internal_return < 0 ||
!res.data.member_id ||
!res.data.uid ||
!res.data.session
) {
// setMsgError("Wrong, email/password");
setLoginError(true);
setLoginLoading(false);
@@ -123,7 +126,7 @@ export default function Login() {
localStorage.setItem("uid", `${res.data.uid}`);
localStorage.setItem("session_token", `${res.data.session}`);
// localStorage.setItem("session", `${res.data.session}`);
dispatch(updateUserDetails({...res.data}));
dispatch(updateUserDetails({ ...res.data }));
setTimeout(() => {
navigate("/", { replace: true });
setLoginLoading(false);
@@ -154,11 +157,12 @@ export default function Login() {
// In order to update the selected login type whenever the component renders
// useEffect(() => {
// Clear the loginType cookie if the user switches to loginfull
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
// Clear the loginType cookie if the user switches to loginfull
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
// }, []);
useLayoutEffect(()=>{ // checks the cookie in order to set the login type before components mounts
useLayoutEffect(() => {
// checks the cookie in order to set the login type before components mounts
// if(document.cookie.includes("loginType=family")){
// setLoginType('family')
// }else if(document.cookie.includes("loginType=full")){
@@ -166,33 +170,34 @@ export default function Login() {
// }else{
// setLoginType('full')
// }
function readCookie(cname) { // checks the cookie in order to set the login type before components mounts
function readCookie(cname) {
// checks the cookie in order to set the login type before components mounts
let name = cname + "=";
let decoded_cookie = decodeURIComponent(document.cookie);
let carr = decoded_cookie.split(';');
for(let i=0; i<carr.length;i++){
let carr = decoded_cookie.split(";");
for (let i = 0; i < carr.length; i++) {
let c = carr[i];
while(c.charAt(0)==' '){
c=c.substring(1);
while (c.charAt(0) == " ") {
c = c.substring(1);
}
if(c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return 'full'
return "full";
}
let loginValue = readCookie('loginType')
setLoginType(loginValue)
let loginValue = readCookie("loginType");
setLoginType(loginValue);
if(state?.error){ //check if the login path has an error state indicating any social handle login with error
if (state?.error) {
//check if the login path has an error state indicating any social handle login with error
setMsgError("Unexpected Error, Please try again soon.");
setTimeout(()=>{
setTimeout(() => {
setMsgError("");
navigate('/login', {replace: true})
},4000)
navigate("/login", { replace: true });
}, 4000);
}
},[])
}, []);
useEffect(() => {
setMail("");
@@ -234,7 +239,9 @@ export default function Login() {
<button
name="full"
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
loginType=='full' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
loginType == "full"
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
: "bg-white text-[#000] border-t-[2px]"
}`}
onClick={handleLoginType}
>
@@ -243,7 +250,9 @@ export default function Login() {
<button
name="family"
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
loginType=='family' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
loginType == "family"
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
: "bg-white text-[#000] border-t-[2px]"
}`}
onClick={handleLoginType}
>
@@ -255,7 +264,7 @@ export default function Login() {
{/* for login component */}
{
loginType == 'full' ? (
loginType == "full" ? (
//user login component
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
<div className="input-item mb-5">
@@ -275,7 +284,7 @@ export default function Login() {
<div className="input-item mb-5">
<InputCom
labelClass="tracking-wider"
fieldClass="sm:px-6 px-2"
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
value={password}
inputHandler={handlePassword}
placeholder="● ● ● ● ● ●"
@@ -321,33 +330,33 @@ export default function Login() {
</button>
</div>
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
<BrandBtn
link="#"
imgSrc={googleLogo}
brand="Google"
onClick={googleLogin}
/>
<BrandBtn
// link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
imgSrc={appleLogo}
brand="Apple"
isAnchor={true}
/>
<BrandBtn
link="#"
imgSrc={googleLogo}
brand="Google"
onClick={googleLogin}
/>
<BrandBtn
// link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
imgSrc={appleLogo}
brand="Apple"
isAnchor={true}
/>
</div>
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
<BrandBtn
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
imgSrc={facebookLogo}
brand="Facebook"
isAnchor={true}
/>
<BrandBtn
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
imgSrc={linkedInLogo}
brand="LinkedIn"
isAnchor={true}
/>
<BrandBtn
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
imgSrc={facebookLogo}
brand="Facebook"
isAnchor={true}
/>
<BrandBtn
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
imgSrc={linkedInLogo}
brand="LinkedIn"
isAnchor={true}
/>
</div>
</div>
</div>
@@ -423,10 +432,12 @@ export default function Login() {
}
{/* END of login component */}
{loginType == "full" &&
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
This site is protected by hCaptcha and the our Privacy Policy
and Terms of Service apply.
</div>
}
</div>
</div>
</div>
@@ -435,7 +446,7 @@ export default function Login() {
);
}
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor = false }) => {
// const doGoogle = async () => {
// alert("start google");
// };
@@ -456,33 +467,28 @@ const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
// };
return (
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
{isAnchor ?
(
{isAnchor ? (
<a
href={link}
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
>
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
Continue with {brand}
</span>
</a>
)
:
(
href={link}
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
>
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
Continue with {brand}
</span>
</a>
) : (
<button
onClick={onClick}
// href="#dd"
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
>
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
Continue with {brand}
</span>
</button>
)
}
onClick={onClick}
// href="#dd"
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
>
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
Continue with {brand}
</span>
</button>
)}
</div>
)
);
};
+54 -10
View File
@@ -1,7 +1,6 @@
import React, { useCallback, useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import facebookLogo from "../../../assets/images/facebook-4.svg";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout";
@@ -69,13 +68,17 @@ export default function SignUp() {
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
if (regEx.test(email) == false) {
setMsgError("Invalid Email");
return setTimeout(()=>{setMsgError("");},3000)
return setTimeout(() => {
setMsgError("");
}, 3000);
}
//checks if terms and condition is checked
if (!checked) {
setMsgError("Terms and condition required");
return setTimeout(()=>{setMsgError("");},3000)
return setTimeout(() => {
setMsgError("");
}, 3000);
}
setSignUpLoading(true);
@@ -95,7 +98,9 @@ export default function SignUp() {
if (res.status === 200) {
const { data } = res;
if (data && data.acc === "DULPICATE") {
setMsgError("Unable to use this username. Please try another username.");
setMsgError(
"Unable to use this username. Please try another username."
);
setSignUpLoading(false);
}
if (data && data.status === "1") {
@@ -205,15 +210,13 @@ export default function SignUp() {
</div>
<div className="input-item mb-5">
<InputCom
fieldClass="px-6"
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
placeholder="● ● ● ● ● ●"
label="Password"
name="password"
type={showPassword ? "text" : "password"}
onClick={togglePasswordVisibility}
passIcon={
showPassword ? "show-password" : "hide-password"
}
passIcon={showPassword ? "show-password" : "hide-password"}
value={formData.password}
inputHandler={handleInputChange}
/>
@@ -223,7 +226,48 @@ export default function SignUp() {
{msgError}
</div>
)}
<div className="forgot-password-area flex justify-between items-center mb-6">
<div className="remember-checkbox flex items-center space-x-2.5 group cursor-pointer">
<button
onClick={rememberMe}
type="button"
className={`w-6 h-6 border-[#4687ba] text-white flex justify-center items-center border rounded-[.45em] group-checked:text-white transition-all duration-200 group-checked:cursor-default ${
checked && "text-white bg-[#4687ba]"
}`}
>
{checked && (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
)}
</button>
<span
onClick={rememberMe}
className="cursor-default text-dark-gray dark:text-white text-[15px] group-checked:text-white transition-all duration-200 group-checked:cursor-default"
>
I agree with all
<Link
href="#"
className="text-base text-[#4687ba] hover:text-[#009ef7] mx-1 inline-block"
>
terms and condition
</Link>
</span>
</div>
</div>
{/* Forgot Password */}
{/* <div className="forgot-password-area flex justify-between items-center mb-6">
<div className="remember-checkbox flex items-center space-x-2.5">
<button
onClick={rememberMe}
@@ -258,7 +302,7 @@ export default function SignUp() {
</Link>
</span>
</div>
</div>
</div> */}
<div className="signin-area mb-1">
<div className="flex justify-center">
<button
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useState } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import debounce from "../../../hooks/debounce";
import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
+119 -83
View File
@@ -1,16 +1,20 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout";
import ForgetPwdResponse from "../ForgetPwdResponse";
import PasswordValidator from "../../../lib/PasswordValidator";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
const VerifyPassword = () => {
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [requestStatus, setRequestStatus] = useState({loading: true, status:false, data: []})
const [msgError, setMsgError] = useState("");
const [linkLoader, setLinkLoader] = useState(false);
const [linkSuccess, setLinkSuccess] = useState(true);
const [linkSuccess, setLinkSuccess] = useState(null);
const [showPassword, setShowPassword] = useState(false);
const navigate = useNavigate();
const location = useLocation();
@@ -23,11 +27,6 @@ const VerifyPassword = () => {
setShowPassword(!showPassword);
};
// little checker for the validity of the token
if (token?.length != 64) {
setLinkSuccess(false);
}
// Password
const handlePassword = (e) => {
let { name, value } = e?.target;
@@ -36,46 +35,60 @@ const VerifyPassword = () => {
};
const completeReset = async () => {
if(!password || !confirmPassword){ // CHECKS IF PASSWORD IS EMPTY
setMsgError("Please fill in fields");
return setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
if(password != confirmPassword){ // CHECKS IF PASSWORD EQUALS CONFIRM PASSWORD
setMsgError("Passwords does not match");
return setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
if(password.length < 6){ // CHECKS IF PASSWORD LENGTH IS UPTO 6 CHARACTERS
setMsgError("Password must be upto six characters");
return setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
if(!PasswordValidator(password)){ // CHECKS IF PASSWORD IS VALID
setMsgError("Password must contain alphanumeric, uppercase and special character: eg: Password1@");
return setTimeout(() => {
setMsgError(null);
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
}
try {
if (password !== "" && confirmPassword !== "") {
if (password === confirmPassword) {
setLinkLoader(true);
var reqData = {
sessionid: "DUMMY-CANNOT_BE_EMPTY",
reset_link: token,
newpass: password,
m_uid: requestStatus.data?.m_uid || '',
reset_uid: requestStatus.data?.reset_uid || '',
step: 300,
action: 730,
};
const res = await userApi?.CompleteResetPassword(reqData);
if (res.status === 200) {
if (res.status == 200) {
const { data } = res;
if (data?.status > 0 && data?.email) {
setTimeout(() => {
navigate("/login", { replace: true });
setLinkLoader(false);
}, 2000);
} else if (data && data?.status == "Invalid Request") {
setLinkLoader(false);
setLinkSuccess(false);
if (data?.internal_return >= 0) {
// setTimeout(() => {
// navigate("/login", { replace: true });
// setLinkLoader(false);
// }, 2000);
setLinkSuccess(true);
} else {
setLinkLoader(false);
setMsgError("An error occurred");
setLinkSuccess(false);
}
} else {
setLinkLoader(false);
setLinkSuccess(false);
}
} else {
setLinkLoader(false);
setMsgError("Passwords does not match");
}
} else {
setMsgError("Please fill in fields");
}
} catch (error) {
setLinkLoader(false);
setLinkSuccess(false);
@@ -87,6 +100,31 @@ const VerifyPassword = () => {
}
};
const verifyResetPwd = () => { // FUNCTION TO VERIFY RESET PASSWORD LINK
setRequestStatus({loading: true, status:false, data: []})
var reqData = {
sessionid: "DUMMY-CANNOT_BE_EMPTY",
reset_link: token,
step: 200,
action: 730,
};
userApi.CompleteResetPassword(reqData).then(res => {
if(res.status != 200 || res.data.internal_return < 0){
return setRequestStatus({loading: false, status:false, data: []})
}
setRequestStatus({loading: false, status:true, data: res.data})
}).catch(error => {
setRequestStatus({loading: false, status:false, data: []})
})
}
useEffect(()=>{
// little checker for the validity of the token
if (token==null || token?.length != 64) {
return setRequestStatus({loading: false, status:false, data: []});
}
verifyResetPwd()
},[])
return (
<>
<AuthLayout slogan="Welcome to WrenchBoard">
@@ -101,39 +139,59 @@ const VerifyPassword = () => {
</Link>
</div>
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
{requestStatus.loading ?
<LoadingSpinner color='sky-blue' size='16' height='h-300px' />
:
!requestStatus.loading && requestStatus.status ?
<div className="w-full">
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
{linkSuccess ? "Password Reset" : "Invalid verification link"}
</h1>
{linkSuccess && (
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
Enter a new password to reset
</span>
)}
{linkSuccess && (
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
We'll send an email to confirm reset
</span>
)}
</div>
{/* If the verification was a success */}
{linkSuccess ? (
<SuccessfulComponent
password={password}
confirmPassword={confirmPassword}
handlePassword={handlePassword}
onSubmit={completeReset}
msgErr={msgError}
loader={linkLoader}
showPassword={showPassword}
onClick={togglePasswordVisibility}
navigateHandler={() => navigate("/login")}
/>
) : (
<ErrorComponent onClick={() => navigate("/login")} />
)}
{linkSuccess == null ?
<>
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
Password Reset
</h1>
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
Enter a new password to reset
</span>
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
We'll send an email to confirm reset
</span>
</div>
<div>
<p className="text-red-500 font-semibold mb-3 leading-[27.3px] text-[13px]">
Must include a special, numeric, uppercase and lowercase character
</p>
</div>
<SuccessfulComponent
password={password}
confirmPassword={confirmPassword}
handlePassword={handlePassword}
onSubmit={completeReset}
msgErr={msgError}
loader={linkLoader}
showPassword={showPassword}
onClick={togglePasswordVisibility}
navigateHandler={() => navigate("/login")}
/>
</>
:
<ForgetPwdResponse
title={linkSuccess? 'Password Reset Complete' : 'Password Reset Error'}
message={linkSuccess? 'Password Reset Complete. You can login now with your new credentials' : 'Password Reset Error. Please get in touch with support for further support'
}
type={linkSuccess}
/>
}
</div>
:
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<ForgetPwdResponse
title={'Forget Password'}
message={'We are unable to continue to reset process. This error is usually due to expired links. Please start all over or contact us'}
type={requestStatus.status}
/>
</div>
}
</div>
</div>
</AuthLayout>
@@ -158,7 +216,7 @@ const SuccessfulComponent = ({
{/* INPUT */}
<div className="mb-5">
<InputCom
fieldClass="px-6"
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
value={password}
inputHandler={handlePassword}
placeholder="● ● ● ● ● ●"
@@ -171,7 +229,7 @@ const SuccessfulComponent = ({
</div>
<div className="mb-5">
<InputCom
fieldClass="px-6"
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
value={confirmPassword}
inputHandler={handlePassword}
placeholder="● ● ● ● ● ●"
@@ -209,25 +267,3 @@ const SuccessfulComponent = ({
</div>
</div>
);
const ErrorComponent = ({ onClick }) => (
<div className="input-area">
<div className="my-5">
<p className="text-[14px] leading-[19px] text-center text-[#181c32]">
This error occurs because you have already used this link or the link
has broken/expired. Start with the reset process again. If it doesn't
work, try to create the account from the start.
</p>
</div>
<div className="signin-area flex justify-center mb-3.5">
<button
onClick={onClick}
type="button"
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
>
<span>Return Home</span>
</button>
</div>
</div>
);
+1 -1
View File
@@ -1,6 +1,6 @@
import { useNavigate, Link } from "react-router-dom";
import AuthLayout from "../AuthLayout";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
export default function VerifyYou() {
const navigate = useNavigate();
+59 -20
View File
@@ -1,38 +1,77 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import usersService from "../../services/UsersService";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import CommonHead from "../UserHeader/CommonHead";
export default function BlogItem(props) {
const apiCall = new usersService()
const navigate = useNavigate()
const [blogdata, setBlogdata] = useState({loading: true, data:{}})
const [selectTab, setValue] = useState("today");
const filterHandler = (value) => {
setValue(value);
};
// eslint-disable-next-line no-restricted-globals
const queryParams = new URLSearchParams(location?.search);
const blog_id = queryParams.get("blog_id");
useEffect(()=>{
if(!blog_id){
navigate('/',{replace:true})
}
apiCall.getSingleBlogData({blog_id}).then(res => {
setBlogdata({loading: false, data:res.data})
}).catch(error => {
setBlogdata({loading: false, data:{}})
console.log('ERROR', error)
})
},[blog_id])
return (
<Layout>
<CommonHead
commonHeadData={props.commonHeadData}
/>
<div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full">
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
Title of this Blog Items
</span>
</h1>
</div>
<div className="slider-btns flex space-x-4">
</div>
<div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
{blogdata.data?.blogdata?.[0]?.post_title}
</span>
</h1>
</div>
<div className="notification-wrapper w-full bg-white p-8 rounded-2xl">
{blogdata.loading ?
<LoadingSpinner size='8' color='sky-blue' height='h-[100px]' />
:
blogdata?.data?.blogdata && blogdata.data?.blogdata.length ?
<div className="w-full">
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
{/* <div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
{blogdata.data?.blogdata?.[0]?.post_title}
</span>
</h1>
</div> */}
{/* <div className="slider-btns flex space-x-4">
</div> */}
</div>
<div dangerouslySetInnerHTML={{__html: blogdata.data?.blogdata?.[0]?.post_content}}>
</div>
</div>
<div>
Blog Items Details need implenet
</div>
:
<h1 className="text-26 font-bold text-dark-gray dark:text-white">No Blog Found!</h1>
}
</div>
</div>
</Layout>
@@ -16,7 +16,8 @@ export default function HomeBannerOffersCard(props) {
return (
<Link
to={link_result}
// to={link_result}
to={link_result == '/blog-page' ? `${link_result}?blog_id=${props.itemData.blog_id}` : `${link_result}`}
className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center"
style={{
backgroundImage: `url('${imageUrl}')`,
+1 -1
View File
@@ -19,7 +19,7 @@ export default function OfferCard({ datas, hidden = false, setOfferPopout }) {
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
style={{
background: `url(${localImgLoad(
`images/taskbanners/${datas.banner}`
`images/taskbanners/${datas?.banner || "default.jpg"}`
)}) center / contain no-repeat`,
}}
>
+7 -6
View File
@@ -50,22 +50,23 @@ export default function ProductCardStyleTwo({
</div>
<div className="details-area">
{/* title */}
<a href={datas.guid} target="_blank" className="mb-2.5" rel="noreferrer">
<Link to={`/blog-page?blog_id=${datas.ID}`} className="mb-2.5" rel="noreferrer">
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{datas.post_title || "dummy title..."}
</h1>
</a>
</Link>
<div className="flex justify-between">
<div className="flex items-center space-x-2"></div>
<div className="my-1">
<a
href={datas.guid}
target="_blank"
<Link
// href={datas.guid}
// target="_blank"
to={`/blog-page?blog_id=${datas.ID}`}
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
rel="noreferrer"
>
View
</a>
</Link>
</div>
</div>
</div>
+11 -10
View File
@@ -10,10 +10,10 @@ import React, {
} from "react";
import { useReactToPrint } from "react-to-print";
import profile from "../../assets/images/profile-info-profile.png";
import localImgLoad from "../../lib/localImgLoad";
import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
import localImgLoad from "../../lib/localImgLoad";
// Lazy Imports for components
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
@@ -193,19 +193,19 @@ export default function FamilyManageTabs({
return (
<div
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ${
className || ""
}`}
>
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<div className="relative w-full sm:rounded-lg overflow-x-auto">
<Suspense
fallback={
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
<div className="h-full min-h-[609px] w-full overflow-hidden flex justify-center items-center">
<LoadingSpinner size="16" color="sky-blue" />
</div>
}
>
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[520px]">
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[575px]">
<div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between">
<ProfileInfo
profileImg={profileImg}
@@ -239,10 +239,10 @@ export default function FamilyManageTabs({
</button>
</div>
</div>
<div className="col-span-3 justify-self-end h-full w-full">
<div className="col-span-3 h-full w-full">
<div className="flex flex-col w-full">
<div className="w-full pr-8 flex items-center gap-1">
<ul className="flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
<div className="w-full pr-8 flex items-center gap-1 border-b border-b-[#FAFAF]">
<ul className="flex gap-2 items-center w-full">
{tabs.map(({ name, id }) => (
<li
onClick={() => tabHandler(name)}
@@ -265,8 +265,9 @@ export default function FamilyManageTabs({
Add task
</button>
</div>
<div className="flex-[0.9] lg:min-h-[450px] h-full">
<div className="h-full p-4 border border-[#dbd9d9] relative overflow-y-auto">
<div className="flex-[0.9] h-full">
<div className="h-full relative overflow-y-auto">
<Suspense
fallback={<LoadingSpinner size="16" color="sky-blue" />}
>
+6 -3
View File
@@ -6,6 +6,7 @@ import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
import familyImage from '../../assets/images/no-family-side.png'
import localImgLoad from "../../lib/localImgLoad";
export default function FamilyTable({ className, familyList, loader, popUpHandler }) {
const navigate = useNavigate();
@@ -22,7 +23,7 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
return (
<div
className={`update-table w-full h-full p-8 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] ${
className={`update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] ${
className || ""
}`}
>
@@ -54,6 +55,7 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
last_login,
task_count,
family_uid,
banner
} = props;
let addedDate = added?.split(" ")[0];
let LoginDate = last_login?.split(" ")[0];
@@ -64,9 +66,10 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
>
<td className=" py-4">
<div className="flex space-x-2 items-center w-full">
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px]">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1]">
<img
src={dataImage1}
// src={dataImage1}
src={localImgLoad(`images/icons/${banner}`)}
alt="data"
className="w-full h-full"
/>
@@ -4,7 +4,7 @@ import QRCode from "react-qr-code";
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
return (
<div
className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center"
className="w-full lg:min-h-[538px] p-3 h-full flex flex-col items-center justify-center"
ref={myRef}
>
<div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
@@ -53,4 +53,4 @@ const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
);
});
export default FamilyAccount;
export default FamilyAccount;
@@ -1,9 +1,8 @@
import { useMemo, useState } from "react";
import { PaginatedList, handlePagingFunc } from "../../Pagination";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import dataImage2 from "../../../assets/images/data-table-user-2.png";
import PendingJobsPopout from "../../jobPopout/PendingJobsPopout";
import localImgLoad from "../../../lib/localImgLoad";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import { PaginatedList, handlePagingFunc } from "../../Pagination";
import PendingJobsPopout from "../../jobPopout/PendingJobsPopout";
export default function FamilyPending({
familyData,
@@ -37,7 +36,7 @@ export default function FamilyPending({
return (
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
className={`update-table w-full p-3 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow lg:min-h-[538px] ${
className || ""
}`}
>
@@ -125,8 +124,10 @@ export default function FamilyPending({
);
})
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Pending Task!</td>
<tr>
<td className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap text-center py-4 px-2">
No Pending Task!
</td>
</tr>
)}
</>
@@ -1,3 +1,11 @@
export default function FamilyProfile() {
return <>Profile</>;
}
export default function FamilyProfile({ className }) {
return (
<div
className={`update-table w-full bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow lg:min-h-[538px] p-3 ${
className || ""
}`}
>
<h1>Profile</h1>
</div>
);
}
+40 -18
View File
@@ -1,20 +1,30 @@
import React, { useState } from "react";
import dataImage2 from "../../../assets/images/data-table-user-2.png";
import { useNavigate, useLocation } from "react-router-dom";
import React, { useMemo, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import localImgLoad from "../../../lib/localImgLoad";
import Icons from "../../Helpers/Icons";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import { handlePagingFunc } from "../../Pagination/HandlePagination";
import PaginatedList from "../../Pagination/PaginatedList";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import Icons from "../../Helpers/Icons";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import ModalCom from "../../Helpers/ModalCom";
import Detail from "../../jobPopout/popoutcomponent/Detail";
import localImgLoad from "../../../lib/localImgLoad";
export default function FamilyTasks({ familyData, className, loader, accountDetails }) {
export default function FamilyTasks({
familyData,
className,
loader,
accountDetails,
}) {
let navigate = useNavigate();
let { pathname } = useLocation();
// ...
const filteredFamilyData = useMemo(
() =>
familyData?.result_list?.filter(
(data) => data?.family_uid === accountDetails?.family_uid
),
[familyData, accountDetails]
);
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
@@ -26,9 +36,10 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
return (
<div
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[538px] overflow-hidden rounded-2xl section-shadow p-3 ${
className || ""
}`}
>
@@ -45,8 +56,8 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
{
<>
{familyData &&
familyData?.result_list &&
familyData.result_list.length > 0 &&
familyData?.result_list &&
familyData.result_list.length > 0 ? (
currentTask.map((value, index) => {
// find due date
const dueDate = value?.delivery_date.split(" ")[0];
@@ -56,7 +67,9 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
value?.currency_code,
value?.currency
);
let image = value.banner ? value.banner : 'default.jpg'
let image = value.banner
? value.banner
: "default.jpg";
return (
<tr
key={index}
@@ -66,7 +79,9 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
<div className="flex space-x-2 items-center w-full">
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img
src={localImgLoad(`images/taskbanners/${image}`)}
src={localImgLoad(
`images/taskbanners/${image}`
)}
alt="data"
className="w-full h-full rounded-full"
/>
@@ -109,8 +124,8 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
state: {
...value,
pathname,
accountDetails
}
accountDetails,
},
});
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
@@ -120,7 +135,14 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
</td>
</tr>
);
})}
})
) : (
<tr>
<td colSpan="2" className="text-center py-4 font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
No Family Task
</td>
</tr>
)}
</>
}
</tbody>
@@ -48,7 +48,7 @@ const FamilyWaitlist = memo(
return (
<div
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[538px] p-3 overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
@@ -1,4 +1,6 @@
import React from "react";
import localImgLoad from "../../../lib/localImgLoad";
export default function ProfileInfo({
profileImg,
@@ -12,7 +14,7 @@ export default function ProfileInfo({
<div className="flex justify-center">
<div className="w-full relative">
<img
src={profileImg}
src={localImgLoad(`images/icons/${accountDetails.banner}`)}
alt=""
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
/>
+3 -3
View File
@@ -504,11 +504,11 @@ export default function Icons({ name }) {
></path>
</svg>
) : name === "atm-card" ? (
<img className="w-[20px]" src={ATMCard} alt="card" />
<img className="w-[30px]" src={ATMCard} alt="card" />
) : name === "visa-card" ? (
<img className="w-[20px]" src={VisaCard} alt="card" />
<img className="w-[30px]" src={VisaCard} alt="card" />
) : name === "master-card" ? (
<img className="w-[20px]" src={MasterCard} alt="card" />
<img className="w-[30px]" src={MasterCard} alt="card" />
) : name === "new-dashboard" ? (
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/dashboard.svg')} alt="dashboard" />
) : name === "new-family" ? (
@@ -21,6 +21,9 @@ export default function InputCom({
blurHandler,
spanTag,
inputBg,
onInput,
maxLength = 45,
minLength = 0,
direction,
error,
}) {
@@ -29,13 +32,13 @@ export default function InputCom({
// for Min Length:
const minLengthValidation = () => {
const inputConfig = inputConfigs[inputRef?.current?.name]?.minLength;
return inputConfig || 0;
return inputConfig || minLength;
};
// for MaxLength
const maxLengthValidation = () => {
const inputConfig = inputConfigs[inputRef?.current?.name]?.maxLength;
return inputConfig || 30;
return inputConfig || maxLength;
};
// for Patterns
@@ -63,7 +66,9 @@ export default function InputCom({
</span>
)}
{/* displays error is any */}
{error && <span className="text-[12px] text-red-500 italic">{error}</span>}
{error && (
<span className="text-[12px] text-red-500 italic">{error}</span>
)}
</label>
)}
{forgotPassword && (
@@ -76,18 +81,23 @@ export default function InputCom({
)}
</div>
<div
className={`input-wrapper w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-base ${inputClass ? inputClass : "text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] border"}`}
className={`input-wrapper w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-base ${
inputClass
? inputClass
: "text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] border"
}`}
>
<input
placeholder={placeholder}
value={value}
onChange={inputHandler}
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide ${
inputBg ? inputBg : "bg-[#FAFAFA]"
className={`input-field placeholder:text-base text-dark-gray w-full h-full ${
inputBg ? inputBg : "bg-[#FAFAFA] tracking-wide"
} dark:bg-[#11131F] focus:ring-0 focus:outline-none ${fieldClass}`}
type={type}
id={name}
name={name}
onInput={onInput}
minLength={minLengthValidation()}
maxLength={maxLengthValidation()}
// pattern={inputPatterns()}
@@ -104,10 +114,7 @@ export default function InputCom({
</div>
)}
{passIcon && (
<div
className="absolute right-6 bottom-3 z-10"
onClick={onClick}
>
<div className="absolute right-6 bottom-3 z-10" onClick={onClick}>
<Icons name={passIcon} />
</div>
)}
@@ -117,7 +124,7 @@ export default function InputCom({
}
const inputConfigs = {
email: { minLength: 7, maxLength: 35 },
email: { minLength: 7, maxLength: 45 },
first_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
last_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
address: { minLength: 5, maxLength: 49, pattern: "[a-zA-Z0-9]+" },
@@ -128,7 +135,8 @@ const inputConfigs = {
amount: { minLength: 1, maxLength: 9, pattern: "[0-9]+" },
description: { minLength: 5, maxLength: 299 },
title: { minLength: 5, maxLength: 149 },
job_detail: { minLength: 4, maxLength: 1440 }
job_detail: { minLength: 4, maxLength: 1440 },
cardNum: { minLength: 4, maxLength: 19 },
};
/* Numbers Only: <input type="text" pattern="[0-9]*" /> strictly numbers
+2
View File
@@ -7,6 +7,7 @@ export default function SearchCom({
placeholder,
handleSearch,
value,
name,
}) {
return (
<div
@@ -22,6 +23,7 @@ export default function SearchCom({
className={`w-full h-full focus:outline-0 focus:ring-0 dark:bg-dark-white dark:text-white ${
inputClasses || ""
}`}
name={name}
type="text"
onInput={handleSearch}
value={value}
+36
View File
@@ -0,0 +1,36 @@
const TimeDifference = ({ time }) => {
const currentTime = new Date();
const providedTime = new Date(time);
const timeDifference = currentTime - providedTime; // Difference in milliseconds
const minutes = Math.floor(timeDifference / (1000 * 60));
const hours = Math.floor(timeDifference / (1000 * 60 * 60));
const days = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
const months = Math.floor(timeDifference / (1000 * 60 * 60 * 24 * 30));
if (minutes < 1) {
return "Just now";
} else if (minutes < 60) {
return `${minutes} ${minutes === 1 ? "minute" : "minutes"} ago`;
} else if (hours < 12) {
return `${hours} ${hours === 1 ? "hour" : "hours"} ago`;
} else if (hours < 24) {
return "Today";
} else if (days < 2) {
return "Tomorrow";
} else if (days < 7) {
return `${days} ${days === 1 ? "day" : "days"} ago`;
} else if (months < 1) {
const weeks = Math.floor(days / 7);
return `${weeks} ${weeks === 1 ? "week" : "weeks"} ago`;
} else if (months < 6) {
return `${months} ${months === 1 ? "month" : "months"} ago`;
}else if (months < 8) {
return `"More than 6 months ago"`;
} else {
return time?.split(" ")[0];
}
};
export default TimeDifference;
+6 -6
View File
@@ -404,7 +404,7 @@ function ActiveJobs(props) {
<div className="files">
<label
htmlFor="file"
className="h-20 btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
>
Select Files to Upload
</label>
@@ -463,7 +463,7 @@ function ActiveJobs(props) {
<button
type="button"
onClick={handleClearAll}
className="border-gradient text-base tracking-wide px-4 py-3 rounded-full"
className="border-gradient text-base tracking-wide px-4 py-2 rounded-full"
>
<span className="text-gradient">Clear</span>
</button>
@@ -471,7 +471,7 @@ function ActiveJobs(props) {
<button
onClick={sendFile}
type="button"
className="btn-gradient text-base tracking-wide px-4 py-3 rounded-full flex justify-center items-center"
className='btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center'
>
{requestStatus.loading ? (
<LoadingSpinner size="6" color="sky-blue" />
@@ -495,7 +495,7 @@ function ActiveJobs(props) {
<button
onClick={sendTaskMessage}
type="button"
className="btn-gradient text-base text-white tracking-wide px-4 py-3 rounded-full"
className='btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer'
>
{requestStatus.loading ? (
<LoadingSpinner size="6" color="sky-blue" />
@@ -520,9 +520,9 @@ function ActiveJobs(props) {
<button
type="button"
onClick={popUpHandler}
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center"
>
view all
View all
</button>
</div>
{props.activeJobMesList.loading ? (
+4 -4
View File
@@ -110,13 +110,13 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
return (
<tr
key={index}
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
>
<td className="py-9">
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
<div className="flex space-x-2 items-center job-items w-full">
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img src={localImgLoad(`images/taskbanners/${value.banner}`)} alt="data" className="w-full h-full rounded-full" />
<img src={localImgLoad(`images/taskbanners/${value.banner ? value.banner : 'default.jpg'}`)} alt="data" className="w-full h-full rounded-full" />
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
@@ -175,7 +175,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
Assign
</button>
</td>
</tr>
@@ -204,7 +204,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
{MyJobList.loading ? (
<LoadingSpinner size="16" color="sky-blue" />
) : (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[520px]">
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
<>
@@ -6,6 +6,7 @@ import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import localImgLoad from "../../lib/localImgLoad";
export default function MyPendingJobTable({ MyJobList, className }) {
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
@@ -58,7 +59,7 @@ export default function MyPendingJobTable({ MyJobList, className }) {
<div className="flex space-x-2 items-center w-full">
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img
src={localImgLoad(`images/taskbanners/${value.banner}`)}
src={localImgLoad(`images/taskbanners/${value.banner || "default.jpg"}`)}
alt="data"
className="w-full h-full rounded-full"
/>
+9 -2
View File
@@ -3,13 +3,14 @@ import { Link } from "react-router-dom";
import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead";
import MyPendingJobTable from "./MyPendingJobTable";
import LoadingSpinner from "../Spinners/LoadingSpinner";
export default function MyPendingJobs(props) {
const [selectTab, setValue] = useState("today");
const filterHandler = (value) => {
setValue(value);
};
console.log("AMEYE LOC1", props.MyJobList);
// console.log("AMEYE LOC1", props.MyJobList);
return (
<Layout>
<CommonHead
@@ -35,7 +36,13 @@ export default function MyPendingJobs(props) {
></div>
</div>
</div>
<MyPendingJobTable MyJobList={props.MyJobList} />
{props.MyJobList.loading ?
<div className="bg-white">
<LoadingSpinner size='16' color='sky-blue' height='min-h-[300px]' />
</div>
:
<MyPendingJobTable MyJobList={props.MyJobList.data} />
}
</div>
</div>
</Layout>
@@ -2,7 +2,7 @@ import { useRef, useState } from "react";
import OfferCard from "../Cards/OfferCard";
import Icons from "../Helpers/Icons";
import SliderCom from "../Helpers/SliderCom";
import OfferJobPopout from "../jobPopout/OfferJobPopout";
import FamilyOfferJobPopout from "../jobPopout/FamilyOfferJobPopout";
export default function MyOffersFamilyTable({ className, familyOffers }) {
let [offerPopout, setOfferPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
@@ -127,7 +127,7 @@ export default function MyOffersFamilyTable({ className, familyOffers }) {
{/* Offer Job Popout */}
{offerPopout.show && (
<OfferJobPopout
<FamilyOfferJobPopout
details={offerPopout.data}
onClose={() => {
setOfferPopout({ show: false, data: {} });
+125 -111
View File
@@ -1,115 +1,129 @@
import React, {useState} from 'react'
import { Link } from 'react-router-dom'
import RecentActivityTable from './WalletComponent/RecentActivityTable'
import PurchasesTable from './WalletComponent/PurchasesTable'
import CouponTable from './WalletComponent/CouponTable'
import LoadingSpinner from '../Spinners/LoadingSpinner'
import { PriceFormatter } from '../Helpers/PriceFormatter'
import React from "react";
import { Link } from "react-router-dom";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import LoadingSpinner from "../Spinners/LoadingSpinner";
function Balance({wallet, coupon}) {
return (
<div className="content-wrapper">
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
Wallet
</h1>
</div>
<div className="slider-btns flex space-x-4">
</div>
</div>
<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>
{/* WALLET SECTION */}
<div className="lg:w-4/4 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full bg-white dark:bg-dark-white rounded-2xl shadow min-h-[520px]">
<div className='flex items-baseline justify-between'>
{/*<h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Wallet</h2>*/}
{/*<p className='text-base text-slate-500 dark:text-white'>Add New Wallet</p>*/}
</div>
{/* wallet balance */}
{wallet.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
wallet.data.length ?
wallet.data.map((item, index)=> (
<div key={index} className="p-3 md:flex items-center flex-wrap my-3 border-t-2 border-slate-400 wallet-box">
<div className='text-slate-900 w-full md:w-1/2 flex space-x-3 items-start justify-start'>
<div className='balance-info bal-col1'>
<p className='py-2'></p>
<span className='text-xl text-dark-gray dark:text-white'><b>{item.description}</b></span>
<p className='text-base text-slate-500'>{item.symbol}</p>
</div>
<div className='balance-info'>
<p className='py-2'>Balance</p>
<span className='py-1 px-2 bg-green-100 text-green-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.amount * 0.01, item.code)}</span>
</div>
<div className='balance-info'>
<p className='py-2'>Escrow</p>
<span className='py-1 px-2 bg-red-100 text-red-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.escrow * 0.01, item.code)}</span>
</div>
</div>
<div className='w-full my-2 md:my-0 md:w-1/2 flex space-x-2 items-center justify-start md:justify-end'>
{
item.action_type != 'AC_AD_FD_ONLY' ?
<Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:''
}
<Link to='add-fund' state={{currency:item.description}} className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'>
<span className="">
<svg xmlns="http://www.w3.org/2000/svg" width="38"
height="38" viewBox="0 0 42 42" fill="none"><path
d="M21 0C16.8466 0 12.7865 1.23163 9.33303 3.53914C5.8796 5.84665 3.18798 9.1264 1.59854 12.9636C0.00909901 16.8009 -0.406771 21.0233 0.403518 25.0969C1.21381 29.1705 3.21386 32.9123 6.15077 35.8492C9.08767 38.7861 12.8295 40.7862 16.9031 41.5965C20.9767 42.4068 25.1991 41.9909 29.0364 40.4015C32.8736 38.812 36.1534 36.1204 38.4609 32.667C40.7684 29.2135 42 25.1534 42 21C41.994 15.4323 39.7796 10.0944 35.8426 6.15741C31.9056 2.22045 26.5677 0.00602189 21 0ZM28 22.75H22.75V28C22.75 28.4641 22.5656 28.9092 22.2374 29.2374C21.9093 29.5656 21.4641 29.75 21 29.75C20.5359 29.75 20.0908 29.5656 19.7626 29.2374C19.4344 28.9092 19.25 28.4641 19.25 28V22.75H14C13.5359 22.75 13.0908 22.5656 12.7626 22.2374C12.4344 21.9092 12.25 21.4641 12.25 21C12.25 20.5359 12.4344 20.0907 12.7626 19.7626C13.0908 19.4344 13.5359 19.25 14 19.25H19.25V14C19.25 13.5359 19.4344 13.0908 19.7626 12.7626C20.0908 12.4344 20.5359 12.25 21 12.25C21.4641 12.25 21.9093 12.4344 22.2374 12.7626C22.5656 13.0908 22.75 13.5359 22.75 14V19.25H28C28.4641 19.25 28.9093 19.4344 29.2374 19.7626C29.5656 20.0907 29.75 20.5359 29.75 21C29.75 21.4641 29.5656 21.9092 29.2374 22.2374C28.9093 22.5656 28.4641 22.75 28 22.75Z"
fill="white"></path>
</svg>
</span>
<span className='text-white'>Add Credit</span>
</Link>
</div>
</div>
))
:
wallet.error ?
(
<div className="md:flex items-center flex-wrap mt-3">
<p className='text-base'>Opps! An Error occurred, please try again</p>
</div>
)
:
(
<div className="md:flex items-center flex-wrap mt-3">
<p className='text-base'>No Wallets Found!</p>
</div>
)
}
{/* end of wallet balance */}
</div>
</div>
{/* END OF WALLET SECTION */}
</div>
{/*<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>*/}
{/* /!* COUPON SECTION *!/*/}
{/* <div className="lg:w-3/4 w-full mb-10 lg:mb-0">*/}
{/* <div className="wallet w-full md:p-8 p-4 h-full max-h-[500px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">*/}
{/* <h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Coupons</h2>*/}
{/* {coupon.loading ?*/}
{/* <LoadingSpinner size='16' color='sky-blue' />*/}
{/* :*/}
{/* <CouponTable coupon={coupon} />*/}
{/* }*/}
{/* </div>*/}
{/* </div>*/}
{/* /!* END OF COUPON SECTION *!/*/}
{/*</div>*/}
function Balance({ wallet, coupon }) {
return (
<div className="content-wrapper">
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
Wallet
</h1>
</div>
)
<div className="slider-btns flex space-x-4"></div>
</div>
<div className="w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
{/* WALLET SECTION */}
<div className="lg:w-4/4 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full bg-white dark:bg-dark-white rounded-2xl shadow min-h-[520px]">
<div className="flex items-baseline justify-between">
{/*<h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Wallet</h2>*/}
{/*<p className='text-base text-slate-500 dark:text-white'>Add New Wallet</p>*/}
</div>
{/* wallet balance */}
{wallet.loading ? (
<LoadingSpinner size="16" color="sky-blue" />
) : wallet.data.length ? (
wallet.data.map((item, index) => (
<div
key={index}
className="p-3 md:flex items-center flex-wrap my-3 border-t-2 border-slate-400 wallet-box"
>
<div className="text-slate-900 w-full md:w-1/2 flex space-x-3 items-start justify-start">
<div className="balance-info bal-col1">
<p className="py-2"></p>
<span className="text-xl text-dark-gray dark:text-white">
<b>{item.description}</b>
</span>
<p className="text-base text-slate-500">{item.symbol}</p>
</div>
<div className="balance-info">
<p className="py-2">Balance</p>
<span className="py-1 px-2 bg-green-100 text-green-500 rounded-lg flex flex-start gap-1">
{PriceFormatter(item.amount * 0.01, item.code)}
</span>
</div>
<div className="balance-info">
<p className="py-2">Escrow</p>
<span className="py-1 px-2 bg-red-100 text-red-500 rounded-lg flex flex-start gap-1">
{PriceFormatter(item.escrow * 0.01, item.code)}
</span>
</div>
</div>
<div className="w-full my-2 md:my-0 md:w-1/2 flex space-x-2 items-center justify-start md:justify-end">
{item.action_type != "AC_AD_FD_ONLY" ? (
<Link
to="transfer-fund"
className="px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white"
>
Transfer
</Link>
) : (
""
)}
<Link
to="add-fund"
state={{ currency: item.description }}
className="px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white"
>
<span className="">
<svg
xmlns="http://www.w3.org/2000/svg"
width="38"
height="38"
viewBox="0 0 42 42"
fill="none"
>
<path
d="M21 0C16.8466 0 12.7865 1.23163 9.33303 3.53914C5.8796 5.84665 3.18798 9.1264 1.59854 12.9636C0.00909901 16.8009 -0.406771 21.0233 0.403518 25.0969C1.21381 29.1705 3.21386 32.9123 6.15077 35.8492C9.08767 38.7861 12.8295 40.7862 16.9031 41.5965C20.9767 42.4068 25.1991 41.9909 29.0364 40.4015C32.8736 38.812 36.1534 36.1204 38.4609 32.667C40.7684 29.2135 42 25.1534 42 21C41.994 15.4323 39.7796 10.0944 35.8426 6.15741C31.9056 2.22045 26.5677 0.00602189 21 0ZM28 22.75H22.75V28C22.75 28.4641 22.5656 28.9092 22.2374 29.2374C21.9093 29.5656 21.4641 29.75 21 29.75C20.5359 29.75 20.0908 29.5656 19.7626 29.2374C19.4344 28.9092 19.25 28.4641 19.25 28V22.75H14C13.5359 22.75 13.0908 22.5656 12.7626 22.2374C12.4344 21.9092 12.25 21.4641 12.25 21C12.25 20.5359 12.4344 20.0907 12.7626 19.7626C13.0908 19.4344 13.5359 19.25 14 19.25H19.25V14C19.25 13.5359 19.4344 13.0908 19.7626 12.7626C20.0908 12.4344 20.5359 12.25 21 12.25C21.4641 12.25 21.9093 12.4344 22.2374 12.7626C22.5656 13.0908 22.75 13.5359 22.75 14V19.25H28C28.4641 19.25 28.9093 19.4344 29.2374 19.7626C29.5656 20.0907 29.75 20.5359 29.75 21C29.75 21.4641 29.5656 21.9092 29.2374 22.2374C28.9093 22.5656 28.4641 22.75 28 22.75Z"
fill="white"
></path>
</svg>
</span>
<span className="text-white">Add Credit</span>
</Link>
</div>
</div>
))
) : wallet.error ? (
<div className="md:flex items-center flex-wrap mt-3">
<p className="text-base">
Opps! An Error occurred, please try again
</p>
</div>
) : (
<div className="md:flex items-center flex-wrap mt-3">
<p className="text-base">No Wallets Found!</p>
</div>
)}
{/* end of wallet balance */}
</div>
</div>
{/* END OF WALLET SECTION */}
</div>
{/*<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>*/}
{/* /!* COUPON SECTION *!/*/}
{/* <div className="lg:w-3/4 w-full mb-10 lg:mb-0">*/}
{/* <div className="wallet w-full md:p-8 p-4 h-full max-h-[500px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">*/}
{/* <h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Coupons</h2>*/}
{/* {coupon.loading ?*/}
{/* <LoadingSpinner size='16' color='sky-blue' />*/}
{/* :*/}
{/* <CouponTable coupon={coupon} />*/}
{/* }*/}
{/* </div>*/}
{/* </div>*/}
{/* /!* END OF COUPON SECTION *!/*/}
{/*</div>*/}
</div>
);
}
export default Balance
export default Balance;
+149 -92
View File
@@ -1,29 +1,38 @@
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Form, Formik } from "formik";
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import * as Yup from "yup";
import usersService from "../../../services/UsersService";
import Icons from "../../Helpers/Icons";
import InputCom from "../../Helpers/Inputs/InputCom";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import { Form, Formik } from "formik";
import { useSelector } from "react-redux";
import * as Yup from "yup";
import Icons from "../../Helpers/Icons";
const validationSchema = Yup.object().shape({
name: Yup.string()
.min(3, "3 chars min.")
.max(50, "50 chars max.")
.required("required"),
cardNum: Yup.string()
.min(3, "3 chars min.")
.max(25, "25 chars max.")
.min(6, "not a card number")
.max(19, "16 chars max.") //16 chars + 3 spaces
.test("luhn-validation", "Invalid Card Number", (value) => {
const sanitizedNumber = value?.replace(/\D/g, "");
const digits = Array?.from(sanitizedNumber, Number);
for (let i = digits.length - 2; i >= 0; i -= 2) {
digits[i] *= 2;
if (digits[i] > 9) {
digits[i] -= 9;
}
}
const sum = digits.reduce((acc, digit) => acc + digit, 0);
return sum % 10 === 0;
})
.required("required"),
code: Yup.string()
.min(3, "3 chars min.")
.max(25, "25 chars max.")
.required("required"),
state: Yup.string()
.min(3, "3 chars min.")
.min(2, "2 chars min.")
.max(25, "25 chars max.")
.required("required"),
address: Yup.string()
@@ -45,7 +54,6 @@ const validationSchema = Yup.object().shape({
});
const initialValues = {
name: "",
cardNum: "",
code: "",
state: "",
@@ -56,25 +64,54 @@ const initialValues = {
};
function AddFundDollars(props) {
const navigate = useNavigate();
const apiCall = new usersService();
let countryWallet = props.walletItem.country;
const [tab, setTab] = useState("previous");
const [loader, setLoader] = useState(false);
const { userDetails } = useSelector((state) => state?.userDetails);
const { firstname, lastname } = userDetails;
const [prevCardDetails, setPrevCardDetails] = useState({});
const [payListCards, setPayListCards] = useState({ loading: true, data: [] });
let __awaitComponent = props.confirmCredit.show.awaitConfirm;
let __acceptComponent = props.confirmCredit.show.awaitConfirm;
const [cardIcons, setCardIcons] = useState("atm-card");
const [prevCardError, setPrevCardError] = useState("");
const { firstname, lastname } = userDetails;
// Handling Card Icons
const handleCards = (event) => {
const { name, value } = event.target;
if (name == "cardNum") {
// Check if the first character is 4 or 5 and set the card icon accordingly
const cardIcon =
value.length > 0
? value[0] === "4"
? "visa-card"
: value[0] === "5"
? "master-card"
: "atm-card"
: "atm-card";
setCardIcons(cardIcon);
}
};
// Handling card change
const handleInputChange = (event) => {
const { name, value } = event.target;
setPrevCardDetails((prevState) => ({
...prevState,
[name]: value,
}));
};
// Handling card number grouping
const handleCardNumberChange = (value) => {
return value
?.replace(/\s/g, "") // Remove existing spaces
.match(/.{1,4}/g) // Group every four characters
?.join(" ");
};
// card slicer
const indexOfFirstItem = 0;
const indexOfLastItem =
indexOfFirstItem + Number(process.env.REACT_APP_ITEM_PER_PAGE);
@@ -83,78 +120,80 @@ function AddFundDollars(props) {
indexOfLastItem
);
// Submission for both prev and new cards
const handleSubmit = async (values, helpers) => {
props.setInputError("");
if (!props.input || props.input === "0") {
props.setInputError("Please Enter Amount");
setTimeout(() => props.setInputError(""), 5000);
return;
}
if (isNaN(props.input)) {
props.setInputError("Amount must be a Number");
setTimeout(() => props.setInputError(""), 5000);
return;
}
if (Number(props.input) * 100 > Number(props.walletItem?.transfer_limit)) {
props.setInputError("Credit limit has been exceeded");
setTimeout(() => props.setInputError(""), 5000);
return;
}
if (tab === "previous") {
if (!prevCardDetails) {
// To check if card is empty
if (Object.keys(prevCardDetails).length === 0) {
setPrevCardError("No card selected!");
setTimeout(() => setPrevCardError(""), 5000);
return;
}
props.setConfirmCredit((prev) => ({
...prev,
show: { awaitConfirm: { loader: true } },
}));
let stateData = {
amount: Number(props.input) * 100,
currency: props.walletItem?.code,
};
try {
const res = await apiCall.getStartCredit(stateData);
if (res.data.internal_return < 0) {
props.setConfirmCredit((prev) => ({
...prev,
show: { awaitConfirm: { loader: false } },
}));
props.setInputError("An Error Occurred");
setTimeout(() => props.setInputError(""), 5000);
return;
}
const _response = res.data;
stateData.amount = Number(props.input);
stateData.card = prevCardDetails["payment-card"];
stateData.cardType = "prev";
stateData = { ...stateData, ..._response };
setTimeout(() => {
props.setConfirmCredit({
show: {
awaitConfirm: { loader: false, state: true },
acceptConfirm: { loader: false, state: false },
},
data: stateData,
});
}, 1500);
} catch (error) {
props.setConfirmCredit((prev) => ({
...prev,
show: { awaitConfirm: { loader: false } },
}));
console.log(error);
}
}
if (tab === "new") {
const stateData = {
amount: Number(props.input),
currency: props.currency,
...values,
};
props.setConfirmCredit((prev) => ({
...prev,
show: { awaitConfirm: { loader: true } },
}));
// Rest of the code for tab "new"
let stateData = {
amount: Number(props.input) * 100,
currency: props.walletItem?.code,
};
try {
const res = await apiCall.getStartCredit(stateData);
if (res.data.internal_return < 0) {
props.setInputError("An Error Occurred");
throw new Error("An Error Occurred");
}
const _response = res.data;
stateData.amount = Number(props.input);
stateData.card =
tab === "previous"
? prevCardDetails["payment-card"]
: { ...values, cvv: values.cvv };
stateData.cardType = tab === "previous" ? "prev" : "new";
stateData = { ...stateData, ..._response };
setTimeout(() => {
props.setConfirmCredit({
show: {
awaitConfirm: { loader: false, state: true },
acceptConfirm: { loader: false, state: false },
},
data: stateData,
});
}, 1500);
} catch (error) {
props.setInputError(error.message);
setTimeout(() => props.setInputError(""), 5000);
props.setConfirmCredit((prev) => ({
...prev,
show: { awaitConfirm: { loader: false } },
}));
console.log(error);
}
};
@@ -221,8 +260,8 @@ function AddFundDollars(props) {
{/* END OF switch button */}
{/* previous tab */}
{tab === "previous" ? (
<div className="p-4 previous-details w-full min-h-[16rem] flex flex-col justify-between items-center">
{tab === "previous" && (
<div className="p-4 previous-details w-full min-h-[16.5rem] flex flex-col">
{payListCards.loading ? (
<LoadingSpinner size="10" color="sky-blue" />
) : payListCards?.data?.length ? (
@@ -267,9 +306,14 @@ function AddFundDollars(props) {
</button>
</div>
)}
<p className="text-base italic text-red-500 h-5">
{prevCardError && prevCardError}
</p>
</div>
) : (
<div className="new-details w-full max-h-[23rem]">
)}
{tab === "new" && (
<div className="new-details w-full max-h-[22rem]">
<div className="w-full flex flex-col justify-between">
<Formik
initialValues={initialValues}
@@ -297,17 +341,21 @@ function AddFundDollars(props) {
<InputCom
fieldClass="px-6"
spanTag="*"
iconName="master-card visa-card atm-card"
iconName={cardIcons}
label="Card Number"
type="text"
name="cardNum"
onInput={handleCards}
placeholder="Enter Card Number"
value={props.values.cardNum}
value={handleCardNumberChange(
props.values.cardNum
)}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
error={props.errors.cardNum}
/>
</div>
{/* Expire Year, Year */}
<div className="sm:grid gap-5 grid-cols-2 flex-[0.4]">
<div className="field w-full mb-6 xl:mb-0 col-span-1">
@@ -348,7 +396,11 @@ function AddFundDollars(props) {
expireMonth.map((item, index) => (
<option
key={index}
value={item.value}
value={
Number(item.value) < 10
? "0" + item.value
: item.value
}
>
{item.name}
</option>
@@ -357,6 +409,7 @@ function AddFundDollars(props) {
</div>
</div>
</div>
<div className="field w-full mb-6 xl:mb-0 col-span-1">
<div className="select-option">
<div
@@ -404,17 +457,18 @@ function AddFundDollars(props) {
</div>
</div>
{/* Address and CVV */}
<div className="flex items-center flex-1 gap-3 my-2">
{/* Address and CVV */}
<div className="field w-full col-span-1 flex-[0.4]">
<InputCom
fieldClass="px-6"
spanTag="*"
iconName="atm-card"
iconName={cardIcons}
label="CVV"
type="text"
name="cvv"
placeholder="CVV"
maxLength={3}
value={props.values.cvv}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
@@ -439,15 +493,16 @@ function AddFundDollars(props) {
{/* Postal Code and State */}
<div className="sm:grid gap-5 grid-cols-3 my-2">
<div className="field w-full mb-6 xl:mb-0 col-span-1">
<div className="field w-full xl:mb-0 col-span-1">
<InputCom
fieldClass="px-6"
spanTag="*"
label="Postal Code"
type="text"
type="number"
name="code"
placeholder="Postal Code"
value={props.values.code}
maxLength={6}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
error={props.errors.code}
@@ -461,7 +516,7 @@ function AddFundDollars(props) {
type="text"
name="state"
placeholder="State"
value={props.values.state}
value={props.values.state.toUpperCase()}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
error={props.errors.state}
@@ -472,18 +527,18 @@ function AddFundDollars(props) {
</div>
</div>
<div className="md:px-8 md:pt-4 px-4 pt-2 add-fund-btn flex justify-end items-center gap-3">
<div className="add-fund-btn flex justify-end items-center gap-2 mt-4">
<button
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center bg-[#f5a430] text-black items-center text-base rounded-full"
onClick={handleClose}
>
Cancel
</button>
<button
type="submit"
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
{loader ? (
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
<LoadingSpinner size="6" color="sky-blue" />
) : (
<>
@@ -501,18 +556,20 @@ function AddFundDollars(props) {
</div>
)}
</div>
{tab == "previous" && (
<div className="md:py-8 px-[38px] add-fund-btn flex justify-end items-center gap-4 py-4">
<div className="md:py-8 add-fund-btn flex justify-end items-center gap-2 py-4">
<button
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center bg-[#f5a430] text-black items-center text-base rounded-full"
onClick={props.onClose}
>
Cancel
</button>
<button
onClick={handleSubmit}
name="previous"
type="button"
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
<LoadingSpinner size="6" color="sky-blue" />
+11 -7
View File
@@ -1,5 +1,4 @@
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import usersService from "../../../services/UsersService";
import Icons from "../../Helpers/Icons";
import InputCom from "../../Helpers/Inputs/InputCom";
@@ -15,10 +14,9 @@ function AddFundPop({
setConfirmCredit,
walletItem,
}) {
const navigate = useNavigate();
const apiCall = new usersService();
let countryWallet = walletItem?.country;
const { payment, currency } = _payment;
const { currency } = _payment;
const [inputError, setInputError] = useState("");
let __awaitComponent = confirmCredit.show.awaitConfirm;
@@ -44,6 +42,12 @@ function AddFundPop({
return;
}
if (Number(input) * 100 > Number(walletItem?.transfer_limit)) {
setInputError("Credit limit has been exceeded");
setTimeout(() => setInputError(""), 5000);
return;
}
if (isNaN(input)) {
setConfirmCredit((prev) => ({
...prev,
@@ -106,14 +110,14 @@ function AddFundPop({
</h1>
<div className="field w-full max-w-[250px]">
<InputCom
fieldClass="px-6"
fieldClass="px-6 text-right"
type="text"
name="amount"
placeholder="0"
value={input}
inputHandler={handleChange}
/>
<p className="text-base text-red-500 h-5">
<p className="text-base text-red-500 italic h-5">
{inputError && inputError}
</p>
</div>
@@ -134,12 +138,12 @@ function AddFundPop({
</div>
)}
{countryWallet == "NG" && <div className="h-[18rem]"></div>}
{countryWallet == "NG" && <div className="h-[19rem]"></div>}
{countryWallet == "NG" && (
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
<button
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center bg-[#f5a430] text-black text-base rounded-full"
onClick={onClose}
>
Cancel
@@ -1,7 +1,6 @@
import React from "react";
function CompleteConfirmCredit({ onClose, confirmCredit }) {
console.log(confirmCredit);
const { data } = confirmCredit;
return (
<div className="logout-modal-body w-full flex flex-col items-center">
@@ -10,10 +9,16 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
<div className="px-4 md:p-8 py-4 add-fund-info">
<div className="field w-full mb-3 min-h-[45px]">
<div className="flex flex-col gap-4">
<div
className={`flex flex-col gap-4 ${
data?.result !== "Charge success" &&
"h-[328px] items-center justify-center"
}`}
>
{/* Success Icon for now */}
<div className="flex items-center w-full justify-center">
{data?.result == "Charge success" ? (
{data?.result == "Charge success" ||
data?.status == "successful" ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="100"
@@ -51,40 +56,46 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
<div className={`flex items-center`}>
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
{data?.result == "Charge success"
{data?.result == "Charge success" ||
data?.status == "successful"
? "Credit was Successful!"
: "Credit was Unsuccessful"}
</h1>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Amount({data?.currency || ""})
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{`${data?.symbol || ""} ${
Number(data?.amount * 0.01).toLocaleString() || ""
}`}
</span>
</div>
{data?.internal_return >= 0 &&
data?.result !== "Charge failed" ? (
<>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Amount({data?.currency || ""})
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{`${data?.symbol || ""} ${
Number(data?.amount * 0.01).toLocaleString() || ""
}`}
</span>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Wallet Balance
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{data?.curr_balance}
</span>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Wallet Balance
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{data?.curr_balance}
</span>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Confirmation Number
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{data?.confirmation}
</span>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Confirmation Number
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{data?.confirmation}
</span>
</div>
</>
) : null}
</div>
</div>
</div>
+264 -143
View File
@@ -1,11 +1,90 @@
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
import React, { useState } from "react";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { toast } from "react-toastify";
import debounce from "../../../hooks/debounce";
import usersService from "../../../services/UsersService";
import { tableReload } from "../../../store/TableReloads";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
function ThePaymentText({ value, type }) {
const cardDetails = value;
value.description =
type === "new"
? cardDetails.cardNum[0] === "4"
? "Visa"
: cardDetails.cardNum[0] == "5"
? "Master"
: "ATM"
: value.description;
value.digits = type === "new" ? cardDetails.cardNum.slice(-4) : value.digits;
return (
<div className="my-2 flex items-center gap-5">
<div className="card-details flex items-center gap-3">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1 space-x-1">
{value.description} Card
</h1>
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
Bank **************{value.digits}
</p>
</div>
</div>
);
}
function AmountSection({ currency, amount, country }) {
const formattedAmount = Number(amount).toFixed(2);
return (
<div
className={`flex items-center ${country == "US" ? "gap-14" : "gap-4"}`}
>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Amount({currency})
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{formattedAmount}
</span>
</div>
);
}
function TransactionFeeSection({ currency, fee, country }) {
const formattedFee = Number(fee).toFixed(2);
return (
<div
className={`flex items-center border-b border-gray-600 ${
country == "US" ? "gap-[2.7rem]" : "gap-4"
}`}
>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Transaction Fee
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{formattedFee}
</span>
</div>
);
}
function TotalSection({ currency, amount, fee, country }) {
const total = Number(amount) + Number(fee);
const formattedTotal = total.toFixed(2);
return (
<div
className={`flex items-center ${
country == "US" ? "gap-[8rem]" : "gap-[6.3rem]"
}`}
>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Total
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{formattedTotal}
</span>
</div>
);
}
function ConfirmAddFund({
confirmCredit,
onClose,
@@ -14,26 +93,67 @@ function ConfirmAddFund({
}) {
const __confirmData = confirmCredit?.data;
const __confirmCountry = walletItem?.country;
const __confirmCardDetails = __confirmData.card
? JSON.parse(__confirmData.card)
: "";
let { userDetails } = useSelector((state) => state.userDetails); // TO GET LOGGEDIN USER DETAILS
const __confirmCardDetails =
__confirmData.cardType === "prev"
? JSON.parse(__confirmData.card)
: __confirmData.card;
let [requestStatus, setRequestStatus] = useState({
const apiURL = new usersService();
const { userDetails } = useSelector((state) => state?.userDetails);
const dispatch = useDispatch();
const [requestStatus, setRequestStatus] = useState({
message: "",
loading: false,
status: false,
}); // STATE FOR API REQUEST
});
const apiURL = new usersService();
const navigate = useNavigate();
const config = {
public_key: __confirmData?.flutterwave_key,
tx_ref: __confirmData?.credit_reference,
currency: "NGN",
amount: Number(__confirmData.amount),
payment_options: "card,mobilemoney,ussd",
customer: {
email: userDetails.email,
phone_number: userDetails.phone,
name: `${userDetails.lastname} ${userDetails.firstname}`,
},
customizations: {
title: "WrenchBoard",
description: "Add Credit Payment",
logo: "https://www.wrenchboard.com/assets/images/wrench-500-500-icon.png",
},
};
//debugger;
const fwConfig = {
...config,
text: "Proceed",
callback: (response) => {
debouncedSuccessPayment(); //delays the call for 5 secs
setTimeout(() => {
closePaymentModal();
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: response,
}));
}, 1500);
},
};
//FUNCTION TO HANDLE SUBMIT
const onSuccessPayment = () => {
setRequestStatus({ message: "", loading: true, status: false });
let reqData = { amount: __confirmData?.account, currency: "NGN" };
const reqData = { tx_ref: __confirmData?.credit_reference };
console.log("**** onSuccessPayment **** THIS WAS REACHED");
apiURL
.startTopUp(reqData)
.resultTopUp(reqData)
.then((res) => {
if (res.data.internal_return < 0) {
setRequestStatus({
@@ -41,59 +161,33 @@ function ConfirmAddFund({
loading: false,
status: false,
});
toast.success("Opps! something went wrong");
}
// do something
setRequestStatus({
message: "Topup successful",
loading: false,
status: true,
});
toast.success("Account Topup was successful");
setTimeout(() => {
navigate("/my-wallet", { replace: true });
}, 1000);
return dispatch(tableReload({ type: "WALLETTABLE" }));
})
.catch((err) => {
// do something
setRequestStatus({
message: "Opps! An Error Occured",
loading: false,
status: false,
});
setTimeout(() => {
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: err,
}));
}, 1500);
toast.success("Opps! something went wrong");
});
};
const config = {
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
tx_ref: Date.now(),
amount: __confirmData?.amount,
currency: "NGN",
payment_options: "card,mobilemoney,ussd",
customer: {
email: `${userDetails.email}`,
phone_number: userDetails.phone,
name: `${userDetails.lastname} ${userDetails.firstname}`,
},
customizations: {
title: "WrenchBoard",
description: "Topup Payment",
logo: "https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg",
},
};
const debouncedSuccessPayment = debounce(onSuccessPayment, 5000);
const fwConfig = {
...config,
text: "Proceed",
callback: (response) => {
onSuccessPayment();
closePaymentModal(); // this will close the modal programmatically
},
onClose: () => {},
};
// Handling Previous Card
const handlePrevCard = async () => {
const { amount, credit_reference, currency } = __confirmData;
const { card_uid } = __confirmCardDetails;
@@ -124,18 +218,17 @@ function ConfirmAddFund({
return;
}
return setTimeout(
() =>
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: _response,
})),
1500
);
setTimeout(() => {
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: _response,
}));
dispatch(tableReload({ type: "WALLETTABLE" }));
}, 1500);
} catch (error) {
setConfirmCredit((prev) => ({
...prev,
@@ -147,18 +240,77 @@ function ConfirmAddFund({
}
};
const ThePaymentText = ({ value }) => (
<div className="my-2 flex items-center gap-5">
<div className="card-details flex items-center gap-3">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{value.description} Card
</h1>
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
Bank **************{value.digits}
</p>
</div>
</div>
);
const handleNewCard = async () => {
const { amount, credit_reference, uid } = __confirmData;
const { address, cardNum, cvv, expirationMonth, expirationYear } =
__confirmCardDetails;
const reqData = {
amount: amount * 100,
cardnumber: cardNum.replace(/\s/g, ""),
credit_reference,
cvc: cvv,
description: address,
exp_month: expirationMonth,
exp_year: expirationYear,
paymenttype: 100,
uid,
};
try {
setConfirmCredit((prev) => ({
...prev,
show: {
acceptConfirm: { loader: true },
},
}));
const res = await apiURL.getPaidNewCard(reqData);
const _response = res.data;
if (res.data.internal_return < 0) {
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: _response,
}));
return;
}
setTimeout(() => {
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: _response,
}));
dispatch(tableReload({ type: "WALLETTABLE" }));
}, 1500);
} catch (error) {
setConfirmCredit((prev) => ({
...prev,
show: {
acceptConfirm: { loader: false },
},
}));
setTimeout(() => onClose, 10000);
console.log(error);
}
};
const getBack = () => {
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: false },
},
data: {},
}));
};
return (
<div className="content-wrapper w-full h-[32rem]">
@@ -166,76 +318,45 @@ function ConfirmAddFund({
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
<div className="px-4 md:p-8 py-4 add-fund-info">
<div className="field w-full mb-3 min-h-[45px]">
{confirmCredit?.show?.awaitConfirm?.state ? (
{confirmCredit?.show?.awaitConfirm?.state && (
<div className="flex flex-col gap-2">
{/* Amount */}
<div
className={`flex items-center ${
__confirmCountry == "US" ? "gap-14" : "gap-4"
}`}
>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Amount({__confirmData?.currency})
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{`${walletItem?.symbol} ${
Number(__confirmData?.amount).toLocaleString() || ""
}`}
</span>
</div>
{/* Transaction Fee */}
<div
className={`flex items-center border-b border-gray-600 ${
__confirmCountry == "US" ? "gap-[2.7rem]" : "gap-4"
}`}
>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Transaction Fee
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{`${walletItem?.symbol} ${
Number(__confirmData?.fee).toLocaleString() || ""
}`}
</span>
</div>
{/* Total */}
<div
className={`flex items-center ${
__confirmCountry == "US" ? "gap-[8rem]" : "gap-4"
}`}
>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Total
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{`${walletItem?.symbol} ${
(
Number(__confirmData?.amount) +
Number(__confirmData?.fee)
).toLocaleString() || ""
}`}
</span>
</div>
{__confirmCountry == "US" && (
<AmountSection
currency={__confirmData?.currency}
amount={__confirmData?.amount}
country={__confirmCountry}
/>
<TransactionFeeSection
currency={__confirmData?.currency}
fee={__confirmData?.fee}
country={__confirmCountry}
/>
<TotalSection
currency={__confirmData?.currency}
amount={__confirmData?.amount}
fee={__confirmData?.fee}
country={__confirmCountry}
/>
{__confirmCountry === "US" && (
<div className="flex items-center gap-8">
<label
htmlFor="payment"
className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1"
>
{__confirmCountry == "US" && "Payment Method"}
Payment Method
</label>
<span className="text-[#181c32] dark:text-white ">
{__confirmCardDetails ? (
<ThePaymentText value={__confirmCardDetails} />
) : null}
<span className="text-[#181c32] dark:text-white">
<ThePaymentText
value={__confirmCardDetails}
type={__confirmData?.cardType}
/>
</span>
</div>
)}
<div
className={`${
__confirmCountry == "US" ? "gap-[3.7rem]" : "gap-8"
__confirmCountry === "US"
? "gap-[3.7rem]"
: "gap-[1.81rem]"
} flex items-center`}
>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
@@ -246,30 +367,30 @@ function ConfirmAddFund({
</span>
</div>
</div>
) : null}
)}
</div>
</div>
<div
className={
__confirmCountry == "US" ? "min-h-[96px]" : "min-h-[200px]"
__confirmCountry === "US" ? "min-h-[96px]" : "min-h-[157px]"
}
></div>
<hr />
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
<button
className="px-4 h-11 flex justify-center items-center border-gradient text-base rounded-full"
onClick={onClose}
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center bg-[#f5a430] text-black items-center text-base rounded-full"
onClick={getBack}
>
Cancel
Back
</button>
{__confirmCountry == "US" && (
{__confirmCountry === "US" && (
<button
className="px-4 h-11 flex justify-center items-center btn-gradient text-white text-base rounded-full"
onClick={
__confirmData?.cardType === "prev"
? handlePrevCard
: () => console.log("Test me")
: handleNewCard
}
>
{confirmCredit?.show?.acceptConfirm?.loader ? (
@@ -279,7 +400,7 @@ function ConfirmAddFund({
)}
</button>
)}
{__confirmCountry == "NG" && (
{__confirmCountry === "NG" && (
<FlutterWaveButton
{...fwConfig}
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
@@ -0,0 +1,432 @@
import { useState } from "react";
import { useDispatch } from "react-redux";
import usersService from "../../../services/UsersService";
import { tableReload } from "../../../store/TableReloads";
import InputCom from "../../Helpers/Inputs/InputCom";
import ModalCom from "../../Helpers/ModalCom";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
function ConfirmNairaWithdraw({
payment,
wallet,
action,
situation,
state,
setShowNairaWithdraw,
}) {
const apiURL = new usersService();
const dispatch = useDispatch();
let [requestStatus, setRequestStatus] = useState({
message: "",
loading: false,
status: false,
});
const [completeNairaWithdraw, setShowCompleteNairaWithdraw] = useState({
show: false,
load: false,
state: {},
}); // DETERMINES WHEN CONFIRM NAIRA WITHDRAWAL POPS UP
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = () => {
setRequestStatus({ message: "", loading: true, status: false });
setShowCompleteNairaWithdraw({ load: true });
let reqData = {
amount: Number(state.amount * 100),
Fee: Number(state.fee),
wallet_uid: wallet.wallet_uid,
};
if (state?.choice === "prev") {
reqData.recipient_uid = state.details?.recipient_uid;
reqData.mode = 100;
}
if (state?.choice === "new") {
reqData.account_no = state?.details?.accountNumber;
reqData.account_type = Number(state?.details?.accountType);
reqData.bank_uid = state?.details?.bank_uid;
reqData.country = state?.details?.country;
reqData.state = state?.details?.state;
reqData.city = state?.details?.city;
reqData.mode = 500;
}
apiURL
.sendMoney(reqData)
.then((res) => {
if (res.data.internal_return < 0) {
// if (res.data?.status_message?.toLowerCase().includes("limit")) {
// setRequestStatus({
// message: ,
// loading: false,
// status: false,
// });
// }
return setTimeout(() => {
setRequestStatus({
message: "",
loading: false,
status: false,
});
setShowCompleteNairaWithdraw({
show: true,
load: false,
state: res.data,
});
}, 5000);
}
setTimeout(() => {
setRequestStatus({
message: "",
loading: false,
status: false,
});
setShowCompleteNairaWithdraw({
show: true,
load: false,
state: res.data,
});
}, 5000);
dispatch(tableReload({ type: "WALLETTABLE" }));
return;
})
.catch((error) => {
setRequestStatus({
message: "Opps! something went wrong! Try Again",
loading: false,
status: false,
});
});
};
return (
<ModalCom action={action} situation={situation} className="edit-popup">
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="w-full">
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
<h2 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
{completeNairaWithdraw.load ? (
"Confirming..."
) : (
<>
{" "}
{completeNairaWithdraw.show
? completeNairaWithdraw?.state?.internal_return >= 0
? "Transfer Success"
: "Transfer Error"
: `Withdraw from ${wallet.description} Wallet : ${
wallet.symbol
}${(wallet.amount * 0.01).toFixed(2)}`}
</>
)}
</h2>
<button
type="button"
className="text-[#374557] dark:text-red-500"
onClick={action}
>
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
fill=""
fillOpacity="0.6"
/>
<path
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
fill="#"
fillOpacity="0.6"
/>
</svg>
</button>
</div>
<hr />
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
{completeNairaWithdraw.load ? (
<div className="h-[35rem] flex items-center justify-center">
<LoadingSpinner size="12" color="sky-blue" />
</div>
) : completeNairaWithdraw.show ? (
<div className="px-4 md:p-8 py-4 add-fund-info">
<div className="field w-full mb-3 min-h-[23rem]">
<div className="flex items-center w-full justify-center mb-3">
{completeNairaWithdraw.state?.sendmoney_message
?.toLowerCase()
?.includes("completed") ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="100"
height="100"
viewBox="0 0 24 24"
fill="none"
stroke="green"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="feather feather-check-circle"
>
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
<polyline points="22 4 12 14.01 9 11.01"></polyline>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
width="100"
height="100"
stroke="red"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="feather feather-x-circle"
>
<circle cx="12" cy="12" r="10"></circle>
<line x1="15" y1="9" x2="9" y2="15"></line>
<line x1="9" y1="9" x2="15" y2="15"></line>
</svg>
)}
</div>
{completeNairaWithdraw.state?.internal_return >= 0 ? (
<>
<div className={`flex items-center`}>
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.sendmoney_message || ""}
</h1>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Amount(
{completeNairaWithdraw.state
?.terminatingcountrycode || ""}
)
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{Number(
completeNairaWithdraw.state?.TerminatingAmount *
0.01
).toLocaleString() || ""}
</span>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Recipient
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.recitient}
</span>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Confirmation Number
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.confirmation}
</span>
</div>{" "}
</>
) : (
<>
<div className={`flex items-center`}>
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("not_found")
? "Wallet Error Occurred"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("recipient_add_error")
? "Recipient Error Occurred"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("limit")
? "Transfer limit Error"
: completeNairaWithdraw.state?.bad_param
?.toLowerCase()
.includes("balance")
? "Insufficient Balance"
: "An Error Occurred"}{" "}
</h1>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Message:
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("not_found")
? "This Wallet is not Found"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("recipient_add_error")
? "No Recipient Found"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("limit")
? "The transfer limit has been exceeded"
: completeNairaWithdraw.state?.bad_param
?.toLowerCase()
.includes("balance")
? "Insufficient Balance for Transaction"
: "Could not perform transaction"}
</span>
</div>
</>
)}
</div>
</div>
) : (
<div className="px-4 md:px-8 py-4 add-fund-info">
<h2 className="my-2 text-slate-900 dark:text-white text-sm xl:text-xl font-medium">
{/* Confirm Withdraw to Account */}
</h2>
{/* AMOUNT */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Amount:"
type="text"
name="amount"
value={state?.amount || ""}
disable={true}
/>
</div>
{state?.choice === "prev" && (
<>
{/* RECIPIENT ACC: */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Recipient Acc:"
type="text"
name="recipient"
value={state?.details?.recipient || ""}
disable={true}
/>
</div>
</>
)}
{state?.choice === "new" && (
<>
{/* RECIPIENT ACC: */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Bank Acc:"
type="text"
name="bank"
value={
`${state?.details?.name} ${state?.details?.country}` ||
""
}
disable={true}
/>
</div>
</>
)}
{/* PROCESSING FEE: */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Processing Fee:"
type="text"
name="processingFee"
value={(state?.fee * 0.01).toFixed(2) || ""}
disable={true}
/>
</div>
{/* TOTAL */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Total"
type="text"
name="total"
value={(state?.total * 0.01).toFixed(2) || ""}
disable={true}
/>
</div>
{/* COMMENT/NOTE */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Comment/Note:"
type="text"
name="comment"
value={state?.comment || ""}
disable={true}
/>
</div>
</div>
)}
{!completeNairaWithdraw.load && (
<>
{" "}
<hr />
<p
className={`text-base ${
requestStatus.status ? "text-green-500" : "text-red-500"
} px-4 md:px-8 py-4 h-5`}
>
{requestStatus.message && requestStatus.message}
</p>
<div className="px-4 md:px-8 py-4 add-fund-btn flex justify-end items-center gap-2">
{!completeNairaWithdraw.show && (
<button
type="button"
onClick={action}
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center bg-[#f5a430] text-black text-base rounded-full"
>
Cancel
</button>
)}
<button
onClick={
completeNairaWithdraw.show
? action
: completeNairaWithdraw?.state?.internal_return < 0
? action
: handleSubmit
}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer min-w-[100px]"
>
{requestStatus.loading ? (
<LoadingSpinner size="6" color="sky-blue" />
) : completeNairaWithdraw.show ? (
"Okay"
) : completeNairaWithdraw?.state?.internal_return < 0 ? (
"Cancel"
) : (
"Transfer"
)}
</button>
</div>
</>
)}
</div>
</div>
</div>
</ModalCom>
);
}
export default ConfirmNairaWithdraw;
@@ -60,14 +60,6 @@ function ConfirmTransfer({ payment, wallet }) {
});
};
useEffect(() => {
// what happens if not state redirect user
if (!state) {
navigate("/my-wallet/transfer-fund", { replace: true });
} else {
setPageLoading(false);
}
}, []);
return (
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
{pageLoading ? (
+17 -7
View File
@@ -24,13 +24,23 @@ const CreditPopup = ({ details, onClose, situation, walletItem }) => {
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
{confirmCredit?.show?.acceptConfirm?.loader
? "Confirming Credit..."
: confirmCredit?.show?.awaitConfirm?.state
? "Confirm Credit Add"
: confirmCredit?.show?.acceptConfirm?.state
? "Credit Add Completed"
: "Add Credit"}
{confirmCredit?.show?.acceptConfirm?.state &&
(confirmCredit?.data?.internal_return < 0
// ||
// confirmCredit?.data?.status !== "successful"
) ? (
"Credit Unsuccessful"
) : (
<>
{confirmCredit?.show?.acceptConfirm?.loader
? "Confirming Credit..."
: confirmCredit?.show?.awaitConfirm?.state
? "Confirm Credit Add"
: confirmCredit?.show?.acceptConfirm?.state
? "Credit Add Completed"
: "Add Credit"}
</>
)}
</h1>
<button
type="button"
@@ -0,0 +1,831 @@
import { Form, Formik } from "formik";
import React, { useEffect, useState } from "react";
import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
import ModalCom from "../../Helpers/ModalCom";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
function NairaWithdraw({
wallet,
action,
situation,
state,
setShowConfirmNairaWithdraw,
}) {
const apiCall = new usersService();
const [tab, setTab] = useState("previous");
let [requestStatus, setRequestStatus] = useState(false);
const initialValues = {
amount: state?.amount || "",
comment: state?.comment || "",
previousAccount: {
recipientID: state?.previousAccount?.recipientID || "",
},
newAccount: {
country: state?.newAccount?.amount || "",
bank: state?.newAccount?.amount || "",
accountNumber: state?.newAccount?.amount || "",
accountType: state?.newAccount?.amount || "",
state: state?.newAccount?.amount || "",
city: state?.newAccount?.amount || "",
},
};
const [errorMsgs, setErrorMsgs] = useState(initialValues);
let [sendMoneyFee, setSendMoneyFee] = useState({
loading: false,
fee: 0,
total: 0,
}); // HOLD THE VALUE FOR walletSEND MONEY FEE
// Previous Account
let [recipients, setRecipients] = useState({
// FOR COUPON HISTORY
loading: true,
data: [],
error: false,
});
// New Account
let [allCountries, setAllCountries] = useState({
// STATE TO HOLD LIST OF COUNTRIES
loading: true,
data: [],
});
let [bankName, setBankName] = useState({
// STATE TO HOLD LIST OF BANK NAME
loading: false,
data: [],
});
let [accType, setAccType] = useState({
// STATE TO HOLD LIST ACCOUNT TYPE
loading: true,
data: [],
});
// Handling card change
const handleBankOptions = (event) => {
const { value } = event.target;
setBankName((prev) => ({ loading: true, data: [] }));
apiCall
.getCountryBank({ country: value })
.then((res) => {
if (res.data.internal_return < 0) {
setBankName((prev) => ({ loading: false, data: [] }));
return;
}
setBankName((prev) => ({ loading: false, data: res.data.result_list }));
})
.catch((error) => {
setBankName((prev) => ({ loading: false, data: [] }));
});
};
//FUNCTION TO GET RECIPIENT LIST
const getRecipients = () => {
apiCall
.getRecipient()
.then((res) => {
if (res.data.internal_return < 0) {
// success but no data
setRecipients((prev) => ({ ...prev, loading: false }));
return;
}
setRecipients((prev) => ({
...prev,
loading: false,
data: res.data.result_list,
}));
})
.catch((error) => {
setRecipients((prev) => ({ ...prev, loading: false, error: true }));
});
};
// FUNCTION TO GET COUNTRIES
const getCountry = () => {
apiCall
.getSignupCountryData()
.then((res) => {
if (res.data.internal_return < 0) {
setAllCountries((prev) => ({ loading: false, data: [] }));
return;
}
setAllCountries((prev) => ({
loading: false,
data: res.data.signup_country,
}));
})
.catch((error) => {
setAllCountries((prev) => ({ loading: false, data: [] }));
});
};
// FUNCTION TO GET ACCOUNT TYPES
const getAccountTypes = () => {
apiCall
.getAccountTypes()
.then((res) => {
if (res.data.internal_return < 0) {
setAccType((prev) => ({ loading: false, data: [] }));
return;
}
setAccType((prev) => ({ loading: false, data: res.data.result_list }));
})
.catch((error) => {
setAccType((prev) => ({ loading: false, data: [] }));
});
};
useEffect(() => {
getCountry(); // TO LOAD LIST COUNTRY
getAccountTypes(); // TO LOAD LIST ACCOUNT TYPES
}, []);
//FUNCTION TO GET SEND MONEY FEE
const getSendMoneyFee = ({ target: { value } }) => {
setSendMoneyFee({ loading: true, fee: 0, total: 0 });
let amount = value;
if (Number(amount) <= 0 || amount == "" || isNaN(amount)) {
setSendMoneyFee({ loading: false, fee: 0, total: 0 });
return;
}
apiCall
.getSendMoneyFee(Number(amount * 100))
.then((res) => {
setSendMoneyFee({
loading: false,
fee: res.data.processing_fee,
total: res.data.total_amount,
});
})
.catch((error) => {
setSendMoneyFee({ loading: false, fee: 0, total: 0 });
});
};
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = async (values, helpers) => {
try {
if (!values?.amount) {
setErrorMsgs({ amount: "amount required" });
setTimeout(() => setErrorMsgs({ amount: "" }), 3000);
return;
} else if (Number(values.amount * 100) > Number(wallet?.transfer_limit)) {
setErrorMsgs({ amount: "Withdraw limit has been exceeded" });
setTimeout(() => setErrorMsgs({ amount: "" }), 3000);
return;
}
if (values?.comment?.length >= 50) {
setErrorMsgs({ comment: "50 chars max" });
setTimeout(() => setErrorMsgs({ comment: "" }), 1000);
}
// form submission logic here
if (tab === "previous") {
if (!values?.previousAccount?.recipientID) {
setErrorMsgs({
previousAccount: { recipientID: "Please select an option" },
});
setTimeout(
() => setErrorMsgs({ previousAccount: { recipientID: "" } }),
1000
);
}
setRequestStatus(true);
// Ensure recipientDetails is an array and not undefined
const recipientDetails = recipients.data?.filter(
(item) => item.recipient_uid === values.previousAccount?.recipientID
);
// Ensure recipientDetails is not empty
if (!recipientDetails || recipientDetails.length === 0) {
// Handle the case when recipientDetails is empty or undefined
setRequestStatus(false);
return;
}
const stateData = {
amount: values.amount,
comment: values.comment,
choice: "prev",
wallet_uid: wallet.wallet_uid,
...sendMoneyFee,
details: { ...recipientDetails[0] },
};
return setTimeout(() => {
setRequestStatus(false);
// navigate("confirm-withdraw-naira", { state: stateData });
action();
setShowConfirmNairaWithdraw({ show: true, state: stateData });
}, 1000);
}
if (tab === "new") {
const { accountNumber, accountType, bank, city, country, state } =
values?.newAccount;
if (
!accountNumber ||
!accountType ||
!bank ||
!city ||
!country ||
!state
) {
return;
}
setRequestStatus(true);
// Ensure bankDetails is an array and not undefined
const bankDetails = bankName.data?.filter(
(item) => item.bank_uid === bank
);
// Ensure bankDetails is not empty
if (!bankDetails || bankDetails.length === 0) {
// Handle the case when bankDetails is empty or undefined
setRequestStatus(false);
return;
}
const stateData = {
amount: values.amount,
comment: values.comment,
choice: "new",
wallet_uid: wallet.wallet_uid,
...sendMoneyFee,
details: { ...bankDetails[0], ...values?.newAccount },
};
return setTimeout(() => {
setRequestStatus(false);
action();
setShowConfirmNairaWithdraw({ show: true, state: stateData });
}, 1000);
}
} catch (errors) {
// If validation fails, handle the validation errors
throw new Error("Validation errors:", errors);
}
};
useEffect(() => {
getRecipients();
}, []);
return (
<ModalCom action={action} situation={situation} className="edit-popup">
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="w-full">
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
{`Withdraw from ${wallet.description} Wallet : ${wallet.symbol}${(
wallet.amount * 0.01
).toFixed(2)}`}
</h1>
<button
type="button"
className="text-[#374557] dark:text-red-500"
onClick={action}
>
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
fill=""
fillOpacity="0.6"
/>
<path
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
fill="#"
fillOpacity="0.6"
/>
</svg>
</button>
</div>
<div className="add-fund w-full md:p-8 p-4 bg-white dark:bg-dark-white h-full rounded-2xl">
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
{(props) => {
return (
<Form className="transfer-fund-info">
{/* Amount Form */}
<div className="flex flex-col">
<div className="field w-full">
<InputCom
fieldClass="px-4 text-end"
parentClass="flex items-center gap-1 justify-between"
labelClass="flex-[0.4] mb-0"
inputClass="flex-[0.6] max-w-[12rem]"
label="Amount:"
type="number"
name="amount"
placeholder="0"
value={props.values.amount}
inputHandler={props.handleChange}
blurHandler={(e) => {
getSendMoneyFee(e);
}}
error={errorMsgs.amount && errorMsgs.amount}
/>
</div>
<div className="field w-full">
<InputCom
fieldClass="px-4 transfer-field"
parentClass="flex items-center gap-1 justify-between"
labelClass="flex-[0.2] mb-0"
inputClass="flex-[0.8] transfer-field max-w-[12rem]"
label="Fee:"
type="text"
name="fee"
direction="rtl"
value={
sendMoneyFee.loading
? "loading"
: (sendMoneyFee.fee * 0.01).toFixed(2)
}
disable={true}
/>
</div>
<div className="field w-full">
<InputCom
fieldClass="px-4 transfer-field"
parentClass="flex items-center gap-1 justify-between"
labelClass="flex-[0.2] mb-0"
inputClass="flex-[0.8] transfer-field max-w-[12rem]"
label="Total:"
type="text"
name="total"
direction="rtl"
value={
sendMoneyFee.loading
? "loading"
: (sendMoneyFee.total * 0.01).toFixed(2)
}
disable={true}
/>
</div>
<div className="field w-full mb-3 flex gap-1 justify-between">
<label className="text-[#181c32] dark:text-white text-base font-semibold flex flex-[0.2] mt-2.5">
Comment:
</label>
<textarea
style={{ resize: "none" }}
className="text-base px-4 py-2 rounded-md sm:max-w-[550px] max-w-[250px] text-dark-gray dark:text-white w-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none flex-[0.8]"
name="comment"
value={props.values.comment}
onChange={props.handleChange}
onBlur={props.handleBlur}
cols="30"
rows="2"
/>
</div>
</div>
{/* Account Selector */}
<div className=" flex items-center gap-[8rem]">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
To:
</h1>
<div className="my-1 flex items-center gap-2">
<label
onClick={() => setTab("previous")}
htmlFor="previous"
className="cursor-pointer flex items-center gap-1"
>
<input
type="radio"
id="previous"
name="choice"
value="previous"
checked={tab === "previous"}
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
tab == "previous" ? "" : ""
} tracking-wide transition duration-200`}
/>
Previous Account
</label>
<label
onClick={() => setTab("new")}
htmlFor="new"
className="cursor-pointer flex items-center gap-1"
>
<input
id="new"
type="radio"
name="choice"
value="new"
checked={tab === "new"}
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
tab == "new" ? "" : ""
} tracking-wide transition duration-200`}
/>
New Account{" "}
</label>
</div>
</div>
<div className="">
{tab == "previous" && (
<>
<div className="w-full">
<div className="relative my-3 md:flex items-center px-4">
<div className="transfer-input w-full flex items-center justify-end">
{/* <label className="text-[#181c32] dark:text-white text-base font-semibold block flex-[0.2] mb-0 mt-3"></label> */}
<div className="flex flex-col gap-3 flex-[0.8] items-center">
<select
className="sm:w-full w-48 text-dark-gray border-slate-300 outline-0 flex-[0.8] my-3 rounded-full p-2 outline-none text-base dark:text-gray-100 bg-[#FAFAFA] dark:bg-[#11131F] border appearance-none"
value={
props.values.previousAccount?.recipientID
}
name="previousAccount.recipientID"
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{recipients.loading ? (
<option
className="text-slate-500 text-lg"
value=""
>
Loading...
</option>
) : recipients.data.length ? (
<>
<option
className="text-slate-500 text-lg"
value=""
>
{errorMsgs.previousAccount
?.recipientID
? errorMsgs.previousAccount
.recipientID
: "Select an account"}
</option>
{recipients.data.map((item, index) => (
<option
key={index}
value={item.recipient_uid}
className="text-slate-500 text-lg"
>
{item.recipient}
</option>
))}
</>
) : recipients.error ? (
<option
className="text-slate-500 text-lg"
value=""
>
Could'nt load, !
</option>
) : (
<option
className="text-slate-500 text-lg"
value=""
>
No Recipient Found!
</option>
)}
</select>
<div className="flex justify-end relative w-full">
{errorMsgs.previousAccount?.recipientID &&
errorMsgs.previousAccount
?.recipientID && (
<p className="sm:text-sm text-[12px] text-red-500 absolute sm:top-1 -top-20 sm:left-0 left-[160px]">
{
errorMsgs.previousAccount
?.recipientID
}
</p>
)}
</div>
</div>
</div>
</div>
</div>
<div className="h-[6.1rem]"></div>
</>
)}
{tab == "new" && (
<div className="w-full mt-3 rounded-md bg-slate-100">
<div className="relative fields w-full flex flex-col p-4">
<div className="flex flex-[2] min-h-[52px]">
{/* country */}
<div className="add-recipient w-full flex items-center flex-1 xl:mb-0">
<label
htmlFor="newAccount.country"
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.3]"
>
Country{" "}
<span className="text-red-500">*</span>
</label>
<select
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding tracking-[1.5px]"
name="newAccount.country"
value={props.values.newAccount?.country}
onChange={(e) => {
props.handleChange(e);
handleBankOptions(e);
}}
>
{allCountries.loading ? (
<option
className="text-slate-500 text-lg"
value=""
>
Loading...
</option>
) : allCountries.data?.length ? (
<>
<option
className="text-slate-500 text-lg"
value=""
>
{errorMsgs.newAccount?.country
? errorMsgs.newAccount.country
: "Select..."}
</option>
{allCountries.data.map((item, index) => (
<option
key={index}
className="text-slate-500 text-lg"
value={item[0]}
>
{item[1]}
</option>
))}
</>
) : (
<option
className="text-slate-500 text-lg"
value=""
>
No Options Found!
</option>
)}
</select>
{/* {props.errors.country &&
props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)} */}
</div>
{/* bank name */}
<div className="add-recipient w-full flex items-center flex-1">
<label
htmlFor="newAccount.bank"
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4] tracking-[1.5px]"
>
Bank Name{" "}
<span className="text-red-500">*</span>
</label>
<select
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding "
name="newAccount.bank"
value={props.values.newAccount?.bank}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{bankName.loading ? (
<option
className="text-slate-500 text-lg"
value=""
>
Loading...
</option>
) : bankName.data?.length ? (
<>
<option
className="text-slate-500 text-lg"
value=""
>
Select...
</option>
{bankName.data?.map((item, index) => (
<option
key={index}
className="text-slate-500 text-lg"
value={item.bank_uid}
>
{item.name}
</option>
))}
</>
) : (
<option
className="text-slate-500 text-lg"
value=""
>
{allCountries.data?.length
? "Select..."
: "No Options Found!"}
</option>
)}
</select>
{/* {props.errors.bank && props.touched.bank && (
<p className="text-sm text-red-500">
{props.errors.bank}
</p>
)} */}
</div>
</div>
<div className="flex flex-[2] gap-4">
{/* ACCOUNT NUMBER */}
<div className="field w-full flex-[1.4] flex items-center gap-2">
<label
htmlFor="newAccount.accountNumber"
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex items-center flex-1"
>
Account Number{" "}
<span className="text-red-500">*</span>
</label>
<InputCom
fieldClass="px-6 tracking-[1.5px]"
inputClass="flex items-center max-w-[15rem]"
type="text"
name="newAccount.accountNumber"
placeholder="Account No"
maxLength={10}
value={props.values.newAccount?.accountNumber}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{/* {props.errors.accountNumber &&
props.touched.accountNumber && (
<p className="text-sm text-red-500">
{props.errors.accountNumber}
</p>
)} */}
</div>
{/* Account Type */}
<div className="add-recipient w-full flex flex-1 items-center">
<label
htmlFor="newAccount.accountType"
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.3]"
>
Type <span className="text-red-500">*</span>
</label>
<select
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding flex-grow tracking-[1.5px]"
name="newAccount.accountType"
value={props.values.newAccount?.accountType}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{accType.loading ? (
<option
className="text-slate-500 text-lg"
value=""
>
Loading...
</option>
) : accType.data?.length ? (
<>
<option
className="text-slate-500 text-lg"
value=""
>
Select...
</option>
{accType.data?.map((item, index) => (
<option
key={index}
className="text-slate-500 text-lg"
value={item.value}
>
{item.name}
</option>
))}
</>
) : (
<option
className="text-slate-500 text-lg"
value=""
>
No Options Found!
</option>
)}
</select>
{/* {props.errors.accountType &&
props.touched.accountType && (
<p className="text-sm text-red-500">
{props.errors.accountType}
</p>
)} */}
</div>
</div>
<div className="flex items-center flex-1">
{/* state */}
<div className="field w-full flex items-center gap-4 flex-[0.4]">
<label
htmlFor="newAccount.state"
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4]"
>
State <span className="text-red-500">*</span>
</label>
<InputCom
fieldClass="px-6 tracking-[1.5px]"
inputClass="max-w-[10rem]"
type="text"
name="newAccount.state"
placeholder="State/Province"
value={props.values.newAccount?.state}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{/* {props.errors.state && props.touched.state && (
<p className="text-sm text-red-500">
{props.errors.state}
</p>
)} */}
</div>
{/* city */}
<div className="field w-full flex items-center flex-[0.4]">
<label
htmlFor="newAccount.city"
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4]"
>
City <span className="text-red-500">*</span>
</label>
<InputCom
fieldClass="px-6 tracking-[1.5px]"
type="text"
inputClass="max-w-[10rem]"
name="newAccount.city"
placeholder="City"
value={props.values.newAccount?.city}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{/* {props.errors.city && props.touched.city && (
<p className="text-sm text-red-500">
{props.errors.city}
</p>
)} */}
</div>
</div>
{/* end of inputs for new accounts */}
</div>
</div>
)}
</div>
<div className="transfer-fund-btn flex justify-end items-center gap-2 py-4">
<button
type="button"
onClick={action}
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center bg-[#f5a430] text-black items-center text-base rounded-full"
>
Cancel
</button>
<button
type="submit"
disabled={
props.isSubmitting || sendMoneyFee.loading
? true
: false
}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer min-w-[100px] flex justify-center items-center"
>
{requestStatus ? (
<LoadingSpinner size="6" color="sky-blue" />
) : (
"Continue"
)}
</button>
</div>
</Form>
);
}}
</Formik>
</div>
</div>
</div>
</ModalCom>
);
}
export default NairaWithdraw;
+38 -95
View File
@@ -4,132 +4,75 @@ import React, {
useCallback,
useEffect,
useMemo,
useReducer,
useState,
} from "react";
import { Routes, Route, Outlet, Navigate } from "react-router-dom";
import { useSelector } from "react-redux";
import usersService from "../../services/UsersService";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
// const AddFund = lazy(() => import("./AddFund"));
// const ConfirmAddFund = lazy(() => import("./ConfirmAddFund"));
// const TransferFund = lazy(() => import("./TransferFund"));
const WalletBox = lazy(() => import("./WalletBox"));
// const AddRecipient = lazy(() => import("./AddRecipient"));
// const ConfirmTransfer = lazy(() => import("./ConfirmTransfer"));
function Wallet() {
return (
<Layout>
<Outlet />
</Layout>
);
}
const initialState = {
loading: true,
data: [],
error: false,
};
// Currently learning better about useReducer, so I converted this since it seemed like something complex
const reducer = (state, action) => {
switch (action.type) {
case "FETCH_SUCCESS":
return {
...state,
loading: false,
data: action.payload,
};
case "FETCH_ERROR":
return {
...state,
loading: false,
error: true,
};
default:
return state;
}
};
const WalletRoutes = () => {
const apiCall = useMemo(() => new usersService(), []);
const apiCall = new usersService();
const { walletTable } = useSelector((state) => state.tableReload);
const [walletList, setWalletList] = useState({
loading: true,
data: [],
reload: false,
});
const [paymentHistory, setPaymentHistory] = useState({
loading: true,
data: [],
});
const [walletList, dispatchWalletList] = useReducer(reducer, initialState);
const [paymentHistory, dispatchPaymentHistory] = useReducer(
reducer,
initialState
);
const getWalletList = useCallback(() => {
const getWalletList = () => {
apiCall
.getUserWallets(null)
.getUserWallets()
.then((res) => {
if (res.data.internal_return < 0) {
dispatchWalletList({ type: "FETCH_SUCCESS", payload: [] });
setWalletList({ loading: false, data: [] });
} else {
dispatchWalletList({
type: "FETCH_SUCCESS",
payload: res.data.result_list,
});
setWalletList({ loading: false, data: res.data?.result_list });
}
})
.catch(() => {
dispatchWalletList({ type: "FETCH_ERROR" });
setWalletList({ loading: false, data: [] });
});
}, [apiCall]);
}
const getPaymentHistory = useCallback(() => {
const getPaymentHistory = () => {
apiCall
.getPaymentHx()
.then((res) => {
if (res.data.internal_return < 0) {
dispatchPaymentHistory({ type: "FETCH_SUCCESS", payload: [] });
setPaymentHistory({ loading: false, data: [] });
} else {
dispatchPaymentHistory({
type: "FETCH_SUCCESS",
payload: res.data.result_list,
});
setPaymentHistory({ loading: false, data: res.data?.result_list });
}
})
.catch(() => {
dispatchPaymentHistory({ type: "FETCH_ERROR" });
setPaymentHistory({ loading: false, data: [] });
});
}, [apiCall]);
}
useEffect(() => {
let isMounted = true;
// const fetchData = async () => {
// await Promise.all([getWalletList(), getPaymentHistory()]);
// };
if (isMounted) {
getWalletList();
getPaymentHistory();
}
return () => {
isMounted = false;
};
}, [getWalletList, getPaymentHistory]);
// if (walletList.loading) {
// fetchData();
// }
getWalletList()
getPaymentHistory()
}, [walletTable]);
return (
<Routes>
<Route
element={
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
<Wallet />
</Suspense>
}
>
<Route
index
element={
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
<WalletBox wallet={walletList} payment={paymentHistory} />
</Suspense>
}
/>
<Route path="*" element={<Navigate to="/" />} />
</Route>
</Routes>
<Layout>
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
<WalletBox wallet={walletList} payment={paymentHistory} />
</Suspense>
</Layout>
);
};
+69 -40
View File
@@ -1,49 +1,78 @@
import React from 'react'
import { Link } from 'react-router-dom';
import React, { useCallback, useState } from "react";
import usersService from "../../services/UsersService";
import ConfirmNairaWithdraw from "./Popup/ConfirmNairaWithdraw";
import NairaWithdraw from "./Popup/NairaWithdraw";
function WalletAction({ walletItem, payment, openPopUp }) {
const [showNairaWithdraw, setShowNairaWithdraw] = useState({
show: false,
state: {},
}); // DETERMINES WHEN NAIRA WITHDRAWAL POPS UP
const [showConfirmNairaWithdraw, setShowConfirmNairaWithdraw] = useState({
show: false,
state: {},
}); // DETERMINES WHEN CONFIRM NAIRA WITHDRAWAL POPS UP
function WalletAction({walletItem, payment, openPopUp}) {
return (
<div className="counters w-full flex justify-between gap-2">
<div className='w-1/2 flex justify-center items-center'>
<Link
to="transfer-fund"
className={`${
walletItem.code != "NAIRA" && "invisible"
} px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
>
Spend
</Link>
</div>
<div className='w-1/2 flex justify-center items-center'>
<div className="w-1/2 flex justify-center items-center">
<button
className='px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white'
onClick={() => {
openPopUp({
payment: payment,
currency: walletItem?.description,
});
}}
onClick={() => {
setShowNairaWithdraw((prev) => ({ ...prev, show: true }));
}}
className={`${
walletItem.code != "NAIRA" && "invisible"
} px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
>
{/* <span className="">
<svg
xmlns="http://www.w3.org/2000/svg"
width="38"
height="38"
viewBox="0 0 42 42"
fill="none"
>
<path
d="M21 0C16.8466 0 12.7865 1.23163 9.33303 3.53914C5.8796 5.84665 3.18798 9.1264 1.59854 12.9636C0.00909901 16.8009 -0.406771 21.0233 0.403518 25.0969C1.21381 29.1705 3.21386 32.9123 6.15077 35.8492C9.08767 38.7861 12.8295 40.7862 16.9031 41.5965C20.9767 42.4068 25.1991 41.9909 29.0364 40.4015C32.8736 38.812 36.1534 36.1204 38.4609 32.667C40.7684 29.2135 42 25.1534 42 21C41.994 15.4323 39.7796 10.0944 35.8426 6.15741C31.9056 2.22045 26.5677 0.00602189 21 0ZM28 22.75H22.75V28C22.75 28.4641 22.5656 28.9092 22.2374 29.2374C21.9093 29.5656 21.4641 29.75 21 29.75C20.5359 29.75 20.0908 29.5656 19.7626 29.2374C19.4344 28.9092 19.25 28.4641 19.25 28V22.75H14C13.5359 22.75 13.0908 22.5656 12.7626 22.2374C12.4344 21.9092 12.25 21.4641 12.25 21C12.25 20.5359 12.4344 20.0907 12.7626 19.7626C13.0908 19.4344 13.5359 19.25 14 19.25H19.25V14C19.25 13.5359 19.4344 13.0908 19.7626 12.7626C20.0908 12.4344 20.5359 12.25 21 12.25C21.4641 12.25 21.9093 12.4344 22.2374 12.7626C22.5656 13.0908 22.75 13.5359 22.75 14V19.25H28C28.4641 19.25 28.9093 19.4344 29.2374 19.7626C29.5656 20.0907 29.75 20.5359 29.75 21C29.75 21.4641 29.5656 21.9092 29.2374 22.2374C28.9093 22.5656 28.4641 22.75 28 22.75Z"
// fill="white"
className="stroke-black fill-white"
></path>
</svg>
</span> */}
<span className="">Add Credit</span>
Spend
</button>
</div>
</div>
<div className="w-1/2 flex justify-center items-center">
<button
className="px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white"
onClick={() => {
openPopUp({
payment: payment,
currency: walletItem?.description,
});
}}
>
<span className="">Add Credit</span>
</button>
</div>
{showNairaWithdraw.show && (
<NairaWithdraw
wallet={walletItem}
action={() => {
setShowNairaWithdraw((prev) => ({
...prev,
show: !prev.show,
}));
}}
situation={showNairaWithdraw.show}
state={showNairaWithdraw.state}
setShowConfirmNairaWithdraw={setShowConfirmNairaWithdraw}
/>
)}
{showConfirmNairaWithdraw.show && (
<ConfirmNairaWithdraw
wallet={walletItem}
state={showConfirmNairaWithdraw.state}
action={() => {
setShowConfirmNairaWithdraw((prev) => ({
...prev,
show: !prev.show,
}));
}}
setShowNairaWithdraw={setShowNairaWithdraw}
situation={showConfirmNairaWithdraw.show}
/>
)}
</div>
)
);
}
export default WalletAction
export default WalletAction;
+1 -237
View File
@@ -1,7 +1,7 @@
import LoadingSpinner from "../Spinners/LoadingSpinner";
import WalletItemCard from "./WalletItemCard";
export default function WalletBox({ wallet, coupon, payment }) {
export default function WalletBox({ wallet, payment }) {
return (
<>
<div className="my-wallet-wrapper w-full mb-10">
@@ -18,243 +18,7 @@ export default function WalletBox({ wallet, coupon, payment }) {
</div>
))
) : null}
{/*<div className="flex-1">*/}
{/* <CurrentBalanceWidget />*/}
{/*</div>*/}
{/* <div className="flex-1">*/}
{/* <div className="my-wallets w-full h-full bg-white dark:bg-dark-white rounded-lg p-6">*/}
{/* <div className="mb-4">*/}
{/* <h1 className="text-xl font-bold tracking-wide text-dark-gray dark:text-white">*/}
{/* My Wallet*/}
{/* </h1>*/}
{/* </div>*/}
{/* <div className="content-area">*/}
{/* <div className="flex justify-between items-center mb-6">*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div className="account-name flex space-x-4 items-center">*/}
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank1} alt="" />*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
{/* MetaMask*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div>*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
{/* $734.79*/}
{/* </p>*/}
{/* <p className="text-sm text-thin-light-gray">*/}
{/* New Add*/}
{/* <span className="text-light-green ml-1">*/}
{/* +324.75*/}
{/* </span>*/}
{/* </p>*/}
{/* </div>*/}
{/* <div>*/}
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
{/* <svg*/}
{/* width="6"*/}
{/* height="26"*/}
{/* viewBox="0 0 6 26"*/}
{/* fill="none"*/}
{/* className="fill-current"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="12.75"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="22.5"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* </svg>*/}
{/*</span>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="flex justify-between items-center mb-6">*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div className="account-name flex space-x-4 items-center">*/}
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank2} alt="" />*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
{/* Coinbase Wallet*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div>*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
{/* $734.79*/}
{/* </p>*/}
{/* <p className="text-sm text-thin-light-gray">*/}
{/* New Add*/}
{/* <span className="text-light-green ml-1">*/}
{/* +324.75*/}
{/* </span>*/}
{/* </p>*/}
{/* </div>*/}
{/* <div>*/}
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
{/* <svg*/}
{/* width="6"*/}
{/* height="26"*/}
{/* viewBox="0 0 6 26"*/}
{/* fill="none"*/}
{/* className="fill-current"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="12.75"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="22.5"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* </svg>*/}
{/*</span>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="flex justify-between items-center mb-6">*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div className="account-name flex space-x-4 items-center">*/}
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank3} alt="" />*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
{/* Bitski*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div>*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
{/* $734.79*/}
{/* </p>*/}
{/* <p className="text-sm text-thin-light-gray">*/}
{/* New Add*/}
{/* <span className="text-light-green ml-1">*/}
{/* +324.75*/}
{/* </span>*/}
{/* </p>*/}
{/* </div>*/}
{/* <div>*/}
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
{/* <svg*/}
{/* width="6"*/}
{/* height="26"*/}
{/* viewBox="0 0 6 26"*/}
{/* fill="none"*/}
{/* className="fill-current"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="12.75"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="22.5"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* </svg>*/}
{/*</span>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="flex justify-between items-center mb-6">*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div className="account-name flex space-x-4 items-center">*/}
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank4} alt="" />*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
{/* WalletConnect*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="flex space-x-5 items-center">*/}
{/* <div>*/}
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
{/* $734.79*/}
{/* </p>*/}
{/* <p className="text-sm text-thin-light-gray">*/}
{/* New Add*/}
{/* <span className="text-light-green ml-1">*/}
{/* +324.75*/}
{/* </span>*/}
{/* </p>*/}
{/* </div>*/}
{/* <div>*/}
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
{/* <svg*/}
{/* width="6"*/}
{/* height="26"*/}
{/* viewBox="0 0 6 26"*/}
{/* fill="none"*/}
{/* className="fill-current"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="12.75"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* <circle*/}
{/* cx="3"*/}
{/* cy="22.5"*/}
{/* r="3"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* </svg>*/}
{/*</span>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
</div>
{/* flex space-x-11 */}
{/*<div className="recent-and-investment grid lg:grid-cols-2 grid-cols-1 2xl:gap-[40px] xl:gap-7 gap-4 lg:h-[416px] w-full justify-between">*/}
{/* <div className=" h-full">*/}
{/* <RecentTransactionWidget />*/}
{/* </div>*/}
{/* <div className=" h-full">*/}
{/* <InvestmentSection />*/}
{/* </div>*/}
{/*</div>*/}
</div>
</div>
</>
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,7 +1,7 @@
const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
if (data?.length > process.env.REACT_APP_ITEM_PER_PAGE) {
return (
<div className="p-3 flex justify-center items-center min-h-[70px] space-x-2 border-t-2">
<div className="p-3 flex justify-center items-center min-h-[70px] space-x-2 border-t-2 w-full">
{/* Render pagination buttons */}
{!prev && (
<button
+97 -289
View File
@@ -1,33 +1,38 @@
import React, { useContext, useState, useEffect } from "react";
import { Link, useLocation } from "react-router-dom";
import React, { useContext, useEffect, useMemo, useState } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import bank1 from "../../assets/images/bank-1.png";
import bank2 from "../../assets/images/bank-2.png";
import bank3 from "../../assets/images/bank-3.png";
import bank4 from "../../assets/images/bank-4.png";
import profileImg from "../../assets/images/profile-pic.jpg";
import profileImg from "../../assets/images/profile.jpg";
import useToggle from "../../hooks/useToggle";
import usersService from "../../services/UsersService";
import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons";
import ModalCom from "../Helpers/ModalCom";
import SearchCom from "../Helpers/SearchCom";
import WalletHeader from "../MyWallet/WalletHeader";
import usersService from "../../services/UsersService";
import siteLogo from "../../assets/images/wrenchboard.png";
import { useDispatch, useSelector } from "react-redux";
import Flag from "../../assets/images/united-states.svg";
import { useSelector } from "react-redux";
import siteLogo from "../../assets/images/wrenchboard-logo-text.png";
import TimeDifference from "../Helpers/TimeDifference";
const DEFAULT_PROFILE_IMAGE = require("../../assets/images/profile.jpg");
export default function Header({ logoutModalHandler, sidebarHandler }) {
const [balanceDropdown, setbalanceValue] = useToggle(false);
const [notificationDropdown, setNotificationValue] = useToggle(false);
const [userProfileDropdown, setProfileDropdown] = useToggle(false);
const [moneyPopup, setPopup] = useToggle(false);
const [toggleNotification, setToggleNotification] = useToggle(false);
const darkMode = useContext(DarkModeContext);
const { userDetails } = useSelector((state) => state?.userDetails);
const { walletTable } = useSelector((state) => state.tableReload); // DETERMINES WHEN WALLET RELOADS
const [myWalletList, setMyWalletList] = useState([]);
const api = new usersService();
const api = useMemo(() => new usersService(), []);
const dispatch = useDispatch();
const navigate = useNavigate();
const { notifications } = useSelector((state) => state?.notifications); // NOTIFICATION STORE
const getMyWalletList = async () => {
try {
@@ -40,7 +45,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
};
useEffect(() => {
getMyWalletList();
}, []);
}, [walletTable]);
const handlerBalance = () => {
setbalanceValue.toggle();
@@ -85,10 +90,6 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
setbalanceValue.set(false);
};
const setNotification = () => {
setToggleNotification.toggle();
};
// getting the location of head
let { pathname } = useLocation();
@@ -99,8 +100,10 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
};
// User Profile
let { firstname, lastname, email, profile_pic } = userDetails;
let { firstname, lastname, email, profile_pic_url } = userDetails;
let userEmail = email?.split("@")[0];
const userProfileImage = profile_pic_url || DEFAULT_PROFILE_IMAGE;
return (
<>
@@ -251,8 +254,8 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
className="lg:w-[48px] lg:h-[48px] w-[38px] h-[38px] bg-white flex justify-center items-center rounded-full overflow-hidden relative"
>
<Icons name="notification" />
<span className="absolute right-2 top-2 z-10 text-xs lg:w-5 lg:h-5 w-4 h-4 flex justify-center items-center rounded-full primary-gradient text-white">
10
<span className="absolute right-2 top-2 z-10 text-xs lg:w-5 lg:h-5 w-4 h-4 flex justify-center items-center rounded-full primary-gradient text-white cursor-default">
{notifications?.loading ? "●" : notifications?.data?.length}
</span>
</div>
<div
@@ -265,197 +268,62 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
Recent Notifications
</h3>
</div>
<div className="content px-7 pb-7">
<ul>
<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">
<div className="notifications flex space-x-4 items-center">
<div className="icon">
<svg
width="52"
height="52"
viewBox="0 0 52 52"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="26" cy="26" r="26" fill="#27AE60" />
<path
d="M21.5404 30.2033C22.185 29.6102 22.818 29.0287 23.451 28.4456C27.4582 24.759 31.4637 21.0724 35.4709 17.3859C35.7849 17.0968 36.0973 16.8044 36.4146 16.517C36.697 16.2611 37.021 16.0834 37.4014 16.0186C38.2055 15.884 38.782 16.4987 38.5877 17.2878C38.5112 17.5985 38.3634 17.8776 38.1574 18.1202C33.9574 23.0362 29.7575 27.9505 25.5576 32.8648C24.5641 34.0261 23.5739 35.1891 22.5787 36.3487C22.3129 36.6594 21.9906 36.8903 21.5786 36.9734C21.2347 37.0431 20.9091 36.975 20.6316 36.779C20.399 36.6145 20.1631 36.4284 19.9937 36.2041C17.7708 33.2237 15.5562 30.2365 13.3465 27.2461C13.0757 26.8789 12.9462 26.4486 13.0209 25.9901C13.1422 25.2342 14.046 24.7274 14.8085 24.9982C15.0445 25.083 15.2721 25.2225 15.4698 25.3787C17.4634 26.957 19.4504 28.5453 21.4391 30.1302C21.4673 30.1535 21.4972 30.1734 21.5404 30.2033Z"
fill="white"
/>
</svg>
</div>
<div className="name">
<p className="text-base text-dark-gray dark:text-white font-medium mb-2">
Your Account has been created
<span className="ml-1 font-bold">
successfully done
</span>
</p>
<p className="text-sm text-thin-light-gray font-medium">
23 house ago
</p>
</div>
</div>
</li>
<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">
<div className="notifications flex space-x-4 items-center">
<div className="icon">
<svg
width="52"
height="52"
viewBox="0 0 52 52"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="26" cy="26" r="26" fill="#5356FB" />
<path
d="M25.9481 24.3684C25.4776 24.213 25.0352 24.1246 24.6425 23.9303C21.1636 22.2082 17.6912 20.4687 14.2167 18.7379C13.962 18.6106 13.7656 18.4466 13.7613 18.1423C13.757 17.8251 13.9534 17.6481 14.221 17.5143C17.6718 15.7943 21.1226 14.07 24.5712 12.3456C25.564 11.8493 26.5416 11.9054 27.5214 12.3996C29.7377 13.5153 31.9627 14.6203 34.1834 15.7295C35.3164 16.295 36.4473 16.8625 37.5781 17.4301C37.6429 17.4625 37.7076 17.4927 37.7745 17.5251C38.0335 17.6459 38.2126 17.8337 38.2126 18.1337C38.2126 18.438 38.0205 18.6084 37.7659 18.7336C36.1581 19.5343 34.5525 20.3392 32.9447 21.1399C31.0887 22.0657 29.2414 23.0045 27.3746 23.9066C26.93 24.1224 26.4272 24.2173 25.9481 24.3684Z"
fill="white"
/>
<path
d="M25.0538 33.4541C25.0538 35.3834 25.056 37.3128 25.0517 39.2421C25.0495 39.9284 24.6632 40.1701 24.0309 39.8787C20.8671 38.422 17.7012 36.9696 14.5439 35.5021C13.5274 35.0295 13.0095 34.2029 13.0052 33.085C12.9965 29.4076 13.0008 25.7302 13.003 22.0528C13.003 21.3428 13.4023 21.0795 14.0367 21.373C17.3084 22.8815 20.5779 24.3987 23.8518 25.9007C24.6827 26.2827 25.0668 26.9042 25.0603 27.8128C25.0474 29.6947 25.056 31.5744 25.056 33.4562C25.056 33.4541 25.056 33.4541 25.0538 33.4541Z"
fill="white"
/>
<path
d="M26.9187 33.4002C26.9187 31.5076 26.923 29.6149 26.9165 27.7223C26.9144 26.8676 27.305 26.2785 28.0711 25.9246C31.3644 24.4053 34.6598 22.8903 37.953 21.3731C38.553 21.0969 38.9652 21.3451 38.9652 21.999C38.9695 25.7131 38.976 29.425 38.9609 33.1391C38.9566 34.2764 38.3739 35.0706 37.3488 35.5454C34.7893 36.728 32.2276 37.9085 29.6681 39.089C29.1199 39.3415 28.5739 39.594 28.0279 39.8465C27.2855 40.1875 26.9165 39.9565 26.9165 39.1494C26.9165 37.233 26.9165 35.3145 26.9165 33.3981C26.9187 33.4002 26.9187 33.4002 26.9187 33.4002Z"
fill="white"
/>
</svg>
</div>
<div className="name">
<p className="text-base text-dark-gray dark:text-white font-medium mb-2">
You upload your frast product
<span className="ml-1 font-bold">
successfully done
</span>
</p>
<p className="text-sm text-thin-light-gray font-medium">
23 house ago
</p>
</div>
</div>
</li>
<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">
<div className="notifications flex space-x-4 items-center">
<div className="icon">
<svg
width="52"
height="52"
viewBox="0 0 52 52"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="26" cy="26" r="26" fill="#F539F8" />
<path
d="M36.2507 24.2795C35.8857 25.5416 35.5884 26.7445 35.1694 27.9018C35.0663 28.1874 34.5662 28.505 34.2452 28.5084C30.4894 28.5523 26.7335 28.5371 22.9777 28.5388C22.4218 28.5388 22.067 28.2651 21.9403 27.7329C21.3456 25.2459 20.7458 22.7589 20.1781 20.2668C20.0058 19.5133 20.3488 19.0487 21.0753 19.0436C24.1367 19.0233 27.1981 19.0352 30.3356 19.0352C30.2984 20.6605 30.7411 22.0814 31.9728 23.1644C33.1774 24.2305 34.6017 24.5481 36.2507 24.2795Z"
fill="white"
/>
<path
d="M21.1615 29.4088C23.689 29.4088 26.1726 29.4088 28.6562 29.4088C30.2816 29.4088 31.9069 29.4054 33.5322 29.4105C34.2891 29.4122 34.7183 29.7518 34.7385 30.338C34.7588 30.9547 34.3162 31.3298 33.5288 31.3298C29.2256 31.3332 24.924 31.3332 20.6208 31.3298C19.749 31.3298 19.5074 31.1169 19.3165 30.2367C18.4987 26.4555 17.6743 22.676 16.8717 18.8914C16.7771 18.4471 16.6031 18.197 16.1452 18.0568C15.096 17.7358 14.0671 17.3472 13.0314 16.9823C12.1613 16.6748 11.8386 16.2051 12.0751 15.6019C12.3083 15.0055 12.8135 14.8535 13.6397 15.1407C14.9254 15.5867 16.1993 16.0665 17.4985 16.472C18.1541 16.6765 18.4666 17.0465 18.6052 17.7088C19.3976 21.4714 20.2204 25.2272 21.0364 28.9847C21.0601 29.0962 21.1006 29.2077 21.1615 29.4088Z"
fill="white"
/>
<path
d="M30.9336 19.6116C30.9218 17.2665 32.8225 15.3607 35.1676 15.3692C37.4654 15.3759 39.3577 17.2851 39.3543 19.5947C39.3509 21.8975 37.4519 23.8016 35.149 23.8067C32.8479 23.8118 30.9455 21.9195 30.9336 19.6116ZM36.9416 17.7396C36.1797 18.5556 35.4329 19.3565 34.5459 20.3077C34.1218 19.7315 33.7788 19.2686 33.3869 18.7381C32.9932 19.1503 32.733 19.4224 32.5641 19.6015C33.2838 20.3448 33.9714 21.0528 34.6067 21.71C35.6373 20.676 36.6983 19.6133 37.8489 18.4593C37.6614 18.3106 37.4367 18.1316 37.2103 17.9525C37.1393 17.8933 37.0667 17.8393 36.9416 17.7396Z"
fill="white"
/>
<path
d="M32.4861 32.1105C33.9779 32.097 35.1944 33.2695 35.2231 34.7495C35.2518 36.2549 34.0286 37.4899 32.5114 37.4899C31.0297 37.4899 29.8183 36.2853 29.8115 34.8103C29.8065 33.3286 30.9993 32.1257 32.4861 32.1105ZM33.7059 34.7918C33.7042 34.1379 33.1906 33.6074 32.5452 33.5939C31.8761 33.5787 31.3186 34.1312 31.322 34.8053C31.3254 35.4524 31.8474 35.9896 32.4861 36.0065C33.1551 36.0234 33.7093 35.4726 33.7059 34.7918Z"
fill="white"
/>
<path
d="M21.557 37.4897C20.0668 37.4779 18.8707 36.28 18.874 34.8017C18.8791 33.276 20.0871 32.0917 21.6212 32.1086C23.1012 32.1255 24.289 33.3453 24.2721 34.8304C24.2535 36.3155 23.0438 37.4999 21.557 37.4897ZM22.7667 34.8034C22.7684 34.1242 22.2142 33.5785 21.5401 33.5954C20.9049 33.6123 20.3625 34.1614 20.3625 34.7932C20.3608 35.4268 20.8981 35.9827 21.53 36.0046C22.2007 36.0283 22.765 35.4792 22.7667 34.8034Z"
fill="white"
/>
</svg>
</div>
<div className="name">
<p className="text-base text-dark-gray dark:text-white font-medium mb-2">
<span className="ml-1 font-bold">Thank you !</span>
you made your frast sell
<span className="ml-1 font-bold">232.98 ETH</span>
</p>
<p className="text-sm text-thin-light-gray font-medium">
23 house ago
</p>
</div>
</div>
</li>
<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">
<div className="notifications flex space-x-4 items-center">
<div className="icon">
<svg
width="52"
height="52"
viewBox="0 0 52 52"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="26" cy="26" r="26" fill="#56CCF2" />
<path
d="M23.1046 14.0017C24.5421 14.0092 25.6981 14.1643 26.7653 14.7031C28.6197 15.6394 29.6086 17.1912 29.8931 19.2172C30.0752 20.5117 29.9292 21.7911 29.6191 23.0509C29.2443 24.5682 28.7386 26.0388 27.9348 27.3889C27.4215 28.2514 26.7833 29.007 25.9223 29.5474C24.3253 30.5513 22.3942 30.449 20.8228 29.287C19.8745 28.5855 19.2017 27.6598 18.6703 26.6228C17.9102 25.1356 17.4842 23.5431 17.1907 21.9085C17.0236 20.9798 16.9664 20.0526 17.117 19.1179C17.5053 16.6975 18.9021 15.1366 21.19 14.3344C21.8929 14.0875 22.6185 13.9852 23.1046 14.0017Z"
fill="white"
/>
<path
d="M31.4126 39.0001C31.3434 39.0001 31.2847 39.0001 31.2245 39.0001C24.8936 39.0001 18.5628 39.0001 12.2319 39.0001C12.0061 39.0001 11.9986 39.0001 12.0001 38.7788C12.0062 37.8727 11.9926 36.9636 12.0317 36.0589C12.0739 35.1197 12.5601 34.4032 13.2901 33.8418C14.0126 33.2879 14.8465 32.9688 15.7059 32.7039C17.4248 32.174 19.192 31.9016 20.9786 31.7481C22.538 31.6141 24.1004 31.6081 25.6628 31.6924C26.0842 31.7149 26.5027 31.7691 26.9241 31.7962C27.0731 31.8068 27.1078 31.8655 27.1078 32.0085C27.1032 33.4098 27.4073 34.7374 28.1223 35.9521C28.8703 37.224 29.9134 38.1858 31.2245 38.8616C31.2802 38.8902 31.3359 38.9173 31.3915 38.9474C31.3991 38.9534 31.3991 38.967 31.4126 39.0001Z"
fill="white"
/>
<path
d="M29.4634 30.8568C29.5432 30.8568 29.6109 30.8568 29.6786 30.8568C30.6886 30.8568 31.6971 30.8568 32.7071 30.8568C32.9328 30.8568 32.9344 30.8568 32.9344 30.622C32.9344 29.612 32.9344 28.6035 32.9344 27.5935C32.9344 27.5273 32.9344 27.4596 32.9344 27.3828C33.9278 27.3828 34.8986 27.3828 35.8936 27.3828C35.8936 28.5388 35.8936 29.6858 35.8936 30.8553C37.0646 30.8553 38.2116 30.8553 39.3691 30.8553C39.3691 31.8322 39.3691 32.788 39.3691 33.7648C38.2161 33.7648 37.0676 33.7648 35.8951 33.7648C35.8951 34.9404 35.8951 36.0934 35.8951 37.2584C35.8168 37.2629 35.7611 37.2689 35.7054 37.2689C34.8444 37.2689 33.9835 37.2659 33.1225 37.2734C32.972 37.2749 32.9298 37.2328 32.9298 37.0823C32.9359 36.0557 32.9328 35.0292 32.9328 34.0027C32.9328 33.9349 32.9328 33.8672 32.9328 33.7754C31.7693 33.7754 30.6224 33.7754 29.4634 33.7754C29.4634 32.794 29.4634 31.8397 29.4634 30.8568Z"
fill="white"
/>
</svg>
</div>
<div className="name">
<p className="text-base text-dark-gray dark:text-white font-medium mb-2">
Your Account has been created
<span className="ml-1 font-bold">
successfully done
</span>
</p>
<p className="text-sm text-thin-light-gray font-medium">
23 house ago
</p>
</div>
</div>
</li>
<li className="content-item py-5">
<div className="notifications flex space-x-4 items-center">
<div className="icon">
<svg
width="52"
height="52"
viewBox="0 0 52 52"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="26" cy="26" r="26" fill="#9B51E0" />
<path
d="M32.8582 12.0043C33.1083 12.133 33.182 12.3469 33.1777 12.6144C33.169 13.1493 33.1748 13.6856 33.1748 14.2551C33.2962 14.2551 33.3931 14.2551 33.4899 14.2551C34.7664 14.2566 36.0414 14.2566 37.3179 14.258C38.0581 14.2595 38.3833 14.5978 38.3674 15.3365C38.3269 17.1449 38.1404 18.9346 37.6142 20.6737C37.2124 22.0051 36.6457 23.2483 35.602 24.2154C34.9558 24.8139 34.1925 25.1782 33.3165 25.2866C33.1517 25.3068 33.0953 25.3661 33.0606 25.5295C32.4737 28.2963 30.8314 30.1019 28.1209 30.9288C28.0038 30.9649 27.9099 30.9924 27.9099 31.1558C27.9157 32.8688 27.9157 34.5819 27.9171 36.2949C27.9171 36.3209 27.9287 36.3469 27.9417 36.399C28.0328 36.4033 28.1296 36.412 28.2265 36.412C28.8004 36.4134 29.3743 36.4163 29.9482 36.4106C30.1968 36.4077 30.3804 36.4958 30.525 36.7055C31.1032 37.5454 31.6901 38.3809 32.2742 39.2165C32.3942 39.3885 32.5113 39.5894 32.3537 39.7629C32.2409 39.8858 32.0356 39.987 31.8708 39.9884C28.0805 40.0014 24.2886 39.9971 20.4982 40C20.2959 40 20.1166 39.9653 20.0082 39.7716C19.8925 39.5634 19.9764 39.39 20.0978 39.2165C20.6775 38.3881 21.2586 37.5613 21.8296 36.7271C21.9858 36.5002 22.1824 36.4077 22.4498 36.4106C23.1047 36.4178 23.7595 36.412 24.4433 36.412C24.4491 36.2949 24.4578 36.198 24.4578 36.1012C24.4592 34.4879 24.4549 32.876 24.4621 31.2627C24.4635 31.0589 24.4086 30.9736 24.199 30.9086C21.5651 30.0875 19.9316 28.3325 19.3374 25.6335C19.2839 25.3907 19.2015 25.3083 18.9457 25.2678C17.6865 25.0726 16.7382 24.3744 16.0111 23.3524C15.1712 22.1713 14.7332 20.8254 14.4382 19.4275C14.152 18.0701 14.0205 16.6924 14.0002 15.3047C13.9901 14.579 14.3226 14.2551 15.0526 14.2537C16.319 14.2523 17.5868 14.2508 18.8531 14.2508C18.9529 14.2508 19.0526 14.2508 19.1957 14.2508C19.1957 13.9949 19.1957 13.7535 19.1957 13.5121C19.1957 13.2114 19.203 12.9107 19.1943 12.61C19.1856 12.3426 19.2637 12.1272 19.5138 12C23.9619 12.0043 28.4101 12.0043 32.8582 12.0043ZM26.1853 16.6086C25.9092 17.1666 25.62 17.6465 25.4307 18.1641C25.2283 18.7177 24.8871 18.9404 24.3089 18.9635C23.7624 18.9866 23.2203 19.1124 22.6305 19.1991C22.7259 19.3003 22.7852 19.3654 22.8488 19.4275C23.3114 19.88 23.7812 20.3253 24.2308 20.7893C24.3146 20.876 24.3681 21.0423 24.3551 21.1623C24.3161 21.5237 24.2351 21.8793 24.173 22.2378C24.1108 22.6064 24.0515 22.9765 23.9836 23.3928C24.6703 23.0314 25.3107 22.7062 25.9395 22.3592C26.1231 22.258 26.2604 22.2682 26.4382 22.365C27.0671 22.7091 27.706 23.0358 28.3609 23.3784C28.3609 23.2974 28.3681 23.2439 28.3595 23.1948C28.2453 22.5313 28.1383 21.8663 28.0096 21.2056C27.972 21.0105 28.014 20.8847 28.1571 20.7517C28.543 20.3918 28.9146 20.0145 29.2948 19.6473C29.435 19.5114 29.5824 19.3827 29.7834 19.2006C28.9999 19.0878 28.3103 18.9808 27.6179 18.8912C27.3938 18.8623 27.2492 18.7929 27.1466 18.5645C26.856 17.9256 26.5279 17.2982 26.1853 16.6086ZM36.6442 16.013C35.4661 16.013 34.3269 16.013 33.195 16.013C33.195 18.537 33.195 21.0365 33.195 23.6053C33.4986 23.4767 33.779 23.3928 34.0219 23.2468C34.7982 22.7799 35.2406 22.0398 35.5832 21.2331C36.053 20.1287 36.3089 18.9664 36.465 17.7824C36.5402 17.197 36.5835 16.61 36.6442 16.013ZM19.1798 23.5548C19.1798 21.0264 19.1798 18.5197 19.1798 16.0072C18.0291 16.0072 16.8972 16.0072 15.7581 16.0072C15.7552 16.0607 15.7494 16.0954 15.7509 16.1301C15.839 17.5786 16.0328 19.0098 16.4794 20.3947C16.7512 21.236 17.0909 22.0528 17.7053 22.7163C18.1029 23.1471 18.5698 23.4579 19.1798 23.5548Z"
fill="white"
/>
</svg>
</div>
<div className="name">
<p className="text-base text-dark-gray dark:text-white font-medium mb-2">
Your Account has been created
<span className="ml-1 font-bold">
successfully done
</span>
</p>
<p className="text-sm text-thin-light-gray font-medium">
23 house ago
</p>
</div>
</div>
</li>
{notifications?.data?.length &&
notifications?.data?.map((item, idx) => {
if (idx < 5) {
return (
<li
className={`content-item ${
idx == 4
? "py-5 "
: "py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple"
}`}
key={idx}
>
<div className="notifications flex space-x-4 items-center">
<div className="icon max-w-[52px] max-h-[52px] w-full h-full rounded-full object-cover">
<img
src={require(`../../assets/images/notifications/${item?.icon}`)}
alt="icon"
className="w-full h-full"
/>
</div>
<div className="name">
<p className="text-base text-dark-gray dark:text-white font-medium mb-2">
{item?.title}
{/* <span className="ml-1 font-bold">
successfully done
</span> */}
</p>
<p className="text-sm text-thin-light-gray font-medium">
<TimeDifference
time={item?.date}
key={item?.uid}
/>
</p>
</div>
</div>
</li>
);
}
})}
</ul>
<div className="add-money-btn flex justify-center items-center">
<Link
to="/notification"
className="text-purple text-sm font-medium"
onClick={handlerNotification}
>
See all Notification
</Link>
{/* <button className="text-purple text-sm font-medium" onClick={()=>{
handlerNotification()
navigate('/notification', {replace: true})
}}>See all Notification</button> */}
</div>
</div>
</div>
@@ -472,26 +340,43 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</Link>
</div>
{/* profile */}
<div className="user-profile relative lg:block hidden">
<div className="user-profile relative">
<div
onClick={() => handlerProfile()}
className="flex items-center space-x-3.5"
className="hidden lg:flex items-center space-x-3.5"
>
{/* profile-image */}
<div className="lg:w-[62px] lg:h-[62px] w-[50px] h-[50px] rounded-full overflow-hidden">
<img
src={profile_pic != "" ? profile_pic : profileImg}
src={userProfileImage}
alt="profile"
className="w-full h-full"
className="w-full h-full object-cover"
/>
</div>
<div className="lg:block hidden">
<h1 className="text-xl font-bold text-dark-gray dark:text-white">
{firstname}
</h1>
{userDetails && userDetails?.account_type !== "FAMILY" && <p className="text-sm text-thin-light-gray">@{userEmail}</p>}
{userDetails && userDetails?.account_type !== "FAMILY" && (
<p className="text-sm text-thin-light-gray">@{userEmail}</p>
)}
</div>
</div>
<div className="for-mobile-profile lg:hidden block">
<div
// to="/profile"
onClick={() => handlerProfile()}
className="lg:w-[62px] lg:h-[62px] w-[50px] h-[50px] rounded-full overflow-hidden block"
>
<img
src={profileImg}
alt="profile"
className="w-full h-full object-cover object-center"
/>
</div>
</div>
<div
className={`profile-dropdown w-[293px] z-30 bg-white dark:bg-dark-white absolute lg:right-16 -right-[16px] rounded-lg ${
userProfileDropdown ? "active" : ""
@@ -502,7 +387,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</div>
<div className="heading border-b dark:border-[#5356fb29] border-light-purple px-7 py-2">
<h3 className="text-xl font-bold text-dark-gray dark:text-white">
{`${firstname} ${lastname}`}
{`${firstname} ${lastname}`}
</h3>
</div>
<div className="content">
@@ -529,84 +414,6 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</li>
{userDetails && userDetails?.account_type !== "FAMILY" && (
<>
<li className="content-item relative my-2 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="#" className="notifications">
<div className="name">
<p className="flex items-center justify-between text-sm py-2 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
<span>Reports</span> <span>&gt;</span>
</p>
</div>
</Link>
{/* report list items*/}
<div
className="inner-list-items absolute rounded-lg"
onClick={setNotification}
>
<ul className="p-3">
<li className="content-item my-1 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="/referral" className="notifications">
<div className="name">
<p className="text-sm py-1 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
Referrals
</p>
</div>
</Link>
</li>
<li className="content-item my-1 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="#" className="notifications">
<div className="name">
<p className="text-sm py-1 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
Billing
</p>
</div>
</Link>
</li>
<li className="content-item my-1 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="#" className="notifications">
<div className="name">
<p className="text-sm py-1 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
Payments
</p>
</div>
</Link>
</li>
<li className="content-item my-1 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="#" className="notifications">
<div className="name">
<p className="text-sm py-1 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
Completed Jobs
</p>
</div>
</Link>
</li>
<li className="content-item my-1 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="#" className="notifications">
<div className="name">
<p className="text-sm py-1 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
Previous Task
</p>
</div>
</Link>
</li>
</ul>
<hr />
<div className="px-7 py-3 cursor-pointer flex items-center">
<div
className={`h-6 w-8 mr-1 p-1 ${
toggleNotification
? "bg-sky-blue flex justify-end items-center"
: "bg-slate-200"
} rounded-full transition`}
>
<div className="w-4 h-full bg-white rounded-full"></div>
</div>
<p className="text-sm py-2 px-4 text-slate-400 dark:text-white">
Notifications
</p>
</div>
</div>
{/* end report list items*/}
</li>
<li className="content-item my-2 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="#" className="notifications">
<div className="name">
@@ -675,7 +482,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
<li className="content-item my-2 hover:bg-slate-100 transition duration-500 rounded-lg cursor-pointer">
<div className="name" onClick={logoutModalHandler}>
<p className="text-sm py-2 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
Sign Out
{process.env.REACT_APP_LOGOUT_TEXT}
</p>
</div>
</li>
@@ -684,14 +491,15 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</div>
</div>
</div>
<div className="for-mobile-profile lg:hidden block">
<Link
to="/profile"
{/* <div className="for-mobile-profile lg:hidden block">
<div
// to="/profile"
onClick={() => handlerProfile()}
className="lg:w-[62px] lg:h-[62px] w-[50px] h-[50px] rounded-full overflow-hidden block"
>
<img src={profileImg} alt="profile" className="w-full h-full" />
</Link>
</div>
</div>
</div> */}
</div>
</div>
</div>
+2 -3
View File
@@ -8,7 +8,6 @@ import Header from "./Header";
import MobileSidebar from "./MobileSideBar";
import RightSideBar from "./RightSideBar";
import Sidebar from "./Sidebar";
import usersService from "../../services/UsersService";
export default function Layout({ children }) {
const { drawer } = useSelector((state) => state.drawer);
@@ -63,7 +62,7 @@ export default function Layout({ children }) {
drawer
? "2xl:w-[335px] w-[280px] 2xl:pl-20 pl-10 pr-6 "
: "w-[70px]"
} bg-white dark:bg-dark-white h-full overflow-y-scroll overflow-style-none fixed left-0 top-0 pt-8`}
} bg-white dark:bg-dark-white h-full overflow-y-scroll overflow-style-none fixed left-0 top-0 pt-[30px]`}
>
<Sidebar
logoutModalHandler={logoutModalHandler}
@@ -179,7 +178,7 @@ export default function Layout({ children }) {
type="button"
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
>
Yes Logout
{`Yes ${process.env.REACT_APP_LOGOUT_TEXT}`}
</button>
<button
onClick={logoutModalHandler}
+68 -65
View File
@@ -4,11 +4,16 @@ import { NavLink } from "react-router-dom";
import {
default as logo,
default as logo3,
} from "../../assets/images/wrenchboard.png"; //logo-2.svg";
} from "../../assets/images/wrenchboard-logo-text.png"; //logo-2.svg";
import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons";
export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJobList }) {
export default function MobileSidebar({
sidebar,
action,
logoutModalHandler,
myJobList,
}) {
let { userDetails } = useSelector((state) => state.userDetails);
const darkMode = useContext(DarkModeContext);
@@ -110,74 +115,72 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
{/* menu and settings item */}
{userDetails?.account_type !== "FAMILY" && (
<div
className={`menu-item transition-all duration-300 ease-in-out ${
sidebar ? "mb-5" : "mb-2"
}`}
>
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-sky-blue">
Family
</h1>
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<ListItem
title="Family Corner"
route="/acc-family"
iconName="new-family"
sidebar={sidebar}
/>
</ul>
</div>
</div>
<div
className={`menu-item transition-all duration-300 ease-in-out ${
sidebar ? "mb-5" : "mb-2"
}`}
>
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-sky-blue">Family</h1>
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<ListItem
title="Family Corner"
route="/acc-family"
iconName="new-family"
sidebar={sidebar}
/>
</ul>
</div>
</div>
)}
{userDetails?.account_type !== "FAMILY" && (
<>
{!userDetails?.post_jobs ? (
<div
className={`menu-item transition-all duration-300 ease-in-out bg-[#f0f8ff] dark:bg-dark-white rounded-2xl p-3 ${
sidebar ? "mb-5" : "mb-2 rounded-none p-0"
}`}
>
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-sky-blue">
Job Post
</h1>
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
to="/start-job"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar
? "justify-start space-x-3.5"
: "justify-center")
<div
className={`menu-item transition-all duration-300 ease-in-out bg-[#f0f8ff] dark:bg-dark-white rounded-2xl p-3 ${
sidebar ? "mb-5" : "mb-2 rounded-none p-0"
}`}
>
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-sky-blue">
Job Post
</h1>
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
to="/start-job"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar
? "justify-start space-x-3.5"
: "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="people-two" />
</span>
<span
className={`item-content group-hover:text-sky-blue text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="people-two" />
</span>
<span
className={`item-content group-hover:text-sky-blue text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
Enable Job Post
</span>
</NavLink>
</li>
</ul>
</div>
Enable Job Post
</span>
</NavLink>
</li>
</ul>
</div>
</div>
) : myJobList?.data?.result_list?.length ? (
<div
className={`menu-item transition-all duration-300 ease-in-out ${
sidebar ? "mb-5" : "mb-2"
}`}
className={`menu-item transition-all duration-300 ease-in-out ${
sidebar ? "mb-5" : "mb-2"
}`}
>
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-sky-blue">
@@ -212,9 +215,9 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
</div>
) : (
<div
className={`menu-item transition-all duration-300 ease-in-out ${
sidebar ? "mb-5" : "mb-2"
}`}
className={`menu-item transition-all duration-300 ease-in-out ${
sidebar ? "mb-5" : "mb-2"
}`}
>
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-sky-blue">
@@ -245,14 +248,14 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
className="signout-btn flex items-center space-x-1 p-2.5 w-2/3 h-[52px] bg-sky-blue transition duration-300 ease-in-out hover:bg-gray-900 rounded-full"
>
<span className="">
<Icons name='new-logout' />
<Icons name="new-logout" />
</span>
<span
className={`signout-btn-content text-white text-xl font-bold ${
sidebar ? "active" : ""
}`}
>
Signout
{process.env.REACT_APP_LOGOUT_TEXT}
</span>
</button>
) : (
File diff suppressed because one or more lines are too long
+9 -7
View File
@@ -13,9 +13,11 @@ import {
CollectionTab,
CreatedTab,
HiddenProductsTab,
MyUploadedFiles,
OnSaleTab,
OwnTab,
} from "./tabs";
//import MyUploadedFiles from "./tabs/MyUploadedFiles";
export default function Resources(props) {
// console.log("RESOURCES=>", props);
@@ -42,9 +44,7 @@ export default function Resources(props) {
blog: <BlogTab blogdata={blogItems} />,
onsale: <QuestionsTab products={onSaleProducts} />,
owned: <OwnTab products={ownProducts} />,
created: (
<CreatedTab marketProducts={CreatedSell} mainProducts={CreatedBits} />
),
created: <MyUploadedFiles marketProducts={CreatedSell} mainProducts={CreatedBits} />,
hidden: (
<HiddenProductsTab
marketProducts={CreatedSell}
@@ -66,6 +66,7 @@ export default function Resources(props) {
return blogItems?.blogdata?.length
}else if(name == 'onsale'){
return onSaleProducts?.length
// return null
}else if(name == 'owned'){
return ownProducts?.length
}else if(name == 'created'){
@@ -88,6 +89,7 @@ export default function Resources(props) {
>
{tabValue.content}
</span>
{tabValue.name != 'onsale' &&
<span
className={`w-5 h-5 group-hover:bg-pink group-hover:text-white text-[10px] rounded-full absolute -top-2 -right-5 flex justify-center items-center ${
isActive
@@ -95,9 +97,9 @@ export default function Resources(props) {
: "text-thin-light-gray bg-[#F2B8FD]"
}`}
>
{/* 16 blog, onsale, owned,created */}
{countNumber(tabValue.name)}
</span>
}
</li>
);
};
@@ -134,14 +136,14 @@ export default function Resources(props) {
<div className="tab-items">
<TabList tabCategories={tab_categories} />
</div>
<div style={{ transform: "translateY(-22px)" }}>
{/* <div style={{ transform: "translateY(-22px)" }}>
<Link
to="/upload-product"
to="/my-uploads"
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
>
Add My Item
</Link>
</div>
</div> */}
</div>
<div className="hidden lg:block w-full h-[1px] bg-[#DCD5FE] dark:bg-[#5356fb29] absolute top-[42px] left-0"></div>
</div>
+27 -27
View File
@@ -18,36 +18,36 @@ export default function CreatedTab({
</div>
{/* filer-dropdown */}
<div className="flex-1 flex sm:justify-end">
<div className="flex space-x-1 items-center">
<span className="text-18 text-thin-light-gray">
Recently Received
</span>
<span>
<svg
width="20"
height="10"
viewBox="0 0 13 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
opacity="0.7"
d="M12.4124 0.247421C12.3327 0.169022 12.2379 0.106794 12.1335 0.0643287C12.0291 0.0218632 11.917 0 11.8039 0C11.6908 0 11.5787 0.0218632 11.4743 0.0643287C11.3699 0.106794 11.2751 0.169022 11.1954 0.247421L7.27012 4.07837C7.19045 4.15677 7.09566 4.219 6.99122 4.26146C6.88678 4.30393 6.77476 4.32579 6.66162 4.32579C6.54848 4.32579 6.43646 4.30393 6.33202 4.26146C6.22758 4.219 6.13279 4.15677 6.05312 4.07837L2.12785 0.247421C2.04818 0.169022 1.95338 0.106794 1.84895 0.0643287C1.74451 0.0218632 1.63249 0 1.51935 0C1.40621 0 1.29419 0.0218632 1.18975 0.0643287C1.08531 0.106794 0.990517 0.169022 0.910844 0.247421C0.751218 0.404141 0.661621 0.616141 0.661621 0.837119C0.661621 1.0581 0.751218 1.2701 0.910844 1.42682L4.84468 5.26613C5.32677 5.73605 5.98027 6 6.66162 6C7.34297 6 7.99647 5.73605 8.47856 5.26613L12.4124 1.42682C12.572 1.2701 12.6616 1.0581 12.6616 0.837119C12.6616 0.616141 12.572 0.404141 12.4124 0.247421Z"
fill="#374557"
fillOpacity="0.6"
/>
</svg>
</span>
</div>
{/*<div className="flex space-x-1 items-center">*/}
{/* <span className="text-18 text-thin-light-gray">*/}
{/* Recently Received*/}
{/* </span>*/}
{/* <span>*/}
{/* <svg*/}
{/* width="20"*/}
{/* height="10"*/}
{/* viewBox="0 0 13 6"*/}
{/* fill="none"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <path*/}
{/* opacity="0.7"*/}
{/* d="M12.4124 0.247421C12.3327 0.169022 12.2379 0.106794 12.1335 0.0643287C12.0291 0.0218632 11.917 0 11.8039 0C11.6908 0 11.5787 0.0218632 11.4743 0.0643287C11.3699 0.106794 11.2751 0.169022 11.1954 0.247421L7.27012 4.07837C7.19045 4.15677 7.09566 4.219 6.99122 4.26146C6.88678 4.30393 6.77476 4.32579 6.66162 4.32579C6.54848 4.32579 6.43646 4.30393 6.33202 4.26146C6.22758 4.219 6.13279 4.15677 6.05312 4.07837L2.12785 0.247421C2.04818 0.169022 1.95338 0.106794 1.84895 0.0643287C1.74451 0.0218632 1.63249 0 1.51935 0C1.40621 0 1.29419 0.0218632 1.18975 0.0643287C1.08531 0.106794 0.990517 0.169022 0.910844 0.247421C0.751218 0.404141 0.661621 0.616141 0.661621 0.837119C0.661621 1.0581 0.751218 1.2701 0.910844 1.42682L4.84468 5.26613C5.32677 5.73605 5.98027 6 6.66162 6C7.34297 6 7.99647 5.73605 8.47856 5.26613L12.4124 1.42682C12.572 1.2701 12.6616 1.0581 12.6616 0.837119C12.6616 0.616141 12.572 0.404141 12.4124 0.247421Z"*/}
{/* fill="#374557"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* </svg>*/}
{/* </span>*/}
{/*</div>*/}
</div>
</div>
<div className="content-section w-full">
<div className="marketplace-products-widgets mb-16">
<CreateSaleSlider products={marketProducts} />
</div>
<div className="main-products-widgets">
<CreatedBidsSlider products={mainProducts} />
</div>
{/*<div className="marketplace-products-widgets mb-16">*/}
{/* <CreateSaleSlider products={marketProducts} />*/}
{/*</div>*/}
{/*<div className="main-products-widgets">*/}
{/* <CreatedBidsSlider products={mainProducts} />*/}
{/*</div>*/}
</div>
</div>
</div>
@@ -0,0 +1,278 @@
import React, { useState } from "react";
import dataImage1 from "../../../assets/images/data-table-user-1.png";
import dataImage2 from "../../../assets/images/data-table-user-2.png";
import { Link } from "react-router-dom";
// import dataImage3 from "../../../assets/images/data-table-user-3.png";
// import dataImage4 from "../../../assets/images/data-table-user-4.png";
// import SelectBox from "../Helpers/SelectBox";
export default function MyUploadedFiles({ className }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
return (
<>
<div className="mb-4 w-full flex justify-end item-center">
<Link
to="/my-uploads"
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
>
Add My Item
</Link>
</div>
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow relative min-h-[520px] ${
className || ""
}`}
>
<div className="header w-full sm:flex justify-between items-center mb-5">
<div className="flex space-x-2 items-center mb-2 sm:mb-0">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
My Uploads
</h1>
</div>
</div>
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{/* table heading */}
{/*<tr className="text-base text-thin-light-gray whitespace-nowrap px-2 border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
{/* <td className="py-4 w-[300px] block whitespace-nowrap">*/}
{/* All Product*/}
{/* </td>*/}
{/* <td className="py-4 whitespace-nowrap text-center">.</td>*/}
{/* <td className="py-4 whitespace-nowrap text-center"></td>*/}
{/* <td className="py-4 whitespace-nowrap text-right"></td>*/}
{/*</tr>*/}
<tr className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
<td className=" py-4">
<div className="flex space-x-2 items-center">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage1}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
Mullican Computer Joy
</h1>
<span className="text-sm text-thin-light-gray">
Owned by <span className="text-purple">Xoeyam</span>
</span>
</div>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
fill="#627EEA"
/>
<path
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
fill="white"
/>
<path
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
fill="white"
/>
<path
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
fill="white"
fillOpacity="0.2"
/>
<path
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
fill="white"
fillOpacity="0.602"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
7473 ETH
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
fill="#59BE59"
/>
<path
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
fill="#FEFEFE"
/>
<path
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
fill="#59BE59"
/>
<path
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
fill="#59BE59"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium">
6392.99$
</span>
</div>
</td>
<td className="text-right py-4">
<button
type="button"
className="text-sm text-white bg-purple px-2.5 py-1.5 rounded-full"
>
Active
</button>
</td>
</tr>
<tr className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
<td className=" py-4">
<div className="flex space-x-2 items-center">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
Mullican Computer Joy
</h1>
<span className="text-sm text-thin-light-gray">
Owned by <span className="text-purple">Xoeyam</span>
</span>
</div>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
fill="#627EEA"
/>
<path
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
fill="white"
/>
<path
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
fill="white"
/>
<path
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
fill="white"
fillOpacity="0.2"
/>
<path
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
fill="white"
fillOpacity="0.602"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
7473 ETH
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
fill="#59BE59"
/>
<path
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
fill="#FEFEFE"
/>
<path
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
fill="#59BE59"
/>
<path
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
fill="#59BE59"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium">
6392.99$
</span>
</div>
</td>
<td className="text-right py-4">
<button
type="button"
className="text-sm text-white bg-light-green px-2.5 py-1.5 rounded-full"
>
Complated
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</>
);
}
+106 -12
View File
@@ -1,24 +1,118 @@
import { useEffect, useState } from "react";
import ProductCardStyleTwo from "../../Cards/ProductCardStyleTwo";
import DataIteration from "../../Helpers/DataIteration";
import SearchCom from "../../Helpers/SearchCom";
import localImgLoad from "../../../lib/localImgLoad";
import usersService from "../../../services/UsersService";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
export default function QuestionsTab({ className, products }) {
const apiCall = new usersService()
const [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: ''})
const [error, setError] = useState({question: '', searchPhrase: ''})
const [questions, setQuestions] = useState({loading: true, data: []})
const [askQuestion, setAskQuestion] = useState({question: '', searchPhrase: ''})
const changeAskQuestion = ({target: {name, value}}) => {
setAskQuestion(prev => ({...prev, [name]: value}))
setRequestStatus({loading: false, status: false, message: ''})
}
const onSearch = () => {
setError({question: '', searchPhrase: ''}) // sets error to false
if(!askQuestion.question){
return setError(prev => ({...prev, question: 'Select a question'}))
}
if(!askQuestion.searchPhrase){
return setError(prev => ({...prev, searchPhrase: 'Enter search parameter'}))
}
if(askQuestion.searchPhrase.length > 60){
return setError(prev => ({...prev, searchPhrase: 'Max of 60 characters'}))
}
setRequestStatus({loading: true, status: false, message: ''})
let reqData = {
question_key: '',
question: ''
}
apiCall.askResourcesResult().then(res => {
console.log(res.data.choices[0].text)
if(!res.data || res.data?.choices?.length < 1){
setRequestStatus({loading: false, status: false, message: 'No result found!'})
}
setRequestStatus({loading: false, status: false, message: res.data?.choices[0].text})
}).catch(error => {
setRequestStatus({loading: false, status: false, message: 'No result found!'})
})
}
useEffect(()=>{
apiCall.getResourceList().then(res => {
setQuestions({loading: false, data: res.data?.ask_categories?.data})
}).catch(error => {
setQuestions({loading: false, data: []})
console.log('ERROR', error)
})
}, [])
return (
<>
<div className={`onsale-tab-wrapper w-full ${className || ""}`}>
<div className="main-container w-full">
<div className="filter-section w-full items-center sm:flex justify-between mb-6">
{/* filter-search */}
<div className="sm:w-1/2 w-full sm:pr-20 pr-0 mb-5 sm:mb-0">
<SearchCom />
</div>
</div>
<div className="content-section w-full-width">
<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-[30px]">
<div className="filter-section w-fullmb-6">
<h1 className="text-xl lg:text-2xl font-bold text-dark-gray dark:text-white tracking-wide">Ask our A.I</h1>
<div className="mt-2 lg:grid grid-cols-2 gap-2 h-full lg:h-[500px]">
<div className="h-full mb-5 lg:mb-0">
<img className="w-full h-full rounded-2xl" src={localImgLoad(`images/resources-ask.jpg`)} alt='AI' />
</div>
<div className="p-8 bg-white rounded-2xl h-full">
<div className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base">
<select value={askQuestion.question} name='question' onChange={changeAskQuestion} className="input-field px-2 placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none">
{questions.loading ?
<option value='' className="">Loading...</option>
:
<>
<option value='' className="">Find answer on:</option>
{questions.data.length > 0 && questions.data.map((item, index)=>(
<option key={index} value={item.question_key} className="">{item.name}</option>
))}
</>
}
</select>
</div>
{error.question && <p className="text-red-500 text-[12px]">{error.question}</p>}
{/* filter-search */}
<div className="w-full my-5 border-2 rounded-full">
<SearchCom
name={'searchPhrase'}
value={askQuestion.searchPhrase}
handleSearch={changeAskQuestion}
/>
</div>
{error.searchPhrase && <p className="text-red-500 text-[12px]">{error.searchPhrase}</p>}
<div className="w-full flex justify-end items-center border-b-2 pb-4">
<button
onClick={onSearch}
disabled={requestStatus.loading}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
>
Search
</button>
</div>
<div className="search_result my-2 max-h-[400px] overflow-auto">
{requestStatus.loading ?
<LoadingSpinner size='8' color='sky-blue' height='h-[100px]' />
:
<p className="py-2 text-sm font-bold text-dark-gray dark:text-white tracking-wide">{requestStatus.message}</p>
}
</div>
</div>
</div>
</div>
</div>
+2
View File
@@ -6,6 +6,7 @@ import OnSaleTab from "./OnSaleTab";
import OwnTab from "./OwnTab";
import BlogTab from "./BlogTab";
import QuestionsTab from "./QuestionsTab";
import MyUploadedFiles from "./MyUploadedFiles";
export {
BlogTab,
@@ -16,4 +17,5 @@ export {
HiddenProductsTab,
OnSaleTab,
OwnTab,
MyUploadedFiles,
};
@@ -1,8 +1,3 @@
import React, { useEffect, useState } from "react";
import method1 from "../../../assets/images/payment-method-1.png";
import method2 from "../../../assets/images/payment-method-2.png";
import method3 from "../../../assets/images/payment-method-3.png";
import method4 from "../../../assets/images/payment-method-4.png";
import CardList from "./CardList";
@@ -1,13 +1,11 @@
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { Link, useNavigate } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import usersService from "../../../services/UsersService";
import Icons from "../../Helpers/Icons";
import InputCom from "../../Helpers/Inputs/InputCom";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import { toast } from "react-toastify";
import { Form, Formik } from "formik";
import * as Yup from "yup";
@@ -60,14 +58,17 @@ export default function PersonalInfoTab({
let navigate = useNavigate();
let [togglePromotion, setTogglePromotion] = useState(false);
const initialValues = {
firstname: userDetails?.firstname,
lastname: userDetails?.lastname,
state: userDetails?.state,
city: userDetails?.city,
email: userDetails?.email,
profile: userDetails?.profile_pic,
pref_email: 0,
pref_phone: 0,
accept_promo: false,
online_name: "",
};
let [profile, setProfile] = useState({
@@ -86,8 +87,17 @@ export default function PersonalInfoTab({
const handleUpdateUser = (values, helpers) => {
setRequestState({ message: "", loading: true, status: false });
// there is no profile accommodation on the payload
delete values?.profile;
const reqData = {
...values,
pref_email: Number(values.pref_email?.toString()),
pref_phone: Number(values.pref_phone?.toString()),
};
apiCall
.updateProfile(values)
.updateProfile(reqData)
.then((res) => {
// API CALL TO UPDATE USER DETAILS
if (res.data.internal_return < 0) {
@@ -98,10 +108,14 @@ export default function PersonalInfoTab({
});
return;
}
// setRequestState({message: 'Profile update successfully', loading: false, status: true})
toast.success("Update Successful");
setRequestState({
message: "Profile update successfully",
loading: false,
status: true,
});
// toast.success("Update Successful");
setTimeout(() => {
// navigate("/", { replace: true });
navigate("/", { replace: true });
window.location.reload(true);
}, 1000);
})
@@ -144,9 +158,9 @@ export default function PersonalInfoTab({
fieldClass="px-6"
label="User Name"
type="text"
name="username"
placeholder=""
value={userDetails.username}
name="online_name"
placeholder="Username"
value={userDetails?.username}
disable={true}
/>
</div>
@@ -206,6 +220,25 @@ export default function PersonalInfoTab({
)}
</div>
</div>
{/* Online Name */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Online Name (optional)"
type="text"
name="online_name"
placeholder=""
value={props.values.online_name}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.online_name &&
props.touched.online_name && (
<p className="text-sm text-red-500">
{props.errors.online_name}
</p>
)}
</div>
{/* Country */}
<div className="field w-full mb-6">
@@ -263,13 +296,17 @@ export default function PersonalInfoTab({
Pref. Communication
</label>
<div className="check-box">
<div className="flex items-center justify-start">
<div
role="group"
className="flex items-center justify-start"
>
<div className="check-input flex items-center mr-1">
<input
className="w-4 h-4 cursor-pointer"
type="checkbox"
name="prefcomm1"
id=""
name="pref_email"
value={1}
onChange={props.handleChange}
/>
<span className="mx-2 text-base text-dark-gray dark:text-white">
Email
@@ -279,8 +316,9 @@ export default function PersonalInfoTab({
<input
className="w-4 h-4 cursor-pointer"
type="checkbox"
name="prefcomm2"
id=""
name="pref_phone"
value={1}
onChange={props.handleChange}
/>
<span className="mx-2 text-base text-dark-gray dark:text-white">
Phone
@@ -292,22 +330,32 @@ export default function PersonalInfoTab({
{/* Allow Promotions */}
<div className="field w-full mb-6 flex items-center space-x-4">
<label className="input-label text-[#181c32] dark:text-white text-base font-semibold">
<label
htmlFor="accept_promo"
className="input-label text-[#181c32] dark:text-white text-base font-semibold"
>
Allow Promotions
</label>
<div
className="cursor-pointer flex items-center"
onClick={() => setTogglePromotion((prev) => !prev)}
>
<div
className={`h-6 w-8 mr-1 p-1 ${
togglePromotion
<div>
<input
type="checkbox"
id="accept_promo"
name="accept_promo"
value={props.values.accept_promo}
checked={props.values.accept_promo}
onChange={props.handleChange}
className="hidden"
/>
<label
htmlFor="accept_promo"
className={`cursor-pointer flex items-center h-6 w-8 mr-1 p-1 ${
props.values.accept_promo
? "bg-sky-blue flex justify-end items-center"
: "bg-slate-200"
} rounded-full transition`}
} rounded-full transition duration-200`}
>
<div className="w-4 h-full bg-white rounded-full"></div>
</div>
</label>
</div>
</div>
{/* inputs ends here */}
@@ -336,8 +384,8 @@ export default function PersonalInfoTab({
<div className="w-full relative">
<img
src={profileImg}
alt=""
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
alt="profile"
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-contain object-center"
/>
<input
ref={profileImgInput}
@@ -384,7 +432,7 @@ export default function PersonalInfoTab({
)}
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
<div className="flex items-center space-x-4 mr-9">
<Link
{/* <Link
to="/"
className="text-18 text-light-red tracking-wide "
>
@@ -392,7 +440,7 @@ export default function PersonalInfoTab({
{" "}
Cancel
</span>
</Link>
</Link> */}
{requestStatus.loading ? (
<LoadingSpinner size="8" color="sky-blue" />
@@ -0,0 +1,107 @@
import { useState } from "react";
import method1 from "../../../assets/images/icons/bank.svg";
import localImgLoad from "../../../lib/localImgLoad";
import { PaginatedList, handlePagingFunc } from "../../Pagination";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
export default function RecipientAccountTab({
recipientAccount,
setRecipientAccount,
}) {
const cardList = recipientAccount?.data?.result_list;
const handleDeleteCardModal = () => {
setRecipientAccount((prev) => ({ ...prev, state: !prev.state }));
};
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentCardList = cardList?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
return (
<>
<div className="payment-method-tab w-full">
<div className="payment-item-wrapper w-full">
<ul className="payment-items w-full min-h-[400px]">
{recipientAccount?.loading ? (
<div className="w-full h-[300px] flex justify-center items-center">
<LoadingSpinner size="8" color="sky-blue" />
</div>
) : cardList?.length ? (
currentCardList.map((item) => {
let image =
item.description &&
localImgLoad(
`images/settings/${item.description.toLowerCase()}.svg`
);
let addedDate = item?.added?.split(" ")[0];
return (
<li
key={item.recipient_id}
className="sm:flex justify-between items-center w-full py-3 border-b border-light-purple dark:border-[#5356fb29] "
>
<div className="flex space-x-5 mb-2 sm:mb-0">
<div className="w-[70px] h-[70px] flex items-center justify-center rounded-full sm:bg-light-purple dark:bg-dark-light-purple ">
<img
src={image ? image : method1}
className="w-[50px] h-[50px]"
alt="payment"
/>
</div>
<div className="flex flex-col justify-around">
<p className="sm:text-xl text-lg tracking-wide text-dark-gray dark:text-white">
Added: {addedDate}
</p>
<p className="text-thin-light-gray sm:text-18 text-base tracking-wide">
{item?.recipient}
</p>
</div>
</div>
<div>
<button
type="button"
onClick={() => {
// setRecipientAccount({ state: true, data: item });
console.log("Testing...")
}}
className="w-[95px] sm:h-[46px] h-[40px] rounded-full btn-gradient text-white sm:text-18 text-md tracking-wide"
>
Delete
</button>
</div>
</li>
);
})
) : (
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
No Cards Found
</h1>
)}
</ul>
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
cardList?.length
? true
: false
}
data={cardList}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
</div>
</>
);
}
+79 -7
View File
@@ -1,6 +1,14 @@
import React, { useRef, useState } from "react";
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { useSelector } from "react-redux";
import cover from "../../assets/images/profile-info-cover.png";
import profile from "../../assets/images/profile-info-profile.png";
import profile from "../../assets/images/profile.jpg";
import usersService from "../../services/UsersService";
import Icons from "../Helpers/Icons";
import Layout from "../Partials/Layout";
import {
@@ -13,16 +21,22 @@ import {
PrivacyPolicyTab,
TermsConditionTab,
} from "./Tabs";
import RecipientAccountTab from "./Tabs/RecipientAccountTab";
export default function Settings({ faq }) {
const [profileImg, setProfileImg] = useState(profile);
const { userDetails } = useSelector((state) => state?.userDetails);
const [profileImg, setProfileImg] = useState(
userDetails?.profile_pic_url ? userDetails.profile_pic_url : profile
);
const [coverImg, setCoverImg] = useState(cover);
const [reloadCardList, setReloadCardList] = useState(false); // STATE TO DETERMINE WHEN CARD LIST RELOADS. EG: WHEN USER DELETES A CARD
// profile img
const profileImgInput = useRef(null);
const browseProfileImg = () => {
profileImgInput.current.click();
};
const profileImgChangHandler = (e) => {
if (e.target.value !== "") {
const imgReader = new FileReader();
@@ -47,6 +61,7 @@ export default function Settings({ faq }) {
}
};
const apiCall = useMemo(() => new usersService(), []);
// Tabs Handling
const tabs = [
{
@@ -63,30 +78,36 @@ export default function Settings({ faq }) {
},
{
id: 3,
name: "recipients-account",
title: "Recipients Account",
iconName: "bank-card",
},
{
id: 4,
name: "notification",
title: "Notification Setting",
iconName: "notification-setting",
},
{
id: 4,
id: 5,
name: "login_activity",
title: "Login Activity",
iconName: "login-activity",
},
{
id: 5,
id: 6,
name: "password",
title: "Change Password",
iconName: "password-hover",
},
{
id: 6,
id: 7,
name: "faq",
title: "FAQ",
iconName: "block-question",
},
{
id: 7,
id: 8,
name: "privacy",
title: "Privacy Policy",
iconName: "page-right",
@@ -103,6 +124,48 @@ export default function Settings({ faq }) {
setTab(value);
};
// Recipient Account
const [recipientAccount, setRecipientAccount] = useState({
state: false,
loader: false,
msg: "",
data: null,
});
const getRecipientAccount = useCallback(async () => {
setRecipientAccount((prev) => ({ loader: true }));
let res;
try {
res = await apiCall.getRecipient();
res = res.data;
if (res?.internal_return < 0) {
setRecipientAccount((prev) => ({
loader: false,
msg: "Sorry, something went wrong",
}));
setTimeout(() => setRecipientAccount((prev) => prev), 5000);
return;
}
return setTimeout(() => {
setRecipientAccount((prev) => ({ loader: false, data: res }));
});
} catch (error) {
setRecipientAccount((prev) => ({
loader: false,
msg: "Sorry, an error occurred",
}));
setTimeout(() => setRecipientAccount((prev) => prev), 5000);
return;
}
}, [apiCall]);
useEffect(() => {
getRecipientAccount();
}, [reloadCardList]);
return (
<>
<Layout>
@@ -162,6 +225,15 @@ export default function Settings({ faq }) {
<PaymentMathodsTab />
</div>
)}
{tab === "recipients-account" && (
<div className="tab-item">
<RecipientAccountTab
recipientAccount={recipientAccount}
setRecipientAccount={setRecipientAccount}
setReloadCardList={setReloadCardList}
/>
</div>
)}
{tab === "notification" && (
<div className="tab-item">
<NotificationSettingTab />
@@ -22,132 +22,134 @@ export default function ProductUploadField({
<div className="w-full lg:pl-[41px]">
<div className="fields w-full">
<form onSubmit={(e) => e.preventDefault()}>
<div className="field w-full mb-6">
<h1 className="field-title">Put on marketplace</h1>
<p className="text-thin-light-gray text-base tracking-wide font-medium mb-3">
Enter price to allow users instantly purchase your NFT
</p>
{/*<div className="field w-full mb-6">*/}
{/* <h1 className="field-title">Put on marketplace</h1>*/}
{/* <p className="text-thin-light-gray text-base tracking-wide font-medium mb-3">*/}
{/* Enter price to allow users instantly purchase your NFT*/}
{/* </p>*/}
{/* <div className="items sm:flex sm:space-x-5">*/}
{/* <div*/}
{/* className="item sm:w-[120px] w-full h-[130px] relative mb-5 sm:mb-0"*/}
{/* onClick={() => cpt("fixed")}*/}
{/* >*/}
{/* <div*/}
{/* className={`w-full h-full bg-white dark:bg-dark-white rounded-md z-20 relative flex justify-center items-center ${*/}
{/* datas.priceType === "fixed"*/}
{/* ? ""*/}
{/* : "border border-light-purple dark:border-[#5356fb29] "*/}
{/* }`}*/}
{/* >*/}
{/* <div className="flex flex-col justify-center items-center">*/}
{/* <div*/}
{/* className={`w-[68px] h-[68px] rounded-full flex justify-center items-center ${*/}
{/* datas.priceType === "fixed"*/}
{/* ? "primary-gradient"*/}
{/* : "bg-[#F2E8FA]"*/}
{/* }`}*/}
{/* >*/}
{/* <GradientIcons*/}
{/* name={`${*/}
{/* datas.priceType === "fixed"*/}
{/* ? "doller"*/}
{/* : "gradient-doller"*/}
{/* }`}*/}
{/* />*/}
{/* </div>*/}
{/* <p className="text-center text-base tracking-wide mt-1 text-dark-gray dark:text-white">*/}
{/* Fixed price*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* {datas.priceType === "fixed" && (*/}
{/* <div*/}
{/* className="sm:w-[122px] w-full h-[132px] primary-gradient rounded-md absolute z-10"*/}
{/* style={{ top: "-1px", left: "-1px" }}*/}
{/* ></div>*/}
{/* )}*/}
{/* </div>*/}
{/* <div*/}
{/* className="item sm:w-[120px] w-full h-[130px] relative mb-5 sm:mb-0"*/}
{/* onClick={() => cpt("bids")}*/}
{/* >*/}
{/* <div*/}
{/* className={`w-full h-full bg-white dark:bg-dark-white rounded-md z-20 relative flex justify-center items-center ${*/}
{/* datas.priceType === "bids"*/}
{/* ? ""*/}
{/* : "border border-light-purple dark:border-[#5356fb29] "*/}
{/* }`}*/}
{/* >*/}
{/* <div className="flex flex-col justify-center items-center">*/}
{/* <div*/}
{/* className={`w-[68px] h-[68px] rounded-full flex justify-center items-center ${*/}
{/* datas.priceType === "bids"*/}
{/* ? "primary-gradient"*/}
{/* : "bg-[#F2E8FA]"*/}
{/* }`}*/}
{/* >*/}
{/* <GradientIcons*/}
{/* name={`${*/}
{/* datas.priceType === "bids"*/}
{/* ? "hammer"*/}
{/* : "gradient-hammer"*/}
{/* }`}*/}
{/* />*/}
{/* </div>*/}
{/* <p className="text-center text-base tracking-wide mt-1 text-dark-gray dark:text-white">*/}
{/* Open for bids*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* {datas.priceType === "bids" && (*/}
{/* <div*/}
{/* className="sm:w-[122px] w-full h-[132px] primary-gradient rounded-md absolute z-10"*/}
{/* style={{ top: "-1px", left: "-1px" }}*/}
{/* ></div>*/}
{/* )}*/}
{/* </div>*/}
{/* <div*/}
{/* className="item sm:w-[120px] w-full h-[130px] relative mb-5 sm:mb-0"*/}
{/* onClick={() => cpt("auction")}*/}
{/* >*/}
{/* <div*/}
{/* className={`w-full h-full bg-white dark:bg-dark-white rounded-md z-20 relative flex justify-center items-center ${*/}
{/* datas.priceType === "auction"*/}
{/* ? ""*/}
{/* : "border border-light-purple dark:border-[#5356fb29] "*/}
{/* }`}*/}
{/* >*/}
{/* <div className="flex flex-col justify-center items-center">*/}
{/* <div*/}
{/* className={`w-[68px] h-[68px] rounded-full flex justify-center items-center ${*/}
{/* datas.priceType === "auction"*/}
{/* ? "primary-gradient"*/}
{/* : "bg-[#F2E8FA]"*/}
{/* }`}*/}
{/* >*/}
{/* <GradientIcons*/}
{/* name={`${*/}
{/* datas.priceType === "auction"*/}
{/* ? "timeout"*/}
{/* : "gradient-timeout"*/}
{/* }`}*/}
{/* />*/}
{/* </div>*/}
{/* <p className="text-center text-base tracking-wide mt-1 text-dark-gray dark:text-white">*/}
{/* Timed auction*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* {datas.priceType === "auction" && (*/}
{/* <div*/}
{/* className="sm:w-[122px] w-full h-[132px] primary-gradient rounded-md absolute z-10"*/}
{/* style={{ top: "-1px", left: "-1px" }}*/}
{/* ></div>*/}
{/* )}*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
<div className="items sm:flex sm:space-x-5">
<div
className="item sm:w-[120px] w-full h-[130px] relative mb-5 sm:mb-0"
onClick={() => cpt("fixed")}
>
<div
className={`w-full h-full bg-white dark:bg-dark-white rounded-md z-20 relative flex justify-center items-center ${
datas.priceType === "fixed"
? ""
: "border border-light-purple dark:border-[#5356fb29] "
}`}
>
<div className="flex flex-col justify-center items-center">
<div
className={`w-[68px] h-[68px] rounded-full flex justify-center items-center ${
datas.priceType === "fixed"
? "primary-gradient"
: "bg-[#F2E8FA]"
}`}
>
<GradientIcons
name={`${
datas.priceType === "fixed"
? "doller"
: "gradient-doller"
}`}
/>
</div>
<p className="text-center text-base tracking-wide mt-1 text-dark-gray dark:text-white">
Fixed price
</p>
</div>
</div>
{datas.priceType === "fixed" && (
<div
className="sm:w-[122px] w-full h-[132px] primary-gradient rounded-md absolute z-10"
style={{ top: "-1px", left: "-1px" }}
></div>
)}
</div>
<div
className="item sm:w-[120px] w-full h-[130px] relative mb-5 sm:mb-0"
onClick={() => cpt("bids")}
>
<div
className={`w-full h-full bg-white dark:bg-dark-white rounded-md z-20 relative flex justify-center items-center ${
datas.priceType === "bids"
? ""
: "border border-light-purple dark:border-[#5356fb29] "
}`}
>
<div className="flex flex-col justify-center items-center">
<div
className={`w-[68px] h-[68px] rounded-full flex justify-center items-center ${
datas.priceType === "bids"
? "primary-gradient"
: "bg-[#F2E8FA]"
}`}
>
<GradientIcons
name={`${
datas.priceType === "bids"
? "hammer"
: "gradient-hammer"
}`}
/>
</div>
<p className="text-center text-base tracking-wide mt-1 text-dark-gray dark:text-white">
Open for bids
</p>
</div>
</div>
{datas.priceType === "bids" && (
<div
className="sm:w-[122px] w-full h-[132px] primary-gradient rounded-md absolute z-10"
style={{ top: "-1px", left: "-1px" }}
></div>
)}
</div>
<div
className="item sm:w-[120px] w-full h-[130px] relative mb-5 sm:mb-0"
onClick={() => cpt("auction")}
>
<div
className={`w-full h-full bg-white dark:bg-dark-white rounded-md z-20 relative flex justify-center items-center ${
datas.priceType === "auction"
? ""
: "border border-light-purple dark:border-[#5356fb29] "
}`}
>
<div className="flex flex-col justify-center items-center">
<div
className={`w-[68px] h-[68px] rounded-full flex justify-center items-center ${
datas.priceType === "auction"
? "primary-gradient"
: "bg-[#F2E8FA]"
}`}
>
<GradientIcons
name={`${
datas.priceType === "auction"
? "timeout"
: "gradient-timeout"
}`}
/>
</div>
<p className="text-center text-base tracking-wide mt-1 text-dark-gray dark:text-white">
Timed auction
</p>
</div>
</div>
{datas.priceType === "auction" && (
<div
className="sm:w-[122px] w-full h-[132px] primary-gradient rounded-md absolute z-10"
style={{ top: "-1px", left: "-1px" }}
></div>
)}
</div>
</div>
</div>
<div className="field w-full mb-6">
<h1 className="field-title">Item Name </h1>
<div className="input-field mt-2">
@@ -161,19 +163,22 @@ export default function ProductUploadField({
/>
</div>
</div>
<div className="field w-full mb-6">
<h1 className="field-title">Exter link </h1>
<div className="input-field mt-2">
<InputCom
fieldClass="px-6"
type="text"
name="link"
inputHandler={linkh}
value={datas.link}
placeholder="https:yoursite.lo/imte/item_name123"
/>
</div>
</div>
{/*<div className="field w-full mb-6">*/}
{/* <h1 className="field-title">Exter link </h1>*/}
{/* <div className="input-field mt-2">*/}
{/* <InputCom*/}
{/* fieldClass="px-6"*/}
{/* type="text"*/}
{/* name="link"*/}
{/* inputHandler={linkh}*/}
{/* value={datas.link}*/}
{/* placeholder="https:yoursite.lo/imte/item_name123"*/}
{/* />*/}
{/* </div>*/}
{/*</div>*/}
<div className="field w-full mb-6">
<h1 className="field-title">Description </h1>
<div className="input-field mt-2">
@@ -188,219 +193,222 @@ export default function ProductUploadField({
</div>
</div>
</div>
<div className="field w-full mb-6">
<h1 className="field-title">Instant sale price </h1>
<div className="input-field my-2">
<div className="input-wrapper border border-light-purple dark:border-[#5356fb29] w-full rounded-[50px] h-[58px] flex items-center overflow-hidden">
<input
value={datas.price}
onChange={(e) => priceHndlr(e)}
placeholder="enter the price for which the item will be instantly sold"
className="input-field placeholder:text-base text-bese px-6 text-dark-gray dark:text-white w-10/12 h-full bg-[#FAFAFA] dark:bg-[#11131F] focus:ring-0 focus:outline-none"
type="number"
/>
<div className="w-[1px] h-[33px] bg-light-purple dark:bg-dark-light-purple "></div>
<div className="flex-1 flex h-full justify-center items-center bg-[#FAFAFA] dark:bg-[#11131F] ">
<div className="flex space-x-1 items-center">
<span className="text-dark-gray dark:text-white text-base">
ETH
</span>
<span>
<svg
width="13"
height="6"
viewBox="0 0 13 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
opacity="0.7"
d="M12.7488 0.247421C12.6691 0.169022 12.5744 0.106794 12.4699 0.0643287C12.3655 0.0218632 12.2535 0 12.1403 0C12.0272 0 11.9152 0.0218632 11.8107 0.0643287C11.7063 0.106794 11.6115 0.169022 11.5318 0.247421L7.60655 4.07837C7.52688 4.15677 7.43209 4.219 7.32765 4.26146C7.22321 4.30393 7.11119 4.32579 6.99805 4.32579C6.88491 4.32579 6.77289 4.30393 6.66845 4.26146C6.56401 4.219 6.46922 4.15677 6.38954 4.07837L2.46427 0.247421C2.3846 0.169022 2.28981 0.106794 2.18537 0.0643287C2.08093 0.0218632 1.96891 0 1.85577 0C1.74263 0 1.63061 0.0218632 1.52617 0.0643287C1.42173 0.106794 1.32694 0.169022 1.24727 0.247421C1.08764 0.404141 0.998047 0.616141 0.998047 0.837119C0.998047 1.0581 1.08764 1.2701 1.24727 1.42682L5.18111 5.26613C5.6632 5.73605 6.31669 6 6.99805 6C7.6794 6 8.33289 5.73605 8.81498 5.26613L12.7488 1.42682C12.9084 1.2701 12.998 1.0581 12.998 0.837119C12.998 0.616141 12.9084 0.404141 12.7488 0.247421Z"
fill="#374557"
/>
</svg>
</span>
</div>
</div>
</div>
</div>
<div className="text-base tracking-wide text-dark-gray dark:text-white">
<p>
<span className="text-thin-light-gray">Service fee :</span> 1.5%
</p>
<p>
<span className="text-thin-light-gray">You will Receive :</span>
.29 ETH $120.56
</p>
</div>
</div>
<div className="field w-full mb-6">
<h1 className="field-title">Royalties</h1>
<div className="input-field my-2">
<div className="mb-2">
<InputCom
fieldClass="px-6"
type="text"
name="link"
inputHandler={roltsHndlr}
value={datas.royalties}
placeholder="0%"
/>
</div>
<p className="text-thin-light-gray text-sm tracking-wide">
Suggested: 10%, 20%, 30%
</p>
</div>
</div>
<div className="field w-full mb-6">
<h1 className="field-title">
Properties
<span className="text-thin-light-gray font-normal ml-2">
(Optional)
</span>
</h1>
<div className="input-field my-2">
<div className="mb-2">
<div className="sm:flex sm:space-x-8">
<div className="sm:w-1/2 w-full mb-2 sm:mb-0">
<InputCom
fieldClass="px-6"
type="text"
name="link"
inputHandler={keyHndlr}
value={datas.propertiesKey}
placeholder="Enter key"
/>
</div>
<div className="flex-1">
<InputCom
fieldClass="px-6"
type="text"
name="link"
inputHandler={valueHndlr}
value={datas.propertiesValue}
placeholder="Enter Value"
/>
</div>
</div>
</div>
</div>
</div>
<div className="field w-full mb-6">
<h1 className="field-title">Choose collection</h1>
<div className="input-field mt-2">
<div className="sm:flex sm:space-x-5">
{/* create collection */}
<div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border border-light-purple dark:border-[#5356fb29] flex justify-center items-center cursor-pointer">
<div>
<span className="mb-1 flex justify-center">
<svg
width="25"
height="25"
viewBox="0 0 25 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M25 12.5125C25.019 19.39 19.3853 24.9989 12.5054 25.0001C5.6017 25.0012 -0.0153836 19.3615 3.1653e-05 12.471C0.0154469 5.59949 5.63965 -0.0224583 12.5469 6.7456e-05C19.396 0.0225932 25.0297 5.61846 25 12.5125ZM14.3007 17.2097C14.3007 16.3324 14.3007 15.4551 14.3007 14.5778C14.3007 14.3525 14.3007 14.3525 14.5224 14.3525C16.2299 14.3525 17.9387 14.3525 19.6462 14.3513C19.7339 14.3513 19.8241 14.349 19.9106 14.3335C20.832 14.1711 21.4581 13.327 21.3798 12.356C21.3099 11.4775 20.4988 10.733 19.6011 10.7306C17.9031 10.7271 16.2062 10.7294 14.5082 10.7294C14.2995 10.7294 14.2995 10.7294 14.2995 10.5243C14.2995 8.7851 14.2995 7.04588 14.2983 5.30784C14.2983 5.22959 14.2983 5.15016 14.2805 5.07547C14.0588 4.16021 13.218 3.59588 12.3465 3.68599C11.3836 3.78676 10.697 4.55026 10.697 5.48212C10.697 7.14309 10.697 8.80288 10.697 10.4639C10.697 10.7555 10.7243 10.7294 10.4243 10.7294C8.79504 10.7294 7.16457 10.7401 5.5353 10.7259C4.40524 10.7152 3.60483 11.6293 3.63922 12.6216C3.67242 13.5451 4.45623 14.3513 5.37996 14.3513C7.08275 14.3513 8.78555 14.3513 10.4883 14.3513C10.697 14.3513 10.697 14.3525 10.697 14.5576C10.697 16.2387 10.697 17.9211 10.697 19.6022C10.697 19.6757 10.6935 19.7492 10.703 19.8215C10.8761 21.1256 12.2884 21.8358 13.4255 21.1719C13.9817 20.847 14.3066 20.3586 14.3018 19.684C14.2947 18.86 14.3007 18.0349 14.3007 17.2097Z"
fill="#374557"
fillOpacity="0.6"
/>
</svg>
</span>
<span className="text-thin-light-gray text-center">
Crteate
</span>
</div>
</div>
{/* saved collection list */}
<div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border-gradient flex justify-center items-center cursor-pointer">
<div>
<div className="mb-1 flex justify-center ">
<div className="w-[50px] h-[50px] rounded-full overflow-hidden">
<img
src={collection1}
alt=""
className="w-full h-full object-cover"
/>
</div>
</div>
<span className="text-thin-light-gray text-center">
Name 1
</span>
</div>
</div>
<div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border border-light-purple dark:border-[#5356fb29] flex justify-center items-center cursor-pointer">
<div>
<div className="mb-1 flex justify-center ">
<div className="w-[50px] h-[50px] rounded-full overflow-hidden">
<img
src={collection2}
alt=""
className="w-full h-full object-cover"
/>
</div>
</div>
<span className="text-thin-light-gray text-center">
Name 2
</span>
</div>
</div>
<div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border border-light-purple dark:border-[#5356fb29] flex justify-center items-center cursor-pointer">
<div>
<div className="mb-1 flex justify-center ">
<div className="w-[50px] h-[50px] rounded-full overflow-hidden">
<img
src={collection3}
alt=""
className="w-full h-full object-cover"
/>
</div>
</div>
<span className="text-thin-light-gray text-center">
Name 3
</span>
</div>
</div>
</div>
</div>
</div>
{/*<div className="field w-full mb-6">*/}
{/* <h1 className="field-title">Instant sale price </h1>*/}
{/* <div className="input-field my-2">*/}
{/* <div className="input-wrapper border border-light-purple dark:border-[#5356fb29] w-full rounded-[50px] h-[58px] flex items-center overflow-hidden">*/}
{/* <input*/}
{/* value={datas.price}*/}
{/* onChange={(e) => priceHndlr(e)}*/}
{/* placeholder="enter the price for which the item will be instantly sold"*/}
{/* className="input-field placeholder:text-base text-bese px-6 text-dark-gray dark:text-white w-10/12 h-full bg-[#FAFAFA] dark:bg-[#11131F] focus:ring-0 focus:outline-none"*/}
{/* type="number"*/}
{/* />*/}
{/* <div className="w-[1px] h-[33px] bg-light-purple dark:bg-dark-light-purple "></div>*/}
{/* <div className="flex-1 flex h-full justify-center items-center bg-[#FAFAFA] dark:bg-[#11131F] ">*/}
{/* <div className="flex space-x-1 items-center">*/}
{/* <span className="text-dark-gray dark:text-white text-base">*/}
{/* ETH*/}
{/* </span>*/}
{/* <span>*/}
{/* <svg*/}
{/* width="13"*/}
{/* height="6"*/}
{/* viewBox="0 0 13 6"*/}
{/* fill="none"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <path*/}
{/* opacity="0.7"*/}
{/* d="M12.7488 0.247421C12.6691 0.169022 12.5744 0.106794 12.4699 0.0643287C12.3655 0.0218632 12.2535 0 12.1403 0C12.0272 0 11.9152 0.0218632 11.8107 0.0643287C11.7063 0.106794 11.6115 0.169022 11.5318 0.247421L7.60655 4.07837C7.52688 4.15677 7.43209 4.219 7.32765 4.26146C7.22321 4.30393 7.11119 4.32579 6.99805 4.32579C6.88491 4.32579 6.77289 4.30393 6.66845 4.26146C6.56401 4.219 6.46922 4.15677 6.38954 4.07837L2.46427 0.247421C2.3846 0.169022 2.28981 0.106794 2.18537 0.0643287C2.08093 0.0218632 1.96891 0 1.85577 0C1.74263 0 1.63061 0.0218632 1.52617 0.0643287C1.42173 0.106794 1.32694 0.169022 1.24727 0.247421C1.08764 0.404141 0.998047 0.616141 0.998047 0.837119C0.998047 1.0581 1.08764 1.2701 1.24727 1.42682L5.18111 5.26613C5.6632 5.73605 6.31669 6 6.99805 6C7.6794 6 8.33289 5.73605 8.81498 5.26613L12.7488 1.42682C12.9084 1.2701 12.998 1.0581 12.998 0.837119C12.998 0.616141 12.9084 0.404141 12.7488 0.247421Z"*/}
{/* fill="#374557"*/}
{/* />*/}
{/* </svg>*/}
{/* </span>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="text-base tracking-wide text-dark-gray dark:text-white">*/}
{/* <p>*/}
{/* <span className="text-thin-light-gray">Service fee :</span> 1.5%*/}
{/* </p>*/}
{/* <p>*/}
{/* <span className="text-thin-light-gray">You will Receive :</span>*/}
{/* .29 ETH $120.56*/}
{/* </p>*/}
{/* </div>*/}
{/*</div>*/}
{/*<div className="field w-full mb-6">*/}
{/* <h1 className="field-title">Royalties</h1>*/}
{/* <div className="input-field my-2">*/}
{/* <div className="mb-2">*/}
{/* <InputCom*/}
{/* fieldClass="px-6"*/}
{/* type="text"*/}
{/* name="link"*/}
{/* inputHandler={roltsHndlr}*/}
{/* value={datas.royalties}*/}
{/* placeholder="0%"*/}
{/* />*/}
{/* </div>*/}
{/* <p className="text-thin-light-gray text-sm tracking-wide">*/}
{/* Suggested: 10%, 20%, 30%*/}
{/* </p>*/}
{/* </div>*/}
{/*</div>*/}
{/*<div className="field w-full mb-6">*/}
{/* <h1 className="field-title">*/}
{/* Properties*/}
{/* <span className="text-thin-light-gray font-normal ml-2">*/}
{/* (Optional)*/}
{/* </span>*/}
{/* </h1>*/}
{/* <div className="input-field my-2">*/}
{/* <div className="mb-2">*/}
{/* <div className="sm:flex sm:space-x-8">*/}
{/* <div className="sm:w-1/2 w-full mb-2 sm:mb-0">*/}
{/* <InputCom*/}
{/* fieldClass="px-6"*/}
{/* type="text"*/}
{/* name="link"*/}
{/* inputHandler={keyHndlr}*/}
{/* value={datas.propertiesKey}*/}
{/* placeholder="Enter key"*/}
{/* />*/}
{/* </div>*/}
{/* <div className="flex-1">*/}
{/* <InputCom*/}
{/* fieldClass="px-6"*/}
{/* type="text"*/}
{/* name="link"*/}
{/* inputHandler={valueHndlr}*/}
{/* value={datas.propertiesValue}*/}
{/* placeholder="Enter Value"*/}
{/* />*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
{/*<div className="field w-full mb-6">*/}
{/* <h1 className="field-title">Choose collection</h1>*/}
{/* <div className="input-field mt-2">*/}
{/* <div className="sm:flex sm:space-x-5">*/}
{/* /!* create collection *!/*/}
{/* <div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border border-light-purple dark:border-[#5356fb29] flex justify-center items-center cursor-pointer">*/}
{/* <div>*/}
{/* <span className="mb-1 flex justify-center">*/}
{/* <svg*/}
{/* width="25"*/}
{/* height="25"*/}
{/* viewBox="0 0 25 25"*/}
{/* fill="none"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <path*/}
{/* d="M25 12.5125C25.019 19.39 19.3853 24.9989 12.5054 25.0001C5.6017 25.0012 -0.0153836 19.3615 3.1653e-05 12.471C0.0154469 5.59949 5.63965 -0.0224583 12.5469 6.7456e-05C19.396 0.0225932 25.0297 5.61846 25 12.5125ZM14.3007 17.2097C14.3007 16.3324 14.3007 15.4551 14.3007 14.5778C14.3007 14.3525 14.3007 14.3525 14.5224 14.3525C16.2299 14.3525 17.9387 14.3525 19.6462 14.3513C19.7339 14.3513 19.8241 14.349 19.9106 14.3335C20.832 14.1711 21.4581 13.327 21.3798 12.356C21.3099 11.4775 20.4988 10.733 19.6011 10.7306C17.9031 10.7271 16.2062 10.7294 14.5082 10.7294C14.2995 10.7294 14.2995 10.7294 14.2995 10.5243C14.2995 8.7851 14.2995 7.04588 14.2983 5.30784C14.2983 5.22959 14.2983 5.15016 14.2805 5.07547C14.0588 4.16021 13.218 3.59588 12.3465 3.68599C11.3836 3.78676 10.697 4.55026 10.697 5.48212C10.697 7.14309 10.697 8.80288 10.697 10.4639C10.697 10.7555 10.7243 10.7294 10.4243 10.7294C8.79504 10.7294 7.16457 10.7401 5.5353 10.7259C4.40524 10.7152 3.60483 11.6293 3.63922 12.6216C3.67242 13.5451 4.45623 14.3513 5.37996 14.3513C7.08275 14.3513 8.78555 14.3513 10.4883 14.3513C10.697 14.3513 10.697 14.3525 10.697 14.5576C10.697 16.2387 10.697 17.9211 10.697 19.6022C10.697 19.6757 10.6935 19.7492 10.703 19.8215C10.8761 21.1256 12.2884 21.8358 13.4255 21.1719C13.9817 20.847 14.3066 20.3586 14.3018 19.684C14.2947 18.86 14.3007 18.0349 14.3007 17.2097Z"*/}
{/* fill="#374557"*/}
{/* fillOpacity="0.6"*/}
{/* />*/}
{/* </svg>*/}
{/* </span>*/}
{/* <span className="text-thin-light-gray text-center">*/}
{/* Crteate*/}
{/* </span>*/}
{/* </div>*/}
{/* </div>*/}
{/* /!* saved collection list *!/*/}
{/* <div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border-gradient flex justify-center items-center cursor-pointer">*/}
{/* <div>*/}
{/* <div className="mb-1 flex justify-center ">*/}
{/* <div className="w-[50px] h-[50px] rounded-full overflow-hidden">*/}
{/* <img*/}
{/* src={collection1}*/}
{/* alt=""*/}
{/* className="w-full h-full object-cover"*/}
{/* />*/}
{/* </div>*/}
{/* </div>*/}
{/* <span className="text-thin-light-gray text-center">*/}
{/* Name 1*/}
{/* </span>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border border-light-purple dark:border-[#5356fb29] flex justify-center items-center cursor-pointer">*/}
{/* <div>*/}
{/* <div className="mb-1 flex justify-center ">*/}
{/* <div className="w-[50px] h-[50px] rounded-full overflow-hidden">*/}
{/* <img*/}
{/* src={collection2}*/}
{/* alt=""*/}
{/* className="w-full h-full object-cover"*/}
{/* />*/}
{/* </div>*/}
{/* </div>*/}
{/* <span className="text-thin-light-gray text-center">*/}
{/* Name 2*/}
{/* </span>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div className="sm:w-[100px] h-[100px] w-full mb-2 sm:mb-0 rounded-[4px] bg-[#FAFAFA] dark:bg-[#11131F] border border-light-purple dark:border-[#5356fb29] flex justify-center items-center cursor-pointer">*/}
{/* <div>*/}
{/* <div className="mb-1 flex justify-center ">*/}
{/* <div className="w-[50px] h-[50px] rounded-full overflow-hidden">*/}
{/* <img*/}
{/* src={collection3}*/}
{/* alt=""*/}
{/* className="w-full h-full object-cover"*/}
{/* />*/}
{/* </div>*/}
{/* </div>*/}
{/* <span className="text-thin-light-gray text-center">*/}
{/* Name 3*/}
{/* </span>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
{/* unlock purchase */}
<div className="sm:flex justify-between items-center mb-5">
<div className="sm:flex sm:space-x-3 items-center mb-5 sm:mb-0">
<div className="w-[60px] h-[60px] rounded-full flex justify-center items-center bg-light-gray">
<svg
width="22"
height="28"
viewBox="0 0 22 28"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.9703 27.9959C8.44944 27.9959 5.92858 28.0078 3.40773 27.9919C1.27205 27.9799 0.0338085 26.7656 0.0196917 24.6347C-0.00450854 21.2735 -0.00854192 17.9123 0.0196917 14.5511C0.0378419 12.4521 1.3265 11.2158 3.44806 11.2118C8.42121 11.2019 13.3964 11.2039 18.3695 11.2118C20.604 11.2158 21.8564 12.4641 21.8644 14.6909C21.8745 17.9862 21.8786 21.2815 21.8644 24.5767C21.8544 26.7616 20.6242 27.9819 18.43 27.9939C15.9434 28.0058 13.4569 27.9959 10.9703 27.9959ZM8.53213 17.9722C8.61078 18.1699 8.65918 18.789 8.99193 19.0466C9.89541 19.7476 9.75424 20.6544 9.75626 21.567C9.75626 21.9984 9.62719 22.5057 9.81071 22.8412C10.0467 23.2706 10.5367 23.8358 10.9219 23.8398C11.3131 23.8438 11.8496 23.3026 12.0613 22.8752C12.261 22.4698 12.1319 21.9006 12.1319 21.4053C12.1319 20.5525 12.0936 19.7716 12.868 19.0706C13.6041 18.4036 13.4871 17.1354 12.8841 16.3086C12.2811 15.4817 11.2002 15.1262 10.2019 15.4258C9.25208 15.7114 8.54826 16.6621 8.53213 17.9722Z"
fill="black"
/>
<path
d="M18.5315 10.2691C17.3356 10.2691 16.2466 10.2691 15.0345 10.2691C15.0345 9.40439 15.0446 8.58556 15.0325 7.76473C14.9982 5.32022 13.2397 3.47086 10.9467 3.45888C8.64969 3.4469 6.88509 5.28028 6.84476 7.73677C6.83064 8.55959 6.84274 9.38441 6.84274 10.2672C5.64483 10.2672 4.55582 10.2672 3.47286 10.2672C2.71257 5.3322 4.5054 1.66744 8.75456 0.347323C13.5603 -1.14654 18.3984 2.36244 18.5274 7.34932C18.5516 8.30396 18.5315 9.26059 18.5315 10.2691Z"
fill="black"
/>
</svg>
</div>
<div>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
Unlock once purchased
</h1>
<p className="text-base text-thin-light-gray tracking-wide">
Unlockable content, only revealed by the owner of the item.
</p>
</div>
</div>
<div>
<SwitchCom value={datas.purchase} handler={unlckPrchesHndlr} />
</div>
</div>
{/*<div className="sm:flex justify-between items-center mb-5">*/}
{/* <div className="sm:flex sm:space-x-3 items-center mb-5 sm:mb-0">*/}
{/* <div className="w-[60px] h-[60px] rounded-full flex justify-center items-center bg-light-gray">*/}
{/* <svg*/}
{/* width="22"*/}
{/* height="28"*/}
{/* viewBox="0 0 22 28"*/}
{/* fill="none"*/}
{/* xmlns="http://www.w3.org/2000/svg"*/}
{/* >*/}
{/* <path*/}
{/* d="M10.9703 27.9959C8.44944 27.9959 5.92858 28.0078 3.40773 27.9919C1.27205 27.9799 0.0338085 26.7656 0.0196917 24.6347C-0.00450854 21.2735 -0.00854192 17.9123 0.0196917 14.5511C0.0378419 12.4521 1.3265 11.2158 3.44806 11.2118C8.42121 11.2019 13.3964 11.2039 18.3695 11.2118C20.604 11.2158 21.8564 12.4641 21.8644 14.6909C21.8745 17.9862 21.8786 21.2815 21.8644 24.5767C21.8544 26.7616 20.6242 27.9819 18.43 27.9939C15.9434 28.0058 13.4569 27.9959 10.9703 27.9959ZM8.53213 17.9722C8.61078 18.1699 8.65918 18.789 8.99193 19.0466C9.89541 19.7476 9.75424 20.6544 9.75626 21.567C9.75626 21.9984 9.62719 22.5057 9.81071 22.8412C10.0467 23.2706 10.5367 23.8358 10.9219 23.8398C11.3131 23.8438 11.8496 23.3026 12.0613 22.8752C12.261 22.4698 12.1319 21.9006 12.1319 21.4053C12.1319 20.5525 12.0936 19.7716 12.868 19.0706C13.6041 18.4036 13.4871 17.1354 12.8841 16.3086C12.2811 15.4817 11.2002 15.1262 10.2019 15.4258C9.25208 15.7114 8.54826 16.6621 8.53213 17.9722Z"*/}
{/* fill="black"*/}
{/* />*/}
{/* <path*/}
{/* d="M18.5315 10.2691C17.3356 10.2691 16.2466 10.2691 15.0345 10.2691C15.0345 9.40439 15.0446 8.58556 15.0325 7.76473C14.9982 5.32022 13.2397 3.47086 10.9467 3.45888C8.64969 3.4469 6.88509 5.28028 6.84476 7.73677C6.83064 8.55959 6.84274 9.38441 6.84274 10.2672C5.64483 10.2672 4.55582 10.2672 3.47286 10.2672C2.71257 5.3322 4.5054 1.66744 8.75456 0.347323C13.5603 -1.14654 18.3984 2.36244 18.5274 7.34932C18.5516 8.30396 18.5315 9.26059 18.5315 10.2691Z"*/}
{/* fill="black"*/}
{/* />*/}
{/* </svg>*/}
{/* </div>*/}
{/* <div>*/}
{/* <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
{/* Unlock once purchased*/}
{/* </h1>*/}
{/* <p className="text-base text-thin-light-gray tracking-wide">*/}
{/* Unlockable content, only revealed by the owner of the item.*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <SwitchCom value={datas.purchase} handler={unlckPrchesHndlr} />*/}
{/* </div>*/}
{/*</div>*/}
</form>
</div>
</div>

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