Compare commits

..

389 Commits

Author SHA1 Message Date
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
victorAnumudu c106e66f44 assign task bug fixed 2023-07-16 22:13:47 +01:00
ameye 222c739663 Merge branch 'notification-bug' of WrenchBoard/Users-Wrench into master 2023-07-16 11:04:22 +00:00
victorAnumudu 96972dbe2f notification bug fixed 2023-07-16 06:51:38 +01:00
CHIEFSOFT\ameye 7146048aee style 2023-07-15 22:16:29 -04:00
CHIEFSOFT\ameye 39f1f5bc73 Resource Question page starter 2023-07-15 21:39:53 -04:00
Ebube fb7913c563 Another fix 2023-07-16 01:36:27 +01:00
Ebube feb301c3c0 . 2023-07-16 01:08:37 +01:00
ameye 752fc6a4a8 Merge branch 'history-page-tab' of WrenchBoard/Users-Wrench into master 2023-07-15 21:39:05 +00:00
victorAnumudu 608d5b92f1 history tab style changed 2023-07-15 22:24:38 +01:00
ameye 45563cc59b Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-15 19:32:37 +00:00
ameye b027e20c20 Merge branch 'job-message-tab' of WrenchBoard/Users-Wrench into master 2023-07-15 19:32:33 +00:00
ameye bbe0777496 Merge branch 'assign-family-hidden' of WrenchBoard/Users-Wrench into master 2023-07-15 19:32:28 +00:00
Ebube 27efbe362b Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-15 20:02:15 +01:00
Ebube 878539a56a Confirm Credit Popup Modifications 2023-07-15 19:47:06 +01:00
victorAnumudu 6ae408029d changed job message tab 2023-07-15 19:21:28 +01:00
victorAnumudu 8016d1bd12 assign to family hidden 2023-07-15 18:59:22 +01:00
ameye 0e9fef218f Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-15 16:19:29 +00:00
CHIEFSOFT\ameye 8116665045 removed yarn lock 2023-07-15 12:13:47 -04:00
Ebube e4addc47d9 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-15 17:10:43 +01:00
Ebube 1682f11efd Confirm Credit Popup 2023-07-15 17:08:52 +01:00
CHIEFSOFT\ameye 80b2abf9e3 glog page 2023-07-15 12:07:42 -04:00
CHIEFSOFT\ameye 5edecb6464 jib actions 2023-07-15 11:46:55 -04:00
CHIEFSOFT\ameye 3a479b3573 action txt 2023-07-15 11:06:04 -04:00
ameye 4034909836 Merge branch 'set-account-settings' of WrenchBoard/Users-Wrench into master 2023-07-15 13:56:30 +00:00
victorAnumudu 8fc61a6289 API for set account settings added 2023-07-15 14:53:34 +01:00
CHIEFSOFT\ameye 940a12a2e9 actio panel 2023-07-15 09:51:53 -04:00
CHIEFSOFT\ameye a9f671eeaa active task messaghe 2023-07-15 08:55:48 -04:00
ameye 481924fa02 Merge branch 'delete-card' of WrenchBoard/Users-Wrench into master 2023-07-15 10:22:24 +00:00
victorAnumudu 6b712089d1 notification icons added 2023-07-15 10:49:46 +01:00
victorAnumudu 85ca2cb15a reloads card list on successful card delete 2023-07-15 10:15:14 +01:00
victorAnumudu d01c4928ff Merge master into delete-card 2023-07-15 09:52:03 +01:00
victorAnumudu b81e62988c delete popout added 2023-07-15 09:48:14 +01:00
ameye a8b63917fb Merge branch 'account-settings' of WrenchBoard/Users-Wrench into master 2023-07-15 08:38:13 +00:00
CHIEFSOFT\ameye 9cf6d13716 images 2023-07-15 04:37:52 -04:00
victorAnumudu c1af2b7fc9 logged info removed 2023-07-15 08:06:44 +01:00
victorAnumudu 494c1f3271 account settings API added 2023-07-15 08:00:25 +01:00
ameye 9f0c33521f Merge branch 'reset-profile-password' of WrenchBoard/Users-Wrench into master 2023-07-14 19:56:14 +00:00
victorAnumudu 1d5875d4e2 reset profile password implemented 2023-07-14 20:28:22 +01:00
ameye 6f6b12f4b5 Merge branch 'card-list-image-added' of WrenchBoard/Users-Wrench into master 2023-07-14 17:46:44 +00:00
victorAnumudu f3ad4d576e card list image added 2023-07-14 18:42:28 +01:00
CHIEFSOFT\ameye e01d0106ad cards images 2023-07-14 13:19:41 -04:00
ameye 68472f8c66 Merge branch 'card-list-page' of WrenchBoard/Users-Wrench into master 2023-07-14 17:00:38 +00:00
victorAnumudu 8def463d80 card listing added 2023-07-14 17:54:44 +01:00
ameye 0320999f72 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-14 13:42:01 +00:00
Ebube 78a97d8b0b Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-14 13:48:25 +01:00
Ebube 6bf6c5d2d4 Added PaidPrevCard api 2023-07-14 13:48:03 +01:00
ameye 33284600e5 Merge branch 'change-passage-mac' of WrenchBoard/Users-Wrench into master 2023-07-14 12:37:26 +00:00
ameye 68bf995078 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-14 12:37:18 +00:00
Ebube fa05f47941 . 2023-07-14 13:30:50 +01:00
victorAnumudu 2391857309 flex display changed to suit mac screen 2023-07-14 12:58:49 +01:00
Ebube ed38cadcee Start credit Api for Dollar acc 2023-07-14 12:53:05 +01:00
ameye ea447a9366 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-13 23:09:01 +00:00
Ebube 4e2f120ab5 Few changes 2023-07-13 23:12:29 +01:00
Ebube 20ce9bf749 Consumed Start credit Api 2023-07-13 22:34:09 +01:00
ameye 04e1bcc5f1 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-13 19:38:17 +00:00
Ebube cbaa8b6f7b Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-13 20:14:54 +01:00
ameye f6bdb1c299 Merge branch 'wallet-card' of WrenchBoard/Users-Wrench into master 2023-07-13 19:11:32 +00:00
Ebube d4061d72da . 2023-07-13 18:20:20 +01:00
Ebube 2d9a8b55b5 . 2023-07-13 18:16:52 +01:00
Ebube 920eafed29 . 2023-07-13 18:10:19 +01:00
Ebube 21d926eb5c Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-13 18:08:23 +01:00
Ebube ec9d793d6b . 2023-07-13 18:07:05 +01:00
victorAnumudu 2fd04dc86d wallet card adjustment 2023-07-13 16:44:05 +01:00
ameye d7752cb70b Merge branch 'wallet-layout-fix' of WrenchBoard/Users-Wrench into master 2023-07-13 13:05:32 +00:00
victorAnumudu dc592f60db layout fix 2023-07-13 14:02:27 +01:00
victorAnumudu 675ba2989e layout fix 2023-07-13 14:00:02 +01:00
ameye b201224fd6 Merge branch 'wallet-size' of WrenchBoard/Users-Wrench into master 2023-07-13 12:45:17 +00:00
ameye c24013eefd Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-13 12:45:12 +00:00
victorAnumudu 234f04ca8f wallet size changed 2023-07-13 13:41:39 +01:00
Ebube 5f222a2d88 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-13 12:37:32 +01:00
Ebube 258434a109 Applied corrections and changes to the wallet 2023-07-13 12:34:39 +01:00
CHIEFSOFT\ameye ed148612a7 more banners 2023-07-13 07:21:37 -04:00
ameye 2287fb5ebb Merge branch 'wallet-cleanup' of WrenchBoard/Users-Wrench into master 2023-07-13 10:16:18 +00:00
victorAnumudu 24545baad5 wallet clean up 2023-07-13 10:27:03 +01:00
ameye ead7589c92 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-13 08:21:23 +00:00
Ebube 51bb8fc421 Corrections on AddFundPop 2023-07-13 03:21:52 +01:00
ameye d2166d9578 Merge branch 'icons-size' of WrenchBoard/Users-Wrench into master 2023-07-12 21:20:53 +00:00
victorAnumudu c4872f522b icon color and size changed 2023-07-12 21:31:09 +01:00
ameye 0aef8c5e1e Merge branch 'wallet-icons' of WrenchBoard/Users-Wrench into master 2023-07-12 19:27:48 +00:00
ameye 767b5c1b32 Merge branch 'wallet-dropdown-icons' of WrenchBoard/Users-Wrench into master 2023-07-12 19:27:43 +00:00
ameye 6fed51443d Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-12 19:27:33 +00:00
victorAnumudu 017ba7bd2f wallet icon added and wallet layout changed 2023-07-12 20:00:17 +01:00
victorAnumudu 86d876b013 wallet dropdown icons added 2023-07-12 19:09:04 +01:00
Ebube fcd8898439 . 2023-07-12 19:05:06 +01:00
Ebube 690f496807 Add New Card Layout 2023-07-12 19:01:27 +01:00
ameye f804e13b56 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-12 16:19:58 +00:00
Ebube 5e248bc108 Restored layout and tiny modifications 2023-07-12 17:14:13 +01:00
ameye 26647b088f Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-12 15:04:53 +00:00
Ebube ae8ada33f4 Increased font 2023-07-12 15:54:57 +01:00
Ebube c31dab92e7 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into my_wallet_layout 2023-07-12 15:51:27 +01:00
Ebube c16764269e Added name to Add new fund 2023-07-12 15:48:57 +01:00
CHIEFSOFT\ameye afe6a1afcb currencies 2023-07-12 10:32:57 -04:00
Ebube e98929627f Compi! 2023-07-12 15:20:39 +01:00
Ebube 3919a2bc4b Layout Readjusting 2023-07-12 15:12:50 +01:00
ameye 93e89f996c Merge branch 'my-facebook-ID' of WrenchBoard/Users-Wrench into master 2023-07-12 13:47:25 +00:00
victorAnumudu 7ede9883ba facebook redirect page 2023-07-12 14:22:51 +01:00
victorAnumudu 7edc7b08e5 added my default facebook client ID 2023-07-12 14:07:07 +01:00
Ebube 7990959e9f Passed values to confirm add fund 2023-07-12 10:08:26 +01:00
CHIEFSOFT\ameye 6ead632c79 facebook 2023-07-11 17:31:52 -04:00
ameye 9c575716cd Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-11 19:13:15 +00:00
CHIEFSOFT\ameye cc93d5980d facebook login added 2023-07-11 14:59:16 -04:00
Ebube e899e5eb2a Convert ConfirmAddFund to Popup 2023-07-11 19:47:04 +01:00
ameye c53ee2833f Merge branch 'apple-login-init' of WrenchBoard/Users-Wrench into master 2023-07-11 14:23:27 +00:00
victorAnumudu 9475961c2d apple login initialization 2023-07-11 15:15:58 +01:00
CHIEFSOFT\ameye 97ae9dd136 env update 2023-07-11 06:43:18 -04:00
ameye ded088c70f Merge branch 'facebook-login-init' of WrenchBoard/Users-Wrench into master 2023-07-11 09:01:06 +00:00
ameye 4dacee11e8 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-11 09:00:52 +00:00
victorAnumudu 960579384c facebook login initiated 2023-07-11 07:56:45 +01:00
Ebube bcca701a6b Family Account Items Icons 2023-07-11 03:30:47 +01:00
ameye 6c29f37a60 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-10 23:29:30 +00:00
Ebube cc22e1a458 Completed conversion to popup 2023-07-10 23:21:59 +01:00
ameye d274a5c56a Merge branch 'family-login-bug-fixed' of WrenchBoard/Users-Wrench into master 2023-07-10 20:13:15 +00:00
victorAnumudu dfe90fbdc2 family login fixed 2023-07-10 20:40:52 +01:00
ameye a2f3c95671 Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-10 19:10:14 +00:00
Ebube 6daa4d6d43 Fixed the prop drill 2023-07-10 19:22:03 +01:00
Ebube 2e25b33110 Wallet modifications and Intro to Credit Popup 2023-07-10 17:47:39 +01:00
ameye a216ab1098 Merge branch 'login-payload' of WrenchBoard/Users-Wrench into master 2023-07-10 15:14:51 +00:00
victorAnumudu 8b01139b93 validated email on user login page 2023-07-10 15:45:38 +01:00
CHIEFSOFT\ameye 8511db6961 favicon 2023-07-10 10:42:47 -04:00
ameye 99c81fd4ee Merge branch 'profile-update' of WrenchBoard/Users-Wrench into master 2023-07-10 13:55:41 +00:00
victorAnumudu ef545c9714 validated email 2023-07-10 13:48:23 +01:00
ameye 029a7327a8 Merge branch 'google-login-fix' of WrenchBoard/Users-Wrench into master 2023-07-10 11:22:19 +00:00
victorAnumudu 5a5d933b24 google login fix 2023-07-10 12:18:43 +01:00
ameye 9f19c930b7 Merge branch 'suggested-task-page' of WrenchBoard/Users-Wrench into master 2023-07-10 08:46:47 +00:00
Ebube 84d7fabae7 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into suggested-task-page 2023-07-10 09:14:54 +01:00
Ebube b245f87556 Optimizations and underlying fixes done yesterday 2023-07-10 09:14:30 +01:00
CHIEFSOFT\ameye bed5303fa4 wallet 2023-07-09 20:42:00 -04:00
ameye a5af8ed722 Merge branch 'home-hero-min-height' of WrenchBoard/Users-Wrench into master 2023-07-09 23:26:57 +00:00
victorAnumudu ec97d118b2 AuthLayout added to redirect page 2023-07-09 23:55:35 +01:00
ameye 85213c31a1 Merge branch 'home-hero-min-height' of WrenchBoard/Users-Wrench into master 2023-07-09 22:55:28 +00:00
victorAnumudu f9b6c68f99 added min height to home page hero section 2023-07-09 23:34:39 +01:00
ameye 2a4b77c9a0 Merge branch 'home-page-hero-adjustment' of WrenchBoard/Users-Wrench into master 2023-07-09 22:28:43 +00:00
victorAnumudu 97aa5dba21 Merge 'master' into home-page-hero-adjustment 2023-07-09 23:19:30 +01:00
victorAnumudu 58a10ca6be home page hero section adjusted and google login success redirect implemented 2023-07-09 23:14:07 +01:00
CHIEFSOFT\ameye f3edf1d90b home banner 2023-07-09 17:57:05 -04:00
CHIEFSOFT\ameye 1f7b310b6f google login 2023-07-09 15:41:49 -04:00
ameye aecb06ca96 Merge branch 'verify-link' of WrenchBoard/Users-Wrench into master 2023-07-09 10:54:08 +00:00
CHIEFSOFT\ameye d89194f18e sty 2023-07-09 00:39:38 -04:00
CHIEFSOFT\ameye 03866d666b banner bg 2023-07-09 00:17:20 -04:00
CHIEFSOFT\ameye 4224be46bc banner issues 2023-07-08 23:19:23 -04:00
victorAnumudu 5dad00096a check for all necessary variables from API to determine verify link success 2023-07-09 03:42:01 +01:00
CHIEFSOFT\ameye 72da5c707a wallet adjust 2023-07-08 21:44:45 -04:00
tolik 625928e34b Message fix 2023-07-09 09:31:45 +08:00
tolik 6fd92600b4 Specify login channel 2023-07-09 08:47:00 +08:00
tolik 133f500849 Specify login channel 2023-07-09 08:19:17 +08:00
tolik b1f1b34924 API calls for authstart and authlogin; Call authlogin with code and redirect URI to do the token exchange on the backend 2023-07-09 07:58:31 +08:00
ameye e80c3528db Merge branch 'suggested-task-page' of WrenchBoard/Users-Wrench into master 2023-07-08 22:38:35 +00:00
Ebube 3eb6960cc7 Fixed underlying bugs 2023-07-08 23:27:10 +01:00
Ebube eb01e35c75 Continue Suggested Task 2023-07-08 22:52:36 +01:00
ameye 0cc70d66b3 Merge branch 'family-account-icon' of WrenchBoard/Users-Wrench into master 2023-07-08 18:34:33 +00:00
victorAnumudu 7111e81f11 added family account login input icon 2023-07-08 19:22:00 +01:00
CHIEFSOFT\ameye 1c64771dcd Job action area 2023-07-08 11:27:21 -04:00
CHIEFSOFT\ameye ac1a4f895a container max with for 4k screens 2023-07-08 11:05:20 -04:00
CHIEFSOFT\ameye 22f5bd01d2 log in error 2023-07-08 10:53:58 -04:00
ameye 467528835a Merge branch 'valid-email-pattern' of WrenchBoard/Users-Wrench into master 2023-07-08 14:36:10 +00:00
victorAnumudu e74119983f manage family icon adjusted 2023-07-08 15:33:31 +01:00
victorAnumudu 0be78a2a1b Merge 'master' into valid-email-pattern branch 2023-07-08 15:30:12 +01:00
ameye 67d5555377 Merge branch 'suggested-task-page' of WrenchBoard/Users-Wrench into master 2023-07-08 13:18:22 +00:00
victorAnumudu 0e65c05505 checks for valid email pattern before signing up an account 2023-07-08 14:13:10 +01:00
Ebube 01d5cdd093 Rearrangement of New Task Layout 2023-07-08 14:02:18 +01:00
ameye 08793ad90d Merge branch 'login-type-btn' of WrenchBoard/Users-Wrench into master 2023-07-08 10:22:02 +00:00
ameye e23bdaa0a5 Merge branch 'family-member-panel' of WrenchBoard/Users-Wrench into master 2023-07-08 10:21:50 +00:00
victorAnumudu 9791d66225 family member panel icon added 2023-07-08 07:58:18 +01:00
victorAnumudu 70e6ae20a4 icons added 2023-07-08 06:19:25 +01:00
victorAnumudu 17d1a84792 login type btn amended 2023-07-08 05:30:51 +01:00
CHIEFSOFT\ameye f51ed44463 Hide facebook on page 2023-07-07 22:31:10 -04:00
CHIEFSOFT\ameye ba45a7bdb9 Link verify 2023-07-07 20:31:21 -04:00
ameye 20909a5b76 Merge branch 'task-banner-family-acct' of WrenchBoard/Users-Wrench into master 2023-07-07 19:51:29 +00:00
victorAnumudu c1a8fb6cf4 banner added to family corner task 2023-07-07 20:19:44 +01:00
ameye a2148aaf3e Merge branch 'banner-missing-pages' of WrenchBoard/Users-Wrench into master 2023-07-07 16:49:19 +00:00
victorAnumudu 919338fd3f banner added to missing pages 2023-07-07 17:40:55 +01:00
ameye 5594d24ce9 Merge branch 'suggested-task-page' of WrenchBoard/Users-Wrench into master 2023-07-07 13:58:16 +00:00
ameye f581de6502 Merge branch 'banners-on-job' of WrenchBoard/Users-Wrench into master 2023-07-07 13:58:06 +00:00
victorAnumudu c89bc0d44b job banners added 2023-07-07 14:39:26 +01:00
Ebube 22dc21a79b Added New Task Component 2023-07-07 14:22:42 +01:00
ameye 809db4ded3 Merge branch 'login-tabs' of WrenchBoard/Users-Wrench into master 2023-07-07 10:07:06 +00:00
victorAnumudu 1ae67ef3a4 changed login type tab and made login route to home page without loading again once user logs in 2023-07-07 09:51:54 +01:00
ameye d32e8e2c8c Merge branch 'suggested-task-page' of WrenchBoard/Users-Wrench into master 2023-07-07 03:12:17 +00:00
Ebube f635372e31 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into suggested-task-page 2023-07-07 03:25:29 +01:00
Ebube 2913ae5bba Waiting Label Format Fixed 2023-07-07 03:25:09 +01:00
ameye f4bd4e4c7d Merge branch 'suggested-task-page' of WrenchBoard/Users-Wrench into master 2023-07-07 01:51:34 +00:00
Ebube 6126564547 . 2023-07-07 02:46:25 +01:00
ameye b5573aedd0 Merge branch 'full-account-offer-list' of WrenchBoard/Users-Wrench into master 2023-07-07 01:06:54 +00:00
CHIEFSOFT\ameye 2b93b09785 sty 2023-07-06 21:06:42 -04:00
victorAnumudu c0281f3734 new layout for full account offer list added 2023-07-07 01:54:56 +01:00
ameye ef045e2bc1 Merge branch 'suggested-task-page' of WrenchBoard/Users-Wrench into master 2023-07-06 23:30:45 +00:00
Ebube cf20c38059 fixed image issue 2023-07-06 23:34:55 +01:00
ameye 6ed1466e2b Merge branch 'family-offer-info-update' of WrenchBoard/Users-Wrench into master 2023-07-06 15:41:42 +00:00
victorAnumudu 6c59a24e6e added more info to family offer card info 2023-07-06 16:17:48 +01:00
ameye 05865c9274 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-06 14:41:53 +00:00
Ebube a868713ae3 Added family pending component 2023-07-06 15:02:26 +01:00
ameye e68603d836 Merge branch 'family-offer-hidden' of WrenchBoard/Users-Wrench into master 2023-07-06 11:48:40 +00:00
victorAnumudu 67e227c554 hides family offer list when none 2023-07-06 12:39:39 +01:00
ameye f6fc004a06 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-06 10:21:44 +00:00
ameye 1682a2221f Merge branch 'family-dash-revamp' of WrenchBoard/Users-Wrench into master 2023-07-06 10:21:33 +00:00
victorAnumudu b16b356532 family offer new layout 2023-07-06 11:01:54 +01:00
victorAnumudu 62b97d903c family dashboard active and waiting list revamp 2023-07-06 07:06:53 +01:00
Ebube abef3bec01 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-06 06:33:54 +01:00
Ebube 626835e1e0 Parent Waiting View Added & Market Link goes to bad page fixed 2023-07-06 06:33:33 +01:00
ameye a6d68bc856 Merge branch 'family-current-task' of WrenchBoard/Users-Wrench into master 2023-07-05 19:55:29 +00:00
victorAnumudu a674688dce family current task added 2023-07-05 20:52:34 +01:00
ameye ef339b163d Merge branch 'cookie-fixing' of WrenchBoard/Users-Wrench into master 2023-07-05 16:54:23 +00:00
victorAnumudu 1ce154cc06 cookie bug fixing 2023-07-05 17:48:40 +01:00
victorAnumudu 67eb142ae2 cookie bug fixing 2023-07-05 17:47:05 +01:00
ameye e784d84699 Merge branch 'cookie-value-reading' of WrenchBoard/Users-Wrench into master 2023-07-05 16:10:01 +00:00
CHIEFSOFT\ameye cd6d540c4b Family Activer Job 2023-07-05 11:12:08 -04:00
victorAnumudu b2beaa7c2b changed how the value of login type is read from the cookie 2023-07-05 15:40:05 +01:00
ameye b0db896f6b Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-05 14:15:03 +00:00
CHIEFSOFT\ameye fafea8b1ad Task banners 2023-07-05 10:13:19 -04:00
Ebube bbb099d51f Modified status for family waitlist 2023-07-05 14:51:24 +01:00
Ebube bfc0521e54 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-05 14:45:51 +01:00
Ebube 6870c145d7 Added banner name to suggested task payload 2023-07-05 14:45:29 +01:00
ameye c18373f9db Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-05 13:34:21 +00:00
CHIEFSOFT\ameye 24ac0daf29 status_text 2023-07-05 08:58:08 -04:00
Ebube 4dd58b16d8 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-05 13:52:39 +01:00
Ebube cc66ebbbde Family waitlist complete 2023-07-05 13:51:10 +01:00
CHIEFSOFT\ameye 3d61b3259d Status label 2023-07-05 08:32:00 -04:00
CHIEFSOFT\ameye 40b614356f active task spread 2023-07-05 08:17:57 -04:00
ameye dbba6c4014 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-05 11:56:34 +00:00
Ebube ae93de5f25 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-05 12:53:41 +01:00
Ebube 4904f1d398 Added waiting component and rendered the offerlist 2023-07-05 12:53:19 +01:00
ameye 880b084547 Merge branch 'cookie-bug-fix' of WrenchBoard/Users-Wrench into master 2023-07-05 10:26:39 +00:00
victorAnumudu c807a2657b adjusted cookie to check for login type before components mounts 2023-07-05 10:24:01 +01:00
ameye 37a0ffed27 Merge branch 'cookies-family-dash-changes' of WrenchBoard/Users-Wrench into master 2023-07-05 08:17:28 +00:00
victorAnumudu 067d9ca5d1 suggest image position adjusted 2023-07-05 08:50:56 +01:00
victorAnumudu 6e3061b9db cookie bug fix and family dash style changes made 2023-07-05 04:39:39 +01:00
CHIEFSOFT\ameye 4f9ca918c9 more graphics 2023-07-04 18:16:32 -04:00
ameye 12f805f0a7 Merge branch 'login-page-box' of WrenchBoard/Users-Wrench into master 2023-07-04 19:43:14 +00:00
CHIEFSOFT\ameye 175ac7e2b6 coffee added 2023-07-04 15:25:05 -04:00
victorAnumudu bb0796d1e6 login input text changed and padding on login page reduced 2023-07-04 19:22:36 +01:00
CHIEFSOFT\ameye c0d01e05fe defualt 2023-07-04 13:51:38 -04:00
CHIEFSOFT\ameye 38a888a8a1 clean dishes 2023-07-04 13:48:55 -04:00
CHIEFSOFT\ameye 8b0aedcbf2 wash cloth 2023-07-04 13:29:13 -04:00
CHIEFSOFT\ameye dfdccc0287 Clean Room 2023-07-04 13:10:46 -04:00
CHIEFSOFT\ameye 12512cef97 wash cars image 2023-07-04 13:00:28 -04:00
ameye d5d0e64070 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-04 15:27:51 +00:00
Ebube d55f7ce175 Correct layout and button 2023-07-04 15:45:19 +01:00
ameye f81b687f9f Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-04 14:04:17 +00:00
Ebube 3de1ef71c9 Fixed the empty params and fixed broken offer link 2023-07-04 15:00:00 +01:00
ameye fe7d23837c Merge branch 'enable-job-bg-color' of WrenchBoard/Users-Wrench into master 2023-07-04 13:07:44 +00:00
victorAnumudu bdc000fb8e Enable job background color changed to alice blue 2023-07-04 13:57:12 +01:00
ameye 01f8c7b49b Merge branch 'family-dashboard' of WrenchBoard/Users-Wrench into master 2023-07-04 12:26:17 +00:00
ameye 05384fe001 Merge branch 'family-task-page' of WrenchBoard/Users-Wrench into master 2023-07-04 12:26:09 +00:00
ameye 66a43ac636 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-04 12:25:36 +00:00
victorAnumudu 0ff4e5cf1e btn color 2023-07-04 10:56:53 +01:00
Ebube 6c0a107919 . 2023-07-04 10:39:00 +01:00
Ebube 5c8d1e72dd . 2023-07-04 10:38:35 +01:00
Ebube 4b11d7ec77 . 2023-07-04 10:38:22 +01:00
victorAnumudu baf2ca155f common header removed for family account on my task page 2023-07-04 10:33:37 +01:00
CHIEFSOFT\ameye fffc51d77a defualt added 2023-07-04 03:23:40 -04:00
ameye c622d73058 Merge branch 'family-suggest-list' of WrenchBoard/Users-Wrench into master 2023-07-04 07:02:18 +00:00
victorAnumudu d0237872ad added family suggest list API 2023-07-04 07:32:40 +01:00
ameye 4403c8650e Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-04 04:29:04 +00:00
Ebube 2afffb1dc9 Added Popup for suggest task 2023-07-04 03:37:56 +01:00
ameye 3a72ebc7a0 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-03 19:26:19 +00:00
Ebube ecfef0d6e1 modified validation rules 2023-07-03 20:13:45 +01:00
Ebube 7abf4fb7f7 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-03 19:40:55 +01:00
ameye 6c601a605a Merge branch 'input-error-changed' of WrenchBoard/Users-Wrench into master 2023-07-03 18:38:30 +00:00
Ebube 4480e2ebd6 removed validation 2023-07-03 19:34:38 +01:00
victorAnumudu 9f11e8b415 input error position changed 2023-07-03 19:32:18 +01:00
CHIEFSOFT\ameye a1d74b773d family pictures 2023-07-02 19:30:48 -04:00
ameye 7969199584 Merge branch 'blog-count' of WrenchBoard/Users-Wrench into master 2023-07-02 21:44:55 +00:00
victorAnumudu 9dd8f49ff8 blog count implemented 2023-07-02 22:12:28 +01:00
ameye fa5e9b8107 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-02 16:56:36 +00:00
Ebube 3e7ab11e62 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-02 17:40:38 +01:00
Ebube 6f259ad8ad . 2023-07-02 16:24:49 +01:00
ameye a31a20652f Merge branch 'resources-blog-tab' of WrenchBoard/Users-Wrench into master 2023-07-02 11:52:54 +00:00
victorAnumudu e3a5952675 made blog component to show first when resources link is hit 2023-07-02 08:10:10 +01:00
ameye f48297c5c0 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-02 02:07:31 +00:00
Ebube 23e5a9aaa4 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-02 03:03:08 +01:00
Ebube 02d90ebb14 Family market added 2023-07-02 03:02:29 +01:00
ameye 38b979a2e9 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-02 00:49:02 +00:00
Ebube 93d9afa417 Moved Offer Table to Dash 2023-07-02 01:34:27 +01:00
ameye 1e2219fb00 Merge branch 'banner-feedback' of WrenchBoard/Users-Wrench into master 2023-07-01 23:07:43 +00:00
victorAnumudu 560897f6f9 banner feedback fixed 2023-07-01 22:29:28 +01:00
ameye 630a029c6e Merge branch 'radio-btn-fix' of WrenchBoard/Users-Wrench into master 2023-07-01 20:26:41 +00:00
ameye 6e2fdc46d1 Merge branch 'add-task-btn-position' of WrenchBoard/Users-Wrench into master 2023-07-01 20:26:37 +00:00
victorAnumudu d3b2cddd6c radio btn size fixed 2023-07-01 21:24:25 +01:00
CHIEFSOFT\ameye f6bd70fdca Change text 2023-07-01 16:17:48 -04:00
victorAnumudu de3bfa2541 add task btn position changed 2023-07-01 19:36:26 +01:00
CHIEFSOFT\ameye cd60831f76 Blog Respurces 2023-07-01 12:44:31 -04:00
ameye 71152f7a05 Merge branch 'manage-family-active-task' of WrenchBoard/Users-Wrench into master 2023-07-01 15:28:38 +00:00
victorAnumudu 8cbdb1b8a6 manage family active task forward and back btn fixed 2023-07-01 16:25:34 +01:00
ameye abbf60ad48 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-07-01 10:51:21 +00:00
Ebube c956befed9 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-07-01 10:38:29 +01:00
Ebube a5dbeaecbf Fixed Offer Popup 2023-07-01 10:37:59 +01:00
CHIEFSOFT\ameye 0b0b563dda parennt waiting 2023-07-01 00:22:08 -04:00
CHIEFSOFT\ameye f8a3e42fe6 Kids waiting 2023-06-30 23:41:09 -04:00
CHIEFSOFT\ameye ced88fa497 no task image 2023-06-30 21:19:59 -04:00
ameye 89e2527ba6 Merge branch 'assign-task-bug-fix' of WrenchBoard/Users-Wrench into master 2023-07-01 00:06:19 +00:00
victorAnumudu 9e6b59624f Delivery detail bug fixed 2023-07-01 01:01:37 +01:00
ameye 1b6b4f17b0 Merge branch 'assign-task-revamp' of WrenchBoard/Users-Wrench into master 2023-06-30 23:12:55 +00:00
victorAnumudu 8a9ec35994 Assign family task API consumed 2023-07-01 00:06:22 +01:00
tokslaw fa2102eb61 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-06-30 18:21:38 +00:00
tokslaw bf73461c64 Merge branch 'price-fix' of WrenchBoard/Users-Wrench into master 2023-06-30 18:21:25 +00:00
victorAnumudu 5ffa6eb691 price fix 2023-06-30 16:01:11 +01:00
Ebube 5a0d8aebdb 1280 width fixed 2023-06-30 13:48:52 +01:00
Ebube e8ed10ddbf Added link to Family Market 2023-06-30 13:28:44 +01:00
ameye cca423a41c Merge branch 'family-assign-task' of WrenchBoard/Users-Wrench into master 2023-06-30 11:08:57 +00:00
victorAnumudu 6a6900a62b family assign task popout added 2023-06-30 11:57:47 +01:00
ameye c6b4fcc43d Merge branch 'delete-edit-icon' of WrenchBoard/Users-Wrench into master 2023-06-29 18:25:39 +00:00
ameye 29510c3b85 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-06-29 18:25:34 +00:00
victorAnumudu 1d8e54c57d delete and edit icon seperator width reduced 2023-06-29 13:56:14 +01:00
victorAnumudu 426599dd1f delete and edit icons added 2023-06-29 13:52:33 +01:00
Ebube c8d6d3d7d4 Removed Bg Img 2023-06-29 13:39:07 +01:00
Ebube 593ea74388 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into resources-page 2023-06-29 13:37:04 +01:00
Ebube d81b9970b3 Improved folder structure for resources and clean up 2023-06-29 13:18:31 +01:00
ameye 777ff54220 Merge branch 'resources-page' of WrenchBoard/Users-Wrench into master 2023-06-29 10:37:20 +00:00
Ebube 382a266b9a Resource Page Data Mapping 2023-06-29 09:09:30 +01:00
ameye 2d80dd9450 Merge branch 'no-interest-table-hidden' of WrenchBoard/Users-Wrench into master 2023-06-28 15:56:41 +00:00
victorAnumudu 0eaa72a5ec made others interest table hidden if its empty 2023-06-28 16:42:16 +01:00
CHIEFSOFT\ameye a2e2df867d resource props 2023-06-28 10:41:08 -04:00
ameye 10d4e169d3 Merge branch 'manage-active-job-delivery-date' of WrenchBoard/Users-Wrench into master 2023-06-28 13:38:48 +00:00
Ebube 79ed578483 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into manage-active-job-delivery-date 2023-06-28 14:10:42 +01:00
Ebube 25440a3c06 fixed minor bug 2023-06-28 14:10:14 +01:00
ameye 5f4c40a318 Merge branch 'manage-active-job-delivery-date' of WrenchBoard/Users-Wrench into master 2023-06-28 01:06:13 +00:00
Ebube ff7e8ea1ab Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into manage-active-job-delivery-date 2023-06-28 02:02:27 +01:00
Ebube cba14f4265 Added error borders 2023-06-28 02:01:53 +01:00
ameye 9c342f87f7 Merge branch 'manage-active-job-delivery-date' of WrenchBoard/Users-Wrench into master 2023-06-27 21:01:38 +00:00
Ebube 498966dd23 Fixed bugs in market popup and made changes to Add/edit 2023-06-27 21:57:39 +01:00
ameye b282295924 Merge branch 'manage-active-job-delivery-date' of WrenchBoard/Users-Wrench into master 2023-06-27 18:21:46 +00:00
Ebube 7222a4d750 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into manage-active-job-delivery-date 2023-06-27 17:12:02 +01:00
Ebube 271f5635a0 Fixed Api Parameter, Banner Button Style and Slider header 2023-06-27 17:11:30 +01:00
ameye 86c4283507 Merge branch 'manage-active-job-delivery-date' of WrenchBoard/Users-Wrench into master 2023-06-27 14:19:36 +00:00
Ebube 5e5d953769 Add Job button Fixed 2023-06-27 15:15:41 +01:00
ameye aa7065c5b4 Merge branch 'manage-active-job-delivery-date' of WrenchBoard/Users-Wrench into master 2023-06-27 14:10:27 +00:00
Ebube 29fee11ec3 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into manage-active-job-delivery-date 2023-06-27 13:49:24 +01:00
Ebube 264d7b8501 . 2023-06-27 13:48:54 +01:00
ameye 8f90bcdf10 Merge branch 'manage-active-job-delivery-date' of WrenchBoard/Users-Wrench into master 2023-06-27 10:52:36 +00:00
Ebube 4b897cb3a9 . 2023-06-27 10:06:51 +01:00
ameye 0977650bf4 Merge branch 'faq-display' of WrenchBoard/Users-Wrench into master 2023-06-26 18:07:41 +00:00
Ebube 1f76dd0db8 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into faq-display 2023-06-26 19:01:49 +01:00
Ebube f772cf0a68 . 2023-06-26 18:57:41 +01:00
CHIEFSOFT\ameye c4c5c7967e Resource Starter 2023-06-26 13:36:43 -04:00
Ebube 45ecec24ac Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into faq-display 2023-06-26 17:48:25 +01:00
Ebube 16fd35df83 . 2023-06-26 17:48:00 +01:00
CHIEFSOFT\ameye 3f6a391d30 witing Jobs 2023-06-26 09:23:28 -04:00
CHIEFSOFT\ameye 5eb64f49c0 text style 2023-06-26 07:50:49 -04:00
CHIEFSOFT\ameye 1761150bd3 My wait jobs 2023-06-26 07:44:03 -04:00
ameye a4b15dd06e Merge branch 'faq-display' of WrenchBoard/Users-Wrench into master 2023-06-25 21:38:00 +00:00
Ebube 1a15410e4c . 2023-06-25 20:07:35 +01:00
Ebube da1133ed43 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into faq-display 2023-06-25 20:00:49 +01:00
Ebube 23605bc358 . 2023-06-25 19:58:54 +01:00
ameye 2092682be6 Merge branch 'faq-display' of WrenchBoard/Users-Wrench into master 2023-06-25 11:19:58 +00:00
Ebube 0e270d8efa . 2023-06-25 07:09:17 +01:00
CHIEFSOFT\ameye 3bb4fe6a02 banner waiting 2023-06-25 00:01:44 -04:00
CHIEFSOFT\ameye fa728d3879 Waiting Jobs 2023-06-24 15:43:59 -04:00
ameye a9ce76123b Merge branch 'privacy-policy' of WrenchBoard/Users-Wrench into master 2023-06-24 11:17:42 +00:00
ameye 3ac1be9b89 Merge branch 'AddJob-Link-Fix' of WrenchBoard/Users-Wrench into master 2023-06-24 11:17:37 +00:00
ameye e4be117c90 Merge branch 'offer-interest-msg-list' of WrenchBoard/Users-Wrench into master 2023-06-24 11:17:11 +00:00
Ebube 58834cd7ca privacy policy 2023-06-24 08:52:33 +01:00
victorAnumudu 0feaf42f49 offer interest message list API added 2023-06-23 23:47:46 +01:00
217 changed files with 9571 additions and 13778 deletions
+25 -4
View File
@@ -17,7 +17,7 @@ REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_MINUTES=600000
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
@@ -42,13 +42,34 @@ REACT_APP_GOOGLE_CLIENT_SECRET=aozK_2G8UjaCmLgPPkv9abIm
REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
REACT_APP_FACEBOOK_CLIENT_ID=390204307987009
REACT_APP_FACEBOOK_CLIENT_SECRET=19f778e312f2ab96d147bacb612910c2
REACT_APP_FACEBOOK_CLIENT_SCOPE="email, public_profile"
#Real Account
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
#developenet Account
REACT_APP_FACEBOOK_CLIENT_ID=677857427521030
REACT_APP_FACEBOOK_CLIENT_SECRET=4801375f22072d8a75f64483fdd89829
#my Account
REACT_APP_FACEBOOK_CLIENT_ID3=1598725580610908
REACT_APP_FACEBOOK_CLIENT_SCOPE="email,public_profile"
REACT_APP_FACEBOOK_REDIRECT_URL="http://localhost:9082/login/auth/flogin"
REACT_APP_APPLE_CLIENT_ID='com.wrenchboard.users.client'
REACT_APP_APPLE_REDIRECT_URL='http://localhost:9082/login/auth/apple'
# /* 'client_id' => */ 'com.wrenchboard.users.client',
# /* 'client_secret' => */ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6Ilc1V1RXQzlEVEoifQ.eyJpc3MiOiJKUjM2M0ZFWThSIiwiaWF0IjoxNjU0MDgzODQxLCJleHAiOjE2NTkyNjc4NDEsImF1ZCI6Imh0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20iLCJzdWIiOiJjb20ud3JlbmNoYm9hcmQudXNlcnMuY2xpZW50In0.TIPMwjS2MgSysqEuw3yu1nrOcrH-6omzerDhx0CadjWn2yCO8wZhQiAlhIFs7F-WPektIJ6h-2BT62yGrILiTA',
# /* 'redirect_uri' => */ site_url('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
+4 -2
View File
@@ -17,7 +17,7 @@ REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_MINUTES=600000
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
@@ -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"
+9 -2
View File
@@ -17,7 +17,7 @@ REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_MINUTES=600000
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
@@ -40,7 +40,14 @@ REACT_APP_GOOGLE_CLIENT_SECRET=aozK_2G8UjaCmLgPPkv9abIm
REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
REACT_APP_GOOGLE_REDIRECT_URL=https://users.wrenchboard.com/login/auth/
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
REACT_APP_FACEBOOK_CLIENT_SCOPE="email,public_profile"
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"
+1
View File
@@ -17,6 +17,7 @@
"flutterwave-react-v3": "^1.3.0",
"formik": "^2.2.9",
"react": "^18.2.0",
"react-apple-login": "^1.1.6",
"react-chartjs-2": "^4.1.0",
"react-countup": "^6.2.0",
"react-dom": "^18.2.0",
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: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

+8
View File
@@ -45,6 +45,10 @@ import BlogPage from "./views/BlogPage";
import MyReviewDueJobsPage from "./views/MyReviewDueJobsPage";
import OffersInterestPage from "./views/OffersInterestPage";
import ManageInterestOfferPage from './views/ManageInterestOfferPage'
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
import FamilyMarketPage from "./views/FamilyMarketPage";
import FacebookRedirect from "./views/FacebookRedirect";
import AppleRedirectPage from "./views/AppleRedirectPage";
export default function Routers() {
return (
@@ -54,6 +58,8 @@ export default function Routers() {
<Route exact path="/login" element={<LoginPage />} />
<Route exact path="/signup" element={<SignupPage />} />
<Route exact path="/login/auth" element={<AuthRedirect />} />
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
<Route exact path="/login/auth/apple" element={<AppleRedirectPage />} />
<Route
exact
path="/forgot-password"
@@ -86,6 +92,7 @@ export default function Routers() {
<Route exact path="/notification" element={<Notification />} />
<Route exact path="/market-place" element={<MarketPlacePage />} />
<Route exact path="/market" element={<MarketPlacePage />} />
<Route exact path="/familymarket" element={<FamilyMarketPage />} />
<Route exact path="/notification" element={<Notification />} />
<Route exact path="/mytask" element={<MyTaskPage />} />
<Route exact path="/myjobs" element={<MyJobsPage />} />
@@ -93,6 +100,7 @@ export default function Routers() {
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
<Route exact path="/my-review-jobs" element={<MyReviewDueJobsPage />} />
<Route exact path="/acc-family" element={<FamilyAccPage />} />
<Route exact path="/manage-family" element={<FamilyManagePage />} />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" id="naira"><path fill="#fff" d="M24,5A19,19,0,1,0,43,24,19,19,0,0,0,24,5Zm7,20a1,1,0,0,1,0,2H29v3A1.94,1.94,0,0,1,27.45,32a2,2,0,0,1-2.26-1.08L20,17.05l0,14a1,1,0,0,1-2,0V27H16a1,1,0,0,1,0-2h2V22H16a1,1,0,0,1,0-2h2V17a1.94,1.94,0,0,1,1.55-1.92,2,2,0,0,1,2.26,1.08L27,30,27,16a1,1,0,0,1,2,0v4h2a1,1,0,0,1,0,2H29v3Z" class="color3b3c3d svgShape"></path><path fill="#e3e3e3" d="M24,48A24,24,0,1,1,48,24,24,24,0,0,1,24,48ZM24,2A22,22,0,1,0,46,24,22,22,0,0,0,24,2Z" class="color3b3c3d svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 563 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.933 16.933" id="Coin"><path d="M8.452 281.052a7.487 7.487 0 0 0-7.483 7.482 7.485 7.485 0 0 0 7.483 7.48 7.484 7.484 0 0 0 7.48-7.48 7.486 7.486 0 0 0-7.48-7.482zm0 1.232a6.253 6.253 0 0 1 6.248 6.25 6.25 6.25 0 0 1-6.248 6.248c-3.449 0-6.25-2.8-6.25-6.248a6.254 6.254 0 0 1 6.25-6.25zm0 .53a5.717 5.717 0 0 0-5.721 5.72 5.715 5.715 0 0 0 5.72 5.719 5.713 5.713 0 0 0 5.72-5.719 5.715 5.715 0 0 0-5.72-5.72zm-.004 2.011a.265.265 0 0 1 .267.268v.596H9.74a.265.265 0 1 1 0 .529H8.715v2.05h.17c.856 0 1.551.697 1.551 1.555s-.696 1.555-1.549 1.555h-.172v.596a.265.265 0 1 1-.529 0v-.596H7.161a.265.265 0 1 1 0-.53h1.025v-2.05h-.172a1.552 1.552 0 0 1-1.547-1.555c0-.858.694-1.554 1.547-1.554h.172v-.596a.265.265 0 0 1 .262-.268zm-.434 1.393a1.01 1.01 0 0 0-1.018 1.025 1.01 1.01 0 0 0 1.018 1.026h.172v-2.051zm.701 2.58v2.05h.172c.57 0 1.02-.448 1.02-1.025s-.449-1.025-1.022-1.025z" color="#e3e3e3" font-family="sans-serif" font-weight="400" overflow="visible" transform="translate(0 -280.067)" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;shape-padding:0;isolation:auto;mix-blend-mode:normal" fill="#fff" class="color000000 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" id="delete"><g color="#000"><path fill="#ee4c45" style="line-height:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;block-progression:tb;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" d="M12 1028.362c-6.626 0-12 5.374-12 12s5.374 12 12 12 12-5.374 12-12-5.374-12-12-12z" font-family="sans-serif" font-weight="400" overflow="visible" transform="translate(0 -1028.362)"></path><path fill="#fff" style="isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" d="M10.5 1034.362v1h-3v1h9v-1h-3v-1h-3zm-2 3v9h7v-9h-7zm1 1h1v7h-1v-7zm2 0h1v7h-1v-7zm2 0h1v7h-1v-7z" overflow="visible" transform="translate(0 -1028.362)"></path></g></svg>

After

Width:  |  Height:  |  Size: 841 B

+19
View File
@@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 60 60" viewBox="0 0 60 60" id="edit"><path fill="#3B4652" d="M52.9687347,19.3099976l-2.7999878-2.7999878c-0.9099731-0.9100342-2.3899536-0.9100342-3.2999878,0
l-1.4129639,1.4129639c0.0185547,0.017395,0.0423584,0.0234985,0.0601196,0.0422974l5.7765503,6.1199341
c0.0361328,0.038269,0.0506592,0.0881348,0.0813599,0.1296997l1.5949097-1.5949097
C53.8787689,21.7099609,53.8787689,20.2199707,52.9687347,19.3099976z"></path><path fill="#2B79C2" d="M10.8887787,25.5499878H34.998764l7.5900269-7.5900269l1.7599487-1.75V9c0-1.6500244-1.3499756-3-3-3h-32
c-1.6599731,0-3,1.3499756-3,3v42c0,1.6499634,1.3400269,3,3,3h32c1.6500244,0,3-1.3500366,3-3V34.0700073l-5.8899536,5.8800049
c-0.3099976,0.3199463-0.7000122,0.5599976-1.1199951,0.7099609l-7.2200317,2.5200195
c-0.3099976,0.1099854-0.6500244,0.1699829-0.9899902,0.1699829c-0.7800293,0-1.5200195-0.2999878-2.0900269-0.8399658
c-0.3399658-0.3400269-0.5799561-0.7400513-0.7299805-1.1600342H10.8887787c-0.5599976,0-1-0.4500122-1-1s0.4400024-1,1-1
h15.4199829v-0.0100098l1.7000122-4.8899536H10.8887787c-0.5599976,0-1-0.4500122-1-1c0-0.5500488,0.4400024-1,1-1H28.708786
l0.0999756-0.3000488c0.1699829-0.4699707,0.4400024-0.8800049,0.789978-1.1900024l3.4000244-3.4099731H10.8887787
c-0.5599976,0-1-0.4500122-1-1S10.3287811,25.5499878,10.8887787,25.5499878z M10.8887787,46.25h24.9099731
c0.5599976,0,1,0.4500122,1,1s-0.4400024,1-1,1H10.8887787c-0.5599976,0-1-0.4500122-1-1S10.3287811,46.25,10.8887787,46.25z
M10.8887787,11.75h24.9099731c0.5599976,0,1,0.4500122,1,1s-0.4400024,1-1,1H10.8887787c-0.5599976,0-1-0.4500122-1-1
S10.3287811,11.75,10.8887787,11.75z M10.8887787,18.6499634h24.9099731c0.5599976,0,1,0.4500122,1,1c0,0.5500488-0.4400024,1-1,1
H10.8887787c-0.5599976,0-1-0.4499512-1-1C9.8887787,19.0999756,10.3287811,18.6499634,10.8887787,18.6499634z"></path><path fill="#3B4652" d="M30.9387665,32.4400024c-0.1099854,0.0999756-0.1900024,0.2299805-0.2399902,0.3699951
l-2.5100098,7.2099609c-0.1300049,0.3600464-0.039978,0.7700195,0.2299805,1.0400391
c0.2000122,0.1900024,0.4500122,0.289978,0.710022,0.289978c0.1099854,0,0.2199707-0.0200195,0.3300171-0.0599976
l7.2099609-2.5100098c0.1400146-0.0499878,0.2700195-0.1300049,0.3800049-0.2399902l12.5599976-12.5599976l-5.9299927-6.2799683
L30.9387665,32.4400024z"></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 66 66" id="Account"><path fill="#4687ba" d="M19 36.5c-5.8 0-10.6 4.7-10.6 10.6S13.1 57.6 19 57.6 29.5 52.9 29.5 47 24.8 36.5 19 36.5zm0 19.6c-5 0-9.1-4.1-9.1-9.1s4.1-9 9.1-9 9 4 9 9-4 9.1-9 9.1z" class="color000100 svgShape"></path><path fill="#4687ba" d="M65.7 49.6l-.9-5.4c-1.2-8-7.4-14.3-15.1-15.9 1.3-1.6 2.7-3.9 3.3-7.1.5-.8 2.1-3.5 1.5-5.3-.1-.3-.3-.6-.6-.9.7-2 2.3-9-4.8-12.6C38-3.9 28.7 4.7 30.8 14.6c-.2.3-.5.6-.6 1.1-.3 1.3.1 3 1.3 4.9.2.8 1.5 5 3.9 7.9-3.2.8-6 2.4-8.4 4.6-1.2-.7-2.5-1.2-3.8-1.6l-.8-3.3h-6.8l-.8 3.3c-1.3.4-2.6.9-3.8 1.6l-2.8-1.8-4.8 4.8L5.1 39c-.7 1.2-1.2 2.5-1.6 3.8l-3.3.8v6.8l3.3.8c.4 1.3.9 2.6 1.6 3.8l-1.8 2.9 4.8 4.8 2.8-1.8c1.2.7 2.5 1.2 3.8 1.6l.8 3.3h6.8l.8-3.3c1.3-.4 2.6-.9 3.8-1.6l2.8 1.8 4.8-4.8-.3-.5H59c2 0 3.8-.9 5.1-2.4 1.3-1.4 1.9-3.4 1.6-5.4zM32.9 20.1l-.1-.2c-1.7-2.8-1.3-4.2-.8-4.5l.5-.3c-1.8-6 1.4-11.4 5.6-12.9C43.4.5 57 4.1 52 15.9c.3.1 1 .3 1 .6.3 1-.9 3.3-1.5 4.3-1.1 5.3-4.3 9.7-9.2 9.8-5.1 0-8.1-5.5-9.4-10.5zm-3.3 40.7L27 59.2c-1.1.7-2.4 1.5-5.1 2.1l-.7 3h-4.4l-.7-3c-2.3-.5-3.4-1.1-5.1-2.1l-2.6 1.6-3.1-3.1 1.6-2.6C5.7 53.2 5.2 52 4.7 50l-3-.7v-4.4l3-.7c.3-1.4.7-2.9 2.1-5.2l-1.6-2.6 3.1-3.1 2.6 1.6c1.1-.7 2.4-1.5 5.1-2.1l.7-3h4.4l.7 3c2.3.5 3.4 1.1 5.1 2.1l2.6-1.6 3.1 3.1-1.5 2.6c1.2 1.9 1.6 3.1 2.1 5.1l3 .7v4.4l-3 .7c-.3 1.2-.6 2.8-2.1 5.1l1.6 2.6-3.1 3.2zM63 54.1c-1 1.2-2.4 1.8-4 1.8H33.4l-.5-.9c.7-1.2 1.2-2.5 1.6-3.8l3.3-.8v-6.8l-3.3-.8c-.4-1.3-.9-2.6-1.6-3.8l1.8-2.8-4-4c1.8-1.1 3.8-1.9 6-2.4 1.7 1.5 3.8 2.4 6.2 2.2 2.7-.2 4.4-1.2 5.7-2.4 7.6 1.1 13.7 7.1 14.9 14.8l.8 5.4c.2 1.6-.3 3.1-1.3 4.3z" class="color000100 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="dashboard"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M4 13h6c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1zm0 8h6c.55 0 1-.45 1-1v-4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1zm10 0h6c.55 0 1-.45 1-1v-8c0-.55-.45-1-1-1h-6c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1zM13 4v4c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1h-6c-.55 0-1 .45-1 1z" fill="#4687ba" class="color000000 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 503 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="identificationcard"><path fill="#4687ba" d="M0 6v13c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2V6" class="color2d98d4 svgShape"></path><path fill="#ff6699" d="M22 3H2a2 2 0 0 0-2 2v2h24V5a2 2 0 0 0-2-2z" class="color0377be svgShape"></path><path fill="#e6e7f9" d="M22 3H2C.897 3 0 3.897 0 5v.25c0-1.103.897-2 2-2h20c1.103 0 2 .897 2 2V5c0-1.103-.897-2-2-2z" opacity=".2" class="colorffffff svgShape"></path><path fill="#4687ba" d="M22 20.75H2c-1.103 0-2-.897-2-2V19c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2v-.25c0 1.103-.897 2-2 2z" opacity=".1" class="color010101 svgShape"></path><path fill="#e6e7f9" d="M13 17h8v1h-8zM13 14h8v1h-8zM13 11h8v1h-8z" class="colorffffff svgShape"></path><circle cx="7" cy="12" r="2" fill="#e6e7f9" class="colorffffff svgShape"></circle><path fill="#e6e7f9" d="M9.987 15.237C9.288 14.9 8.203 14.5 7 14.5s-2.288.4-2.987.737c-.625.3-1.013.9-1.013 1.566V18h8v-1.197c0-.665-.388-1.265-1.013-1.566z" class="colorffffff svgShape"></path><circle cx="17" cy="5" r="1" fill="#ff6699" class="color0a70b9 svgShape"></circle><path fill="#4687ba" d="M17 4.25a.99.99 0 0 1 .975.875C17.98 5.082 18 5.045 18 5a1 1 0 0 0-2 0c0 .044.02.082.025.125A.99.99 0 0 1 17 4.25z" opacity=".1" class="color010101 svgShape"></path><linearGradient id="a" x1="6.973" x2="21.55" y1="1.973" y2="16.55" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#010101" stop-opacity=".1" class="stopColor010101 svgShape"></stop><stop offset="1" stop-color="#010101" stop-opacity="0" class="stopColor010101 svgShape"></stop></linearGradient><path fill="url(#a)" d="M22 21c1.103 0 2-.897 2-2V7H0l14 14h8z"></path><circle cx="7" cy="5" r="1" fill="#ff6699" class="color0a70b9 svgShape"></circle><path fill="#4687ba" d="M7 4.25a.99.99 0 0 1 .975.875C7.98 5.082 8 5.045 8 5a1 1 0 0 0-2 0c0 .044.02.082.025.125A.99.99 0 0 1 7 4.25z" opacity=".1" class="color010101 svgShape"></path><linearGradient id="b" x1="-.708" x2="24.708" y1="6.074" y2="17.925" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffffff" stop-opacity=".2" class="stopColorffffff svgShape"></stop><stop offset="1" stop-color="#ffffff" stop-opacity="0" class="stopColorffffff svgShape"></stop></linearGradient><path fill="url(#b)" d="M22 3H2a2 2 0 0 0-2 2v14c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2V5a2 2 0 0 0-2-2z"></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 128 128" viewBox="0 0 128 128" id="Pin"><path fill="#4687ba" d="M106,13.8L91.7,4.6C86.2,1,78.9,2,74.5,7L41.9,46.9c-9.1,0.4-17.9,3.3-25.4,8.7c-0.7,0.5-0.7,1.6,0.1,2.1
l10.2,6.6l0,0L46.4,77l-24,41.4c-1.2,2.1-0.7,4.9,1.4,6.3c2.2,1.6,5.2,1.1,6.7-1.1l28-38.8L78,97.5l0,0l10.2,6.6
c0.7,0.5,1.7,0.1,1.9-0.8c1.8-9,0.9-18.3-2.5-26.8l23.1-46C113.6,24.5,111.5,17.4,106,13.8z" class="color2d3e50 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 482 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 32 32" id="Family"><path d="M26.305 22.723a4.972 4.972 0 0 0-3.176-8.71 9.917 9.917 0 0 0-3.438-2.292 6 6 0 1 0-7.382 0 9.917 9.917 0 0 0-3.438 2.292 4.972 4.972 0 0 0-3.171 8.71A8.005 8.005 0 0 0 1 30a1 1 0 0 0 2 0 6 6 0 0 1 12 0 1 1 0 0 0 2 0 6 6 0 0 1 12 0 1 1 0 0 0 2 0 8.005 8.005 0 0 0-4.695-7.277ZM26 19a3 3 0 1 1-3-3 3 3 0 0 1 3 3ZM12 7a4 4 0 1 1 4 4 4 4 0 0 1-4-4ZM6 19a3 3 0 1 1 3 3 3 3 0 0 1-3-3Zm10 7.136a8.04 8.04 0 0 0-3.695-3.413 4.949 4.949 0 0 0-1.05-8.16 7.984 7.984 0 0 1 9.49 0 4.949 4.949 0 0 0-1.05 8.16A8.04 8.04 0 0 0 16 26.136Z" 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 24 24" id="Logout"><path d="M4,12a1,1,0,0,0,1,1h7.59l-2.3,2.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l4-4a1,1,0,0,0,.21-.33,1,1,0,0,0,0-.76,1,1,0,0,0-.21-.33l-4-4a1,1,0,1,0-1.42,1.42L12.59,11H5A1,1,0,0,0,4,12ZM17,2H7A3,3,0,0,0,4,5V8A1,1,0,0,0,6,8V5A1,1,0,0,1,7,4H17a1,1,0,0,1,1,1V19a1,1,0,0,1-1,1H7a1,1,0,0,1-1-1V16a1,1,0,0,0-2,0v3a3,3,0,0,0,3,3H17a3,3,0,0,0,3-3V5A3,3,0,0,0,17,2Z" fill="#e07c8a" class="color000000 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 487 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 512 512" id="FindJobs"><path d="M499.22 437.51 433.68 372a23.19 23.19 0 0 0-26.63-4.41l-22.18-22.18A214.71 214.71 0 0 0 62.78 62.78a214.72 214.72 0 0 0 282.6 322.09l22.18 22.18a23.19 23.19 0 0 0 4.44 26.63l65.54 65.54a43.64 43.64 0 0 0 61.71-61.71ZM341.29 369l-.2.18A199.71 199.71 0 0 1 73.39 73.39a199.71 199.71 0 0 1 295.76 267.67l-.22.26q-6.18 7.5-13.14 14.47T341.29 369Zm15.71 6.26c3.21-2.86 6.36-5.8 9.42-8.86s6-6.21 8.86-9.42l20.29 20.3-18.27 18.27Zm131.61 113.35a28.65 28.65 0 0 1-40.49 0l-65.54-65.54a8.22 8.22 0 0 1 0-11.61l28.88-28.88a8.22 8.22 0 0 1 11.61 0l65.54 65.54a28.65 28.65 0 0 1 0 40.49ZM296.08 161h-31v-11.53A21.13 21.13 0 0 0 244 128.36h-58.8a21.13 21.13 0 0 0-21.11 21.11V161h-31a19.82 19.82 0 0 0-19.81 19.81V281a19.83 19.83 0 0 0 19.81 19.82h163A19.84 19.84 0 0 0 315.9 281V180.81A19.83 19.83 0 0 0 296.08 161Zm-117-11.53a6.12 6.12 0 0 1 6.11-6.11H244a6.12 6.12 0 0 1 6.11 6.11V161h-71ZM300.9 281a4.82 4.82 0 0 1-4.82 4.82h-163a4.82 4.82 0 0 1-4.81-4.82v-63.6l63.8 27.77v4.88a14.52 14.52 0 0 0 14.5 14.5h16a14.52 14.52 0 0 0 14.5-14.5v-4.88l63.83-27.77Zm-93.81-31.45v-15h15v15ZM300.9 201l-64.67 28.14a14.5 14.5 0 0 0-13.64-9.63h-16a14.52 14.52 0 0 0-13.59 9.67L128.29 201v-20.19a4.82 4.82 0 0 1 4.81-4.81h163a4.82 4.82 0 0 1 4.82 4.81Zm36.89-109.61c-67.93-67.93-178.47-67.93-246.4 0a174.23 174.23 0 0 0 246.4 246.4 174.23 174.23 0 0 0 0-246.4Zm-10.6 235.8a159.25 159.25 0 1 1 46.63-112.6 158.76 158.76 0 0 1-46.63 112.6Z" fill="#4687ba" class="color000000 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 9362 9362" id="jobsact"><path d="M8967 8103l-423 0 0 -856 423 0c181,0 329,193 329,428l0 0c0,235 -148,428 -329,428zm-4636 0l4066 0 0 -856 -4066 0 0 856zm-139 0l-738 -327 -268 0c-43,0 -138,-45 -138,-101 0,-56 95,-101 138,-101l268 0 738 -327 0 428 0 428zm-3982 -8103l6388 0 210 0 0 210 0 809 -420 0 0 -600 -5969 0 0 8523 5969 0 0 -551 420 0 0 761 0 210 -210 0 -6388 0 -210 0 0 -210 0 -8942 0 -210 210 0zm6598 6523l0 436 -420 0 0 -436 420 0zm2554 -3158l0 2557c0,175 -143,317 -317,317l-5224 0c-174,0 -317,-142 -317,-317l0 -2557 2486 0 0 491c0,244 199,443 443,443 244,0 443,-199 443,-443l0 -491 2486 0zm-3843 -2062l1827 0c121,0 219,98 219,219l0 626 -340 0 0 -506 -1585 0 0 506 -340 0 0 -626c0,-121 99,-219 219,-219zm-1698 1011l5224 0c174,0 317,143 317,317l0 568 -2650 0 0 657c0,154 -126,279 -279,279l0 0c-154,0 -280,-125 -280,-279l0 -657 -2649 0 0 -568c0,-174 143,-317 317,-317zm2612 1387c74,0 134,60 134,134 0,74 -60,134 -134,134 -74,0 -134,-60 -134,-134 0,-74 60,-134 134,-134zm-4430 -2741l2801 0 0 420 -2801 0 0 -420zm-806 4786l2023 0 0 176c0,87 19,170 52,244l-2075 0 0 -420zm0 -3657l2366 0c-167,80 -292,235 -330,421l-2036 0 0 -421zm0 914l2023 0 0 421 -2023 0 0 -421zm0 914l2023 0 0 421 -2023 0 0 -421zm0 915l2023 0 0 420 -2023 0 0 -420zm0 1828l1371 0 0 421 -1371 0 0 -421z" fill="#4687ba" class="color000000 svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" id="Profile"><path fill="#ffffff" d="M108 124H20c-8.8 0-16-7.2-16-16V20c0-8.8 7.2-16 16-16h88c8.8 0 16 7.2 16 16v88c0 8.8-7.2 16-16 16z" class="colorffffff svgShape"></path><path fill="#d2d4d6" d="M4 18.1v21.2h120V18.1c0-7.8-6.3-14.1-14.1-14.1H18.1C10.3 4 4 10.3 4 18.1z" class="colord2d5d6 svgShape"></path><circle cx="20.5" cy="21.1" r="7.1" fill="#7bbaec" class="colorec7bb0 svgShape"></circle><circle cx="59.5" cy="21.1" r="7.1" fill="#4687ba" class="color82cfcd svgShape"></circle><path fill="#57636d" d="M59.5 29.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1 4.4 0 8.1 3.6 8.1 8.1-.1 4.5-3.7 8.1-8.1 8.1zm0-14.1c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1-2.8-6.1-6.1-6.1z" class="color6a576d svgShape"></path><circle cx="40" cy="21.1" r="7.1" fill="#7bbdf1" class="colorf1ed7b svgShape"></circle><path fill="#57636d" d="M20.5 29.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1 4.4 0 8.1 3.6 8.1 8.1s-3.6 8.1-8.1 8.1zm0-14.1c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1-2.7-6.1-6.1-6.1zm39 14.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1 4.4 0 8.1 3.6 8.1 8.1-.1 4.5-3.7 8.1-8.1 8.1zm0-14.1c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1-2.8-6.1-6.1-6.1zM40 29.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1s8.1 3.6 8.1 8.1-3.7 8.1-8.1 8.1zM40 15c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1S43.3 15 40 15zM4 38.3h120v2H4zM108 104.3H20c-.6 0-1-.4-1-1s.4-1 1-1h88c.6 0 1 .4 1 1s-.4 1-1 1zm-48-48H20c-.6 0-1-.4-1-1s.4-1 1-1h40c.6 0 1 .4 1 1s-.4 1-1 1zm0 16H20c-.6 0-1-.4-1-1s.4-1 1-1h40c.6 0 1 .4 1 1s-.4 1-1 1zm0 16H20c-.6 0-1-.4-1-1s.4-1 1-1h40c.6 0 1 .4 1 1s-.4 1-1 1z" class="color6a576d svgShape"></path><path fill="#57636d" d="M108 125H20c-9.4 0-17-7.6-17-17V20c0-9.4 7.6-17 17-17h88c9.4 0 17 7.6 17 17v88c0 9.4-7.6 17-17 17zM20 5C11.7 5 5 11.7 5 20v88c0 8.3 6.7 15 15 15h88c8.3 0 15-6.7 15-15V20c0-8.3-6.7-15-15-15H20z" class="color6a576d svgShape"></path><path fill="#ffffff" d="M108.9 28.1H79.6c-3.9 0-7.1-3.2-7.1-7.1 0-3.9 3.2-7.1 7.1-7.1h29.3c3.9 0 7.1 3.2 7.1 7.1 0 4-3.2 7.1-7.1 7.1z" class="colorffffff svgShape"></path><path fill="#57636d" d="M108.9 29.1H79.6c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1h29.3c4.4 0 8.1 3.6 8.1 8.1s-3.6 8.1-8.1 8.1zM79.6 15c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1h29.3c3.3 0 6.1-2.7 6.1-6.1s-2.7-6.1-6.1-6.1H79.6z" class="color6a576d svgShape"></path><path fill="#5587af" d="M76 55.3h32v32H76z" class="coloraf5655 svgShape"></path><path fill="#57636d" d="M104.8 88.3H79.2c-2.3 0-4.2-1.9-4.2-4.2V58.5c0-2.3 1.9-4.2 4.2-4.2h25.6c2.3 0 4.2 1.9 4.2 4.2v25.6c0 2.3-1.9 4.2-4.2 4.2zm-25.6-32c-1.2 0-2.2 1-2.2 2.2v25.6c0 1.2 1 2.2 2.2 2.2h25.6c1.2 0 2.2-1 2.2-2.2V58.5c0-1.2-1-2.2-2.2-2.2H79.2z" class="color6a576d svgShape"></path></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.0 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" id="Visacard"><g fill="#767fad" class="color303c42 svgShape"><path d="M28 4H2C.897 4 0 4.897 0 6v18c0 1.103.897 2 2 2h26c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm1 20c0 .551-.449 1-1 1H2c-.551 0-1-.449-1-1V6c0-.551.449-1 1-1h26c.551 0 1 .449 1 1v18z" fill="#5218ed" class="color000000 svgShape"></path><path d="M7.677 14.266a.2.2 0 0 0 .228.053.17.17 0 0 0 .106-.194l-.314-1.368a.121.121 0 0 0-.002-.009c-.113-.39-.47-.449-.729-.459H6.96l-1.768-.002c-.091 0-.17.06-.185.143a.172.172 0 0 0 .121.193c1.078.358 1.96.926 2.55 1.643zM23.535 12.303h-1.15c-.46 0-.724.141-.883.473l-2.383 4.981a.162.162 0 0 0 .014.165c.035.05.094.079.158.079h1.35a.189.189 0 0 0 .176-.112c.165-.404.272-.661.307-.744h.974l1.183.002c.039.151.134.552.173.717.019.08.095.137.184.137h1.177c.057 0 .11-.024.146-.065s.05-.095.038-.146l-1.28-5.351a.185.185 0 0 0-.184-.136zm-1.926 3.675.895-2.138.114.492.39 1.646h-1.4z" fill="#5218ed" class="color000000 svgShape"></path><path d="M11.816 12.38a.193.193 0 0 0-.157-.078h-1.37a.188.188 0 0 0-.175.11L8.511 16.19l-.172-.575a.142.142 0 0 0-.009-.023c-.253-.542-.933-1.39-1.881-2.062-.065-.046-.154-.048-.221-.006s-.097.12-.074.192L7.47 17.87a.187.187 0 0 0 .18.124l1.518-.002a.19.19 0 0 0 .173-.104l2.49-5.344a.162.162 0 0 0-.016-.164zM14.088 12.297h-1.303a.184.184 0 0 0-.186.144l-.989 5.355a.165.165 0 0 0 .042.141c.036.04.088.062.144.062h1.302c.092 0 .17-.061.186-.145l.99-5.354a.164.164 0 0 0-.042-.141.195.195 0 0 0-.144-.062zM17.696 13.452h.05c.51 0 .87.107 1.097.187a.202.202 0 0 0 .16-.011.175.175 0 0 0 .093-.122l.152-.826c.016-.085-.039-.168-.128-.194a4.634 4.634 0 0 0-1.3-.182c-1.607 0-2.735.746-2.744 1.814-.01.79.807 1.231 1.422 1.494.632.269.844.441.841.682-.004.369-.506.536-.97.536a3.676 3.676 0 0 1-1.522-.285.202.202 0 0 0-.163.008.175.175 0 0 0-.095.123l-.161.87a.173.173 0 0 0 .123.193c.444.144 1.064.233 1.66.24h.001c1.705-.001 2.815-.739 2.827-1.88.006-.627-.427-1.1-1.36-1.49-.57-.256-.92-.426-.917-.686 0-.234.32-.47.934-.47z" fill="#5218ed" class="color000000 svgShape"></path></g></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

+83 -71
View File
@@ -1,33 +1,38 @@
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Field, Form, Formik } from "formik";
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import * as Yup from "yup";
import usersService from "../../services/UsersService";
import { tableReload } from "../../store/TableReloads";
import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService";
import { useSelector, useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads";
import { Field, Form, Formik } from "formik";
import * as Yup from "yup";
const validationSchema = Yup.object().shape({
country: Yup.string()
.min(1, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Country is required"),
price: Yup.number()
.typeError("you must specify a number")
price: Yup.string()
.typeError("Invalid number")
.min(1, "Price must be greater than 0")
.test("no-e", "Invalid number", (value) => {
if (value && /\d+e/.test(value)) {
return false;
}
return true;
})
.required("Price is required"),
title: Yup.string()
.min(3, "Minimum 3 characters")
.max(100, "Maximum 25 characters")
.min(5, "Minimum 5 characters")
.max(149, "Maximum 149 characters")
.required("Title is required"),
description: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.min(5, "Minimum 5 characters")
.max(299, "Maximum 299 characters")
.required("Description is required"),
job_detail: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.max(1440, "Maximum 1440 characters")
.required("Details is required"),
timeline_days: Yup.number()
.typeError("you must specify a number")
@@ -38,19 +43,18 @@ const validationSchema = Yup.object().shape({
function AddJob({ popUpHandler, categories }) {
const ApiCall = new usersService();
let dispatch = useDispatch();
let { userDetails } = useSelector((state) => state.userDetails);
let [country, setCountry] = useState({
let [currency, setCurrency] = useState({
loading: true,
status: false,
data: [],
}); // To Hold the array of country getUserCountry returns
data: null,
}); // To Hold the array of currency getUserCurrency returns
let initialValues = {
// initial values for formik
country: userDetails.country,
country: "",
price: "",
title: "",
description: "",
@@ -65,31 +69,41 @@ function AddJob({ popUpHandler, categories }) {
message: "",
}); // Holds state when submit button is pressed
// FUNCTION TO GET COUNTRY
const getUserCountry = () => {
setCountry((prev) => ({ ...prev, loading: true }));
ApiCall.getSignupCountryData()
// FUNCTION TO GET Currency
const getUserCurrency = () => {
setCurrency((prev) => ({ ...prev, loading: true }));
ApiCall.getUserWallets()
.then((res) => {
if (res.data.internal_return < 1) {
setCountry({ loading: false, status: true, data: [] });
if (res.data.internal_return < 0) {
setCurrency({ loading: false, status: true, data: [] });
return;
}
setCountry({
setCurrency({
loading: false,
status: true,
data: res.data.signup_country,
data: res.data.result_list,
});
})
.catch((err) => {
setCountry({ loading: false, status: false, data: [] });
setCurrency({ loading: false, status: false, data: [] });
});
};
// FUNCTION TO HANDLE ADD JOB FORM
const handleAddJob = (values, helpers) => {
values.category = values.category?.join("@");
let reqData = {
country: values?.country,
price: Number(values.price) * 100,
title: values?.title,
description: values?.description,
job_detail: values?.job_detail,
timeline_days: values?.timeline_days,
category: values.category?.join("@"),
};
setRequestStatus({ loading: true, status: false, message: "" });
ApiCall.jobManagerCreateJob(values)
ApiCall.jobManagerCreateJob(reqData)
.then((res) => {
if (res.data.internal_return < 1) {
setRequestStatus({
@@ -97,6 +111,9 @@ function AddJob({ popUpHandler, categories }) {
status: false,
message: "Could not complete your request at the moment",
});
setTimeout(() => {
popUpHandler();
}, 1500);
return;
}
setRequestStatus({
@@ -113,7 +130,7 @@ function AddJob({ popUpHandler, categories }) {
setRequestStatus({
loading: false,
status: false,
message: "Opps! soemthing went wrong. Try Again",
message: "Opps! something went wrong. Try Again",
});
})
.finally(() => {
@@ -124,7 +141,7 @@ function AddJob({ popUpHandler, categories }) {
};
useEffect(() => {
getUserCountry();
getUserCurrency();
}, []);
return (
@@ -140,46 +157,41 @@ function AddJob({ popUpHandler, categories }) {
<div className="flex flex-col-reverse sm:flex-row">
<div className="fields w-full">
{/* inputs starts here */}
{/* country */}
<div className="xl:flex xl:space-x-7 mb-[5px]">
<div className="field w-full mb-6 xl:mb-0">
<label
htmlFor="country"
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex item-center gap-1"
>
Country
Currency
{props.errors.country && props.touched.country && <span className="text-[12px] text-red-500">{props.errors.country}</span>}
</label>
<select
id="country"
name="country"
disabled
value={props.values.country}
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{country.loading ? (
{currency.loading ? (
<option className="text-slate-500 text-lg" value="">
Loading...
</option>
) : country.data.length ? (
) : currency.data.length ? (
<>
<option className="text-slate-500 text-lg" value="">
Select...
Select a currency
</option>
{country.data.map((item, index) => {
if (item[0] == userDetails.country) {
return (
<option
key={index}
className="text-slate-500 text-lg"
value={item[0]}
>
{item[1]}
</option>
);
}
})}
{currency.data?.map((item, index) => (
<option
key={index}
className="text-slate-500 text-lg"
value={item?.country}
>
{item?.description}
</option>
))}
</>
) : (
<option className="text-slate-500 text-lg" value="">
@@ -202,13 +214,12 @@ function AddJob({ popUpHandler, categories }) {
value={props.values.price}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
errorBorder={props.errors.price && props.touched.price}
error={props.errors.price && props.touched.price && props.errors.price}
/>
</div>
</div>
{/* Title */}
<div className="field w-full mb-[5px]">
<InputCom
fieldClass="px-6"
@@ -220,7 +231,7 @@ function AddJob({ popUpHandler, categories }) {
value={props.values.title}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
errorBorder={props.errors.title && props.touched.title}
error={props.errors.title && props.touched.title && props.errors.title}
/>
</div>
@@ -236,9 +247,7 @@ function AddJob({ popUpHandler, categories }) {
value={props.values.description}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
errorBorder={
props.errors.description && props.touched.description
}
error={props.errors.description && props.touched.description && props.errors.description}
/>
</div>
@@ -247,14 +256,15 @@ function AddJob({ popUpHandler, categories }) {
<div className="sm:w-[60%] w-full">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1'
>
Job Delivery Details
{props.errors.job_detail && props.touched.job_detail && <span className="text-[12px] text-red-500">{props.errors.job_detail}</span>}
</label>
<textarea
id="Job Delivery Details"
rows="5"
className={`input-field px-6 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] border border-[#dce4e9] rounded-[10px]`}
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px]`}
style={{ resize: "none" }}
name="job_detail"
value={props.values.job_detail}
@@ -276,7 +286,7 @@ function AddJob({ popUpHandler, categories }) {
role="group"
aria-labelledby="checked-group"
>
{Object.entries(categories).map(([key, value]) => (
{Object?.entries(categories).map(([key, value]) => (
<label
key={key}
className="flex gap-1 w-full items-center"
@@ -289,16 +299,13 @@ function AddJob({ popUpHandler, categories }) {
<span className="text-[13.975px]">{value}</span>
</label>
))}
<span className="h-5 text-sm italic text-[#cf3917]">
{props.errors.category &&
props.touched.category &&
"please select a category"}
</span>
</div>
</div>
{/* <div className={`${!props.errors && "invisible"} h-5`}>
{props.errors.job_detail && props.touched.job_detail && (
<p className="text-sm text-red-500">
{props.errors.job_detail}
</p>
)}
</div> */}
</div>
<div className="field w-full mb-[5px]">
@@ -317,7 +324,12 @@ function AddJob({ popUpHandler, categories }) {
<Field
component="select"
name="timeline_days"
className="input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none"
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none ${
props.errors.timeline_days &&
props.touched.timeline_days
? "border-[#ff0a0a63] shadow-red-500 border-[0.5px] animate-shake"
: "border border-[#f5f8fa] dark:border-[#5e6278]"
}`}
value={props.values.timeline_days}
>
<option value="">Select Duration</option>
+5 -5
View File
@@ -4,12 +4,12 @@ import { Link } from "react-router-dom";
export default function LoginLayout({ slogan, children }) {
return (
<div className={`layout-wrapper login`}>
<div className={`main-wrapper login-wrapper w-full h-screen overflow-y-auto p-2 sm:p-20`}>
<div className={`main-wrapper login-wrapper w-full h-screen overflow-y-auto p-2 sm:px-20 sm:py-5`}>
<div className="w-full h-full">
<div className="flex-1 flex justify-center items-center">
{children && children}
</div>
<div className="flex-1 flex justify-center items-center p-10">
<div className="flex-1 flex justify-center items-center px-10 pt-10">
<div className="flex items-center">
<a
href="https://www.wrenchboard.com/about-us"
@@ -37,9 +37,9 @@ export default function LoginLayout({ slogan, children }) {
</a>
</div>
</div>
<div className="flex-1 flex justify-center items-center p-10">
<p className="text-black text-[15px] px-2 font-medium flex items-center">
<span className="text-3xl mt-2 mr-1">©</span> 2023 - {" "}
<div className="flex-1 flex justify-center items-center px-10 py-1">
<p className="text-black text-[15px] px-2 font-medium flex items-center gap-1">
<span className="">&copy; {new Date().getFullYear()} -</span>
<Link to="/" className="text-[#009ef7] ml-1">
WrenchBoard
</Link>{" "}
@@ -43,7 +43,7 @@ export default function CollectionTab({ className, products }) {
<DataIteration
datas={products}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products.length}
endLength={products?.length}
>
{({ datas }) => (
<CollectionCard key={datas.uniqKey} collectionData={datas} />
@@ -42,7 +42,9 @@ export default function CreateSaleSlider({
{/* heading */}
<div className="flex justify-between items-center mb-6">
<div>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Sell</h1>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
Create for Sell
</h1>
</div>
<div className="slider-btns flex space-x-4">
<button onClick={nextHandler} type="button">
@@ -89,7 +91,7 @@ export default function CreateSaleSlider({
<div className="trending-products relative w-full">
<SliderCom selector={trendingSlider} settings={settings}>
{products &&
products.length > 0 &&
products?.length > 0 &&
products.map((item) => (
<ProductCardStyleTwo
key={item.id}
@@ -49,7 +49,9 @@ export default function CreatedBidsSlider({
{/* heading */}
<div className="flex justify-between items-center mb-6">
<div>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Bits</h1>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
Create for Bits
</h1>
</div>
<div className="slider-btns flex space-x-4">
<button onClick={nextHandler} type="button">
@@ -96,7 +98,7 @@ export default function CreatedBidsSlider({
<div className="trending-products relative w-full">
<SliderCom selector={trendingSlider} settings={settings}>
{products &&
products.length > 0 &&
products?.length > 0 &&
products.map((item) => (
<ProductCardStyleOne
key={item.id}
@@ -43,7 +43,7 @@ export default function OnSaleTab({ className, products }) {
<DataIteration
datas={products}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products.length}
endLength={products?.length}
>
{({ datas }) => (
<ProductCardStyleTwo key={datas.id} datas={datas} />
@@ -43,7 +43,7 @@ export default function OwnTab({ className, products }) {
<DataIteration
datas={products}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products.length}
endLength={products?.length}
>
{({ datas }) => (
<ProductCardStyleOne key={datas.id} datas={datas} />
@@ -0,0 +1,69 @@
import React, { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import usersService from '../../../services/UsersService';
import {updateUserDetails} from "../../../store/UserDetails";
import { useDispatch } from "react-redux";
import AuthLayout from "../AuthLayout";
function AppleRedirect() {
const location = useLocation();
const navigate = useNavigate();
const userApi = new usersService();
const dispatch = useDispatch()
const queryParams = new URLSearchParams(location?.search);
const codeResponse = queryParams.get("code");
useEffect(()=>{
if(!codeResponse){
navigate('/login', {state: {error: true}})
return
}
console.log(codeResponse);
setTimeout(()=>{ // remove LATER
navigate('/login', {state: {error: true}})
},2000)
/*
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
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
*/
var reqData = {
auth_type: "APPLE",
code: codeResponse,
redirect_uri: process.env.REACT_APP_GOOGLE_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);
// });
},[])
return (
<AuthLayout>
<div className='min-h-[70vh]'>Redirecting ... </div>
</AuthLayout>
)
}
export default AppleRedirect
@@ -0,0 +1,65 @@
import React, { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import usersService from '../../../services/UsersService';
import {updateUserDetails} from "../../../store/UserDetails";
import { useDispatch } from "react-redux";
import AuthLayout from "../AuthLayout";
function FbookRedirect() {
const location = useLocation();
const navigate = useNavigate();
const userApi = new usersService();
const dispatch = useDispatch()
const queryParams = new URLSearchParams(location?.search);
const codeResponse = queryParams.get("code");
useEffect(()=>{
if(!codeResponse){
navigate('/login', {state: {error: true}})
return
}
console.log(codeResponse);
/*
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
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
*/
var reqData = {
auth_type: "FACEBOOK",
code: codeResponse,
redirect_uri: process.env.REACT_APP_GOOGLE_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);
// });
},[])
return (
<AuthLayout>
<div className='min-h-[70vh]'>Redirecting ... </div>
</AuthLayout>
)
}
export default FbookRedirect
@@ -1,23 +1,64 @@
import React, {useState, useEffect} from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import React, { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import usersService from '../../../services/UsersService';
import {updateUserDetails} from "../../../store/UserDetails";
import { useDispatch } from "react-redux";
import AuthLayout from "../AuthLayout";
function Redirect() {
const location = useLocation();
const navigate = useNavigate();
const userApi = new usersService();
const dispatch = useDispatch()
const queryParams = new URLSearchParams(location?.search);
const codeResponse = queryParams.get("code");
useEffect(()=>{
if(!codeResponse){
navigate('/login', {replace: true})
if(!codeResponse){
navigate('/login', {state: {error: true}})
return
}
console.log(codeResponse);
/*
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
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
*/
var reqData = {
auth_type: "GOOGLE",
code: codeResponse,
redirect_uri: process.env.REACT_APP_GOOGLE_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
}
console.log(codeResponse)
}
navigate('/login', {state: {error: true}})
})
.catch((error) => {
navigate('/login', {state: {error: true}})
console.log(error);
});
},[])
return (
<div>Redirecting ... </div>
<AuthLayout>
<div className='min-h-[70vh]'>Redirecting ... </div>
</AuthLayout>
)
}
export default Redirect
export default Redirect
+137 -72
View File
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import React, { useEffect, useLayoutEffect, useState } from "react";
import { Link, useNavigate, useLocation } 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";
@@ -16,15 +16,15 @@ import { updateUserDetails } from "../../../store/UserDetails";
export default function Login() {
const dispatch = useDispatch();
const {state} = useLocation()
let [loginType, setLoginType] = useState({ full: true, family: false });
const [selectedLoginType, setSelectedLoginType] = useState(
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
);
let [loginType, setLoginType] = useState('');
const [checked, setValue] = useState(false);
const [loginLoading, setLoginLoading] = useState(false);
const [showPassword, setShowPassword] = useState(false);
//login error state
const [loginError, setLoginError] = useState(false);
// for the catch error
@@ -34,13 +34,19 @@ export default function Login() {
setValue(!checked);
};
// To Show and Hide Password
const togglePasswordVisibility = () => {
setShowPassword(!showPassword);
};
//FUNCTION TO DETERMINE/CHANGE LOGIN COMPONENT
const handleLoginType = ({ target: { name } }) => {
if (name == "full") {
setLoginType({ [name]: true, family: false });
} else if ((name = "family")) {
setLoginType({ [name]: false, family: true });
}
setLoginType(name);
let currentDate = new Date();
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=/;`;
};
// email
@@ -71,7 +77,14 @@ export default function Login() {
return;
}
if (name == "loginfull") {
if (name == "full") {
//checks if email is a valid email address
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
if (regEx.test(email) == false) {
setLoginLoading(false);
setMsgError("Invalid Email");
return setTimeout(()=>{setMsgError("");},3000)
}
// Post Data Info for normal Login
postData = {
username: email,
@@ -80,11 +93,7 @@ export default function Login() {
login_mode: 1100,
action: 11025,
};
// Clear the loginType cookie if the user switches to loginfull
document.cookie =
"loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
} else if (name == "loginfamily") {
} else if (name == "family") {
// Post Data Info for family Login
postData = {
username: email,
@@ -93,8 +102,6 @@ export default function Login() {
login_mode: 1105,
action: 11025,
};
// Set the loginType cookie to remember the user's selection
document.cookie = "loginType=family; expires=Session; path=/;";
} else {
setLoginLoading(false);
setMsgError("Invalid Login Type. Consider refreshing the page");
@@ -106,7 +113,7 @@ export default function Login() {
userApi
.logInUser(postData)
.then((res) => {
if (res.status != 200 || res.data.internal_return < 0) {
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);
@@ -116,7 +123,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);
@@ -146,24 +153,57 @@ export default function Login() {
});
// In order to update the selected login type whenever the component renders
useEffect(() => {
setSelectedLoginType(
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
);
}, []);
// useEffect(() => {
// Clear the loginType cookie if the user switches to loginfull
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
// }, []);
console.log("Looking for the cookies >>", selectedLoginType)
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")){
// setLoginType('full')
// }else{
// setLoginType('full')
// }
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 c = carr[i];
while(c.charAt(0)==' '){
c=c.substring(1);
}
if(c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return 'full'
}
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
setMsgError("Unexpected Error, Please try again soon.");
setTimeout(()=>{
setMsgError("");
navigate('/login', {replace: true})
},4000)
}
},[])
useEffect(() => {
setMail("");
setPassword("");
}, [loginType.full, loginType.family]);
}, [loginType]);
return (
<>
<AuthLayout slogan="Welcome to WrenchBoard">
<div className="w-full">
<div className="mb-12">
<div className="mb-5">
<Link to="#">
<img
src={WrenchBoard}
@@ -172,7 +212,7 @@ export default function Login() {
/>
</Link>
</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="content-wrapper login shadow-md w-full lg:max-w-[530px] 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="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]">
@@ -190,11 +230,11 @@ export default function Login() {
</div>
{/* switch login component */}
<div className="flex justify-start items-end">
<div className="ml-7 flex justify-start items-center gap-3">
<button
name="full"
className={`px-2 py-1 w-[100px] text-left h-[40px] text-lg font-bold text-[#4687ba] hover:text-[#009ef7] tracking-wide transition outline-none border-2 border-b-0 border-r-0 border-[#4687ba] ${
loginType.full && "border-r-2 h-[45px]"
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]"
}`}
onClick={handleLoginType}
>
@@ -202,12 +242,12 @@ export default function Login() {
</button>
<button
name="family"
className={`px-2 py-1 w-[100px] text-left h-[40px] text-lg font-bold text-[#4687ba] hover:text-[#009ef7] tracking-wide transition outline-none border-2 border-b-0 border-l-0 border-[#4687ba] ${
loginType.family && "border-l-2 h-[45px]"
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]"
}`}
onClick={handleLoginType}
>
Family
Family Account
</button>
</div>
@@ -215,16 +255,16 @@ export default function Login() {
{/* for login component */}
{
loginType.full ? (
loginType == 'full' ? (
//user login component
<div className="p-2 input-area border-2 border-[#4687ba]">
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
<div className="input-item mb-5">
<InputCom
labelClass="tracking-wider"
fieldClass="sm:px-6 px-2"
value={email}
inputHandler={handleEmail}
placeholder="support@mermsemr.com"
placeholder="Your Email"
label="Email"
name="email"
type="email"
@@ -235,14 +275,15 @@ export default function Login() {
<div className="input-item mb-5">
<InputCom
labelClass="tracking-wider"
fieldClass="sm:px-6 px-2"
value={password}
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
value={password.replace(/./g, "●")}
inputHandler={handlePassword}
placeholder="● ● ● ● ● ●"
label="Password"
name="password"
type="password"
iconName="password"
type={showPassword ? "text" : "password"}
onClick={togglePasswordVisibility}
passIcon={showPassword ? "password" : "password"}
forgotPassword
/>
</div>
@@ -266,7 +307,7 @@ export default function Login() {
<div className="signin-area mb-3.5">
<div className="flex justify-center">
<button
name="loginfull"
name="full"
onClick={doLogin}
type="button"
disabled={loginLoading}
@@ -280,43 +321,51 @@ 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="#" imgSrc={appleLogo} brand="Apple" />
<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="#"
imgSrc={facebookLogo}
brand="Facebook"
/>
<BrandBtn
link="#"
imgSrc={linkedInLogo}
brand="LinkedIn"
/>
<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>
) : (
// END of user login compoenent
// family login compoenent
<div className="p-2 input-area border-2 border-[#4687ba]">
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
<div className="input-item mb-5">
<InputCom
labelClass="tracking-wider"
fieldClass="px-6"
value={email}
inputHandler={handleEmail}
placeholder="support@mermsemr.com"
placeholder="Account ID"
label="Username"
name="email"
type="email"
iconName="message"
iconName="family-id"
/>
</div>
@@ -329,9 +378,9 @@ export default function Login() {
placeholder="● ● ● ● ● ●"
label="Pin"
name="password"
type="password"
iconName="password"
// forgotPassword
type={showPassword ? "text" : "password"}
onClick={togglePasswordVisibility}
passIcon={showPassword ? "family-pin" : "family-pin"}
/>
</div>
{loginError && (
@@ -354,7 +403,7 @@ export default function Login() {
<div className="signin-area mb-1.5">
<div className="flex justify-center">
<button
name="loginfamily"
name="family"
onClick={doLogin}
disabled={loginLoading}
type="button"
@@ -386,7 +435,7 @@ export default function Login() {
);
}
const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
// const doGoogle = async () => {
// alert("start google");
// };
@@ -405,10 +454,23 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
// const doFacebook = async () => {
// alert("start facebook");
// };
return (
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
<button
{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>
)
:
(
<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"
@@ -418,6 +480,9 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
Continue with {brand}
</span>
</button>
)
}
</div>
);
)
};
+158 -197
View File
@@ -4,6 +4,7 @@ import facebookLogo from "../../../assets/images/facebook-4.svg";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout";
export default function SignUp() {
const [signUpLoading, setSignUpLoading] = useState(false);
@@ -64,6 +65,19 @@ export default function SignUp() {
last_name !== "" &&
country !== ""
) {
//checks if email is a valid email address
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)
}
//checks if terms and condition is checked
if (!checked) {
setMsgError("Terms and condition required");
return setTimeout(()=>{setMsgError("");},3000)
}
setSignUpLoading(true);
const reqData = {
country: country,
@@ -80,8 +94,8 @@ export default function SignUp() {
if (res.status === 200) {
const { data } = res;
if (data.status === -1 && data.acc === "DULPICATE") {
setMsgError("This account has been already created");
if (data && data.acc === "DULPICATE") {
setMsgError("Unable to use this username. Please try another username.");
setSignUpLoading(false);
}
if (data && data.status === "1") {
@@ -108,216 +122,163 @@ export default function SignUp() {
useEffect(() => {
getCountryList();
});
}, []);
return (
<>
<div className="layout-wrapper login">
<div className="main-wrapper w-full xl:h-screen h-full xl:py-10 py-12 overflow-y-auto">
<div className=" h-full">
<div className="flex-1 flex justify-center items-center">
<div className="w-full">
<div className="mb-12">
<Link to="#">
<img
src={WrenchBoard}
alt="wrenchboard"
className="h-10 mx-auto"
/>
<AuthLayout slogan="Welcome to WrenchBoard">
<div className="w-full">
<div className="mb-5">
<Link to="#">
<img
src={WrenchBoard}
alt="wrenchboard"
className="h-10 mx-auto"
/>
</Link>
</div>
<div className="content-wrapper login relative shadow-md w-full lg:max-w-[530px] 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 mb-0">
<div>
<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]">
Create Account
</h1>
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
Already have an account?{" "}
<Link
to="/login"
className="font-semibold text-[#4687ba] hover:text-[#009ef7] transition"
>
Sign in here
</Link>
</span>
</div>
<div className="w-full flex items-center gap-2">
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
<span className="text-[#b5b5c3] font-medium text-[0.7rem] w-[2%]">
OR
</span>
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
</div>
<div className="input-area">
<SelectOption
label="Country"
data={countries}
name="country"
value={formData.country}
inputHandler={handleInputChange}
/>
<div className="input-fl-name mb-5 sm:flex w-full sm:space-x-6 ">
<div className="input-item sm:w-1/2 w-full mb-5 sm:mb-0">
<InputCom
fieldClass="px-6"
placeholder="Firstname"
label="First Name"
name="first_name"
type="text"
value={formData.first_name}
inputHandler={handleInputChange}
/>
</div>
<div className="input-item flex-1">
<InputCom
fieldClass="px-6"
placeholder="Lastname"
label="Last Name"
name="last_name"
type="text"
value={formData.last_name}
inputHandler={handleInputChange}
/>
</div>
</div>
<div className="content-wrapper login shadow-md w-full lg:max-w-[600px] 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 mb-7">
<div>
<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]">
Create Account
</h1>
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
Already have an account?{" "}
<Link
to="/login"
className="font-semibold text-[#4687ba] hover:text-[#009ef7] transition"
<div className="input-item mb-5">
<InputCom
fieldClass="px-6"
placeholder="support@mermsemr.com"
label="Email"
name="email"
type="email"
value={formData.email}
inputHandler={handleInputChange}
/>
</div>
<div className="input-item mb-5">
<InputCom
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"
}
value={formData.password.replace(/./g, "●")}
inputHandler={handleInputChange}
/>
</div>
{msgError && (
<div className="p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">
{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">
<button
onClick={rememberMe}
type="button"
className="w-6 h-6 bg-[#4687ba] text-white flex justify-center items-center border border-light-gray rounded-[.45em]"
>
{checked && (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
Sign in here
</Link>
</span>
</div>
<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]"
>
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>
<div className="signin-area mb-1">
<div className="flex justify-center">
<button
type="button"
className={`rounded-[0.475rem] w-full mb-6 text-[15px] h-[42px] 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]`}
onClick={handleSignUp}
className={`rounded-[0.475rem] mb-6 text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
>
<img
className="mr-3 h-6"
src={facebookLogo}
alt="logo-icon(s)"
/>
Sign in with Facebook
</button>
<div className="w-full flex items-center gap-2">
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
<span className="text-[#b5b5c3] font-medium text-[0.7rem] w-[2%]">
OR
</span>
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
</div>
<div className="input-area">
<SelectOption
label="Country"
data={countries}
name="country"
value={formData.country}
inputHandler={handleInputChange}
/>
<div className="input-fl-name mb-5 sm:flex w-full sm:space-x-6 ">
<div className="input-item sm:w-1/2 w-full mb-5 sm:mb-0">
<InputCom
fieldClass="px-6"
placeholder="Firstname"
label="First Name"
name="first_name"
type="text"
value={formData.first_name}
inputHandler={handleInputChange}
/>
</div>
<div className="input-item flex-1">
<InputCom
fieldClass="px-6"
placeholder="Lastname"
label="Last Name"
name="last_name"
type="text"
value={formData.last_name}
inputHandler={handleInputChange}
/>
</div>
</div>
<div className="input-item mb-5">
<InputCom
fieldClass="px-6"
placeholder="support@mermsemr.com"
label="Email"
name="email"
type="email"
value={formData.email}
inputHandler={handleInputChange}
/>
</div>
<div className="input-item mb-5">
<InputCom
fieldClass="px-6"
placeholder="● ● ● ● ● ●"
label="Password"
name="password"
type={showPassword ? "text" : "password"}
onClick={togglePasswordVisibility}
passIcon={
showPassword ? "show-password" : "hide-password"
}
value={formData.password}
inputHandler={handleInputChange}
/>
</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]">
{msgError}
</div>
{signUpLoading ? (
<div className="signup btn-loader"></div>
) : (
<span>Sign Up</span>
)}
<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}
type="button"
className="w-6 h-6 bg-[#4687ba] text-white flex justify-center items-center border border-light-gray rounded-[.45em]"
>
{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]"
>
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>
<div className="signin-area mb-1">
<div className="flex justify-center">
<button
type="button"
onClick={handleSignUp}
className={`rounded-[0.475rem] mb-6 text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
>
{signUpLoading ? (
<div className="signup btn-loader"></div>
) : (
<span>Sign Up</span>
)}
</button>
</div>
</div>
</div>
</button>
</div>
</div>
</div>
</div>
<div className="flex-1 flex justify-center items-center p-10">
<div className="flex items-center">
<a
href="https://www.wrenchboard.com/about-us"
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
target="_blank"
rel="noreferrer"
>
About
</a>
<a
href="https://www.wrenchboard.com/service"
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
target="_blank"
rel="noreferrer"
>
Services
</a>
<a
href="https://www.wrenchboard.com/contact"
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
target="_blank"
rel="noreferrer"
>
Contact Us
</a>
</div>
</div>
<div className="flex-1 flex justify-center items-center p-10">
<p className="text-black text-[15px] px-2 font-medium flex items-center">
<span className="text-3xl mt-2 mr-1">©</span> 2023 -{" "}
<Link to="/" className="text-[#009ef7] ml-1">
WrenchBoard
</Link>{" "}
</p>
</div>
</div>
</div>
</div>
</AuthLayout>
</>
);
}
@@ -343,7 +304,7 @@ const SelectOption = ({
<select
name={name}
id={name}
className="input-wrapper border border-[#f5f8fa]] dark:border-[#5e6278] w-full rounded-[0.475rem] 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 focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
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 focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
onChange={inputHandler}
value={value}
>
@@ -43,7 +43,7 @@ export default function CollectionTab({ className, products }) {
<DataIteration
datas={products}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products.length}
endLength={products?.length}
>
{({ datas }) => (
<CollectionCard key={datas.uniqKey} collectionData={datas} />
@@ -42,7 +42,9 @@ export default function CreateSaleSlider({
{/* heading */}
<div className="flex justify-between items-center mb-6">
<div>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Sell</h1>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
Create for Sell
</h1>
</div>
<div className="slider-btns flex space-x-4">
<button onClick={nextHandler} type="button">
@@ -89,7 +91,7 @@ export default function CreateSaleSlider({
<div className="trending-products relative w-full">
<SliderCom selector={trendingSlider} settings={settings}>
{products &&
products.length > 0 &&
products?.length > 0 &&
products.map((item) => (
<ProductCardStyleTwo
key={item.id}
@@ -49,7 +49,9 @@ export default function CreatedBidsSlider({
{/* heading */}
<div className="flex justify-between items-center mb-6">
<div>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Bits</h1>
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
Create for Bits
</h1>
</div>
<div className="slider-btns flex space-x-4">
<button onClick={nextHandler} type="button">
@@ -96,7 +98,7 @@ export default function CreatedBidsSlider({
<div className="trending-products relative w-full">
<SliderCom selector={trendingSlider} settings={settings}>
{products &&
products.length > 0 &&
products?.length > 0 &&
products.map((item) => (
<ProductCardStyleOne
key={item.id}
@@ -43,7 +43,7 @@ export default function OnSaleTab({ className, products }) {
<DataIteration
datas={products}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products.length}
endLength={products?.length}
>
{({ datas }) => (
<ProductCardStyleTwo key={datas.id} datas={datas} />
@@ -43,7 +43,7 @@ export default function OwnTab({ className, products }) {
<DataIteration
datas={products}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products.length}
endLength={products?.length}
>
{({ datas }) => (
<ProductCardStyleOne key={datas.id} datas={datas} />
@@ -86,11 +86,15 @@ export default function VerifyLink() {
const verifyRes = await userApi.verifyEmail(code);
if (verifyRes.status === 200) {
let { data } = verifyRes;
console.log('TESTING VERIFY',data)
if (
data &&
data.internal_return >= 0 &&
data.status_text === "Link Verfied"
data.internal_return >= 0 &&
data.status == 0 &&
data.pending_id != '' &&
data.pending_uid != '' &&
data.username != '' &&
data.status_text === "Link Verified"
) {
setPageLoader(false);
} else {
@@ -158,8 +158,8 @@ const SuccessfulComponent = ({
{/* INPUT */}
<div className="mb-5">
<InputCom
fieldClass="px-6"
value={password}
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
value={password?.replace(/./g, "●")}
inputHandler={handlePassword}
placeholder="● ● ● ● ● ●"
label="Password"
@@ -171,8 +171,8 @@ const SuccessfulComponent = ({
</div>
<div className="mb-5">
<InputCom
fieldClass="px-6"
value={confirmPassword}
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
value={confirmPassword?.replace(/./g, "●")}
inputHandler={handlePassword}
placeholder="● ● ● ● ● ●"
label="Confirm Password"
+1 -1
View File
@@ -31,7 +31,7 @@ export default function BlogItem(props) {
</div>
</div>
<div>
Blog Items Details
Blog Items Details need implenet
</div>
</div>
</div>
+143 -156
View File
@@ -9,163 +9,154 @@ export default function AvailableJobsCard({
className,
datas,
hidden = false,
contentDisplay
contentDisplay,
}) {
//debugger;
const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} });
const [manageInt, setManageInt] = useState(null);
const [imageUrl, setImageUrl] = useState("");
const navigate = useNavigate();
const apiCall = useMemo(() => new usersService(), []);
const marketInterestData = useCallback(async () => {
let { offer_code } = datas;
let reqData = { offer_code };
try {
const manageInt = await apiCall.MarketInterest(reqData);
const manageIntRes = await manageInt?.data;
setManageInt(manageIntRes);
} catch (error) {
throw new Error(error);
}
}, [apiCall, datas]);
let thePrice = PriceFormatter(
let thePrice = PriceFormatter(
datas?.price * 0.01,
datas?.currency_code,
datas?.currency
);
useEffect(() => {
if (!datas) {
navigate("/market", { replace: true });
}
marketInterestData();
}, []);
useEffect(() => {
const imagePath = require(`../../assets/images/${datas.thumbnil}`); // Replace with your directory path for local images
setImageUrl(imagePath);
}, []);
return (
<>
{contentDisplay == 'grid' ?
<div
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
className || ""
}`}
>
<div className="flex flex-col justify-between w-full h-full">
<Link to="/shop-details" className="mb-2.5">
{contentDisplay == "grid" ? (
<div
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
className || ""
}`}
>
<div
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
className="flex flex-col justify-between w-full h-full"
>
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{datas.title}
</h1>
</Link>
<div className="card-two-info flex justify-between items-center">
<div className="owned-by flex space-x-2 items-center">
<div>
<p className="text-thin-light-gray text-sm leading-3">Added</p>
<p className="text-base text-dark-gray dark:text-white">
{datas.offer_added}
</p>
</div>
</div>
<div className="w-[1px] bg-light-purple dark:bg-dark-light-purple h-7"></div>
<div className="created-by flex space-x-2 items-center flex-row-reverse">
<div>
<p className="text-thin-light-gray text-sm leading-3 text-right">
Expires
</p>
<p className="text-base text-dark-gray dark:text-white text-right">
{datas.expire}
</p>
</div>
</div>
</div>
<div className="thumbnail-area w-full">
<div
className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-center bg-cover bg-no-repeat"
style={{
backgroundImage: `url('${imageUrl}')`,
}}
>
<div className="flex justify-center">{datas.description}</div>
</div>
</div>
<div className="details-area">
<div className="product-two-options flex justify-between mb-5 relative">
{/* <div className="status">*/}
{/* {datas.isActive && (*/}
{/* <span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">*/}
{/* Active*/}
{/*</span>*/}
{/* )}*/}
{/* </div>*/}
{/*<div className=" review flex space-x-2">*/}
{/* <button*/}
{/* onClick={favoriteHandler}*/}
{/* type="button"*/}
{/* className={`w-7 h-7 bg-white rounded-full flex justify-center items-center ${*/}
{/* addFavorite ? "text-red-500" : "text-thin-light-gray"*/}
{/* }`}*/}
{/* >*/}
{/* <Icons name="star" />*/}
{/* </button>*/}
{/*</div>*/}
</div>
<div className="flex justify-between">
<div className="flex items-center space-x-2">
<div className="card-two-info flex justify-between items-center">
<div className="owned-by flex space-x-2 items-center">
<div>
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
{/* {thePrice} | {datas.timeline_days} day(s) */}
{thePrice}
<p className="text-thin-light-gray text-sm leading-3">
Added
</p>
<p className="text-sm text-lighter-gray">
( {datas.offer_code}) |
<span className="italic ml-1">
{datas.timeline_days} day(s)
</span>
<p className="text-base text-dark-gray dark:text-white">
{datas.offer_added}
</p>
</div>
</div>
<div>
<button
type="button"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
>
View
</button>
<div className="w-[1px] bg-light-purple dark:bg-dark-light-purple h-7"></div>
<div className="created-by flex space-x-2 items-center flex-row-reverse">
<div>
<p className="text-thin-light-gray text-sm leading-3 text-right">
Expires
</p>
<p className="text-base text-dark-gray dark:text-white text-right">
{datas.expire}
</p>
</div>
</div>
</div>
<div className="thumbnail-area w-full">
<div
className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-center bg-cover bg-no-repeat"
style={{
backgroundImage: `url('${imageUrl}')`,
}}
>
<div className="flex justify-center">{datas.description}</div>
</div>
</div>
<div className="details-area">
<div className="product-two-options flex justify-between mb-5 relative">
{/* <div className="status">*/}
{/* {datas.isActive && (*/}
{/* <span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">*/}
{/* Active*/}
{/*</span>*/}
{/* )}*/}
{/* </div>*/}
{/*<div className=" review flex space-x-2">*/}
{/* <button*/}
{/* onClick={favoriteHandler}*/}
{/* type="button"*/}
{/* className={`w-7 h-7 bg-white rounded-full flex justify-center items-center ${*/}
{/* addFavorite ? "text-red-500" : "text-thin-light-gray"*/}
{/* }`}*/}
{/* >*/}
{/* <Icons name="star" />*/}
{/* </button>*/}
{/*</div>*/}
</div>
<div className="flex justify-between">
<div className="flex items-center space-x-2">
<div>
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
{/* {thePrice} | {datas.timeline_days} day(s) */}
{thePrice}
</p>
<p className="text-sm text-lighter-gray">
( {datas.offer_code}) |
<span className="italic ml-1">
{datas.timeline_days} day(s)
</span>
</p>
</div>
</div>
<div>
<button
type="button"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
>
View
</button>
</div>
</div>
</div>
</div>
</div>
</div>
:
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
<div className="flex gap-5 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] max-w-[60px]">
<img src={dataImage2} alt="data" className="w-full h-full" />
</div>
<div className="flex flex-col flex-[0.9]">
<Link to="/shop-details" className="">
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
) : (
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
<div className="flex gap-5 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] max-w-[60px]">
<img src={dataImage2} alt="data" className="w-full h-full" />
</div>
<div className="flex flex-col flex-[0.9]">
<h1
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize"
>
{datas?.title}
</h1>
</Link>
<div className="my-2">
<p className="text-dark-gray dark:text-white">{datas?.description}</p>
</div>
<div
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
className="my-2"
>
<p className="text-dark-gray dark:text-white">
{datas?.description}
</p>
</div>
{/* <div className="card-two-info flex gap-2 items-center">
{/* <div className="card-two-info flex gap-2 items-center">
<div className="owned-by flex space-x-2 items-center">
<div>
<p className="text-thin-light-gray text-sm leading-3">Added</p>
@@ -186,40 +177,37 @@ export default function AvailableJobsCard({
</div>
</div>
</div> */}
<div className="block sm:flex flex-wrap gap-4">
<p className="text-sm text-thin-light-gray flex flext-start gap-1">
Price: <span className="text-purple">{thePrice}</span>
</p>
<p className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple italic">
{" "}
{datas?.timeline_days} day(s)
</span>
</p>
<p className="text-sm text-thin-light-gray">
Code:{" "}
<span className="text-purple">
{" "}
{datas?.offer_code}
</span>
</p>
<div className="block sm:flex flex-wrap gap-4">
<p className="text-sm text-thin-light-gray flex flext-start gap-1">
Price: <span className="text-purple">{thePrice}</span>
</p>
<p className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple italic">
{" "}
{datas?.timeline_days} day(s)
</span>
</p>
<p className="text-sm text-thin-light-gray">
Code:{" "}
<span className="text-purple"> {datas?.offer_code}</span>
</p>
</div>
</div>
</div>
<div className="">
<button
type="button"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
>
View
</button>
</div>
</div>
<div className="">
<button
type="button"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
>
View
</button>
</div>
</div>
}
)}
{marketPopUp.show && (
<MarketPopUp
details={datas}
@@ -227,7 +215,6 @@ export default function AvailableJobsCard({
setMarketPopUp({ show: false, data: {} });
}}
situation={marketPopUp.show}
marketInt={manageInt}
/>
)}
</>
@@ -0,0 +1,120 @@
import { useState } from "react";
import { Link, useLocation } from "react-router-dom";
import { toast } from "react-toastify";
import localImgLoad from "../../lib/localImgLoad";
import CountDown from "../Helpers/CountDown";
import Icons from "../Helpers/Icons";
export default function FamilyActiveJobsCard({ datas, hidden = false }) {
let { pathname } = useLocation();
const [imageUrl, setImageUrl] = useState("");
const [addFavorite, setValue] = useState(false);
const [options, setOption] = useState(false);
const favoriteHandler = () => {
if (!addFavorite) {
setValue(true);
toast.success("Added to Favorite List");
} else {
setValue(false);
toast.warn("Remove to Favorite List");
}
};
//debugger;
const bannerName = datas.banner == null ?'default.jpg':datas.banner;
return (
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
<div className="content">
{/* thumbnail */}
<div className="w-full h-40">
{/* thumbnail image */}
<div
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
style={{
background: `url(${localImgLoad(
`images/taskbanners/${bannerName}`
)}) center / contain no-repeat`,
}}
>
{/* <div className="product-options flex justify-between relative">*/}
{/*<span*/}
{/* onClick={favoriteHandler}*/}
{/* className={`w-7 h-7 bg-white rounded-full flex justify-center items-center cursor-pointer ${*/}
{/* addFavorite ? "text-pink" : " text-dark-gray"*/}
{/* }`}*/}
{/*>*/}
{/* <Icons name="love" />*/}
{/*</span>*/}
{/* <span*/}
{/* onClick={() => setOption(!options)}*/}
{/* className="w-7 h-7 flex justify-center items-center bg-white rounded-full cursor-pointer"*/}
{/* >*/}
{/* <Icons name="dots" />*/}
{/*</span>*/}
{/* {options && (*/}
{/* <div*/}
{/* onClick={() => setOption(!options)}*/}
{/* className="w-full h-screen fixed top-0 left-0 z-10"*/}
{/* ></div>*/}
{/* )}*/}
{/* <div*/}
{/* style={{ boxShadow: "0px 4px 87px 0px #0000002B" }}*/}
{/* className={`drop-down-content w-[80px] bg-white dark:bg-dark-white rounded-[4px] p-2.5 absolute right-0 top-[100%] z-20 ${*/}
{/* options ? "active" : ""*/}
{/* }`}*/}
{/* >*/}
{/* </div>*/}
{/* </div>*/}
{hidden && (
<div className="flex justify-center">
</div>
)}
</div>
</div>
{/* details */}
<div className="details">
{/* product title */}
<Link
to="/manage-active-job"
state={{ ...datas, pathname }}
className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1"
>
{datas.title}
</Link>
{/* countdown */}
<div className="w-full h-[54px] flex justify-evenly items-center p-2 rounded-lg border border-[#E3E4FE] dark:border-[#a7a9b533] ">
<div className="flex flex-col justify-between">
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
Task Code
</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
{datas.contract}
</p>
</div>
<div className="w-[1px] h-full bg-[#E3E4FE] dark:bg-[#a7a9b533] "></div>
<div className="flex flex-col justify-between">
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
Remaining Time
</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
<CountDown lastDate={datas.delivery_date} />
</p>
</div>
</div>
</div>
</div>
<div className="card-buttons flex justify-end items-center space-x-2">
<Link
to="/manage-active-job"
state={{ ...datas, pathname }}
className="btn-shine w-[98px] h-[33px] text-white rounded-full text-sm bg-pink flex justify-center items-center"
>
View
</Link>
</div>
</div>
);
}
+78
View File
@@ -0,0 +1,78 @@
import { useState } from "react";
import SuggestTask from "../FamilyPopup/SuggestTask";
export default function FamilyMarketCard({ className, datas, hidden = false }) {
// debugger;
const [popUp, setPopUp] = useState(false);
const popUpHandler = () => {
setPopUp((prev) => !prev);
};
// Image
let selectedImage = require(`../../assets/images/family/${
datas.banner || "default.jpg"
}`);
return (
<>
<div
className={`card-style-two w-full h-[336px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
className || ""
}`}
key={datas?.uid}
>
<div className="flex flex-col justify-between w-full h-full">
<div className="thumbnail-area w-full">
<div
className="w-full h-[236px] p-6 rounded-xl overflow-hidden"
onClick={popUpHandler}
style={{
// background: `url(${selectedImage}) 0% 0% / cover no-repeat`,
background: `url(${selectedImage}) center / contain no-repeat`,
}}
>
<div className="product-two-options flex justify-between mb-5 relative">
<div className="status">
{/* <span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">
Active
</span> */}
</div>
</div>
{hidden && <div className="flex justify-center"></div>}
</div>
</div>
<div className="details-area mt-12 flex justify-between items-center gap-2">
{/* title */}
<button onClick={popUpHandler}>
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{datas?.title}
</h1>
</button>
<div className="flex justify-between">
{/* <div className="flex items-center space-x-2">
<p className="italic text-gray-400">
{getTimeAgo(datas?.added)}
</p>
</div> */}
<div>
<button
type="button"
onClick={popUpHandler}
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
>
View
</button>
</div>
</div>
</div>
</div>
</div>
{popUp && (
<SuggestTask
onClose={popUpHandler}
situation={popUp}
details={{ ...datas, selectedImage }}
/>
)}
</>
);
}
+10 -10
View File
@@ -17,26 +17,26 @@ export default function HomeBannerOffersCard(props) {
return (
<Link
to={link_result}
className="item w-full block group banner-630-340 bg-cover bg-center"
className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center"
style={{
backgroundImage: `url('${imageUrl}')`,
}}
>
<div className="flex flex-col justify-between h-full">
<div className="content flex justify-between items-center mb-5">
<div className="siderCardHeader">
<h1 className="text-2xl font-bold text-dark-gray dark:text-white tracking-wide">
<div className="w-[80%] h-full mx-auto flex flex-col justify-between">
<div className="content flex justify-between items-center">
<div className="mb-2">
<h1 className="text-2xl lg:text-4xl font-bold text-dark-gray dark:text-white tracking-wide">
<span className="heroSilderTitle">{props.itemData.title}</span>
</h1>
</div>
</div>
<div className="h-[233px]">
<div className="siderCardDescription">
<div className="flex flex-col justify-around items-center flex-1">
<div className="siderCardDescription mb-2">
{props.itemData.description}
</div>
<div className="siderCardButton">
[ {props.itemData.button_text} ]
</div>
<button className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
{props.itemData.button_text}
</button>
</div>
</div>
</Link>
+108
View File
@@ -0,0 +1,108 @@
import localImgLoad from "../../lib/localImgLoad";
import CountDown from "../Helpers/CountDown";
import { PriceFormatter } from "../Helpers/PriceFormatter";
export default function OfferCard({ datas, hidden = false, setOfferPopout }) {
let thePrice = PriceFormatter(
datas?.price * 0.01,
datas?.currency_code,
datas?.currency
);
return (
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
<div className="content">
{/* thumbnail */}
<div className="w-full h-40">
{/* thumbnail image */}
<div
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
style={{
background: `url(${localImgLoad(
`images/taskbanners/${datas.banner}`
)}) center / contain no-repeat`,
}}
>
{hidden && <div className="flex justify-center"></div>}
</div>
</div>
{/* details */}
<div className="details">
<h1 className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
{datas.title}
</h1>
{/* countdown */}
{/* <div className="w-full h-[54px] flex justify-evenly items-center p-2 rounded-lg border border-[#E3E4FE] dark:border-[#a7a9b533] ">
<div className="flex flex-col justify-between">
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
Task Code
</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
{datas.contract}
</p>
</div>
<div className="w-[1px] h-full bg-[#E3E4FE] dark:bg-[#a7a9b533] "></div>
<div className="flex flex-col justify-between">
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
Remaining Time
</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
<CountDown lastDate={datas.expire} />
</p>
</div>
</div> */}
<div className="w-full p-2 rounded-lg border border-[#E3E4FE] dark:border-[#a7a9b533] ">
<div className="grid grid-cols-2 gap-2">
<div className="flex flex-col justify-between items-center border-r-2">
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
Task Code
</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
{datas.contract}
</p>
</div>
<div className="flex flex-col justify-between items-center">
<p className="text-sm text-red-500 tracking-wide">Expires</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
<CountDown lastDate={datas.expire} />
</p>
</div>
</div>
<hr className="my-2" />
<div className="grid grid-cols-2 gap-2">
<div className="flex flex-col justify-between items-center border-r-2">
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
Reward
</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
{thePrice}
</p>
</div>
<div className="flex flex-col justify-between items-center">
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
Timeline
</p>
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
{`${datas.timeline_days} day(s)`}
</p>
</div>
</div>
</div>
</div>
</div>
<div className="card-buttons flex justify-end items-center space-x-2">
<button
type="button"
onClick={() =>
setOfferPopout({ show: true, data: { ...datas, thePrice } })
}
className="btn-shine w-[98px] h-[33px] text-white rounded-full text-sm bg-pink flex justify-center items-center"
>
Start Task
</button>
</div>
</div>
);
}
+4 -1
View File
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import { useState } from "react";
import { Link } from "react-router-dom";
import { toast } from "react-toastify";
import localImgLoad from "../../lib/localImgLoad";
@@ -6,6 +6,7 @@ import CountDown from "../Helpers/CountDown";
import Icons from "../Helpers/Icons";
export default function ProductCardStyleOne({ datas, hidden = false }) {
const [imageUrl, setImageUrl] = useState("");
const [addFavorite, setValue] = useState(false);
const [options, setOption] = useState(false);
const favoriteHandler = () => {
@@ -17,6 +18,8 @@ export default function ProductCardStyleOne({ datas, hidden = false }) {
toast.warn("Remove to Favorite List");
}
};
return (
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
<div className="content">
+75
View File
@@ -0,0 +1,75 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import { toast } from "react-toastify";
export default function ProductCardStyleTwo({
className,
datas,
hidden = false,
bg
}) {
// debugger;
const [addFavorite, setValue] = useState(datas.whishlisted);
const [options, setOption] = useState(false);
const favoriteHandler = () => {
if (!addFavorite) {
setValue(true);
toast.success("Added to Favorite List");
} else {
setValue(false);
toast.warn("Remove to Favorite List");
}
};
return (
<div
className={`card-style-two w-full h-[336px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
className || ""
}`}
>
<div className="flex flex-col justify-between w-full h-full">
<div className="thumbnail-area w-full">
<div
className="w-full h-[236px] p-6 rounded-xl overflow-hidden"
style={{
// background: `url(${`https://blog.wrenchboard.com/wp-content/uploads/${datas.meta_value}`}) 0% 0% / cover no-repeat`,
background: `url(${`${bg}${datas.meta_value}`}) 0% 0% / cover no-repeat`,
}}
>
<div className="product-two-options flex justify-between mb-5 relative">
<div className="status">
{datas?.isActive && (
<span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">
Active
</span>
)}
</div>
</div>
{hidden && <div className="flex justify-center"></div>}
</div>
</div>
<div className="details-area">
{/* title */}
<a href={datas.guid} target="_blank" 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>
<div className="flex justify-between">
<div className="flex items-center space-x-2"></div>
<div className="my-1">
<a
href={datas.guid}
target="_blank"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
rel="noreferrer"
>
View
</a>
</div>
</div>
</div>
</div>
</div>
);
}
+4 -3
View File
@@ -1,8 +1,8 @@
import React, { useState, useEffect } from "react";
import Layout from "../Partials/Layout";
import FamilyManageTabs from "./Tabs/FamilyManageTabs";
import React, { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import FamilyManageTabs from "./FamilyManageTabs";
export default function FamilyManage() {
const [selectTab, setValue] = useState("today");
@@ -11,6 +11,7 @@ export default function FamilyManage() {
let location = useLocation();
let navigate = useNavigate();
let accountDetails = location?.state;
// tab handler
const filterHandler = (value) => {
setValue(value);
@@ -0,0 +1,292 @@
import React, {
Suspense,
lazy,
useCallback,
useEffect,
useMemo,
useRef,
useState,
useTransition,
} from "react";
import { useReactToPrint } from "react-to-print";
import profile from "../../assets/images/profile-info-profile.png";
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"));
const FamilyAccount = lazy(() => import("./Tabs/FamilyAccount"));
const FamilyProfile = lazy(() => import("./Tabs/FamilyProfile"));
const FamilyTasks = lazy(() => import("./Tabs/FamilyTasks"));
const ProfileInfo = lazy(() => import("./Tabs/ProfileInfo"));
const FamilyPending = lazy(() => import("./Tabs/FamilyPending"));
export default function FamilyManageTabs({
className,
accountDetails,
listReload,
loader,
}) {
const [details, setDetails] = useState({
familyDetails: { loading: false, data: null },
familyTasks: { loading: false, data: null },
familyWaitList: { loading: false, data: null },
familyPending: { loading: false, data: null },
});
const [errMsg, setErrMsg] = useState("");
const [familyTaskPopout, setFamilyTaskPopout] = useState(false);
const [profileImg, setProfileImg] = useState(profile);
const profileImgInput = useRef(null);
const [isPending, startTransition] = useTransition();
const apiCall = useMemo(() => new usersService(), []);
const familyPopUpHandler = () => {
setFamilyTaskPopout((prev) => !prev);
};
const browseProfileImg = () => {
profileImgInput.current.click();
};
const profileImgChangeHandler = (e) => {
if (e.target.value !== "") {
const imgReader = new FileReader();
imgReader.onload = (event) => {
setProfileImg(event.target.result);
};
imgReader.readAsDataURL(e.target.files[0]);
}
};
const manageFamily = useCallback(async () => {
try {
setDetails((prevDetails) => ({
...prevDetails,
familyDetails: { loading: true },
familyTasks: { loading: true },
familyWaitList: { loading: true },
familyPending: { loading: true },
}));
const { family_uid } = accountDetails;
const reqData = { family_uid };
const [familyRes, tasksRes, familyWaitRes, familyPending] =
await Promise.all([
apiCall.ManageFamily(reqData),
apiCall.ManageTasks(reqData),
apiCall.ManageFamilyWaitlist(),
apiCall.ManageFamilyPending(),
]);
const familyData = familyRes.data;
const tasksData = tasksRes.data;
const familyWaitData = familyWaitRes.data;
const familyPendingData = familyPending.data;
if (
familyData?.internal_return < 0 ||
tasksData?.internal_return < 0 ||
familyWaitData?.internal_return < 0 ||
familyPendingData?.internal_return < 0
) {
return;
}
startTransition(() => {
setDetails({
familyDetails: { loading: false, data: familyData },
familyTasks: { loading: false, data: tasksData },
familyWaitList: { loading: false, data: familyWaitData },
familyPending: { loading: false, data: familyPendingData },
});
});
} catch (error) {
setDetails((prevDetails) => ({
...prevDetails,
familyDetails: { loading: false },
familyTasks: { loading: false },
familyWaitList: { loading: false },
familyPending: { loading: false },
}));
setErrMsg("An error occurred");
throw new Error(error);
}
}, [apiCall, accountDetails]);
const accountRef = useRef();
const useHandlePrint = useReactToPrint({
content: () => accountRef.current,
});
const tabs = [
{ id: 1, name: "Tasks" },
{ id: 2, name: "Waiting" },
{ id: 3, name: "Pending" },
];
const [tab, setTab] = useState(tabs[0].name);
const tabHandler = (value) => {
startTransition(() => {
setTab(value);
});
};
const tabComponents = {
Tasks: (
<FamilyTasks
className={className}
loader={details.familyTasks.loading}
familyData={details.familyTasks.data}
accountDetails={accountDetails}
/>
),
Waiting: (
<FamilyWaitlist
familyData={details.familyWaitList.data}
accountDetails={accountDetails}
loader={details.familyWaitList.loading}
/>
),
Pending: (
<FamilyPending
familyData={details.familyPending.data}
accountDetails={accountDetails}
loader={details.familyWaitList.loading}
/>
),
Account: (
<FamilyAccount
familyData={details.familyDetails.data}
myRef={accountRef}
loader={details.familyDetails.loading}
handlePrint={useHandlePrint}
/>
),
Profile: <FamilyProfile />,
};
const defaultTabComponent = (
<FamilyTasks
className={className}
loader={details.familyTasks.loading}
familyData={details.familyTasks.data}
accountDetails={accountDetails}
/>
);
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
useEffect(() => {
let __manageFamily = true;
if (__manageFamily) {
manageFamily();
}
return () => {
__manageFamily = false;
};
}, [tab, manageFamily]);
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 || ""
}`}
>
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<Suspense
fallback={
<div className="h-full min-h-[500px] 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="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between">
<ProfileInfo
profileImg={profileImg}
profileImgInput={profileImgInput}
profileImgChangeHandler={profileImgChangeHandler}
browseProfileImg={browseProfileImg}
accountDetails={accountDetails}
/>
<div className="mt-4 flex justify-start items-center gap-2">
<button
onClick={() => tabHandler("Account")}
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
>
<img
src={localImgLoad("images/icons/account.svg")}
className="max-w-[30px] w-full"
alt="Settings-Icon"
/>
<p className="text-lg text-sky-blue">Acc.</p>
</button>
<button
onClick={() => tabHandler("Profile")}
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
>
<img
src={localImgLoad("images/icons/profile.svg")}
className="max-w-[30px] w-full"
alt="Settings-Icon"
/>
<p className="text-lg text-sky-blue">Profile</p>
</button>
</div>
</div>
<div className="col-span-3 justify-self-end 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">
{tabs.map(({ name, id }) => (
<li
onClick={() => tabHandler(name)}
className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl relative top-[2px] ${
tab === name
? "text-purple border-r"
: "text-thin-light-gray"
}`}
key={id}
>
<h1>{name}</h1>
</li>
))}
</ul>
<button
type="button"
onClick={familyPopUpHandler}
className="p-1 my-1 w-[100px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
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">
<Suspense
fallback={<LoadingSpinner size="16" color="sky-blue" />}
>
{selectedTabComponent}
</Suspense>
</div>
</div>
</div>
</div>
</div>
</Suspense>
</div>
{familyTaskPopout && (
<AssignTaskPopout
action={familyPopUpHandler}
situation={familyTaskPopout}
familyDetails={details.familyDetails.data}
/>
)}
</div>
);
}
+95
View File
@@ -0,0 +1,95 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import Layout from "../Partials/Layout";
import SearchCom from "../Helpers/SearchCom";
import FamilyMarketCard from "../Cards/FamilyMarketCard";
import usersService from "../../services/UsersService";
import SuggestTask from "../FamilyPopup/SuggestTask";
export default function FamilyMarket() {
const [popUp, setPopUp] = useState(false);
const [searchQuery, setSearchQuery] = useState("");
const [myFamilySampleTasks, setMyFamilySampleTasks] = useState({
loading: true,
status: false,
data: [],
});
const apiCall = useMemo(() => new usersService(), []);
const getMyFamilySampleTasks = useCallback(async () => {
try {
setMyFamilySampleTasks({ loading: true, status: false, data: [] });
const res = await apiCall.getFamilySampleTasks();
setMyFamilySampleTasks({
loading: false,
status: true,
data: res.data.result_list,
});
} catch (error) {
setMyFamilySampleTasks({ loading: false, status: false, data: [] });
console.log("Error getting tasks:", error);
}
}, [apiCall]);
useEffect(() => {
getMyFamilySampleTasks();
}, [getMyFamilySampleTasks]);
const handleSearch = (event) => {
setSearchQuery(event.target.value);
};
const filteredTasks =
myFamilySampleTasks.data?.filter((task) =>
task.title.toLowerCase().includes(searchQuery.toLowerCase())
) || [];
const popUpHandler = () => {
setPopUp((prev) => !prev);
};
return (
<Layout>
<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 inline-flex gap-3 text-dark-gray dark:text-white items-center">
<span>Suggest Task to the Parents</span>
</h1>
</div>
</div>
{/* Body */}
<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
placeholder="Search for tasks..."
handleSearch={handleSearch}
value={searchQuery}
/>
</div>
{/* filer-dropdown */}
<div className="flex-1 flex sm:justify-end">
<button
onClick={popUpHandler}
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
>
Any Other Task
</button>
</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]">
{filteredTasks.map((task) => (
<FamilyMarketCard key={task.id} datas={task} />
))}
</div>
</div>
</div>
</div>
{popUp && <SuggestTask onClose={popUpHandler} situation={popUp} />}
</Layout>
);
}
@@ -0,0 +1,441 @@
import React, { useState, useEffect, useTransition } from "react";
import ModalCom from "../../Helpers/ModalCom";
import Detail from "../../jobPopout/popoutcomponent/Detail";
import usersService from "../../../services/UsersService";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import { NewTasks } from "./forms";
const AssignTaskPopout = React.memo(({ action, details, situation, familyDetails }) => {
const apiCall = new usersService();
let [requestStatus, setRequestStatus] = useState({
loading: false,
status: false,
message: "",
}); // HOLDS RESPONSE FOR SENDING API REQUEST
let [familyTask, setFamilyTask] = useState({ loading: false, data: [] });
let [taskType, setTaskType] = useState(details ? "new" : "select"); // SWITCHES BTW SELECT TASK AND NEW TASK
let [activeTask, setActiveTask] = useState({ id: 0, data: {} }); // HOLDS SELECTED TASK
const switchTaskType = ({ target: { value } }) => {
// FUNCTION TO CHANGE SELECTED ACTIVE TASK
setTaskType(value);
};
const handleActiveTask = (id = 0, data = {}) => {
// FUNCTION TO CHANGE SELECTED ACTIVE TASK
setActiveTask({ id, data });
};
// New Task
const [formState, setFormState] = useState({
// Initialize form state with desired fields
banner: details?.banner || "default.jpg",
country: details?.country || "",
price: details?.price || "",
title: details?.title || "",
description: details?.description || "",
job_detail: details?.job_detail || "",
timeline_days: details?.timeline_days || "",
category: details?.category || "",
});
const assignFamilyTask = () => {
setRequestStatus({ loading: true, status: false, message: "" });
let reqData = {};
if (taskType == "select") {
// RUNS HERE IF TASK TYPE IS SELECT
if (!Object.keys(activeTask.data).length) {
setRequestStatus({
loading: false,
status: false,
message: "No Task is seleted",
});
return setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
}, 3000);
}
reqData = {
// API PAYLOADS
job_id: activeTask.data?.job_id,
job_uid: activeTask.data?.job_uid,
family_uid: familyDetails?.uid || details?.family_uid,
job_description: activeTask.data?.description,
assign_mode: 110011,
};
}
if (taskType === "new") {
const {
banner,
category,
country,
description,
job_detail,
price,
timeline_days,
title,
} = formState;
const requiredFields = {
banner,
// category,
country,
description,
job_detail,
price,
timeline_days,
title,
};
for (let field in requiredFields) {
if (requiredFields[field] == "") {
// let currencyErrMsg = field == "country" && "currency"
setRequestStatus({
loading: false,
status: false,
message: `${field} is empty`,
});
return setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
}, 3000);
}
}
reqData = {
banner,
category,
country,
description,
job_detail,
price: price * 100,
timeline_days,
title,
assign_mode: 110055,
family_uid: details?.family_uid || familyDetails?.uid,
};
}
apiCall
.assignFamilyTask(reqData)
.then((res) => {
if (res.status != 200 || res.data.internal_return < 0) {
setRequestStatus({
loading: false,
status: false,
message: "failed to assign task",
});
return setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
}, 5000);
}
setRequestStatus({
loading: false,
status: true,
message: "action successful",
});
setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
action(); // FUNCTION THAT CLOSES THE MODAL BOX
}, 5000);
})
.catch((err) => {
setRequestStatus({
loading: false,
status: false,
message: "An Error occured, try again",
});
setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
}, 5000);
});
};
useEffect(() => {
let checkFamilyTask = true;
const reqData = {
limit: 30,
offset: 0,
job_type: "FAMILY",
action: 13005,
};
apiCall
.getMyJobList(reqData)
.then((res) => {
if (checkFamilyTask) {
setFamilyTask({ loading: false, data: res?.data?.result_list });
if (res?.data?.result_list?.length) {
setActiveTask((prev) => ({
...prev,
data: res?.data?.result_list[0],
}));
}
}
})
.catch((err) => {
setFamilyTask({ loading: false, data: [] });
console.log("Error", err);
});
return () => {
checkFamilyTask = false;
};
}, []);
return (
<>
<ModalCom
action={action}
situation={situation}
className="assign-task-popup"
>
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="w-full flex items-center justify-between lg:px-10 lg:py-8 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">
Assign task to {familyDetails?.firstname || details.firstName}
</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>
{familyTask.loading ? (
<div className="h-[100px] w-full flex justify-center items-center">
<LoadingSpinner color="sky-blue" size="16" />
</div>
) : (
<>
<div
className={`job-action-modal-body w-full md:grid ${
taskType !== "new" ? "md:grid-cols-2" : "md:grid-cols-1"
}`}
>
<div className="p-4">
<div className="mb-2 w-full flex items-center gap-4">
<div className="flex items-center gap-2 text-sky-blue text-base">
<input
type="radio"
name="task-type"
value="select"
className="w-[20px] h-[20px] cursor-pointer"
checked={taskType == "select"}
onChange={switchTaskType}
/>
<span>Select Task</span>
</div>
<div className="flex items-center gap-2 text-sky-blue text-base">
<input
type="radio"
name="task-type"
value="new"
className="w-[20px] h-[20px] cursor-pointer"
checked={taskType == "new"}
onChange={switchTaskType}
/>
<span>New Task</span>
</div>
</div>
{/* Task Type === select */}
{taskType == "select" && (
<div className="p-4 w-full h-[400px] overflow-y-auto bg-slate-100">
{familyTask?.data?.length ? (
familyTask?.data?.map((item, index) => (
<div
key={item.job_uid}
className="mb-2 flex justify-start items-center gap-2 text-sky-blue text-base cursor-pointer"
onClick={() => handleActiveTask(item.job_uid, item)}
>
<input
type="radio"
name="task-list"
checked={
activeTask.id == item.job_uid ||
(activeTask.id == index && true)
}
onChange={() =>
handleActiveTask(item.job_uid, item)
}
className="w-[15px] h-[15px] cursor-pointer"
/>
<p className="w-full text-dark-gray tracking-wide">
{item?.title}
</p>
</div>
))
) : (
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center cursor-default">
No Task found!
</p>
)}
</div>
)}
{taskType == "new" && (
<div className="p-4 w-full h-[400px]">
<NewTasks
formState={formState}
setFormState={setFormState}
/>
</div>
)}
</div>
{/*Right Hand Side for details && Task Type === select */}
{taskType == "select" && (
<>
{familyTask?.data?.length > 0 ? (
<div className="p-4">
<div className="w-full">
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">
{activeTask?.data?.title}
</p>
<div className="my-3">
<Detail
label="Description"
value={activeTask?.data?.description}
/>
</div>
<div className="flex items-center">
<div className="my-3 w-full flex items-center gap-1">
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
Price
</label>
<p className="p-1 text-sm text-slate-900 dark:text-white">
{PriceFormatter(
activeTask?.data?.price * 0.01,
activeTask?.data?.currency,
activeTask?.data?.curreny_code
)}
</p>
</div>
<div className="my-3 w-full flex items-center gap-1">
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
Timeline
</label>
<p className="p-1 text-sm text-slate-900 dark:text-white">{`${activeTask?.data?.timeline_days} day(s)`}</p>
</div>
</div>
<div className="my-3 sm:flex items-center">
<Detail
label="Created"
value={`Dummy, no value found for created!`}
/>
</div>
<div className="my-3">
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
Delivery Detail
</label>
<textarea
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
rows="5"
style={{ resize: "none" }}
value={activeTask?.data?.job_detail}
readOnly
// onChange={handleInputChange}
/>
</div>
</div>
</div>
) : (
<></>
)}
</>
)}
</div>
{/* BTN */}
<div className="py-2 px-4 border-t-2 flex justify-between items-center">
{/* error or success display */}
<div className="w-auto h-auto flex items-center">
{requestStatus.message != "" &&
(!requestStatus.status ? (
<div
className={`relative p-2 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px] self-start`}
>
{requestStatus.message}
</div>
) : (
requestStatus.status && (
<div
className={`relative p-2 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
)
))}
</div>
{/* End of error or success display */}
<div className="w-auto h-auto flex items-center gap-3">
<button
disabled={requestStatus.loading}
onClick={action}
type="button"
className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white cursor-pointer"
>
<span className="text-gradient">Close</span>
</button>
<div className="">
{requestStatus.loading ? (
<LoadingSpinner color="sky-blue" size="8" />
) : taskType == "select" ? (
<button
type="button"
disabled={requestStatus.loading}
onClick={assignFamilyTask}
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
>
Assign
</button>
) : (
<button
type="button"
disabled={requestStatus.loading}
onClick={assignFamilyTask}
className="px-1 w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
>
{`Assign to ${
familyDetails?.firstname || details?.firstName
}`}
</button>
)}
</div>
</div>
</div>
</>
)}
</div>
</ModalCom>
</>
);
})
export default AssignTaskPopout;
@@ -0,0 +1,232 @@
import React, { useEffect, useState } from "react";
import usersService from "../../../../services/UsersService";
import InputCom from "../../../Helpers/Inputs/InputCom";
export default function NewTasks({ formState, setFormState }) {
let [currency, setCurrency] = useState({
loading: true,
status: false,
data: null,
});
const selectImage = require(`../../../../assets/images/taskbanners/${
formState.banner || "default.jpg"
}`);
const ApiCall = new usersService();
// FUNCTION TO GET Currency
const getUserCurrency = () => {
setCurrency((prev) => ({ ...prev, loading: true }));
ApiCall.getUserWallets()
.then((res) => {
if (res.data.internal_return < 0) {
setCurrency({ loading: false, status: true, data: [] });
return;
}
setCurrency({
loading: false,
status: true,
data: res.data.result_list,
});
})
.catch((err) => {
setCurrency({ loading: false, status: false, data: [] });
});
};
const handleInputChange = (event) => {
const { name, value } = event.target;
setFormState((prevState) => ({
...prevState,
[name]: value,
}));
};
useEffect(() => {
getUserCurrency();
}, []);
return (
<form className="w-full flex justify-between items-start">
<div className="flex flex-col gap-3 max-w-[77%]">
{/* inputs starts here */}
<div className="grid md:grid-cols-3 grid-cols-1 gap-6 mb-[5px]">
{/* Currency */}
<div className="field w-full mb-6 xl:mb-0">
<label
htmlFor="country"
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex item-center gap-1"
>
Currency
{/* {props.errors.country && props.touched.country && <span className="text-[12px] text-red-500">{props.errors.country}</span>} */}
</label>
<select
id="country"
name="country"
value={formState.country}
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
onChange={handleInputChange}
// onBlur={props.handleBlur}
>
{currency.loading ? (
<option className="text-slate-500 text-[13.975px]" value="">
Loading...
</option>
) : currency.data.length ? (
<>
<option className="text-slate-500 text-[13.975px]" value="">
Currency
</option>
{currency.data?.map((item, index) => (
<option
key={index}
className="text-slate-500 text-lg"
value={item?.country}
>
{item?.description}
</option>
))}
</>
) : (
<option className="text-slate-500 text-lg" value="">
No Options Found! Try Again
</option>
)}
</select>
</div>
{/* Price */}
<div className="field w-full">
<InputCom
fieldClass="px-6 text-right"
label="Price"
labelClass="tracking-wide"
inputBg="bg-slate-100"
type="number"
name="price"
placeholder="0"
value={formState.price}
inputHandler={handleInputChange}
// blurHandler={props.handleBlur}
// error={props.errors.price && props.touched.price && props.errors.price}
/>
</div>
{/* Duration */}
<div className="field w-full mb-6 xl:mb-0">
<label
htmlFor="timeline_days"
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex item-center gap-1"
>
Timeline
{/* {props.errors.country && props.touched.country && <span className="text-[12px] text-red-500">{props.errors.country}</span>} */}
</label>
<select
id="timeline_days"
name="timeline_days"
value={formState.timeline_days}
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
onChange={handleInputChange}
// onBlur={props.handleBlur}
>
{publicArray.length && (
<>
<option className="text-slate-500 text-[13.975px]" value="">
Duration
</option>
{publicArray.map(({ name, duration }, idx) => (
<option
className="text-slate-500 text-[13.975px]"
value={duration}
>
{name}
</option>
))}
</>
)}
</select>
</div>
</div>
{/* Title */}
<div className="field w-full mb-[5px]">
<InputCom
fieldClass="px-6"
label="Title"
labelClass="tracking-wide"
inputBg="bg-slate-100"
type="text"
name="title"
value={formState.title}
inputHandler={handleInputChange}
// blurHandler={props.handleBlur}
// error={props.errors.title && props.touched.title && props.errors.title}
/>
</div>
{/* Description */}
<div className="field w-full mb-[5px]">
<InputCom
fieldClass="px-6"
label="Description"
labelClass="tracking-wide"
inputBg="bg-slate-100"
type="text"
name="description"
value={formState.description}
inputHandler={handleInputChange}
// blurHandler={props.handleBlur}
// error={props.errors.description && props.touched.description && props.errors.description}
/>
</div>
{/* Details */}
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
<div className="w-full">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1'
>
Job Delivery Details
{/* {props.errors.job_detail && props.touched.job_detail && <span className="text-[12px] text-red-500">{props.errors.job_detail}</span>} */}
</label>
<textarea
id="Job Delivery Details"
rows="5"
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px]`}
style={{ resize: "none" }}
name="job_detail"
value={formState.job_detail}
onChange={handleInputChange}
// onBlur={props.handleBlur}
/>
</div>
</div>
</div>
{/* Banner Image */}
<div className="max-w-[20%] w-full">
<div className="h-32 w-full">
<img
src={selectImage}
alt="task_banner_img"
className="w-full h-full object-contain"
/>
</div>
</div>
</form>
);
}
const publicArray = [
{ duration: 1, name: "1 day" },
{ duration: 2, name: "2 days" },
{ duration: 3, name: "3 days" },
{ duration: 4, name: "4 days" },
{ duration: 5, name: "5 days" },
{ duration: 6, name: "6 days" },
{ duration: 7, name: "1 week" },
{ duration: 14, name: "2 weeks" },
{ duration: 21, name: "3 weeks" },
{ duration: 28, name: "4 weeks" },
];
@@ -0,0 +1,3 @@
import NewTasks from "./NewTasks";
export {NewTasks}
+6 -6
View File
@@ -1,17 +1,15 @@
import React, { useState } from "react";
import dataImage1 from "../../assets/images/data-table-user-1.png";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useNavigate, useLocation, Link } from "react-router-dom";
import { useNavigate } from "react-router-dom";
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 filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
const navigate = useNavigate();
// let location = useLocation();
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
@@ -57,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];
@@ -67,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"
/>
@@ -0,0 +1,56 @@
import { forwardRef } from "react";
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"
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 ">
<div className="flex items-center justify-around h-[380px]">
<div className="flex flex-col">
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
Username:{" "}
<span className="ml-2 normal-case">
{familyData?.username ? familyData?.username : "please wait..."}
</span>
</h2>
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
Pin:{" "}
<span className="ml-2 normal-case">
{familyData?.pin ? familyData?.pin : "please wait..."}
</span>
</h2>
</div>
<span className="text-5xl text-gray-400 opacity-20 font-bold">
or
</span>
<div className="max-w-[200px]">
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
Scan the code from mobile app
</p>
<QRCode
size={256}
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
value={`https://www.google.com`}
viewBox={`0 0 256 256`}
/>
</div>
</div>
<div className="h-[50px] w-full flex justify-center items-center">
<button
className="btn-shine w-[116px] h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center"
onClick={handlePrint}
>
Print
</button>
</div>
</div>
</div>
);
});
export default FamilyAccount;
@@ -1,312 +0,0 @@
import React, {
Suspense,
forwardRef,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import QRCode from "react-qr-code";
import { useReactToPrint } from "react-to-print";
import usersService from "../../../services/UsersService";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import profile from "../../../assets/images/profile-info-profile.png";
import FamilyTasks from "./FamilyTasks";
export default function FamilyManageTabs({
className,
accountDetails,
listReload,
loader,
}) {
const [details, setDetails] = useState({
familyDetails: {
loading: false,
data: null,
},
familyTasks: {
loading: false,
data: null,
},
});
const [errMsg, setErrMsg] = useState("");
// List of tabs
const tabs = [
{
id: 1,
name: "Tasks",
},
{
id: 2,
name: "Account",
},
{
id: 3,
name: "Profile",
},
];
const [tab, setTab] = useState(tabs[0].name);
const tabHandler = (value) => {
setTab(value);
};
// For profile uploads
const [profileImg, setProfileImg] = useState(profile);
// profile img
const profileImgInput = useRef(null);
const browseProfileImg = () => {
profileImgInput.current.click();
};
const profileImgChangHandler = (e) => {
if (e.target.value !== "") {
const imgReader = new FileReader();
imgReader.onload = (event) => {
setProfileImg(event.target.result);
};
imgReader.readAsDataURL(e.target.files[0]);
}
};
// Api call
const apiCall = useMemo(() => new usersService(), []);
// function for manage family
const manageFamily = useCallback(async () => {
try {
setDetails({
familyDetails: { loading: true },
familyTasks: { loading: true },
});
let { family_uid } = accountDetails;
let reqData = { family_uid };
// the family response
const familyRes = await apiCall.ManageFamily(reqData);
const familyData = familyRes.data;
// the tasks response
const tasksRes = await apiCall.ManageTasks(reqData);
const tasksData = tasksRes.data;
// checking the internal return
if (familyData?.internal_return < 0 || tasksData?.internal_return < 0)
return;
setDetails({
familyDetails: { loading: false, data: familyData },
familyTasks: { loading: false, data: tasksData },
});
} catch (error) {
setDetails({
familyDetails: { loading: false },
familyTasks: { loading: false },
});
setErrMsg("An error occurred");
throw new Error(error);
}
}, [apiCall, accountDetails]);
useEffect(() => {
manageFamily();
}, [tab, manageFamily]);
const accountRef = useRef();
// to handle printing
const useHandlePrint = useReactToPrint({
content: () => accountRef.current,
});
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 || ""
}`}
>
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<Suspense
fallback={
<div className="h-full min-h-[500px] 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="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full">
<ProfileInfo
profileImg={profileImg}
profileImgInput={profileImgInput}
profileImgChangHandler={profileImgChangHandler}
browseProfileImg={browseProfileImg}
accountDetails={accountDetails}
/>
</div>
<div className="col-span-3 justify-self-end h-full w-full">
<div className="flex flex-col w-full">
<ul className="flex-[0.1] flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
{tabs.map(({ name, id }) => (
<li
onClick={() => tabHandler(name)}
className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl ${
tab === name
? "text-purple border-r"
: " text-thin-light-gray"
}`}
key={id}
>
<h1>{name}</h1>
</li>
))}
</ul>
<div className="flex-[0.9] lg:min-h-[450px] h-full">
{/* Your content here */}
{tabs.map(({ name, id }) => {
return (
<div
className={`${
tab === name ? "block" : "hidden"
} h-full p-4 border border-[#dbd9d9] relative overflow-y-auto`}
key={id}
>
{name === "Tasks" && (
<FamilyTasks
className={className}
loader={details.familyTasks.loading}
familyData={details.familyTasks.data}
/>
)}
{name === "Account" && (
<Account
familyData={details.familyDetails.data}
myRef={accountRef}
loader={details.familyDetails.loading}
handlePrint={useHandlePrint}
/>
)}
{name === "Profile" && <Profile />}
</div>
);
})}
</div>
</div>
</div>
</div>
</Suspense>
</div>
</div>
);
}
function ProfileInfo({
profileImg,
profileImgInput,
profileImgChangHandler,
browseProfileImg,
accountDetails,
}) {
return (
<div className="flex flex-col items-center gap-6">
<div className="flex justify-center">
<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"
/>
<input
ref={profileImgInput}
onChange={(e) => profileImgChangHandler(e)}
type="file"
className="hidden"
/>
<div
onClick={browseProfileImg}
className="w-[32px] h-[32px] absolute bottom-7 sm:right-2 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
fill="white"
/>
<path
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
fill="white"
/>
</svg>
</div>
</div>
</div>
<div className="flex flex-col justify-center gap-3 items-center">
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{accountDetails?.firstname}
</h1>
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{accountDetails?.lastname}
</h1>
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{accountDetails?.age}
</h1>
</div>
</div>
);
}
const Account = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
return (
<div
className="w-full lg:min-h-[500px] 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 ">
<div className="flex items-center justify-around h-[380px]">
<div className="flex flex-col">
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
Username:{" "}
<span className="ml-2 normal-case">
{familyData?.username ? familyData?.username : "please wait..."}
</span>
</h2>
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
Pin:{" "}
<span className="ml-2 normal-case">
{familyData?.pin ? familyData?.pin : "please wait..."}
</span>
</h2>
</div>
<span className="text-5xl text-gray-400 opacity-20 font-bold">
or
</span>
<div className="max-w-[200px]">
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
Scan the code from mobile app
</p>
<QRCode
size={256}
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
value={`https://www.google.com`}
viewBox={`0 0 256 256`}
/>
</div>
</div>
<div className="h-[50px] w-full flex justify-center items-center">
<button
className="btn-shine w-[116px] h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center"
onClick={handlePrint}
>
Print
</button>
</div>
</div>
</div>
);
});
function Profile() {
return <>Profile</>;
}
@@ -0,0 +1,162 @@
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";
export default function FamilyPending({
familyData,
className,
accountDetails,
loader,
}) {
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
let filteredFamilyData = useMemo(
() =>
familyData?.result_list?.filter(
(data) => data?.family_uid === accountDetails?.family_uid
),
[accountDetails?.family_uid, familyData?.result_list]
);
const [currentPage, setCurrentPage] = useState(0);
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentPendingTasks = filteredFamilyData?.slice(
indexOfFirstItem,
indexOfLastItem
);
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
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 || ""
}`}
>
{filteredFamilyData && (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{
<>
{currentPendingTasks.length > 0 ? (
currentPendingTasks.map((value, index) => {
let deliveryDate = value?.expire?.split(" ")[0];
let thePrice = PriceFormatter(
value?.price * 0.01,
value?.currency_code,
value?.currency
);
let image = value.banner ? value.banner : "default.jpg";
return (
<tr
key={index}
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 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}`
)}
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">
{value.title}
</h1>
<div>{value.description}</div>
<span className="text-sm text-thin-light-gray flex items-start gap-1">
Price:{" "}
<span className="text-purple">
{thePrice}
</span>
</span>
<div className="flex items-center gap-4">
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
</span>
</span>
<span className="text-sm text-thin-light-gray">
Expire:{" "}
<span className="text-purple">
{" "}
{deliveryDate}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Sent to:{" "}
<span className="text-purple">
{" "}
{value.job_to}
</span>
</span>
</div>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
onClick={() => {
setJobPopout({ show: true, data: value });
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
View
</button>
</td>
</tr>
);
})
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Pending Task!</td>
</tr>
)}
</>
}
</tbody>
</table>
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0}
next={currentPage + itemsPerPage >= filteredFamilyData.length}
data={filteredFamilyData}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
)}
{/* Active Job Popout */}
{jobPopout.show && (
<PendingJobsPopout
details={jobPopout.data}
onClose={() => {
setJobPopout({ show: false, data: {} });
}}
situation={jobPopout.show}
/>
)}
{/* End of Active Job Popout */}
</div>
);
}
@@ -0,0 +1,3 @@
export default function FamilyProfile() {
return <>Profile</>;
}
+11 -8
View File
@@ -6,8 +6,12 @@ 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 }) {
export default function FamilyTasks({ familyData, className, loader, accountDetails }) {
let navigate = useNavigate();
let { pathname } = useLocation();
@@ -34,7 +38,6 @@ export default function FamilyTasks({ familyData, className, loader }) {
</div>
) : (
<>
{" "}
{familyData && familyData?.result_list && (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
@@ -53,6 +56,7 @@ export default function FamilyTasks({ familyData, className, loader }) {
value?.currency_code,
value?.currency
);
let image = value.banner ? value.banner : 'default.jpg'
return (
<tr
key={index}
@@ -60,11 +64,11 @@ export default function FamilyTasks({ familyData, className, loader }) {
>
<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] max-w-[60px] min-w-[60px]">
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage2}
src={localImgLoad(`images/taskbanners/${image}`)}
alt="data"
className="w-full h-full"
className="w-full h-full rounded-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
@@ -105,9 +109,8 @@ export default function FamilyTasks({ familyData, className, loader }) {
state: {
...value,
pathname,
dueDate,
thePrice,
},
accountDetails
}
});
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
@@ -0,0 +1,152 @@
import { memo, useMemo, useState } from "react";
import SuggestTask from "../../FamilyPopup/SuggestTask";
import { PaginatedList, handlePagingFunc } from "../../Pagination";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import AssignTaskPopout from "../FamilyPopout/AssignTaskPopout";
const FamilyWaitlist = memo(
({ familyData, className, accountDetails, loader }) => {
const [popUp, setPopUp] = useState({ show: false, data: {} });
const [continueTaskPopup, setContinueTaskPopup] = useState({
show: false,
data: {},
});
const filteredFamilyData = useMemo(
() =>
familyData?.result_list?.filter(
(data) => data?.family_uid === accountDetails?.family_uid
),
[familyData, accountDetails]
);
const [currentPage, setCurrentPage] = useState(0);
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
const indexOfFirstItem = currentPage;
const indexOfLastItem = currentPage + itemsPerPage;
const currentTask = useMemo(
() => filteredFamilyData?.slice(indexOfFirstItem, indexOfLastItem),
[filteredFamilyData, indexOfFirstItem, indexOfLastItem]
);
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
const openPopUp = (value) => {
setPopUp({ show: true, data: { ...value } });
};
const closePopUp = () => {
setPopUp({ show: false, data: {} });
};
const openContinueTaskPopup = (value) => {
setContinueTaskPopup({ show: true, data: { ...value } });
};
const closeContinueTaskPopup = () => {
setContinueTaskPopup({ show: false, data: {} });
};
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 || ""
}`}
>
{loader ? (
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
<LoadingSpinner size={16} color="sky-blue" />
</div>
) : (
<>
{filteredFamilyData && (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{currentTask.map((value) => {
const addedDate = value?.added.split(" ")[0];
const selectedImage = require(`../../../assets/images/family/${
value?.banner || "default.jpg"
}`);
return (
<tr
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
key={value.uid}
>
<td className="py-4">
<div className="w-full flex justify-between items-center">
<div className="account-name flex space-x-4 items-center">
<div className="icon w-14 h-14 flex justify-center items-center">
<img
src={selectedImage}
alt="task_img"
className="w-full object-cover"
/>
</div>
<div className="">
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
{value.title}
</p>
<p className="text-sm text-thin-light-gray font-medium">
{value.description}
</p>
</div>
</div>
<div className="px-2 flex flex-col items-center justify-center">
<p className="text-sm font-bold text-dark-gray dark:text-white">
{addedDate}
</p>
<p className="text-xs py-1.5 w-[70px] cursor-default tracking-wide rounded-full bg-gold text-white flex justify-center items-center">
{value.status_text}
</p>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<button
onClick={() => openPopUp(value)}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
View
</button>
</td>
</tr>
);
})}
</tbody>
</table>
<PaginatedList
onClick={handlePagination}
prev={currentPage === 0}
next={
currentPage + itemsPerPage >= filteredFamilyData?.length
}
data={filteredFamilyData}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
</div>
)}
</>
)}
{popUp.show && (
<SuggestTask
details={popUp.data}
onClose={closePopUp}
continuePopupData={openContinueTaskPopup}
situation={popUp.show}
/>
)}
{continueTaskPopup.show && (
<AssignTaskPopout
details={continueTaskPopup.data}
action={closeContinueTaskPopup}
situation={continueTaskPopup.show}
/>
)}
</div>
);
}
);
export default FamilyWaitlist;
@@ -0,0 +1,63 @@
import React from "react";
import localImgLoad from "../../../lib/localImgLoad";
export default function ProfileInfo({
profileImg,
profileImgInput,
profileImgChangHandler,
browseProfileImg,
accountDetails,
}) {
return (
<div className="flex flex-col items-center gap-4">
<div className="flex justify-center">
<div className="w-full relative">
<img
src={localImgLoad(`images/icons/${accountDetails.banner}`)}
alt=""
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
/>
<input
ref={profileImgInput}
onChange={(e) => profileImgChangHandler(e)}
type="file"
className="hidden"
/>
<div
onClick={browseProfileImg}
className="w-[32px] h-[32px] absolute bottom-7 sm:right-2 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
fill="white"
/>
<path
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
fill="white"
/>
</svg>
</div>
</div>
</div>
<div className="flex flex-col justify-center gap-3 items-center">
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{accountDetails?.firstname}
</h1>
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{accountDetails?.lastname}
</h1>
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{accountDetails?.age}
</h1>
</div>
</div>
);
}
+15
View File
@@ -0,0 +1,15 @@
import FamilyAccount from "./FamilyAccount";
import FamilyProfile from "./FamilyProfile";
import FamilyTasks from "./FamilyTasks";
import FamilyWaitlist from "./FamilyWaitlist";
import FamilyPending from "./FamilyPending";
import ProfileInfo from "./ProfileInfo";
export {
FamilyAccount,
FamilyProfile,
FamilyTasks,
FamilyWaitlist,
FamilyPending,
ProfileInfo,
};

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