Compare commits
255 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bce00b5c0e | |||
| 312cd54f87 | |||
| a0c3437eae | |||
| 711226f913 | |||
| f46c6232b0 | |||
| 172f0ccbce | |||
| a2047cc2de | |||
| 6ea52e6481 | |||
| a7bbcfdc1b | |||
| ff28be3e70 | |||
| e91b4a4424 | |||
| 9960033b72 | |||
| ef135f1a9b | |||
| 1df6380c4a | |||
| fc8cf551e5 | |||
| b1feb0438a | |||
| a89649f774 | |||
| b96e8a3ed5 | |||
| f3226a6cfc | |||
| ff4c503100 | |||
| f543a2d893 | |||
| 41badd52be | |||
| eeddd4e0a5 | |||
| ee4d136834 | |||
| 283efa42b3 | |||
| 5cbab4933c | |||
| 4de2181c18 | |||
| c8f0161a29 | |||
| 60222b6d88 | |||
| 9ea3963239 | |||
| a87592623b | |||
| bfcf53f763 | |||
| df4489c6f2 | |||
| 37185812b4 | |||
| eb3e78244d | |||
| b302d7ba57 | |||
| d6c16169d9 | |||
| 57129da0bd | |||
| 9eaf7123d4 | |||
| 096da29149 | |||
| c8331c51cf | |||
| 3b7618702b | |||
| 84968b4435 | |||
| 98f11a3d80 | |||
| 98d734e869 | |||
| 47004fec8c | |||
| 48ce89489e | |||
| 1ce05a3be3 | |||
| 28ab1116e9 | |||
| 994060d929 | |||
| a5c62564b7 | |||
| 22e61d2b41 | |||
| 6ab5eae0c0 | |||
| 3fbb47ee82 | |||
| 3327b2b0df | |||
| ec204d0389 | |||
| cb1259d2c8 | |||
| 706cf141e7 | |||
| 2229ebb9a0 | |||
| 05022c29b2 | |||
| 9718cfc574 | |||
| aef082ac60 | |||
| 754340fcba | |||
| 16afd4f90c | |||
| b69e2ff53b | |||
| 4ac799f8c9 | |||
| c93d3b61a6 | |||
| 4fb6dbf30f | |||
| 11dc8fc659 | |||
| 4876ba80c1 | |||
| 71f799d157 | |||
| 77c538ca79 | |||
| 6b473b5dc6 | |||
| 6aa11793a5 | |||
| e098eb4626 | |||
| 4f8edc3998 | |||
| 7dd805b804 | |||
| 2aa1219ea9 | |||
| c1a17949f7 | |||
| 24302c7435 | |||
| 27f4fda129 | |||
| 7ddef6d52d | |||
| 187ac61396 | |||
| 31297efb5b | |||
| f8d6475ff8 | |||
| 22a45ac15e | |||
| 0489be5e69 | |||
| 0f8ef167bb | |||
| aa6e3f4b94 | |||
| 68beda891b | |||
| 61bef08a24 | |||
| a6409a037f | |||
| f3ab8241a3 | |||
| f3defdca85 | |||
| f3b1a42819 | |||
| e65d538709 | |||
| 98aef302de | |||
| b3bbf11f0a | |||
| 973517215f | |||
| a3782e2dfc | |||
| 25830d5bf3 | |||
| 1615a7ac8a | |||
| 232211a297 | |||
| eda3d76d4c | |||
| 87f1a1e3e8 | |||
| 5257f89acb | |||
| d4cf7419bf | |||
| 1ffb732bfa | |||
| 9007463f6d | |||
| a4b6b9e493 | |||
| ccf820da7c | |||
| 7c51896bbf | |||
| aa80bab930 | |||
| 1704fc60b4 | |||
| c3e6c90c49 | |||
| 1a65b1daa3 | |||
| ba2c009896 | |||
| bc2b71ecda | |||
| 1d315018a4 | |||
| 56f8b75525 | |||
| 59531df377 | |||
| 06a7386211 | |||
| 4bb3a11261 | |||
| f308eeca8d | |||
| 8e562ed1a5 | |||
| 23dd7571a3 | |||
| 8530b2d1a0 | |||
| acdbddbc79 | |||
| 15fc5f4f14 | |||
| 2ba3b01646 | |||
| 4e960a2f53 | |||
| ab700edcf2 | |||
| 42e80c7a11 | |||
| d4472a881a | |||
| 5d12ab4f62 | |||
| 8b3c586456 | |||
| e456b55e16 | |||
| 89c5936212 | |||
| 7bedf76945 | |||
| 54bf020c55 | |||
| 78145eee77 | |||
| d75b6ee26c | |||
| bf5c9d4671 | |||
| d2db38ba21 | |||
| eecbca6b0e | |||
| dd1430a350 | |||
| 0eca0c52ce | |||
| c2c7ad7bb4 | |||
| 98ccbce4c0 | |||
| 6484640e1a | |||
| ba3c4e1918 | |||
| fa4fe35bdf | |||
| c106e66f44 | |||
| 222c739663 | |||
| 96972dbe2f | |||
| 7146048aee | |||
| 39f1f5bc73 | |||
| fb7913c563 | |||
| feb301c3c0 | |||
| 752fc6a4a8 | |||
| 608d5b92f1 | |||
| 45563cc59b | |||
| b027e20c20 | |||
| bbe0777496 | |||
| 27efbe362b | |||
| 878539a56a | |||
| 6ae408029d | |||
| 8016d1bd12 | |||
| 0e9fef218f | |||
| 8116665045 | |||
| e4addc47d9 | |||
| 1682f11efd | |||
| 80b2abf9e3 | |||
| 5edecb6464 | |||
| 3a479b3573 | |||
| 4034909836 | |||
| 8fc61a6289 | |||
| 940a12a2e9 | |||
| a9f671eeaa | |||
| 481924fa02 | |||
| 6b712089d1 | |||
| 85ca2cb15a | |||
| d01c4928ff | |||
| b81e62988c | |||
| a8b63917fb | |||
| 9cf6d13716 | |||
| c1af2b7fc9 | |||
| 494c1f3271 | |||
| 9f0c33521f | |||
| 1d5875d4e2 | |||
| 6f6b12f4b5 | |||
| f3ad4d576e | |||
| e01d0106ad | |||
| 68472f8c66 | |||
| 8def463d80 | |||
| 0320999f72 | |||
| 78a97d8b0b | |||
| 6bf6c5d2d4 | |||
| 33284600e5 | |||
| 68bf995078 | |||
| fa05f47941 | |||
| 2391857309 | |||
| ed38cadcee | |||
| ea447a9366 | |||
| 4e2f120ab5 | |||
| 20ce9bf749 | |||
| 04e1bcc5f1 | |||
| cbaa8b6f7b | |||
| f6bdb1c299 | |||
| d4061d72da | |||
| 2d9a8b55b5 | |||
| 920eafed29 | |||
| 21d926eb5c | |||
| ec9d793d6b | |||
| 2fd04dc86d | |||
| d7752cb70b | |||
| dc592f60db | |||
| 675ba2989e | |||
| b201224fd6 | |||
| c24013eefd | |||
| 234f04ca8f | |||
| 5f222a2d88 | |||
| 258434a109 | |||
| ed148612a7 | |||
| 2287fb5ebb | |||
| 24545baad5 | |||
| ead7589c92 | |||
| 51bb8fc421 | |||
| d2166d9578 | |||
| c4872f522b | |||
| 0aef8c5e1e | |||
| 767b5c1b32 | |||
| 6fed51443d | |||
| 017ba7bd2f | |||
| 86d876b013 | |||
| fcd8898439 | |||
| 690f496807 | |||
| f804e13b56 | |||
| 5e248bc108 | |||
| 26647b088f | |||
| ae8ada33f4 | |||
| c31dab92e7 | |||
| c16764269e | |||
| afe6a1afcb | |||
| e98929627f | |||
| 3919a2bc4b | |||
| 93e89f996c | |||
| 7ede9883ba | |||
| 7edc7b08e5 | |||
| 7990959e9f | |||
| 6ead632c79 | |||
| 9c575716cd | |||
| cc93d5980d | |||
| e899e5eb2a | |||
| c53ee2833f |
@@ -42,8 +42,18 @@ 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_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_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||||
|
|
||||||
REACT_APP_FACEBOOK_CLIENT_ID=390204307987009
|
#Real Account
|
||||||
REACT_APP_FACEBOOK_CLIENT_SECRET=19f778e312f2ab96d147bacb612910c2
|
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
|
||||||
|
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
|
||||||
|
|
||||||
|
#development Account Social
|
||||||
|
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_CLIENT_SCOPE="email,public_profile"
|
||||||
REACT_APP_FACEBOOK_REDIRECT_URL="http://localhost:9082/login/auth/flogin"
|
REACT_APP_FACEBOOK_REDIRECT_URL="http://localhost:9082/login/auth/flogin"
|
||||||
|
|
||||||
@@ -58,6 +68,8 @@ REACT_APP_APPLE_REDIRECT_URL='http://localhost:9082/login/auth/apple'
|
|||||||
REACT_APP_MAX_FILE_SIZE=1000000
|
REACT_APP_MAX_FILE_SIZE=1000000
|
||||||
REACT_APP_TOTAL_NUM_FILE=4
|
REACT_APP_TOTAL_NUM_FILE=4
|
||||||
|
|
||||||
|
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||||
|
|
||||||
|
|
||||||
#apigate.lotus.g1.wrenchboard.com:76.209.103.227
|
#apigate.lotus.g1.wrenchboard.com:76.209.103.227
|
||||||
#apigate.orion.g1.wrenchboard.com:76.209.103.227
|
#apigate.orion.g1.wrenchboard.com:76.209.103.227
|
||||||
|
|||||||
@@ -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_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||||
|
|
||||||
REACT_APP_MAX_FILE_SIZE=1000000
|
REACT_APP_MAX_FILE_SIZE=1000000
|
||||||
REACT_APP_TOTAL_NUM_FILE=4
|
REACT_APP_TOTAL_NUM_FILE=4
|
||||||
|
|
||||||
|
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||||
@@ -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_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_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
|
DISABLE_ESLINT_PLUGIN=true
|
||||||
|
|
||||||
REACT_APP_MAX_FILE_SIZE=1000000
|
REACT_APP_MAX_FILE_SIZE=1000000
|
||||||
REACT_APP_TOTAL_NUM_FILE=4
|
REACT_APP_TOTAL_NUM_FILE=4
|
||||||
|
|
||||||
|
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"flutterwave-react-v3": "^1.3.0",
|
"flutterwave-react-v3": "^1.3.0",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-apple-login": "^1.1.6",
|
||||||
"react-chartjs-2": "^4.1.0",
|
"react-chartjs-2": "^4.1.0",
|
||||||
"react-countup": "^6.2.0",
|
"react-countup": "^6.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|||||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 713 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1 @@
|
|||||||
|
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 31 KiB |
@@ -56,6 +56,8 @@ export default function Routers() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
{/* guest routes */}
|
{/* guest routes */}
|
||||||
<Route exact path="/login" element={<LoginPage />} />
|
<Route exact path="/login" element={<LoginPage />} />
|
||||||
|
<Route exact path="/eoffer" element={<LoginPage />} />
|
||||||
|
|
||||||
<Route exact path="/signup" element={<SignupPage />} />
|
<Route exact path="/signup" element={<SignupPage />} />
|
||||||
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
||||||
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
||||||
|
|||||||
|
After Width: | Height: | Size: 172 KiB |
|
After Width: | Height: | Size: 215 B |
@@ -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 |
@@ -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 |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792" id="Bank"><path d="m896 78.526 896 358.4v119.466h-119.467q0 24.267-19.133 42-19.133 17.734-45.267 17.734H183.867q-26.134 0-45.267-17.734-19.133-17.733-19.133-42H0V436.926ZM238.933 675.859h238.934v716.8h119.466v-716.8h238.934v716.8h119.466v-716.8h238.934v716.8h119.466v-716.8h238.934v716.8h55.066q26.134 0 45.267 17.733 19.133 17.734 19.133 42v59.734H119.467v-59.734q0-24.266 19.133-42 19.133-17.733 45.267-17.733h55.066v-716.8zm1488.667 896q26.133 0 45.267 17.733 19.133 17.734 19.133 42v119.467H0v-119.467q0-24.266 19.133-42 19.134-17.733 45.267-17.733h1663.2z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 684 B |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 128 128" viewBox="0 0 128 128" id="Alert"><path fill="#f34093" d="M122.9,100.2L74.3,15.9c-4.6-7.9-16-7.9-20.6,0L5.1,100.2C0.5,108.1,6.2,118,15.4,118h97.3
|
||||||
|
C121.8,118,127.5,108.1,122.9,100.2z M63.9,101c-3.5-0.1-6.7-3.3-6.6-6.8c0.1-3.5,3.3-6.7,6.8-6.6c3.5,0.1,6.7,3.3,6.6,6.8
|
||||||
|
C70.6,98,67.4,101.1,63.9,101z M71.3,51.8c-0.7,7.8-1.5,15.6-2.3,23.4c-0.5,4.4-3.2,6.1-7.3,4.5c-1-0.4-2-2-2.2-3.2
|
||||||
|
C58.6,70,58,63.4,57.3,56.8c-0.3-2.8-0.5-5.6-0.8-8.5c-0.4-3.3,0.6-4.5,4-4.5c1.1,0,2.3,0,3.4,0C72,43.8,72,43.8,71.3,51.8z" class="color343433 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 621 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="Messages"><path fill="#4687ba" d="m447.372 413.112-17.544-52.629c-1-3.002-.674-6.23.775-9.043 13.184-25.615 18.629-55.858 12.925-87.736-8.746-48.868-44.53-89.475-90.943-105.048 11.976 28.924 15.628 61.084 9.645 92.984-12.155 64.837-64.074 116.246-129.191 127.924-8.429 1.512-16.945 2.248-25.396 2.463 19.776 21.336 46.173 36.503 75.619 41.784 31.682 5.682 61.784.393 87.322-12.594 2.802-1.425 6.007-1.742 8.99-.748l52.83 17.61c9.251 3.084 18.052-5.716 14.968-14.967z" class="color173042 svgShape"></path><path fill="#4687ba" d="M177.161 85.744C122.283 95.941 78.306 140.526 68.472 195.47c-5.704 31.878-.259 62.121 12.925 87.736 1.449 2.813 1.775 6.041.776 9.043l-17.545 52.629c-3.083 9.251 5.717 18.051 14.968 14.968l52.83-17.61c2.984-.994 6.19-.677 8.991.748 25.537 12.987 55.638 18.276 87.321 12.594 54.809-9.829 99.281-53.698 109.541-108.428 18.078-96.414-64.733-179.316-161.118-161.406zm34.938 177.536h-68.234c-6.73 0-12.185-5.454-12.185-12.185 0-6.73 5.455-12.185 12.185-12.185h68.234c6.731 0 12.185 5.455 12.185 12.185 0 6.731-5.454 12.185-12.185 12.185zm48.739-48.739H143.864c-6.73 0-12.185-5.454-12.185-12.185 0-6.73 5.455-12.185 12.185-12.185h116.973c6.731 0 12.185 5.455 12.185 12.185.001 6.731-5.453 12.185-12.184 12.185z" class="color173042 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="phone" x="0" y="0" version="1.1" viewBox="0 0 29 29" xml:space="preserve"><path d="M5.661 23.339c4.882 4.882 12.796 4.882 17.678 0 4.882-4.882 4.882-12.796 0-17.678s-12.796-4.882-17.678 0C.78 10.543.78 18.457 5.661 23.339zm5.545-16.613l1.86 1.86c.372.372.451.947.193 1.406l-.699 1.241a.781.781 0 0 0 .129.937l4.141 4.141a.781.781 0 0 0 .937.128l1.241-.699a1.173 1.173 0 0 1 1.406.193l1.861 1.861a1.175 1.175 0 0 1 0 1.66l-.881.881a3.135 3.135 0 0 1-3.786.493l-.084-.048a24.54 24.54 0 0 1-8.868-8.681l-.423-.706a3.128 3.128 0 0 1 .469-3.823l.844-.844a1.173 1.173 0 0 1 1.66 0z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 678 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 512 512" id="Sms"><circle cx="256" cy="256" r="256" fill="#4687ba" class="color00aebb svgShape"></circle><path fill="#ffffff" d="M256 129.3c-88.4 0-160 52-160 116.2 0 26.6 12.3 51.1 33 70.7-11.6 26.2-22.6 66.2-22.6 66.2 6.1 3.1 60.9-23.9 78.4-32.8 21.4 7.7 45.6 12.1 71.2 12.1 88.4 0 160-52 160-116.2s-71.6-116.2-160-116.2zm-59.2 148.9c-5.2 3.8-12 5.7-20.4 5.7-8.3 0-15.4-2.1-21.4-6.2-6-4.1-8.8-10.3-8.7-18.5l.1-.3h15c0 4.6 1.3 7.9 4 10.1 2.7 2.2 6.3 3.2 10.9 3.2 4.1 0 7.3-.9 9.5-2.6 2.2-1.7 3.3-4 3.3-6.9 0-3-1-5.3-3.1-7.1-2.1-1.8-5.7-3.5-10.9-5.1-8.9-2.7-15.6-5.8-20.3-9.5-4.6-3.6-6.9-8.6-6.9-14.9 0-6.3 2.6-11.5 7.8-15.5 5.2-4 11.8-6 19.9-6 8.5 0 15.4 2.2 20.6 6.5 5.2 4.3 7.7 10 7.5 16.9l-.1.3h-15c0-3.8-1.2-6.8-3.5-8.9-2.3-2.1-5.6-3.1-9.8-3.1-3.8 0-6.8.9-8.8 2.8-2.1 1.8-3.1 4.2-3.1 7 0 2.6 1.1 4.8 3.4 6.4 2.3 1.7 6.2 3.5 11.7 5.3 8.5 2.4 14.9 5.5 19.4 9.4 4.4 3.9 6.7 9 6.7 15.3-.1 6.7-2.7 11.9-7.8 15.7zm99.3 4.7h-15.5v-52.6l-.3-.1-19.1 52.7h-10.5l-19.1-52.8-.3.1v52.7h-15.5v-77.1h20.3l19.6 56.8h.3l19.8-56.8H296v77.1zm62.1-4.7c-5.2 3.8-12 5.7-20.4 5.7-8.3 0-15.4-2.1-21.4-6.2-5.9-4.1-8.8-10.3-8.7-18.5l.1-.3h15c0 4.6 1.3 7.9 4 10.1 2.7 2.2 6.3 3.2 10.9 3.2 4.1 0 7.3-.9 9.5-2.6 2.2-1.7 3.3-4 3.3-6.9 0-3-1-5.3-3.1-7.1-2.1-1.8-5.7-3.5-10.9-5.1-8.9-2.7-15.7-5.8-20.3-9.5-4.6-3.6-6.9-8.6-6.9-14.9 0-6.3 2.6-11.5 7.8-15.5 5.2-4 11.8-6 19.9-6 8.5 0 15.4 2.2 20.6 6.5 5.2 4.3 7.7 10 7.5 16.9l-.1.3h-15c0-3.8-1.2-6.8-3.5-8.9-2.3-2.1-5.6-3.1-9.8-3.1-3.8 0-6.8.9-8.8 2.8-2.1 1.8-3.1 4.2-3.1 7 0 2.6 1.1 4.8 3.4 6.4 2.3 1.7 6.2 3.5 11.7 5.3 8.5 2.4 14.9 5.5 19.4 9.4 4.4 3.9 6.7 9 6.7 15.3-.1 6.7-2.6 11.9-7.8 15.7z" class="colorffffff svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
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 |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 110 KiB |
@@ -20,10 +20,6 @@ function FbookRedirect() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log(codeResponse);
|
console.log(codeResponse);
|
||||||
|
|
||||||
setTimeout(()=>{ // remove LATER
|
|
||||||
navigate('/login', {state: {error: true}})
|
|
||||||
},2000)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
POST /token HTTP/1.1
|
POST /token HTTP/1.1
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||||
import AuthLayout from "../AuthLayout";
|
import AuthLayout from "../AuthLayout";
|
||||||
|
|||||||
@@ -1,26 +1,25 @@
|
|||||||
import React, { useEffect, useLayoutEffect, useState } from "react";
|
import React, { useEffect, useLayoutEffect, useState } from "react";
|
||||||
import { Link, useNavigate, useLocation } from "react-router-dom";
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import linkedInLogo from "../../../assets/images/Linkedin.png";
|
import linkedInLogo from "../../../assets/images/Linkedin.png";
|
||||||
import appleLogo from "../../../assets/images/apple-black.svg";
|
import appleLogo from "../../../assets/images/apple-black.svg";
|
||||||
import facebookLogo from "../../../assets/images/facebook-4.svg";
|
import facebookLogo from "../../../assets/images/facebook-4.svg";
|
||||||
import googleLogo from "../../../assets/images/google-logo.svg";
|
import googleLogo from "../../../assets/images/google-logo.svg";
|
||||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||||
import AuthLayout from "../AuthLayout";
|
import AuthLayout from "../AuthLayout";
|
||||||
// import { GoogleOAuthProvider } from '@react-oauth/google';
|
// import { GoogleOAuthProvider } from '@react-oauth/google';
|
||||||
import { googleLogout, useGoogleLogin } from "@react-oauth/google";
|
import { useGoogleLogin } from "@react-oauth/google";
|
||||||
|
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { updateUserDetails } from "../../../store/UserDetails";
|
import { updateUserDetails } from "../../../store/UserDetails";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const {state} = useLocation()
|
const { state } = useLocation();
|
||||||
|
|
||||||
let [loginType, setLoginType] = useState('');
|
let [loginType, setLoginType] = useState("");
|
||||||
|
|
||||||
const [checked, setValue] = useState(false);
|
|
||||||
const [loginLoading, setLoginLoading] = useState(false);
|
const [loginLoading, setLoginLoading] = useState(false);
|
||||||
|
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
@@ -30,12 +29,8 @@ export default function Login() {
|
|||||||
// for the catch error
|
// for the catch error
|
||||||
const [msgError, setMsgError] = useState("");
|
const [msgError, setMsgError] = useState("");
|
||||||
|
|
||||||
const rememberMe = () => {
|
// To Show and Hide Password
|
||||||
setValue(!checked);
|
const togglePasswordVisibility = () => {
|
||||||
};
|
|
||||||
|
|
||||||
// To Show and Hide Password
|
|
||||||
const togglePasswordVisibility = () => {
|
|
||||||
setShowPassword(!showPassword);
|
setShowPassword(!showPassword);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,7 +38,7 @@ export default function Login() {
|
|||||||
const handleLoginType = ({ target: { name } }) => {
|
const handleLoginType = ({ target: { name } }) => {
|
||||||
setLoginType(name);
|
setLoginType(name);
|
||||||
let currentDate = new Date();
|
let currentDate = new Date();
|
||||||
let expirationDate = new Date(currentDate.getTime() + (24 * 60 * 60 * 1000));
|
let expirationDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000);
|
||||||
// Convert the expiration date to the appropriate format
|
// Convert the expiration date to the appropriate format
|
||||||
let expirationDateString = expirationDate.toUTCString();
|
let expirationDateString = expirationDate.toUTCString();
|
||||||
document.cookie = `loginType=${name}; expires=${expirationDateString}; path=/;`;
|
document.cookie = `loginType=${name}; expires=${expirationDateString}; path=/;`;
|
||||||
@@ -83,7 +78,9 @@ export default function Login() {
|
|||||||
if (regEx.test(email) == false) {
|
if (regEx.test(email) == false) {
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
setMsgError("Invalid Email");
|
setMsgError("Invalid Email");
|
||||||
return setTimeout(()=>{setMsgError("");},3000)
|
return setTimeout(() => {
|
||||||
|
setMsgError("");
|
||||||
|
}, 3000);
|
||||||
}
|
}
|
||||||
// Post Data Info for normal Login
|
// Post Data Info for normal Login
|
||||||
postData = {
|
postData = {
|
||||||
@@ -113,7 +110,13 @@ export default function Login() {
|
|||||||
userApi
|
userApi
|
||||||
.logInUser(postData)
|
.logInUser(postData)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status != 200 || res.data.internal_return < 0 || !res.data.member_id || !res.data.uid || !res.data.session) {
|
if (
|
||||||
|
res.status != 200 ||
|
||||||
|
res.data.internal_return < 0 ||
|
||||||
|
!res.data.member_id ||
|
||||||
|
!res.data.uid ||
|
||||||
|
!res.data.session
|
||||||
|
) {
|
||||||
// setMsgError("Wrong, email/password");
|
// setMsgError("Wrong, email/password");
|
||||||
setLoginError(true);
|
setLoginError(true);
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
@@ -123,7 +126,7 @@ export default function Login() {
|
|||||||
localStorage.setItem("uid", `${res.data.uid}`);
|
localStorage.setItem("uid", `${res.data.uid}`);
|
||||||
localStorage.setItem("session_token", `${res.data.session}`);
|
localStorage.setItem("session_token", `${res.data.session}`);
|
||||||
// localStorage.setItem("session", `${res.data.session}`);
|
// localStorage.setItem("session", `${res.data.session}`);
|
||||||
dispatch(updateUserDetails({...res.data}));
|
dispatch(updateUserDetails({ ...res.data }));
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/", { replace: true });
|
navigate("/", { replace: true });
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
@@ -154,11 +157,12 @@ export default function Login() {
|
|||||||
|
|
||||||
// In order to update the selected login type whenever the component renders
|
// In order to update the selected login type whenever the component renders
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// Clear the loginType cookie if the user switches to loginfull
|
// Clear the loginType cookie if the user switches to loginfull
|
||||||
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
// }, []);
|
// }, []);
|
||||||
|
|
||||||
useLayoutEffect(()=>{ // checks the cookie in order to set the login type before components mounts
|
useLayoutEffect(() => {
|
||||||
|
// checks the cookie in order to set the login type before components mounts
|
||||||
// if(document.cookie.includes("loginType=family")){
|
// if(document.cookie.includes("loginType=family")){
|
||||||
// setLoginType('family')
|
// setLoginType('family')
|
||||||
// }else if(document.cookie.includes("loginType=full")){
|
// }else if(document.cookie.includes("loginType=full")){
|
||||||
@@ -166,33 +170,34 @@ export default function Login() {
|
|||||||
// }else{
|
// }else{
|
||||||
// setLoginType('full')
|
// setLoginType('full')
|
||||||
// }
|
// }
|
||||||
function readCookie(cname) { // checks the cookie in order to set the login type before components mounts
|
function readCookie(cname) {
|
||||||
|
// checks the cookie in order to set the login type before components mounts
|
||||||
let name = cname + "=";
|
let name = cname + "=";
|
||||||
let decoded_cookie = decodeURIComponent(document.cookie);
|
let decoded_cookie = decodeURIComponent(document.cookie);
|
||||||
let carr = decoded_cookie.split(';');
|
let carr = decoded_cookie.split(";");
|
||||||
for(let i=0; i<carr.length;i++){
|
for (let i = 0; i < carr.length; i++) {
|
||||||
let c = carr[i];
|
let c = carr[i];
|
||||||
while(c.charAt(0)==' '){
|
while (c.charAt(0) == " ") {
|
||||||
c=c.substring(1);
|
c = c.substring(1);
|
||||||
}
|
}
|
||||||
if(c.indexOf(name) == 0) {
|
if (c.indexOf(name) == 0) {
|
||||||
return c.substring(name.length, c.length);
|
return c.substring(name.length, c.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 'full'
|
return "full";
|
||||||
}
|
}
|
||||||
let loginValue = readCookie('loginType')
|
let loginValue = readCookie("loginType");
|
||||||
setLoginType(loginValue)
|
setLoginType(loginValue);
|
||||||
|
|
||||||
if(state?.error){ //check if the login path has an error state indicating any social handle login with error
|
if (state?.error) {
|
||||||
|
//check if the login path has an error state indicating any social handle login with error
|
||||||
setMsgError("Unexpected Error, Please try again soon.");
|
setMsgError("Unexpected Error, Please try again soon.");
|
||||||
setTimeout(()=>{
|
setTimeout(() => {
|
||||||
setMsgError("");
|
setMsgError("");
|
||||||
navigate('/login', {replace: true})
|
navigate("/login", { replace: true });
|
||||||
},4000)
|
}, 4000);
|
||||||
}
|
}
|
||||||
},[])
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMail("");
|
setMail("");
|
||||||
@@ -234,7 +239,9 @@ export default function Login() {
|
|||||||
<button
|
<button
|
||||||
name="full"
|
name="full"
|
||||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||||
loginType=='full' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
loginType == "full"
|
||||||
|
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||||
|
: "bg-white text-[#000] border-t-[2px]"
|
||||||
}`}
|
}`}
|
||||||
onClick={handleLoginType}
|
onClick={handleLoginType}
|
||||||
>
|
>
|
||||||
@@ -243,7 +250,9 @@ export default function Login() {
|
|||||||
<button
|
<button
|
||||||
name="family"
|
name="family"
|
||||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||||
loginType=='family' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
loginType == "family"
|
||||||
|
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||||
|
: "bg-white text-[#000] border-t-[2px]"
|
||||||
}`}
|
}`}
|
||||||
onClick={handleLoginType}
|
onClick={handleLoginType}
|
||||||
>
|
>
|
||||||
@@ -255,7 +264,7 @@ export default function Login() {
|
|||||||
|
|
||||||
{/* for login component */}
|
{/* for login component */}
|
||||||
{
|
{
|
||||||
loginType == 'full' ? (
|
loginType == "full" ? (
|
||||||
//user login component
|
//user login component
|
||||||
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||||
<div className="input-item mb-5">
|
<div className="input-item mb-5">
|
||||||
@@ -275,7 +284,7 @@ export default function Login() {
|
|||||||
<div className="input-item mb-5">
|
<div className="input-item mb-5">
|
||||||
<InputCom
|
<InputCom
|
||||||
labelClass="tracking-wider"
|
labelClass="tracking-wider"
|
||||||
fieldClass="sm:px-6 px-2"
|
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
|
||||||
value={password}
|
value={password}
|
||||||
inputHandler={handlePassword}
|
inputHandler={handlePassword}
|
||||||
placeholder="● ● ● ● ● ●"
|
placeholder="● ● ● ● ● ●"
|
||||||
@@ -321,33 +330,33 @@ export default function Login() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||||
<BrandBtn
|
<BrandBtn
|
||||||
link="#"
|
link="#"
|
||||||
imgSrc={googleLogo}
|
imgSrc={googleLogo}
|
||||||
brand="Google"
|
brand="Google"
|
||||||
onClick={googleLogin}
|
onClick={googleLogin}
|
||||||
/>
|
/>
|
||||||
<BrandBtn
|
<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=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`}
|
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}
|
imgSrc={appleLogo}
|
||||||
brand="Apple"
|
brand="Apple"
|
||||||
isAnchor={true}
|
isAnchor={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||||
<BrandBtn
|
<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}`}
|
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}
|
imgSrc={facebookLogo}
|
||||||
brand="Facebook"
|
brand="Facebook"
|
||||||
isAnchor={true}
|
isAnchor={true}
|
||||||
/>
|
/>
|
||||||
<BrandBtn
|
<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"
|
// 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}
|
imgSrc={linkedInLogo}
|
||||||
brand="LinkedIn"
|
brand="LinkedIn"
|
||||||
isAnchor={true}
|
isAnchor={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -423,10 +432,12 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
{/* END of login component */}
|
{/* END of login component */}
|
||||||
|
|
||||||
|
{loginType == "full" &&
|
||||||
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
||||||
This site is protected by hCaptcha and the our Privacy Policy
|
This site is protected by hCaptcha and the our Privacy Policy
|
||||||
and Terms of Service apply.
|
and Terms of Service apply.
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -435,7 +446,7 @@ export default function Login() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
|
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor = false }) => {
|
||||||
// const doGoogle = async () => {
|
// const doGoogle = async () => {
|
||||||
// alert("start google");
|
// alert("start google");
|
||||||
// };
|
// };
|
||||||
@@ -456,33 +467,28 @@ const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
|
|||||||
// };
|
// };
|
||||||
return (
|
return (
|
||||||
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
|
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
|
||||||
{isAnchor ?
|
{isAnchor ? (
|
||||||
(
|
|
||||||
<a
|
<a
|
||||||
href={link}
|
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"
|
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)" />
|
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||||
Continue with {brand}
|
Continue with {brand}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
)
|
) : (
|
||||||
:
|
|
||||||
(
|
|
||||||
<button
|
<button
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
// href="#dd"
|
// 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"
|
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)" />
|
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||||
Continue with {brand}
|
Continue with {brand}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import facebookLogo from "../../../assets/images/facebook-4.svg";
|
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||||
import AuthLayout from "../AuthLayout";
|
import AuthLayout from "../AuthLayout";
|
||||||
@@ -69,13 +68,17 @@ export default function SignUp() {
|
|||||||
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||||
if (regEx.test(email) == false) {
|
if (regEx.test(email) == false) {
|
||||||
setMsgError("Invalid Email");
|
setMsgError("Invalid Email");
|
||||||
return setTimeout(()=>{setMsgError("");},3000)
|
return setTimeout(() => {
|
||||||
|
setMsgError("");
|
||||||
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
//checks if terms and condition is checked
|
//checks if terms and condition is checked
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
setMsgError("Terms and condition required");
|
setMsgError("Terms and condition required");
|
||||||
return setTimeout(()=>{setMsgError("");},3000)
|
return setTimeout(() => {
|
||||||
|
setMsgError("");
|
||||||
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSignUpLoading(true);
|
setSignUpLoading(true);
|
||||||
@@ -95,7 +98,9 @@ export default function SignUp() {
|
|||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
const { data } = res;
|
const { data } = res;
|
||||||
if (data && data.acc === "DULPICATE") {
|
if (data && data.acc === "DULPICATE") {
|
||||||
setMsgError("Unable to use this username. Please try another username.");
|
setMsgError(
|
||||||
|
"Unable to use this username. Please try another username."
|
||||||
|
);
|
||||||
setSignUpLoading(false);
|
setSignUpLoading(false);
|
||||||
}
|
}
|
||||||
if (data && data.status === "1") {
|
if (data && data.status === "1") {
|
||||||
@@ -205,15 +210,13 @@ export default function SignUp() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="input-item mb-5">
|
<div className="input-item mb-5">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
|
||||||
placeholder="● ● ● ● ● ●"
|
placeholder="● ● ● ● ● ●"
|
||||||
label="Password"
|
label="Password"
|
||||||
name="password"
|
name="password"
|
||||||
type={showPassword ? "text" : "password"}
|
type={showPassword ? "text" : "password"}
|
||||||
onClick={togglePasswordVisibility}
|
onClick={togglePasswordVisibility}
|
||||||
passIcon={
|
passIcon={showPassword ? "show-password" : "hide-password"}
|
||||||
showPassword ? "show-password" : "hide-password"
|
|
||||||
}
|
|
||||||
value={formData.password}
|
value={formData.password}
|
||||||
inputHandler={handleInputChange}
|
inputHandler={handleInputChange}
|
||||||
/>
|
/>
|
||||||
@@ -223,7 +226,48 @@ export default function SignUp() {
|
|||||||
{msgError}
|
{msgError}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="forgot-password-area flex justify-between items-center mb-6">
|
<div className="forgot-password-area flex justify-between items-center mb-6">
|
||||||
|
<div className="remember-checkbox flex items-center space-x-2.5 group cursor-pointer">
|
||||||
|
<button
|
||||||
|
onClick={rememberMe}
|
||||||
|
type="button"
|
||||||
|
className={`w-6 h-6 border-[#4687ba] text-white flex justify-center items-center border rounded-[.45em] group-checked:text-white transition-all duration-200 group-checked:cursor-default ${
|
||||||
|
checked && "text-white bg-[#4687ba]"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{checked && (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className="h-5 w-5"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
<span
|
||||||
|
onClick={rememberMe}
|
||||||
|
className="cursor-default text-dark-gray dark:text-white text-[15px] group-checked:text-white transition-all duration-200 group-checked:cursor-default"
|
||||||
|
>
|
||||||
|
I agree with all
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-base text-[#4687ba] hover:text-[#009ef7] mx-1 inline-block"
|
||||||
|
>
|
||||||
|
terms and condition
|
||||||
|
</Link>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Forgot Password */}
|
||||||
|
{/* <div className="forgot-password-area flex justify-between items-center mb-6">
|
||||||
<div className="remember-checkbox flex items-center space-x-2.5">
|
<div className="remember-checkbox flex items-center space-x-2.5">
|
||||||
<button
|
<button
|
||||||
onClick={rememberMe}
|
onClick={rememberMe}
|
||||||
@@ -258,7 +302,7 @@ export default function SignUp() {
|
|||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
<div className="signin-area mb-1">
|
<div className="signin-area mb-1">
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||||
import debounce from "../../../hooks/debounce";
|
import debounce from "../../../hooks/debounce";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||||
import AuthLayout from "../AuthLayout";
|
import AuthLayout from "../AuthLayout";
|
||||||
@@ -158,8 +158,8 @@ const SuccessfulComponent = ({
|
|||||||
{/* INPUT */}
|
{/* INPUT */}
|
||||||
<div className="mb-5">
|
<div className="mb-5">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
|
||||||
value={password}
|
value={password?.replace(/./g, "●")}
|
||||||
inputHandler={handlePassword}
|
inputHandler={handlePassword}
|
||||||
placeholder="● ● ● ● ● ●"
|
placeholder="● ● ● ● ● ●"
|
||||||
label="Password"
|
label="Password"
|
||||||
@@ -171,8 +171,8 @@ const SuccessfulComponent = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-5">
|
<div className="mb-5">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
|
||||||
value={confirmPassword}
|
value={confirmPassword?.replace(/./g, "●")}
|
||||||
inputHandler={handlePassword}
|
inputHandler={handlePassword}
|
||||||
placeholder="● ● ● ● ● ●"
|
placeholder="● ● ● ● ● ●"
|
||||||
label="Confirm Password"
|
label="Confirm Password"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useNavigate, Link } from "react-router-dom";
|
import { useNavigate, Link } from "react-router-dom";
|
||||||
import AuthLayout from "../AuthLayout";
|
import AuthLayout from "../AuthLayout";
|
||||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||||
|
|
||||||
export default function VerifyYou() {
|
export default function VerifyYou() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|||||||
@@ -1,38 +1,76 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import Layout from "../Partials/Layout";
|
import Layout from "../Partials/Layout";
|
||||||
import CommonHead from "../UserHeader/CommonHead";
|
import CommonHead from "../UserHeader/CommonHead";
|
||||||
|
import usersService from "../../services/UsersService";
|
||||||
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
export default function BlogItem(props) {
|
export default function BlogItem(props) {
|
||||||
|
|
||||||
|
const apiCall = new usersService()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const [blogdata, setBlogdata] = useState({loading: true, data:{}})
|
||||||
|
|
||||||
const [selectTab, setValue] = useState("today");
|
const [selectTab, setValue] = useState("today");
|
||||||
const filterHandler = (value) => {
|
const filterHandler = (value) => {
|
||||||
setValue(value);
|
setValue(value);
|
||||||
};
|
};
|
||||||
|
const queryParams = new URLSearchParams(location?.search);
|
||||||
|
const blog_id = queryParams.get("blog_id");
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(!blog_id){
|
||||||
|
navigate('/',{replace:true})
|
||||||
|
}
|
||||||
|
apiCall.getSingleBlogData({blog_id}).then(res => {
|
||||||
|
setBlogdata({loading: false, data:res.data})
|
||||||
|
}).catch(error => {
|
||||||
|
setBlogdata({loading: false, data:{}})
|
||||||
|
console.log('ERROR', error)
|
||||||
|
})
|
||||||
|
},[blog_id])
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<CommonHead
|
<CommonHead
|
||||||
commonHeadData={props.commonHeadData}
|
commonHeadData={props.commonHeadData}
|
||||||
/>
|
/>
|
||||||
<div className="notification-page w-full mb-10">
|
<div className="notification-page w-full mb-10">
|
||||||
<div className="notification-wrapper w-full">
|
<div className="mb-5">
|
||||||
{/* heading */}
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||||
<div className="sm:flex justify-between items-center mb-6">
|
<span
|
||||||
<div className="mb-5 sm:mb-0">
|
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
>
|
||||||
<span
|
{blogdata.data?.blogdata?.[0]?.post_title}
|
||||||
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
</span>
|
||||||
>
|
</h1>
|
||||||
Title of this Blog Items
|
</div>
|
||||||
</span>
|
<div className="notification-wrapper w-full bg-white p-8 rounded-2xl">
|
||||||
</h1>
|
{blogdata.loading ?
|
||||||
</div>
|
<LoadingSpinner size='8' color='sky-blue' height='h-[100px]' />
|
||||||
<div className="slider-btns flex space-x-4">
|
:
|
||||||
|
blogdata?.data?.blogdata && blogdata.data?.blogdata.length ?
|
||||||
</div>
|
<div className="w-full">
|
||||||
|
{/* heading */}
|
||||||
|
<div className="sm:flex justify-between items-center mb-6">
|
||||||
|
{/* <div className="mb-5">
|
||||||
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||||
|
<span
|
||||||
|
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||||
|
>
|
||||||
|
{blogdata.data?.blogdata?.[0]?.post_title}
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
</div> */}
|
||||||
|
{/* <div className="slider-btns flex space-x-4">
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
<div dangerouslySetInnerHTML={{__html: blogdata.data?.blogdata?.[0]?.post_content}}>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
:
|
||||||
Blog Items Details
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white">No Blog Found!</h1>
|
||||||
</div>
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ export default function HomeBannerOffersCard(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to={link_result}
|
// to={link_result}
|
||||||
|
to={link_result == '/blog-page' ? `${link_result}?blog_id=${props.itemData.blog_id}` : `${link_result}`}
|
||||||
className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center"
|
className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `url('${imageUrl}')`,
|
backgroundImage: `url('${imageUrl}')`,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function OfferCard({ datas, hidden = false, setOfferPopout }) {
|
|||||||
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
|
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
|
||||||
style={{
|
style={{
|
||||||
background: `url(${localImgLoad(
|
background: `url(${localImgLoad(
|
||||||
`images/taskbanners/${datas.banner}`
|
`images/taskbanners/${datas?.banner || "default.jpg"}`
|
||||||
)}) center / contain no-repeat`,
|
)}) center / contain no-repeat`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -50,22 +50,23 @@ export default function ProductCardStyleTwo({
|
|||||||
</div>
|
</div>
|
||||||
<div className="details-area">
|
<div className="details-area">
|
||||||
{/* title */}
|
{/* title */}
|
||||||
<a href={datas.guid} target="_blank" className="mb-2.5" rel="noreferrer">
|
<Link to={`/blog-page?blog_id=${datas.ID}`} className="mb-2.5" rel="noreferrer">
|
||||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||||
{datas.post_title || "dummy title..."}
|
{datas.post_title || "dummy title..."}
|
||||||
</h1>
|
</h1>
|
||||||
</a>
|
</Link>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<div className="flex items-center space-x-2"></div>
|
<div className="flex items-center space-x-2"></div>
|
||||||
<div className="my-1">
|
<div className="my-1">
|
||||||
<a
|
<Link
|
||||||
href={datas.guid}
|
// href={datas.guid}
|
||||||
target="_blank"
|
// target="_blank"
|
||||||
|
to={`/blog-page?blog_id=${datas.ID}`}
|
||||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
View
|
View
|
||||||
</a>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import React, {
|
|||||||
} from "react";
|
} from "react";
|
||||||
import { useReactToPrint } from "react-to-print";
|
import { useReactToPrint } from "react-to-print";
|
||||||
import profile from "../../assets/images/profile-info-profile.png";
|
import profile from "../../assets/images/profile-info-profile.png";
|
||||||
|
import localImgLoad from "../../lib/localImgLoad";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
|
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
|
||||||
import localImgLoad from "../../lib/localImgLoad";
|
|
||||||
|
|
||||||
// Lazy Imports for components
|
// Lazy Imports for components
|
||||||
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
|
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
|
||||||
@@ -193,19 +193,19 @@ export default function FamilyManageTabs({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${
|
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
<div className="relative w-full sm:rounded-lg overflow-x-auto">
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
|
<div className="h-full min-h-[609px] w-full overflow-hidden flex justify-center items-center">
|
||||||
<LoadingSpinner size="16" color="sky-blue" />
|
<LoadingSpinner size="16" color="sky-blue" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[520px]">
|
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[575px]">
|
||||||
<div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between">
|
<div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between">
|
||||||
<ProfileInfo
|
<ProfileInfo
|
||||||
profileImg={profileImg}
|
profileImg={profileImg}
|
||||||
@@ -239,10 +239,10 @@ export default function FamilyManageTabs({
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-3 justify-self-end h-full w-full">
|
<div className="col-span-3 h-full w-full">
|
||||||
<div className="flex flex-col w-full">
|
<div className="flex flex-col w-full">
|
||||||
<div className="w-full pr-8 flex items-center gap-1">
|
<div className="w-full pr-8 flex items-center gap-1 border-b border-b-[#FAFAF]">
|
||||||
<ul className="flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
|
<ul className="flex gap-2 items-center w-full">
|
||||||
{tabs.map(({ name, id }) => (
|
{tabs.map(({ name, id }) => (
|
||||||
<li
|
<li
|
||||||
onClick={() => tabHandler(name)}
|
onClick={() => tabHandler(name)}
|
||||||
@@ -265,8 +265,9 @@ export default function FamilyManageTabs({
|
|||||||
Add task
|
Add task
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-[0.9] lg:min-h-[450px] h-full">
|
|
||||||
<div className="h-full p-4 border border-[#dbd9d9] relative overflow-y-auto">
|
<div className="flex-[0.9] h-full">
|
||||||
|
<div className="h-full relative overflow-y-auto">
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={<LoadingSpinner size="16" color="sky-blue" />}
|
fallback={<LoadingSpinner size="16" color="sky-blue" />}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ const AssignTaskPopout = React.memo(({ action, details, situation, familyDetail
|
|||||||
// API PAYLOADS
|
// API PAYLOADS
|
||||||
job_id: activeTask.data?.job_id,
|
job_id: activeTask.data?.job_id,
|
||||||
job_uid: activeTask.data?.job_uid,
|
job_uid: activeTask.data?.job_uid,
|
||||||
family_uid: familyDetails.uid,
|
family_uid: familyDetails?.uid || details?.family_uid,
|
||||||
job_description: activeTask.data?.description,
|
job_description: activeTask.data?.description,
|
||||||
assign_mode: 110011,
|
assign_mode: 110011,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { handlePagingFunc } from "../Pagination/HandlePagination";
|
|||||||
import PaginatedList from "../Pagination/PaginatedList";
|
import PaginatedList from "../Pagination/PaginatedList";
|
||||||
|
|
||||||
import familyImage from '../../assets/images/no-family-side.png'
|
import familyImage from '../../assets/images/no-family-side.png'
|
||||||
|
import localImgLoad from "../../lib/localImgLoad";
|
||||||
|
|
||||||
export default function FamilyTable({ className, familyList, loader, popUpHandler }) {
|
export default function FamilyTable({ className, familyList, loader, popUpHandler }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -22,7 +23,7 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`update-table w-full h-full p-8 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] ${
|
className={`update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -54,6 +55,7 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
|
|||||||
last_login,
|
last_login,
|
||||||
task_count,
|
task_count,
|
||||||
family_uid,
|
family_uid,
|
||||||
|
banner
|
||||||
} = props;
|
} = props;
|
||||||
let addedDate = added?.split(" ")[0];
|
let addedDate = added?.split(" ")[0];
|
||||||
let LoginDate = last_login?.split(" ")[0];
|
let LoginDate = last_login?.split(" ")[0];
|
||||||
@@ -64,9 +66,10 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
|
|||||||
>
|
>
|
||||||
<td className=" py-4">
|
<td className=" py-4">
|
||||||
<div className="flex space-x-2 items-center w-full">
|
<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
|
<img
|
||||||
src={dataImage1}
|
// src={dataImage1}
|
||||||
|
src={localImgLoad(`images/icons/${banner}`)}
|
||||||
alt="data"
|
alt="data"
|
||||||
className="w-full h-full"
|
className="w-full h-full"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import QRCode from "react-qr-code";
|
|||||||
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center"
|
className="w-full lg:min-h-[538px] p-3 h-full flex flex-col items-center justify-center"
|
||||||
ref={myRef}
|
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="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
|
||||||
@@ -53,4 +53,4 @@ const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default FamilyAccount;
|
export default FamilyAccount;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
|
||||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
|
||||||
import dataImage2 from "../../../assets/images/data-table-user-2.png";
|
|
||||||
import PendingJobsPopout from "../../jobPopout/PendingJobsPopout";
|
|
||||||
import localImgLoad from "../../../lib/localImgLoad";
|
import localImgLoad from "../../../lib/localImgLoad";
|
||||||
|
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||||
|
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||||
|
import PendingJobsPopout from "../../jobPopout/PendingJobsPopout";
|
||||||
|
|
||||||
export default function FamilyPending({
|
export default function FamilyPending({
|
||||||
familyData,
|
familyData,
|
||||||
@@ -37,7 +36,7 @@ export default function FamilyPending({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
className={`update-table w-full p-3 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow lg:min-h-[538px] ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -125,8 +124,10 @@ export default function FamilyPending({
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
<tr>
|
||||||
<td className="p-2">No Pending Task!</td>
|
<td className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap text-center py-4 px-2">
|
||||||
|
No Pending Task!
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
export default function FamilyProfile() {
|
export default function FamilyProfile({ className }) {
|
||||||
return <>Profile</>;
|
return (
|
||||||
}
|
<div
|
||||||
|
className={`update-table w-full bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow lg:min-h-[538px] p-3 ${
|
||||||
|
className || ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<h1>Profile</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
import dataImage2 from "../../../assets/images/data-table-user-2.png";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { useNavigate, useLocation } from "react-router-dom";
|
import localImgLoad from "../../../lib/localImgLoad";
|
||||||
|
import Icons from "../../Helpers/Icons";
|
||||||
|
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||||
import { handlePagingFunc } from "../../Pagination/HandlePagination";
|
import { handlePagingFunc } from "../../Pagination/HandlePagination";
|
||||||
import PaginatedList from "../../Pagination/PaginatedList";
|
import PaginatedList from "../../Pagination/PaginatedList";
|
||||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
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({
|
||||||
export default function FamilyTasks({ familyData, className, loader, accountDetails }) {
|
familyData,
|
||||||
|
className,
|
||||||
|
loader,
|
||||||
|
accountDetails,
|
||||||
|
}) {
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
let { pathname } = useLocation();
|
let { pathname } = useLocation();
|
||||||
|
|
||||||
|
// ...
|
||||||
|
const filteredFamilyData = useMemo(
|
||||||
|
() =>
|
||||||
|
familyData?.result_list?.filter(
|
||||||
|
(data) => data?.family_uid === accountDetails?.family_uid
|
||||||
|
),
|
||||||
|
[familyData, accountDetails]
|
||||||
|
);
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
const indexOfFirstItem = Number(currentPage);
|
const indexOfFirstItem = Number(currentPage);
|
||||||
const indexOfLastItem =
|
const indexOfLastItem =
|
||||||
@@ -26,9 +36,10 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
|||||||
|
|
||||||
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
|
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[538px] overflow-hidden rounded-2xl section-shadow p-3 ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -45,8 +56,8 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
|||||||
{
|
{
|
||||||
<>
|
<>
|
||||||
{familyData &&
|
{familyData &&
|
||||||
familyData?.result_list &&
|
familyData?.result_list &&
|
||||||
familyData.result_list.length > 0 &&
|
familyData.result_list.length > 0 ? (
|
||||||
currentTask.map((value, index) => {
|
currentTask.map((value, index) => {
|
||||||
// find due date
|
// find due date
|
||||||
const dueDate = value?.delivery_date.split(" ")[0];
|
const dueDate = value?.delivery_date.split(" ")[0];
|
||||||
@@ -56,7 +67,9 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
|||||||
value?.currency_code,
|
value?.currency_code,
|
||||||
value?.currency
|
value?.currency
|
||||||
);
|
);
|
||||||
let image = value.banner ? value.banner : 'default.jpg'
|
let image = value.banner
|
||||||
|
? value.banner
|
||||||
|
: "default.jpg";
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={index}
|
key={index}
|
||||||
@@ -66,7 +79,9 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
|||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="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">
|
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||||
<img
|
<img
|
||||||
src={localImgLoad(`images/taskbanners/${image}`)}
|
src={localImgLoad(
|
||||||
|
`images/taskbanners/${image}`
|
||||||
|
)}
|
||||||
alt="data"
|
alt="data"
|
||||||
className="w-full h-full rounded-full"
|
className="w-full h-full rounded-full"
|
||||||
/>
|
/>
|
||||||
@@ -109,8 +124,8 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
|||||||
state: {
|
state: {
|
||||||
...value,
|
...value,
|
||||||
pathname,
|
pathname,
|
||||||
accountDetails
|
accountDetails,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
@@ -120,7 +135,14 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
})}
|
})
|
||||||
|
) : (
|
||||||
|
<tr>
|
||||||
|
<td colSpan="2" className="text-center py-4 font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||||
|
No Family Task
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,148 +1,152 @@
|
|||||||
import { useState, useMemo, memo } from "react";
|
import { memo, useMemo, useState } from "react";
|
||||||
import { handlePagingFunc, PaginatedList } from "../../Pagination";
|
|
||||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
|
||||||
import SuggestTask from "../../FamilyPopup/SuggestTask";
|
import SuggestTask from "../../FamilyPopup/SuggestTask";
|
||||||
|
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||||
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||||
import AssignTaskPopout from "../FamilyPopout/AssignTaskPopout";
|
import AssignTaskPopout from "../FamilyPopout/AssignTaskPopout";
|
||||||
|
|
||||||
const FamilyWaitlist = memo(({ familyData, className, accountDetails, loader }) => {
|
const FamilyWaitlist = memo(
|
||||||
const [popUp, setPopUp] = useState({ show: false, data: {} });
|
({ familyData, className, accountDetails, loader }) => {
|
||||||
const [continueTaskPopup, setContinueTaskPopup] = useState({
|
const [popUp, setPopUp] = useState({ show: false, data: {} });
|
||||||
show: false,
|
const [continueTaskPopup, setContinueTaskPopup] = useState({
|
||||||
data: {},
|
show: false,
|
||||||
});
|
data: {},
|
||||||
const filteredFamilyData = useMemo(
|
});
|
||||||
() =>
|
const filteredFamilyData = useMemo(
|
||||||
familyData?.result_list?.filter(
|
() =>
|
||||||
(data) => data?.family_uid === accountDetails?.family_uid
|
familyData?.result_list?.filter(
|
||||||
),
|
(data) => data?.family_uid === accountDetails?.family_uid
|
||||||
[familyData, accountDetails]
|
),
|
||||||
);
|
[familyData, accountDetails]
|
||||||
|
);
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
const indexOfFirstItem = currentPage;
|
const indexOfFirstItem = currentPage;
|
||||||
const indexOfLastItem = currentPage + itemsPerPage;
|
const indexOfLastItem = currentPage + itemsPerPage;
|
||||||
const currentTask = useMemo(
|
const currentTask = useMemo(
|
||||||
() => filteredFamilyData?.slice(indexOfFirstItem, indexOfLastItem),
|
() => filteredFamilyData?.slice(indexOfFirstItem, indexOfLastItem),
|
||||||
[filteredFamilyData, indexOfFirstItem, indexOfLastItem]
|
[filteredFamilyData, indexOfFirstItem, indexOfLastItem]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
||||||
|
|
||||||
const openPopUp = (value) => {
|
const openPopUp = (value) => {
|
||||||
setPopUp({ show: true, data: { ...value } });
|
setPopUp({ show: true, data: { ...value } });
|
||||||
};
|
};
|
||||||
|
|
||||||
const closePopUp = () => {
|
const closePopUp = () => {
|
||||||
setPopUp({ show: false, data: {} });
|
setPopUp({ show: false, data: {} });
|
||||||
};
|
};
|
||||||
|
|
||||||
const openContinueTaskPopup = (value) => {
|
const openContinueTaskPopup = (value) => {
|
||||||
setContinueTaskPopup({ show: true, data: { ...value } });
|
setContinueTaskPopup({ show: true, data: { ...value } });
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeContinueTaskPopup = () => {
|
const closeContinueTaskPopup = () => {
|
||||||
setContinueTaskPopup({ show: false, data: {} });
|
setContinueTaskPopup({ show: false, data: {} });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
|
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[538px] p-3 overflow-hidden rounded-2xl section-shadow ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{loader ? (
|
{loader ? (
|
||||||
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
|
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
|
||||||
<LoadingSpinner size={16} color="sky-blue" />
|
<LoadingSpinner size={16} color="sky-blue" />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{filteredFamilyData && (
|
{filteredFamilyData && (
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
<tbody>
|
<tbody>
|
||||||
{currentTask.map((value) => {
|
{currentTask.map((value) => {
|
||||||
const addedDate = value?.added.split(" ")[0];
|
const addedDate = value?.added.split(" ")[0];
|
||||||
const selectedImage = require(`../../../assets/images/family/${
|
const selectedImage = require(`../../../assets/images/family/${
|
||||||
value?.banner || "default.jpg"
|
value?.banner || "default.jpg"
|
||||||
}`);
|
}`);
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||||
key={value.uid}
|
key={value.uid}
|
||||||
>
|
>
|
||||||
<td className="py-4">
|
<td className="py-4">
|
||||||
<div className="w-full flex justify-between items-center">
|
<div className="w-full flex justify-between items-center">
|
||||||
<div className="account-name flex space-x-4 items-center">
|
<div className="account-name flex space-x-4 items-center">
|
||||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||||
<img
|
<img
|
||||||
src={selectedImage}
|
src={selectedImage}
|
||||||
alt="task_img"
|
alt="task_img"
|
||||||
className="w-full object-cover"
|
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>
|
||||||
<div className="">
|
<div className="px-2 flex flex-col items-center justify-center">
|
||||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
||||||
{value.title}
|
{addedDate}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-thin-light-gray font-medium">
|
<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.description}
|
{value.status_text}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="px-2 flex flex-col items-center justify-center">
|
</td>
|
||||||
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
<td className="text-right py-4 px-2">
|
||||||
{addedDate}
|
<button
|
||||||
</p>
|
onClick={() => openPopUp(value)}
|
||||||
<p className="text-xs py-1.5 w-[70px] cursor-default tracking-wide rounded-full bg-gold text-white flex justify-center items-center">
|
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
{value.status_text}
|
>
|
||||||
</p>
|
View
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
<td className="text-right py-4 px-2">
|
);
|
||||||
<button
|
})}
|
||||||
onClick={() => openPopUp(value)}
|
</tbody>
|
||||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
</table>
|
||||||
>
|
<PaginatedList
|
||||||
View
|
onClick={handlePagination}
|
||||||
</button>
|
prev={currentPage === 0}
|
||||||
</td>
|
next={
|
||||||
</tr>
|
currentPage + itemsPerPage >= filteredFamilyData?.length
|
||||||
);
|
}
|
||||||
})}
|
data={filteredFamilyData}
|
||||||
</tbody>
|
start={indexOfFirstItem}
|
||||||
</table>
|
stop={indexOfLastItem}
|
||||||
<PaginatedList
|
/>
|
||||||
onClick={handlePagination}
|
</div>
|
||||||
prev={currentPage === 0}
|
)}
|
||||||
next={currentPage + itemsPerPage >= filteredFamilyData?.length}
|
</>
|
||||||
data={filteredFamilyData}
|
)}
|
||||||
start={indexOfFirstItem}
|
{popUp.show && (
|
||||||
stop={indexOfLastItem}
|
<SuggestTask
|
||||||
/>
|
details={popUp.data}
|
||||||
</div>
|
onClose={closePopUp}
|
||||||
)}
|
continuePopupData={openContinueTaskPopup}
|
||||||
</>
|
situation={popUp.show}
|
||||||
)}
|
/>
|
||||||
{popUp.show && (
|
)}
|
||||||
<SuggestTask
|
|
||||||
details={popUp.data}
|
|
||||||
onClose={closePopUp}
|
|
||||||
continuePopupData={openContinueTaskPopup}
|
|
||||||
situation={popUp.show}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{continueTaskPopup.show && (
|
{continueTaskPopup.show && (
|
||||||
<AssignTaskPopout
|
<AssignTaskPopout
|
||||||
details={continueTaskPopup.data}
|
details={continueTaskPopup.data}
|
||||||
action={closeContinueTaskPopup}
|
action={closeContinueTaskPopup}
|
||||||
situation={continueTaskPopup.show}
|
situation={continueTaskPopup.show}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default FamilyWaitlist;
|
export default FamilyWaitlist;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import localImgLoad from "../../../lib/localImgLoad";
|
||||||
|
|
||||||
|
|
||||||
export default function ProfileInfo({
|
export default function ProfileInfo({
|
||||||
profileImg,
|
profileImg,
|
||||||
@@ -12,7 +14,7 @@ export default function ProfileInfo({
|
|||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
<div className="w-full relative">
|
<div className="w-full relative">
|
||||||
<img
|
<img
|
||||||
src={profileImg}
|
src={localImgLoad(`images/icons/${accountDetails.banner}`)}
|
||||||
alt=""
|
alt=""
|
||||||
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -504,11 +504,11 @@ export default function Icons({ name }) {
|
|||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
) : name === "atm-card" ? (
|
) : name === "atm-card" ? (
|
||||||
<img className="w-[20px]" src={ATMCard} alt="card" />
|
<img className="w-[30px]" src={ATMCard} alt="card" />
|
||||||
) : name === "visa-card" ? (
|
) : name === "visa-card" ? (
|
||||||
<img className="w-[20px]" src={VisaCard} alt="card" />
|
<img className="w-[30px]" src={VisaCard} alt="card" />
|
||||||
) : name === "master-card" ? (
|
) : name === "master-card" ? (
|
||||||
<img className="w-[20px]" src={MasterCard} alt="card" />
|
<img className="w-[30px]" src={MasterCard} alt="card" />
|
||||||
) : name === "new-dashboard" ? (
|
) : name === "new-dashboard" ? (
|
||||||
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/dashboard.svg')} alt="dashboard" />
|
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/dashboard.svg')} alt="dashboard" />
|
||||||
) : name === "new-family" ? (
|
) : name === "new-family" ? (
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ export default function InputCom({
|
|||||||
blurHandler,
|
blurHandler,
|
||||||
spanTag,
|
spanTag,
|
||||||
inputBg,
|
inputBg,
|
||||||
|
onInput,
|
||||||
|
maxLength = 45,
|
||||||
|
minLength = 0,
|
||||||
direction,
|
direction,
|
||||||
error,
|
error,
|
||||||
}) {
|
}) {
|
||||||
@@ -29,13 +32,13 @@ export default function InputCom({
|
|||||||
// for Min Length:
|
// for Min Length:
|
||||||
const minLengthValidation = () => {
|
const minLengthValidation = () => {
|
||||||
const inputConfig = inputConfigs[inputRef?.current?.name]?.minLength;
|
const inputConfig = inputConfigs[inputRef?.current?.name]?.minLength;
|
||||||
return inputConfig || 0;
|
return inputConfig || minLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
// for MaxLength
|
// for MaxLength
|
||||||
const maxLengthValidation = () => {
|
const maxLengthValidation = () => {
|
||||||
const inputConfig = inputConfigs[inputRef?.current?.name]?.maxLength;
|
const inputConfig = inputConfigs[inputRef?.current?.name]?.maxLength;
|
||||||
return inputConfig || 30;
|
return inputConfig || maxLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
// for Patterns
|
// for Patterns
|
||||||
@@ -63,7 +66,9 @@ export default function InputCom({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{/* displays error is any */}
|
{/* displays error is any */}
|
||||||
{error && <span className="text-[12px] text-red-500">{error}</span>}
|
{error && (
|
||||||
|
<span className="text-[12px] text-red-500 italic">{error}</span>
|
||||||
|
)}
|
||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
{forgotPassword && (
|
{forgotPassword && (
|
||||||
@@ -76,18 +81,23 @@ export default function InputCom({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`input-wrapper w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-base ${inputClass ? inputClass : "text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] border"}`}
|
className={`input-wrapper w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-base ${
|
||||||
|
inputClass
|
||||||
|
? inputClass
|
||||||
|
: "text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] border"
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={inputHandler}
|
onChange={inputHandler}
|
||||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide ${
|
className={`input-field placeholder:text-base text-dark-gray w-full h-full ${
|
||||||
inputBg ? inputBg : "bg-[#FAFAFA]"
|
inputBg ? inputBg : "bg-[#FAFAFA] tracking-wide"
|
||||||
} dark:bg-[#11131F] focus:ring-0 focus:outline-none ${fieldClass}`}
|
} dark:bg-[#11131F] focus:ring-0 focus:outline-none ${fieldClass}`}
|
||||||
type={type}
|
type={type}
|
||||||
id={name}
|
id={name}
|
||||||
name={name}
|
name={name}
|
||||||
|
onInput={onInput}
|
||||||
minLength={minLengthValidation()}
|
minLength={minLengthValidation()}
|
||||||
maxLength={maxLengthValidation()}
|
maxLength={maxLengthValidation()}
|
||||||
// pattern={inputPatterns()}
|
// pattern={inputPatterns()}
|
||||||
@@ -97,17 +107,14 @@ export default function InputCom({
|
|||||||
dir={direction}
|
dir={direction}
|
||||||
/>
|
/>
|
||||||
{iconName && (
|
{iconName && (
|
||||||
<div className="absolute right-6 bottom-[10px] z-10 flex gap-2">
|
<div className="absolute right-6 bottom-3 z-10 flex gap-2">
|
||||||
{iconName.split(" ").map((item, index) => (
|
{iconName.split(" ").map((item, index) => (
|
||||||
<Icons key={index} name={item} />
|
<Icons key={index} name={item} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{passIcon && (
|
{passIcon && (
|
||||||
<div
|
<div className="absolute right-6 bottom-3 z-10" onClick={onClick}>
|
||||||
className="absolute right-6 bottom-[10px] z-10"
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
<Icons name={passIcon} />
|
<Icons name={passIcon} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -117,7 +124,7 @@ export default function InputCom({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const inputConfigs = {
|
const inputConfigs = {
|
||||||
email: { minLength: 7, maxLength: 35 },
|
email: { minLength: 7, maxLength: 45 },
|
||||||
first_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
first_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
||||||
last_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
last_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
||||||
address: { minLength: 5, maxLength: 49, pattern: "[a-zA-Z0-9]+" },
|
address: { minLength: 5, maxLength: 49, pattern: "[a-zA-Z0-9]+" },
|
||||||
@@ -128,7 +135,8 @@ const inputConfigs = {
|
|||||||
amount: { minLength: 1, maxLength: 9, pattern: "[0-9]+" },
|
amount: { minLength: 1, maxLength: 9, pattern: "[0-9]+" },
|
||||||
description: { minLength: 5, maxLength: 299 },
|
description: { minLength: 5, maxLength: 299 },
|
||||||
title: { minLength: 5, maxLength: 149 },
|
title: { minLength: 5, maxLength: 149 },
|
||||||
job_detail: { minLength: 4, maxLength: 1440 }
|
job_detail: { minLength: 4, maxLength: 1440 },
|
||||||
|
cardNum: { minLength: 4, maxLength: 19 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Numbers Only: <input type="text" pattern="[0-9]*" /> strictly numbers
|
/* Numbers Only: <input type="text" pattern="[0-9]*" /> strictly numbers
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export default function SearchCom({
|
|||||||
placeholder,
|
placeholder,
|
||||||
handleSearch,
|
handleSearch,
|
||||||
value,
|
value,
|
||||||
|
name,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -22,6 +23,7 @@ export default function SearchCom({
|
|||||||
className={`w-full h-full focus:outline-0 focus:ring-0 dark:bg-dark-white dark:text-white ${
|
className={`w-full h-full focus:outline-0 focus:ring-0 dark:bg-dark-white dark:text-white ${
|
||||||
inputClasses || ""
|
inputClasses || ""
|
||||||
}`}
|
}`}
|
||||||
|
name={name}
|
||||||
type="text"
|
type="text"
|
||||||
onInput={handleSearch}
|
onInput={handleSearch}
|
||||||
value={value}
|
value={value}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
const TimeDifference = ({ time }) => {
|
||||||
|
const currentTime = new Date();
|
||||||
|
const providedTime = new Date(time);
|
||||||
|
|
||||||
|
const timeDifference = currentTime - providedTime; // Difference in milliseconds
|
||||||
|
|
||||||
|
const minutes = Math.floor(timeDifference / (1000 * 60));
|
||||||
|
const hours = Math.floor(timeDifference / (1000 * 60 * 60));
|
||||||
|
const days = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
|
||||||
|
const months = Math.floor(timeDifference / (1000 * 60 * 60 * 24 * 30));
|
||||||
|
|
||||||
|
if (minutes < 1) {
|
||||||
|
return "Just now";
|
||||||
|
} else if (minutes < 60) {
|
||||||
|
return `${minutes} ${minutes === 1 ? "minute" : "minutes"} ago`;
|
||||||
|
} else if (hours < 12) {
|
||||||
|
return `${hours} ${hours === 1 ? "hour" : "hours"} ago`;
|
||||||
|
} else if (hours < 24) {
|
||||||
|
return "Today";
|
||||||
|
} else if (days < 2) {
|
||||||
|
return "Tomorrow";
|
||||||
|
} else if (days < 7) {
|
||||||
|
return `${days} ${days === 1 ? "day" : "days"} ago`;
|
||||||
|
} else if (months < 1) {
|
||||||
|
const weeks = Math.floor(days / 7);
|
||||||
|
return `${weeks} ${weeks === 1 ? "week" : "weeks"} ago`;
|
||||||
|
} else if (months < 6) {
|
||||||
|
return `${months} ${months === 1 ? "month" : "months"} ago`;
|
||||||
|
}else if (months < 8) {
|
||||||
|
return `"More than 6 months ago"`;
|
||||||
|
} else {
|
||||||
|
return time?.split(" ")[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TimeDifference;
|
||||||
@@ -217,22 +217,22 @@ export default function History() {
|
|||||||
{/* <TopHxBox className="mb-11" /> */}
|
{/* <TopHxBox className="mb-11" /> */}
|
||||||
<div className='w-full p-4 md:p-8 bg-white dark:bg-dark-white rounded-2xl shadow bottomMargin'>
|
<div className='w-full p-4 md:p-8 bg-white dark:bg-dark-white rounded-2xl shadow bottomMargin'>
|
||||||
{/* switch button */}
|
{/* switch button */}
|
||||||
<div className="my-1 flex items-center border-b border-slate-300">
|
<div className="pl-7 my-2 flex items-center border-b border-slate-300 gap-3">
|
||||||
<button
|
<button
|
||||||
name="purchases"
|
name="purchases"
|
||||||
onClick={(e) => setTab(e.target.name)}
|
onClick={(e) => setTab(e.target.name)}
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
className={`px-4 py-1 rounded-t-2xl ${
|
||||||
tab == "purchases" ? "border-sky-blue" : "border-slate-300"
|
tab == "purchases" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||||
} tracking-wide transition duration-200`}
|
}`}
|
||||||
>
|
>
|
||||||
Purchases
|
Purchases
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
name="recent"
|
name="recent"
|
||||||
onClick={(e) => setTab(e.target.name)}
|
onClick={(e) => setTab(e.target.name)}
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
className={`px-4 py-1 rounded-t-2xl ${
|
||||||
tab == "recent" ? "border-sky-blue" : "border-slate-300"
|
tab == "recent" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||||
} tracking-wide transition duration-200`}
|
}`}
|
||||||
>
|
>
|
||||||
Recent Activity
|
Recent Activity
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import ModalCom from "../../Helpers/ModalCom";
|
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
import ModalCom from "../../Helpers/ModalCom";
|
||||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||||
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||||
|
const [textValue, setTextValue] = useState("");
|
||||||
|
const apiCall = useMemo(() => new usersService(), []);
|
||||||
|
|
||||||
|
const handleInputChange = ({ target: { value } }) => {
|
||||||
|
setTextValue(value);
|
||||||
|
};
|
||||||
|
|
||||||
const MarketCalls = (details) => {
|
const MarketCalls = (details) => {
|
||||||
const [marketMsg, setMarketMsg] = useState({
|
const [marketMsg, setMarketMsg] = useState({
|
||||||
loading: false,
|
loading: false,
|
||||||
@@ -24,8 +31,8 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
|
|
||||||
const MarketDetail = async () => {
|
const MarketDetail = async () => {
|
||||||
try {
|
try {
|
||||||
setMarketMsg({ loading: true });
|
|
||||||
if (!textValue) return;
|
if (!textValue) return;
|
||||||
|
setMarketMsg({ loading: true });
|
||||||
|
|
||||||
reqData.yourmessage = textValue;
|
reqData.yourmessage = textValue;
|
||||||
|
|
||||||
@@ -87,22 +94,11 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// ManageInterest();
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
return { MarketDetail, ManageInterest, manageInt, marketMsg };
|
return { MarketDetail, ManageInterest, manageInt, marketMsg };
|
||||||
};
|
};
|
||||||
|
|
||||||
const [textValue, setTextValue] = useState("");
|
let { manageInt, ManageInterest, MarketDetail, marketMsg } =
|
||||||
|
MarketCalls(details);
|
||||||
const handleInputChange = ({ target: { value } }) => {
|
|
||||||
setTextValue(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const apiCall = useMemo(() => new usersService(), []);
|
|
||||||
|
|
||||||
let { manageInt, ManageInterest, MarketDetail, marketMsg } = MarketCalls(details);
|
|
||||||
|
|
||||||
let thePrice = PriceFormatter(
|
let thePrice = PriceFormatter(
|
||||||
details?.price * 0.01,
|
details?.price * 0.01,
|
||||||
@@ -270,9 +266,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
Interest: <b className="ml-1">{details.interest_count}</b>
|
Interest: <b className="ml-1">{details.interest_count}</b>
|
||||||
</p>
|
</p>
|
||||||
<hr />
|
<hr />
|
||||||
<p className="my-1">
|
<p className="my-1">Expire: {details.expire}</p>
|
||||||
Expire: {details.expire}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -9,59 +9,61 @@ import PaginatedList from "../Pagination/PaginatedList";
|
|||||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||||
|
|
||||||
export default function ActiveJobMessage({ activeJobMesList }) {
|
export default function ActiveJobMessage({ activeJobMesList }) {
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
// const [currentPage, setCurrentPage] = useState(0);
|
||||||
const indexOfFirstItem = Number(currentPage);
|
// const indexOfFirstItem = Number(currentPage);
|
||||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
// const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
const currentActiveJobMesList = activeJobMesList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
// const currentActiveJobMesList = activeJobMesList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||||
|
|
||||||
const handlePagination = (e) => {
|
// const handlePagination = (e) => {
|
||||||
handlePagingFunc(e,setCurrentPage)
|
// handlePagingFunc(e,setCurrentPage)
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col justify-between h-full'>
|
<div className='flex flex-col justify-between'>
|
||||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
<div className="w-full min-h-[450px] max-h-[450px] overflow-y-scroll">
|
||||||
<thead className='border-b-2'>
|
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||||
<tr className='text-slate-600'>
|
<thead className='border-b-2'>
|
||||||
<th className="p-2"></th>
|
<tr className='text-slate-600'>
|
||||||
</tr>
|
<th className="p-2"></th>
|
||||||
</thead>
|
</tr>
|
||||||
{activeJobMesList.data.length ?
|
</thead>
|
||||||
(
|
{activeJobMesList?.data?.length ?
|
||||||
<tbody>
|
(
|
||||||
{currentActiveJobMesList.map((item, index) => (
|
<tbody>
|
||||||
<tr key={index} className='text-slate-500'>
|
{activeJobMesList.data.map((item, index) => (
|
||||||
<td>
|
<tr key={index} className='text-slate-500'>
|
||||||
<div className="msg_box">
|
<td>
|
||||||
<div className="msg_header">{item.msg_date} {item.msg_firstname}</div>
|
<div className={`msg_box ${item.who}`}>
|
||||||
<span className="p-2" dangerouslySetInnerHTML={{__html: item.message}}></span>
|
<div className="msg_header">{item.msg_date} {item.msg_firstname}</div>
|
||||||
</div>
|
<span className="p-2" dangerouslySetInnerHTML={{__html: item.message}}></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
activeJobMesList.error ?
|
activeJobMesList.error ?
|
||||||
(
|
(
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr className='text-slate-500'>
|
<tr className='text-slate-500'>
|
||||||
<td className="p-2" colSpan={4}>Opps! an error occurred. Please try again!</td>
|
<td className="p-2" colSpan={4}>Opps! an error occurred. Please try again!</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr className='text-slate-500'>
|
<tr className='text-slate-500'>
|
||||||
<td className="p-2" colSpan={4}>No Message Found!</td>
|
<td className="p-2" colSpan={4}>No Message Found!</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* PAGINATION BUTTON */}
|
{/* PAGINATION BUTTON */}
|
||||||
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= activeJobMesList?.data?.length ? true : false} data={activeJobMesList?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
|
{/* <PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= activeJobMesList?.data?.length ? true : false} data={activeJobMesList?.data} start={indexOfFirstItem} stop={indexOfLastItem} /> */}
|
||||||
{/* END OF PAGINATION BUTTON */}
|
{/* END OF PAGINATION BUTTON */}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ function ActiveJobs(props) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="my-4 py-[20px] bg-white dark:bg-black px-4 rounded-2xl shadow-md lg:flex justify-between items-start space-y-4 lg:space-x-4 lg:space-y-0">
|
<div className="my-4 py-[20px] bg-white dark:bg-black px-4 rounded-2xl shadow-md lg:flex justify-between items-start space-y-4 lg:space-x-4 lg:space-y-0">
|
||||||
<div className="w-full lg:w-1/2">
|
<div className="w-full lg:w-1/2 mb-4 border-b pb-4 lg:pb-0 lg:mb-0 lg:border-b-0">
|
||||||
<div className="">
|
<div className="">
|
||||||
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
Actions
|
Actions
|
||||||
@@ -367,23 +367,25 @@ function ActiveJobs(props) {
|
|||||||
{/* TEXTAREA SECTION */}
|
{/* TEXTAREA SECTION */}
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
<div className="">
|
<div className="">
|
||||||
{/* <p className="relative py-2 my-2 text-lg font-bold text-slate-600 dark:text-black border-b-2 border-slate-300 tracking-wide after:absolute after:-bottom-0.5 after:content-[''] after:w-[100px] after:h-[2px] after:bg-sky-blue after:left-0">Message(s)</p> */}
|
<div
|
||||||
<div className="my-2 flex items-center border-b border-slate-300">
|
className="pl-7 my-2 flex items-center border-b border-slate-300 gap-3"
|
||||||
|
// className='ml-7 flex justify-start items-center gap-3'
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
name="message"
|
name="message"
|
||||||
onClick={(e) => setTab(e.target.name)}
|
onClick={(e) => setTab(e.target.name)}
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
className={`px-4 py-1 rounded-t-2xl ${
|
||||||
tab == "message" ? "border-sky-blue" : "border-slate-300"
|
tab == "message" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||||
} tracking-wide transition duration-200`}
|
}`}
|
||||||
>
|
>
|
||||||
Send Message
|
Send Message
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
name="files"
|
name="files"
|
||||||
onClick={(e) => setTab(e.target.name)}
|
onClick={(e) => setTab(e.target.name)}
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
className={`px-4 py-1 rounded-t-2xl ${
|
||||||
tab == "files" ? "border-sky-blue" : "border-slate-300"
|
tab == "files" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||||
} tracking-wide transition duration-200`}
|
}`}
|
||||||
>
|
>
|
||||||
Send Files
|
Send Files
|
||||||
</button>
|
</button>
|
||||||
@@ -402,7 +404,7 @@ function ActiveJobs(props) {
|
|||||||
<div className="files">
|
<div className="files">
|
||||||
<label
|
<label
|
||||||
htmlFor="file"
|
htmlFor="file"
|
||||||
className="h-20 btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
|
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
|
||||||
>
|
>
|
||||||
Select Files to Upload
|
Select Files to Upload
|
||||||
</label>
|
</label>
|
||||||
@@ -457,11 +459,11 @@ function ActiveJobs(props) {
|
|||||||
|
|
||||||
{/* Buttons Sections */}
|
{/* Buttons Sections */}
|
||||||
<div className="py-2 sm:flex sm:justify-end sm:items-center">
|
<div className="py-2 sm:flex sm:justify-end sm:items-center">
|
||||||
<div className="w-full sm:w-2/4 flex justify-between items-center space-x-2">
|
<div className="w-full sm:w-3/4 flex justify-between items-center space-x-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleClearAll}
|
onClick={handleClearAll}
|
||||||
className="border-gradient text-base tracking-wide px-4 py-3 rounded-full"
|
className="border-gradient text-base tracking-wide px-4 py-2 rounded-full"
|
||||||
>
|
>
|
||||||
<span className="text-gradient">Clear</span>
|
<span className="text-gradient">Clear</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -469,7 +471,7 @@ function ActiveJobs(props) {
|
|||||||
<button
|
<button
|
||||||
onClick={sendFile}
|
onClick={sendFile}
|
||||||
type="button"
|
type="button"
|
||||||
className="btn-gradient text-base tracking-wide px-4 py-3 rounded-full flex justify-center items-center"
|
className='btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center'
|
||||||
>
|
>
|
||||||
{requestStatus.loading ? (
|
{requestStatus.loading ? (
|
||||||
<LoadingSpinner size="6" color="sky-blue" />
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
@@ -493,7 +495,7 @@ function ActiveJobs(props) {
|
|||||||
<button
|
<button
|
||||||
onClick={sendTaskMessage}
|
onClick={sendTaskMessage}
|
||||||
type="button"
|
type="button"
|
||||||
className="btn-gradient text-base text-white tracking-wide px-4 py-3 rounded-full"
|
className='btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer'
|
||||||
>
|
>
|
||||||
{requestStatus.loading ? (
|
{requestStatus.loading ? (
|
||||||
<LoadingSpinner size="6" color="sky-blue" />
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
@@ -518,9 +520,9 @@ function ActiveJobs(props) {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={popUpHandler}
|
onClick={popUpHandler}
|
||||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center"
|
||||||
>
|
>
|
||||||
view all
|
View all
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{props.activeJobMesList.loading ? (
|
{props.activeJobMesList.loading ? (
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ function CurrentJobAction() {
|
|||||||
return (
|
return (
|
||||||
<div className='job-action dark:bg-black'>
|
<div className='job-action dark:bg-black'>
|
||||||
<p className="my-3 py-1 text-base active-owner">
|
<p className="my-3 py-1 text-base active-owner">
|
||||||
<table className="w-full text-sm text-left text-gray-500">
|
<table className="w-full text-sm text-left text-gray-500 ">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||||
|
|
||||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
<div>
|
||||||
Waiting for the completion message from the client before you can approve.
|
Waiting for the completion message from the client before you can approve.
|
||||||
</h1>
|
</div>
|
||||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -62,14 +62,14 @@ function CurrentTaskAction({jobDetails}) {
|
|||||||
return (
|
return (
|
||||||
<div className='job-action dark:bg-black'>
|
<div className='job-action dark:bg-black'>
|
||||||
|
|
||||||
<table className="w-full text-sm text-left text-gray-500 active-worker">
|
<table className="w-full text-sm text-left text-gray-500 active-worker ">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
<div>
|
||||||
I completed this task and ready for review and acceptance.
|
I completed this task and ready for review and acceptance.
|
||||||
</h1>
|
</div>
|
||||||
{/*<div className="flex flex-col flex-[0.9]">*/}
|
{/*<div className="flex flex-col flex-[0.9]">*/}
|
||||||
|
|
||||||
{/*</div>*/}
|
{/*</div>*/}
|
||||||
|
|||||||
@@ -107,19 +107,18 @@ function PastDueJobAction({jobDetails}) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||||
|
|
||||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
<div className="dark:text-red-700">
|
||||||
Time allocated has passed
|
Time allocated has passed
|
||||||
</h1>
|
</div>
|
||||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div className="flex justify-center items-center">
|
<div className="flex justify-center items-center">
|
||||||
<button type="button" onClick={popUpHandler} className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
<button type="button" onClick={popUpHandler} className="w-[180px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||||
Cancel or Extend Timeline
|
Cancel or Extend Timeline
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ function PastDueTaskAction() {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||||
|
|
||||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
<div>
|
||||||
You have missed the allocated time
|
You have missed the allocated time
|
||||||
</h1>
|
</div>
|
||||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -96,11 +96,11 @@ function ReviewJobAction({jobDetails}) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||||
|
|
||||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
<div>
|
||||||
This Job is Ready for your review
|
This Job is Ready for your review
|
||||||
</h1>
|
</div>
|
||||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
|
|
||||||
function ReviewTaskAction() {
|
function ReviewTaskAction() {
|
||||||
return (
|
return (
|
||||||
<div className='job-action dark:bg-black'>
|
<div className='job-action dark:bg-black task_action_panel'>
|
||||||
<p className="my-3 py-1 text-base text-dark-gray dark:text-white">
|
<p className="my-3 py-1 text-base text-dark-gray dark:text-white">
|
||||||
Waiting for the completion message from the client before you can approve. Worker True & Review Job
|
Waiting for the completion message from the client before you can approve. Worker True & Review Job
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -110,13 +110,13 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={index}
|
key={index}
|
||||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
<td className="py-9">
|
<td className="py-9">
|
||||||
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
|
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
|
||||||
<div className="flex space-x-2 items-center job-items w-full">
|
<div className="flex space-x-2 items-center job-items w-full">
|
||||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||||
<img src={localImgLoad(`images/taskbanners/${value.banner}`)} alt="data" className="w-full h-full rounded-full" />
|
<img src={localImgLoad(`images/taskbanners/${value.banner ? value.banner : 'default.jpg'}`)} alt="data" className="w-full h-full rounded-full" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col flex-[0.9]">
|
<div className="flex flex-col flex-[0.9]">
|
||||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||||
@@ -175,7 +175,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
}}
|
}}
|
||||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
>
|
>
|
||||||
Manage
|
Assign
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -204,7 +204,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
{MyJobList.loading ? (
|
{MyJobList.loading ? (
|
||||||
<LoadingSpinner size="16" color="sky-blue" />
|
<LoadingSpinner size="16" color="sky-blue" />
|
||||||
) : (
|
) : (
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[520px]">
|
||||||
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
<tbody>
|
<tbody>
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
|
|||||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
import localImgLoad from "../../lib/localImgLoad";
|
import localImgLoad from "../../lib/localImgLoad";
|
||||||
|
|
||||||
|
|
||||||
export default function MyPendingJobTable({ MyJobList, className }) {
|
export default function MyPendingJobTable({ MyJobList, className }) {
|
||||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
|||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="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">
|
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||||
<img
|
<img
|
||||||
src={localImgLoad(`images/taskbanners/${value.banner}`)}
|
src={localImgLoad(`images/taskbanners/${value.banner || "default.jpg"}`)}
|
||||||
alt="data"
|
alt="data"
|
||||||
className="w-full h-full rounded-full"
|
className="w-full h-full rounded-full"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ import { Link } from "react-router-dom";
|
|||||||
import Layout from "../Partials/Layout";
|
import Layout from "../Partials/Layout";
|
||||||
import CommonHead from "../UserHeader/CommonHead";
|
import CommonHead from "../UserHeader/CommonHead";
|
||||||
import MyPendingJobTable from "./MyPendingJobTable";
|
import MyPendingJobTable from "./MyPendingJobTable";
|
||||||
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
export default function MyPendingJobs(props) {
|
export default function MyPendingJobs(props) {
|
||||||
const [selectTab, setValue] = useState("today");
|
const [selectTab, setValue] = useState("today");
|
||||||
const filterHandler = (value) => {
|
const filterHandler = (value) => {
|
||||||
setValue(value);
|
setValue(value);
|
||||||
};
|
};
|
||||||
console.log("AMEYE LOC1", props.MyJobList);
|
// console.log("AMEYE LOC1", props.MyJobList);
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<CommonHead
|
<CommonHead
|
||||||
@@ -35,7 +36,13 @@ export default function MyPendingJobs(props) {
|
|||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MyPendingJobTable MyJobList={props.MyJobList} />
|
{props.MyJobList.loading ?
|
||||||
|
<div className="bg-white">
|
||||||
|
<LoadingSpinner size='16' color='sky-blue' height='min-h-[300px]' />
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<MyPendingJobTable MyJobList={props.MyJobList.data} />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useRef, useState } from "react";
|
|||||||
import OfferCard from "../Cards/OfferCard";
|
import OfferCard from "../Cards/OfferCard";
|
||||||
import Icons from "../Helpers/Icons";
|
import Icons from "../Helpers/Icons";
|
||||||
import SliderCom from "../Helpers/SliderCom";
|
import SliderCom from "../Helpers/SliderCom";
|
||||||
import OfferJobPopout from "../jobPopout/OfferJobPopout";
|
import FamilyOfferJobPopout from "../jobPopout/FamilyOfferJobPopout";
|
||||||
|
|
||||||
export default function MyOffersFamilyTable({ className, familyOffers }) {
|
export default function MyOffersFamilyTable({ className, familyOffers }) {
|
||||||
let [offerPopout, setOfferPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
let [offerPopout, setOfferPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||||
@@ -127,7 +127,7 @@ export default function MyOffersFamilyTable({ className, familyOffers }) {
|
|||||||
|
|
||||||
{/* Offer Job Popout */}
|
{/* Offer Job Popout */}
|
||||||
{offerPopout.show && (
|
{offerPopout.show && (
|
||||||
<OfferJobPopout
|
<FamilyOfferJobPopout
|
||||||
details={offerPopout.data}
|
details={offerPopout.data}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setOfferPopout({ show: false, data: {} });
|
setOfferPopout({ show: false, data: {} });
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
import React, {useState} from 'react'
|
|
||||||
import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
|
||||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
|
||||||
import { useNavigate, useLocation } from 'react-router-dom'
|
|
||||||
import InputCom from '../Helpers/Inputs/InputCom'
|
|
||||||
|
|
||||||
import AddFundDollars from './AddFundDollars'
|
|
||||||
|
|
||||||
function AddFund({payment}) {
|
|
||||||
|
|
||||||
const navigate = useNavigate()
|
|
||||||
const {currency} = useLocation()?.state //GETS THE USER CURRENCY FOR ADD FUND
|
|
||||||
|
|
||||||
//STATE FOR CONTROLLED INPUT
|
|
||||||
let [input, setInput] = useState('')
|
|
||||||
|
|
||||||
let [inputError, setInputError] = useState('')
|
|
||||||
|
|
||||||
// FUNCTION TO HANDLE INPUT CHANGE
|
|
||||||
const handleChange = ({target:{name, value}}) => {
|
|
||||||
setInput(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
|
||||||
const handleSubmit = () => {
|
|
||||||
setInputError('')
|
|
||||||
if(!input || input == '0'){
|
|
||||||
setInputError('Please Enter Amount')
|
|
||||||
return setTimeout(()=>{setInputError('')}, 5000)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isNaN(input)){
|
|
||||||
setInputError('Amount must be a Number')
|
|
||||||
return setTimeout(()=>{setInputError('')}, 5000)
|
|
||||||
}
|
|
||||||
|
|
||||||
const stateData = {amount: Number(input), currency: 'naira'}
|
|
||||||
navigate('confirm-add-fund', {state: stateData})
|
|
||||||
|
|
||||||
setInput('')
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{/* heading */}
|
|
||||||
{/* <div className="sm:flex justify-between items-center mb-6">
|
|
||||||
<div className="w-full flex justify-start space-x-3 items-center">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="min-w-[45px] h-auto text-[#374557] border border-sky-blue p-1 rounded-full"
|
|
||||||
onClick={() =>
|
|
||||||
navigate('/my-wallet', { replace: true })
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="35"
|
|
||||||
height="35"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="skyblue"
|
|
||||||
>
|
|
||||||
<path d="M19 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H19v-2z" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
|
||||||
Add Credit
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div className="slider-btns flex space-x-4">
|
|
||||||
<div
|
|
||||||
onClick={() => filterHandler("today")}
|
|
||||||
className="relative"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
|
||||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
|
||||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
|
||||||
{/*<h2 className='md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Add Credit with Account Deposit</h2>*/}
|
|
||||||
{/*<hr />*/}
|
|
||||||
<form className='md:p-8 p-4 add-fund-info'>
|
|
||||||
<div className="field w-full mb-6">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
label={currency == 'US Dollars' ? "Amount (USD)" : "Amount (Naira)"}
|
|
||||||
type="text"
|
|
||||||
name="amount"
|
|
||||||
placeholder="0"
|
|
||||||
value={input}
|
|
||||||
inputHandler={handleChange}
|
|
||||||
/>
|
|
||||||
{inputError && <p className='text-base text-red-500'>{inputError}</p>}
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
|
||||||
{currency == 'US Dollars' &&
|
|
||||||
<div className='w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow'>
|
|
||||||
<AddFundDollars setInputError={setInputError} input={input} setInput={setInput} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
{/* HIDES THIS BUTTON IF CURENCY IS NAIRA */}
|
|
||||||
{currency != 'US Dollars' &&
|
|
||||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
|
||||||
<button
|
|
||||||
onClick={handleSubmit}
|
|
||||||
type="button"
|
|
||||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
>
|
|
||||||
<span className="text-white">Continue</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
|
|
||||||
{currency != 'US Dollars' &&
|
|
||||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
|
||||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
|
||||||
<h2 className='text-gray-900 dark:text-white text-xl lg:text-2xl font-medium'>Recent Activity</h2>
|
|
||||||
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
|
||||||
{payment.loading ?
|
|
||||||
<LoadingSpinner size='16' color='sky-blue' />
|
|
||||||
:
|
|
||||||
<RecentActivityTable payment={payment}/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AddFund
|
|
||||||
@@ -1,562 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import usersService from "../../services/UsersService";
|
|
||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
|
||||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
|
||||||
|
|
||||||
import { Form, Formik } from "formik";
|
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
|
||||||
name: Yup.string()
|
|
||||||
.min(3, "Minimum 3 characters")
|
|
||||||
.max(50, "Maximum 50 characters")
|
|
||||||
.required("Name is required"),
|
|
||||||
cardNum: Yup.string()
|
|
||||||
.min(3, "Minimum 3 characters")
|
|
||||||
.max(25, "Maximum 25 characters")
|
|
||||||
.required("Card Number is required"),
|
|
||||||
code: Yup.string()
|
|
||||||
.min(3, "Minimum 3 characters")
|
|
||||||
.max(25, "Maximum 25 characters")
|
|
||||||
.required("Postal Code is required"),
|
|
||||||
state: Yup.string()
|
|
||||||
.min(3, "Minimum 3 characters")
|
|
||||||
.max(25, "Maximum 25 characters")
|
|
||||||
.required("State is required"),
|
|
||||||
address: Yup.string()
|
|
||||||
.min(3, "Minimum 3 characters")
|
|
||||||
.max(50, "Maximum 50 characters")
|
|
||||||
.required("Address is required"),
|
|
||||||
expirationYear: Yup.string()
|
|
||||||
.min(4, "Minimum 4 characters")
|
|
||||||
.max(4, "Maximum 4 characters")
|
|
||||||
.required("Expiration Year is required"),
|
|
||||||
expirationMonth: Yup.string()
|
|
||||||
.min(1, "Minimum 1 characters")
|
|
||||||
.max(2, "Maximum 2 characters")
|
|
||||||
.required("Expiration Month is required"),
|
|
||||||
cvv: Yup.string()
|
|
||||||
.min(3, "Minimum 3 characters")
|
|
||||||
.max(4, "Maximum 4 characters")
|
|
||||||
.required("CVV Year is required"),
|
|
||||||
});
|
|
||||||
|
|
||||||
const initialValues = {
|
|
||||||
name: "",
|
|
||||||
cardNum: "",
|
|
||||||
code: "",
|
|
||||||
state: "",
|
|
||||||
address: "",
|
|
||||||
expirationYear: "",
|
|
||||||
expirationMonth: "",
|
|
||||||
cvv: "",
|
|
||||||
};
|
|
||||||
|
|
||||||
function AddFundDollars(props) {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
let apiCall = new usersService();
|
|
||||||
|
|
||||||
let [tab, setTab] = useState("previous"); //STATE FOR SWITCHING BETWEEN TABS
|
|
||||||
|
|
||||||
let [prevCardDetails, setPrevCardDetails] = useState(null); // STATE TO HOLD PREVIOUS CARD SELECTED
|
|
||||||
|
|
||||||
let [payListCard, setPayListCard] = useState({ loading: true, data: [] }); //USER PREVIOUS CARDS
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
|
||||||
const indexOfFirstItem = Number(currentPage);
|
|
||||||
const indexOfLastItem =
|
|
||||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
|
||||||
const currentPreviousCards = payListCard?.data?.slice(
|
|
||||||
indexOfFirstItem,
|
|
||||||
indexOfLastItem
|
|
||||||
);
|
|
||||||
|
|
||||||
const handlePagination = (e) => {
|
|
||||||
handlePagingFunc(e, setCurrentPage);
|
|
||||||
};
|
|
||||||
|
|
||||||
// FUNCTION TO SUBMIT
|
|
||||||
const handleSubmit = (values, helpers) => {
|
|
||||||
props.setInputError("");
|
|
||||||
if (!props.input || props.input == "0") {
|
|
||||||
props.setInputError("Please Enter Amount");
|
|
||||||
return setTimeout(() => {
|
|
||||||
props.setInputError("");
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNaN(props.input)) {
|
|
||||||
props.setInputError("Amount must be a Number");
|
|
||||||
return setTimeout(() => {
|
|
||||||
props.setInputError("");
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
if (tab == "previous") {
|
|
||||||
const stateData = { amount: Number(props.input), currency: "dollars" };
|
|
||||||
navigate("confirm-add-fund", { state: stateData }); // State will change later dummy for now
|
|
||||||
}
|
|
||||||
if (tab == "new") {
|
|
||||||
const stateData = {
|
|
||||||
amount: Number(props.input),
|
|
||||||
currency: "dollars",
|
|
||||||
...values,
|
|
||||||
};
|
|
||||||
navigate("confirm-add-fund", { state: stateData }); // State will change later dummy for now
|
|
||||||
}
|
|
||||||
props.setInput("");
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
apiCall
|
|
||||||
.payListCard()
|
|
||||||
.then((res) => {
|
|
||||||
setPayListCard({ loading: false, data: res.data.result_list });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("PAYCARDLIST ERROR", err);
|
|
||||||
setPayListCard({ loading: false, data: [] });
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="w-full">
|
|
||||||
{/* switch button */}
|
|
||||||
<div className="my-1 flex items-center gap-2">
|
|
||||||
<label
|
|
||||||
onClick={() => setTab("previous")}
|
|
||||||
htmlFor="previous"
|
|
||||||
className="cursor-pointer flex items-center gap-1"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
id="previous"
|
|
||||||
name="card-option"
|
|
||||||
checked={tab === "previous"}
|
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
|
||||||
tab == "previous" ? "" : ""
|
|
||||||
} tracking-wide transition duration-200`}
|
|
||||||
/>
|
|
||||||
Previous Cards
|
|
||||||
</label>
|
|
||||||
<label
|
|
||||||
onClick={() => setTab("new")}
|
|
||||||
htmlFor="new"
|
|
||||||
className="cursor-pointer flex items-center gap-1"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
id="new"
|
|
||||||
type="radio"
|
|
||||||
name="card-option"
|
|
||||||
checked={tab === "new"}
|
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
|
||||||
tab == "new" ? "" : ""
|
|
||||||
} tracking-wide transition duration-200`}
|
|
||||||
/>
|
|
||||||
Add New Card
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{/* END OF switch button */}
|
|
||||||
|
|
||||||
{/* previous tab */}
|
|
||||||
{tab == "previous" ? (
|
|
||||||
<div className="p-4 previous-details w-full min-h-[177px] flex flex-col justify-between items-center">
|
|
||||||
{payListCard.loading ? (
|
|
||||||
<LoadingSpinner size="10" color="sky-blue" />
|
|
||||||
) : payListCard?.data?.length ? (
|
|
||||||
<select className="my-3 w-full rounded-full p-4 outline-none border-none">
|
|
||||||
<option value="">Select a card</option>
|
|
||||||
{currentPreviousCards.map((item, index) => (
|
|
||||||
<option key={index} className={index != 0 && "border-t-2"}>
|
|
||||||
<div className="my-2 flex items-center gap-5">
|
|
||||||
{/* <input
|
|
||||||
type="radio"
|
|
||||||
className="w-8 h-8"
|
|
||||||
name="card"
|
|
||||||
value="value"
|
|
||||||
/> */}
|
|
||||||
<div className="card-details">
|
|
||||||
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
|
||||||
{item.description} Card
|
|
||||||
</h1>
|
|
||||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
|
||||||
Bank **************{item.digits}
|
|
||||||
</p>
|
|
||||||
{/* <div className="w-full sm:flex items-center gap-5">
|
|
||||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
|
||||||
{item.added}
|
|
||||||
</p>
|
|
||||||
<p className="text-sm font-bold text-green-700 dark:text-white tracking-wide">
|
|
||||||
Verified
|
|
||||||
</p>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <td>
|
|
||||||
<button
|
|
||||||
// onClick={handleSubmit}
|
|
||||||
type="button"
|
|
||||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
>
|
|
||||||
<span className="text-white">Manage</span>
|
|
||||||
</button>
|
|
||||||
</td> */}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
) : (
|
|
||||||
<div className="w-full flex flex-col items-center">
|
|
||||||
<p className="my-5 text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
|
||||||
No Previous Card Found!
|
|
||||||
</p>
|
|
||||||
<button
|
|
||||||
onClick={() => setTab("new")}
|
|
||||||
type="button"
|
|
||||||
className="my-5 px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
>
|
|
||||||
<span className="text-white">Add Card</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{/* PAGINATION BUTTON */}
|
|
||||||
{/* <div className="w-full">
|
|
||||||
<PaginatedList
|
|
||||||
onClick={handlePagination}
|
|
||||||
prev={currentPage == 0 ? true : false}
|
|
||||||
next={
|
|
||||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
|
||||||
payListCard?.data?.length
|
|
||||||
? true
|
|
||||||
: false
|
|
||||||
}
|
|
||||||
data={payListCard?.data}
|
|
||||||
start={indexOfFirstItem}
|
|
||||||
stop={indexOfLastItem}
|
|
||||||
/>
|
|
||||||
</div> */}
|
|
||||||
{/* END OF PAGINATION BUTTON */}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="new-details w-full max-h-[19.063rem] overflow-y-scroll">
|
|
||||||
<div className="w-full flex flex-col justify-between">
|
|
||||||
<Formik
|
|
||||||
initialValues={initialValues}
|
|
||||||
validationSchema={validationSchema}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
>
|
|
||||||
{(props) => {
|
|
||||||
return (
|
|
||||||
<Form>
|
|
||||||
<div className="flex flex-col-reverse sm:flex-row">
|
|
||||||
<div className="flex-1 sm:mr-10">
|
|
||||||
<div className="fields w-full">
|
|
||||||
{/* inputs starts here */}
|
|
||||||
{/* Name */}
|
|
||||||
<div className="field w-full my-6">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
spanTag="*"
|
|
||||||
label="Name on Card"
|
|
||||||
type="text"
|
|
||||||
name="name"
|
|
||||||
placeholder="DUMMY NAME"
|
|
||||||
value={props.values.name}
|
|
||||||
inputHandler={props.handleChange}
|
|
||||||
blurHandler={props.handleBlur}
|
|
||||||
/>
|
|
||||||
{props.errors.name && props.touched.name && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.name}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* CARD NUMBER */}
|
|
||||||
<div className="field w-full mb-6">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
spanTag="*"
|
|
||||||
iconName="master-card visa-card atm-card"
|
|
||||||
label="Card Number"
|
|
||||||
type="text"
|
|
||||||
name="cardNum"
|
|
||||||
placeholder="Enter Card Number"
|
|
||||||
value={props.values.cardNum}
|
|
||||||
inputHandler={props.handleChange}
|
|
||||||
blurHandler={props.handleBlur}
|
|
||||||
/>
|
|
||||||
{props.errors.cardNum &&
|
|
||||||
props.touched.cardNum && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.cardNum}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{/* EXPIRE YEAR, YEAR AND CVV */}
|
|
||||||
<div className="sm:grid gap-5 grid-cols-3 mb-6">
|
|
||||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
|
||||||
<div className="select-option">
|
|
||||||
<div
|
|
||||||
className={`flex items-center justify-between mb-2.5`}
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
|
||||||
htmlFor="expiration"
|
|
||||||
>
|
|
||||||
Expiration Month{" "}
|
|
||||||
<span className="text-red-700 text-sm tracking-wide">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
|
||||||
>
|
|
||||||
<select
|
|
||||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
|
|
||||||
value={props.values.expirationMonth}
|
|
||||||
onChange={props.handleChange}
|
|
||||||
onBlur={props.handleBlur}
|
|
||||||
name="expirationMonth"
|
|
||||||
>
|
|
||||||
<option value="">Select...</option>
|
|
||||||
{expireMonth?.length &&
|
|
||||||
expireMonth.map((item, index) => (
|
|
||||||
<option
|
|
||||||
key={index}
|
|
||||||
value={item.value}
|
|
||||||
>
|
|
||||||
{item.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{props.errors.expirationMonth &&
|
|
||||||
props.touched.expirationMonth && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.expirationMonth}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
|
||||||
<div className="select-option">
|
|
||||||
<div
|
|
||||||
className={`flex items-center justify-between mb-2.5`}
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
|
||||||
htmlFor="expiration"
|
|
||||||
>
|
|
||||||
Expiration Year{" "}
|
|
||||||
<span className="text-red-700 text-sm tracking-wide">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
|
||||||
>
|
|
||||||
<select
|
|
||||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
|
|
||||||
value={props.values.expirationYear}
|
|
||||||
onChange={props.handleChange}
|
|
||||||
onBlur={props.handleBlur}
|
|
||||||
name="expirationYear"
|
|
||||||
>
|
|
||||||
<option value="">Select...</option>
|
|
||||||
{expireYear?.length &&
|
|
||||||
expireYear.map((item, index) => (
|
|
||||||
<option key={index} value={item}>
|
|
||||||
{item}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{props.errors.expirationYear &&
|
|
||||||
props.touched.expirationYear && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.expirationYear}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="field w-full col-span-1">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
spanTag="*"
|
|
||||||
iconName="atm-card"
|
|
||||||
label="CVV"
|
|
||||||
type="text"
|
|
||||||
name="cvv"
|
|
||||||
placeholder="CVV"
|
|
||||||
value={props.values.cvv}
|
|
||||||
inputHandler={props.handleChange}
|
|
||||||
blurHandler={props.handleBlur}
|
|
||||||
/>
|
|
||||||
{props.errors.cvv && props.touched.cvv && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.cvv}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* Address */}
|
|
||||||
<div className="field w-full my-6">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
spanTag="*"
|
|
||||||
label="Billing Address"
|
|
||||||
type="text"
|
|
||||||
name="address"
|
|
||||||
placeholder="Billing Address"
|
|
||||||
value={props.values.Address}
|
|
||||||
inputHandler={props.handleChange}
|
|
||||||
blurHandler={props.handleBlur}
|
|
||||||
/>
|
|
||||||
{props.errors.address &&
|
|
||||||
props.touched.address && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.address}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{/* postal code and state */}
|
|
||||||
<div className="sm:grid gap-5 grid-cols-3 mb-6">
|
|
||||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
spanTag="*"
|
|
||||||
label="Postal Code"
|
|
||||||
type="text"
|
|
||||||
name="code"
|
|
||||||
placeholder="Postal Code"
|
|
||||||
value={props.values.code}
|
|
||||||
inputHandler={props.handleChange}
|
|
||||||
blurHandler={props.handleBlur}
|
|
||||||
/>
|
|
||||||
{props.errors.code && props.touched.code && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.code}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="field w-full col-span-1">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
spanTag="*"
|
|
||||||
label="State"
|
|
||||||
type="text"
|
|
||||||
name="state"
|
|
||||||
placeholder="State"
|
|
||||||
value={props.values.state}
|
|
||||||
inputHandler={props.handleChange}
|
|
||||||
blurHandler={props.handleBlur}
|
|
||||||
/>
|
|
||||||
{props.errors.state && props.touched.state && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.state}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <div className="w-full">
|
|
||||||
{requestStatus.message != "" && (
|
|
||||||
<p
|
|
||||||
className={`text-center text-base ${
|
|
||||||
requestStatus.status ? "text-green-800" : "text-red-600"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{requestStatus.message}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
|
||||||
<div className="flex items-center space-x-4 mr-9">
|
|
||||||
<Link
|
|
||||||
to="/"
|
|
||||||
className="text-18 text-light-red tracking-wide "
|
|
||||||
>
|
|
||||||
<span className="border-b dark:border-[#5356fb29] border-light-red">
|
|
||||||
{" "}
|
|
||||||
Cancel
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{requestStatus.loading ? (
|
|
||||||
<LoadingSpinner size="8" color="sky-blue" />
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
>
|
|
||||||
Update Profile
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
className="py-1 px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
>
|
|
||||||
<span className="text-white">Continue</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Formik>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{tab == "previous" && (
|
|
||||||
<div className="md:py-8 px-[38px] add-fund-btn flex justify-end items-center py-4">
|
|
||||||
<button
|
|
||||||
onClick={handleSubmit}
|
|
||||||
type="button"
|
|
||||||
className="px-4 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
>
|
|
||||||
<span className="text-white">Continue</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AddFundDollars;
|
|
||||||
|
|
||||||
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
|
|
||||||
const expireYear = [];
|
|
||||||
let currentYear = new Date().getFullYear();
|
|
||||||
for (let i = 0; i <= 6; i++) {
|
|
||||||
expireYear.push(currentYear + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
|
|
||||||
let month = [
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
const expireMonth = [];
|
|
||||||
for (let i = 0; i < month.length; i++) {
|
|
||||||
expireMonth.push({ name: month[i], value: i + 1 });
|
|
||||||
}
|
|
||||||
@@ -1,115 +1,129 @@
|
|||||||
import React, {useState} from 'react'
|
import React from "react";
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from "react-router-dom";
|
||||||
import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
import PurchasesTable from './WalletComponent/PurchasesTable'
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import CouponTable from './WalletComponent/CouponTable'
|
|
||||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
|
||||||
import { PriceFormatter } from '../Helpers/PriceFormatter'
|
|
||||||
|
|
||||||
function Balance({wallet, coupon}) {
|
function Balance({ wallet, coupon }) {
|
||||||
return (
|
return (
|
||||||
<div className="content-wrapper">
|
<div className="content-wrapper">
|
||||||
{/* heading */}
|
{/* heading */}
|
||||||
<div className="sm:flex justify-between items-center mb-6">
|
<div className="sm:flex justify-between items-center mb-6">
|
||||||
<div className="mb-5 sm:mb-0">
|
<div className="mb-5 sm:mb-0">
|
||||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||||
Wallet
|
Wallet
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
|
||||||
<div className="slider-btns flex space-x-4">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>
|
|
||||||
{/* WALLET SECTION */}
|
|
||||||
<div className="lg:w-4/4 w-full mb-10 lg:mb-0">
|
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full bg-white dark:bg-dark-white rounded-2xl shadow min-h-[520px]">
|
|
||||||
<div className='flex items-baseline justify-between'>
|
|
||||||
{/*<h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Wallet</h2>*/}
|
|
||||||
{/*<p className='text-base text-slate-500 dark:text-white'>Add New Wallet</p>*/}
|
|
||||||
</div>
|
|
||||||
{/* wallet balance */}
|
|
||||||
{wallet.loading ?
|
|
||||||
<LoadingSpinner size='16' color='sky-blue' />
|
|
||||||
:
|
|
||||||
wallet.data.length ?
|
|
||||||
wallet.data.map((item, index)=> (
|
|
||||||
<div key={index} className="p-3 md:flex items-center flex-wrap my-3 border-t-2 border-slate-400 wallet-box">
|
|
||||||
<div className='text-slate-900 w-full md:w-1/2 flex space-x-3 items-start justify-start'>
|
|
||||||
<div className='balance-info bal-col1'>
|
|
||||||
<p className='py-2'></p>
|
|
||||||
<span className='text-xl text-dark-gray dark:text-white'><b>{item.description}</b></span>
|
|
||||||
<p className='text-base text-slate-500'>{item.symbol}</p>
|
|
||||||
</div>
|
|
||||||
<div className='balance-info'>
|
|
||||||
<p className='py-2'>Balance</p>
|
|
||||||
<span className='py-1 px-2 bg-green-100 text-green-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.amount * 0.01, item.code)}</span>
|
|
||||||
</div>
|
|
||||||
<div className='balance-info'>
|
|
||||||
<p className='py-2'>Escrow</p>
|
|
||||||
<span className='py-1 px-2 bg-red-100 text-red-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.escrow * 0.01, item.code)}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='w-full my-2 md:my-0 md:w-1/2 flex space-x-2 items-center justify-start md:justify-end'>
|
|
||||||
{
|
|
||||||
item.action_type != 'AC_AD_FD_ONLY' ?
|
|
||||||
<Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:''
|
|
||||||
}
|
|
||||||
<Link to='add-fund' state={{currency:item.description}} className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'>
|
|
||||||
<span className="">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="38"
|
|
||||||
height="38" viewBox="0 0 42 42" fill="none"><path
|
|
||||||
d="M21 0C16.8466 0 12.7865 1.23163 9.33303 3.53914C5.8796 5.84665 3.18798 9.1264 1.59854 12.9636C0.00909901 16.8009 -0.406771 21.0233 0.403518 25.0969C1.21381 29.1705 3.21386 32.9123 6.15077 35.8492C9.08767 38.7861 12.8295 40.7862 16.9031 41.5965C20.9767 42.4068 25.1991 41.9909 29.0364 40.4015C32.8736 38.812 36.1534 36.1204 38.4609 32.667C40.7684 29.2135 42 25.1534 42 21C41.994 15.4323 39.7796 10.0944 35.8426 6.15741C31.9056 2.22045 26.5677 0.00602189 21 0ZM28 22.75H22.75V28C22.75 28.4641 22.5656 28.9092 22.2374 29.2374C21.9093 29.5656 21.4641 29.75 21 29.75C20.5359 29.75 20.0908 29.5656 19.7626 29.2374C19.4344 28.9092 19.25 28.4641 19.25 28V22.75H14C13.5359 22.75 13.0908 22.5656 12.7626 22.2374C12.4344 21.9092 12.25 21.4641 12.25 21C12.25 20.5359 12.4344 20.0907 12.7626 19.7626C13.0908 19.4344 13.5359 19.25 14 19.25H19.25V14C19.25 13.5359 19.4344 13.0908 19.7626 12.7626C20.0908 12.4344 20.5359 12.25 21 12.25C21.4641 12.25 21.9093 12.4344 22.2374 12.7626C22.5656 13.0908 22.75 13.5359 22.75 14V19.25H28C28.4641 19.25 28.9093 19.4344 29.2374 19.7626C29.5656 20.0907 29.75 20.5359 29.75 21C29.75 21.4641 29.5656 21.9092 29.2374 22.2374C28.9093 22.5656 28.4641 22.75 28 22.75Z"
|
|
||||||
fill="white"></path>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
<span className='text-white'>Add Credit</span>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
:
|
|
||||||
wallet.error ?
|
|
||||||
(
|
|
||||||
<div className="md:flex items-center flex-wrap mt-3">
|
|
||||||
<p className='text-base'>Opps! An Error occurred, please try again</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
:
|
|
||||||
(
|
|
||||||
<div className="md:flex items-center flex-wrap mt-3">
|
|
||||||
<p className='text-base'>No Wallets Found!</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{/* end of wallet balance */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* END OF WALLET SECTION */}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/*<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>*/}
|
|
||||||
|
|
||||||
{/* /!* COUPON SECTION *!/*/}
|
|
||||||
{/* <div className="lg:w-3/4 w-full mb-10 lg:mb-0">*/}
|
|
||||||
{/* <div className="wallet w-full md:p-8 p-4 h-full max-h-[500px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">*/}
|
|
||||||
{/* <h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Coupons</h2>*/}
|
|
||||||
{/* {coupon.loading ?*/}
|
|
||||||
{/* <LoadingSpinner size='16' color='sky-blue' />*/}
|
|
||||||
{/* :*/}
|
|
||||||
{/* <CouponTable coupon={coupon} />*/}
|
|
||||||
{/* }*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* /!* END OF COUPON SECTION *!/*/}
|
|
||||||
|
|
||||||
{/*</div>*/}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
<div className="slider-btns flex space-x-4"></div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||||
|
{/* WALLET SECTION */}
|
||||||
|
<div className="lg:w-4/4 w-full mb-10 lg:mb-0">
|
||||||
|
<div className="wallet w-full md:p-8 p-4 h-full bg-white dark:bg-dark-white rounded-2xl shadow min-h-[520px]">
|
||||||
|
<div className="flex items-baseline justify-between">
|
||||||
|
{/*<h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Wallet</h2>*/}
|
||||||
|
{/*<p className='text-base text-slate-500 dark:text-white'>Add New Wallet</p>*/}
|
||||||
|
</div>
|
||||||
|
{/* wallet balance */}
|
||||||
|
{wallet.loading ? (
|
||||||
|
<LoadingSpinner size="16" color="sky-blue" />
|
||||||
|
) : wallet.data.length ? (
|
||||||
|
wallet.data.map((item, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="p-3 md:flex items-center flex-wrap my-3 border-t-2 border-slate-400 wallet-box"
|
||||||
|
>
|
||||||
|
<div className="text-slate-900 w-full md:w-1/2 flex space-x-3 items-start justify-start">
|
||||||
|
<div className="balance-info bal-col1">
|
||||||
|
<p className="py-2"></p>
|
||||||
|
<span className="text-xl text-dark-gray dark:text-white">
|
||||||
|
<b>{item.description}</b>
|
||||||
|
</span>
|
||||||
|
<p className="text-base text-slate-500">{item.symbol}</p>
|
||||||
|
</div>
|
||||||
|
<div className="balance-info">
|
||||||
|
<p className="py-2">Balance</p>
|
||||||
|
<span className="py-1 px-2 bg-green-100 text-green-500 rounded-lg flex flex-start gap-1">
|
||||||
|
{PriceFormatter(item.amount * 0.01, item.code)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="balance-info">
|
||||||
|
<p className="py-2">Escrow</p>
|
||||||
|
<span className="py-1 px-2 bg-red-100 text-red-500 rounded-lg flex flex-start gap-1">
|
||||||
|
{PriceFormatter(item.escrow * 0.01, item.code)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full my-2 md:my-0 md:w-1/2 flex space-x-2 items-center justify-start md:justify-end">
|
||||||
|
{item.action_type != "AC_AD_FD_ONLY" ? (
|
||||||
|
<Link
|
||||||
|
to="transfer-fund"
|
||||||
|
className="px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white"
|
||||||
|
>
|
||||||
|
Transfer
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<Link
|
||||||
|
to="add-fund"
|
||||||
|
state={{ currency: item.description }}
|
||||||
|
className="px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white"
|
||||||
|
>
|
||||||
|
<span className="">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="38"
|
||||||
|
height="38"
|
||||||
|
viewBox="0 0 42 42"
|
||||||
|
fill="none"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M21 0C16.8466 0 12.7865 1.23163 9.33303 3.53914C5.8796 5.84665 3.18798 9.1264 1.59854 12.9636C0.00909901 16.8009 -0.406771 21.0233 0.403518 25.0969C1.21381 29.1705 3.21386 32.9123 6.15077 35.8492C9.08767 38.7861 12.8295 40.7862 16.9031 41.5965C20.9767 42.4068 25.1991 41.9909 29.0364 40.4015C32.8736 38.812 36.1534 36.1204 38.4609 32.667C40.7684 29.2135 42 25.1534 42 21C41.994 15.4323 39.7796 10.0944 35.8426 6.15741C31.9056 2.22045 26.5677 0.00602189 21 0ZM28 22.75H22.75V28C22.75 28.4641 22.5656 28.9092 22.2374 29.2374C21.9093 29.5656 21.4641 29.75 21 29.75C20.5359 29.75 20.0908 29.5656 19.7626 29.2374C19.4344 28.9092 19.25 28.4641 19.25 28V22.75H14C13.5359 22.75 13.0908 22.5656 12.7626 22.2374C12.4344 21.9092 12.25 21.4641 12.25 21C12.25 20.5359 12.4344 20.0907 12.7626 19.7626C13.0908 19.4344 13.5359 19.25 14 19.25H19.25V14C19.25 13.5359 19.4344 13.0908 19.7626 12.7626C20.0908 12.4344 20.5359 12.25 21 12.25C21.4641 12.25 21.9093 12.4344 22.2374 12.7626C22.5656 13.0908 22.75 13.5359 22.75 14V19.25H28C28.4641 19.25 28.9093 19.4344 29.2374 19.7626C29.5656 20.0907 29.75 20.5359 29.75 21C29.75 21.4641 29.5656 21.9092 29.2374 22.2374C28.9093 22.5656 28.4641 22.75 28 22.75Z"
|
||||||
|
fill="white"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span className="text-white">Add Credit</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : wallet.error ? (
|
||||||
|
<div className="md:flex items-center flex-wrap mt-3">
|
||||||
|
<p className="text-base">
|
||||||
|
Opps! An Error occurred, please try again
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="md:flex items-center flex-wrap mt-3">
|
||||||
|
<p className="text-base">No Wallets Found!</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* end of wallet balance */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* END OF WALLET SECTION */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/*<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>*/}
|
||||||
|
|
||||||
|
{/* /!* COUPON SECTION *!/*/}
|
||||||
|
{/* <div className="lg:w-3/4 w-full mb-10 lg:mb-0">*/}
|
||||||
|
{/* <div className="wallet w-full md:p-8 p-4 h-full max-h-[500px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">*/}
|
||||||
|
{/* <h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Coupons</h2>*/}
|
||||||
|
{/* {coupon.loading ?*/}
|
||||||
|
{/* <LoadingSpinner size='16' color='sky-blue' />*/}
|
||||||
|
{/* :*/}
|
||||||
|
{/* <CouponTable coupon={coupon} />*/}
|
||||||
|
{/* }*/}
|
||||||
|
{/* </div>*/}
|
||||||
|
{/* </div>*/}
|
||||||
|
{/* /!* END OF COUPON SECTION *!/*/}
|
||||||
|
|
||||||
|
{/*</div>*/}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Balance
|
export default Balance;
|
||||||
|
|||||||
@@ -1,165 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { useSelector } from "react-redux";
|
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
|
||||||
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
|
||||||
|
|
||||||
import usersService from "../../services/UsersService";
|
|
||||||
|
|
||||||
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
|
|
||||||
|
|
||||||
function ConfirmAddFund({ payment }) {
|
|
||||||
let { userDetails } = useSelector((state) => state.userDetails); // TO GET LOGGEDIN USER DETAILS
|
|
||||||
|
|
||||||
let [pageLoading, setPageLoading] = useState(true);
|
|
||||||
|
|
||||||
let [requestStatus, setRequestStatus] = useState({
|
|
||||||
message: "",
|
|
||||||
loading: false,
|
|
||||||
status: false,
|
|
||||||
}); // STATE FOR API REQUEST
|
|
||||||
|
|
||||||
const apiURL = new usersService();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
let { state } = useLocation();
|
|
||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
|
||||||
const onSuccessPayment = () => {
|
|
||||||
setRequestStatus({ message: "", loading: true, status: false });
|
|
||||||
let reqData = { amount: state?.account, currency: "NGN" };
|
|
||||||
apiURL
|
|
||||||
.startTopUp(reqData)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.data.internal_return < 0) {
|
|
||||||
setRequestStatus({
|
|
||||||
message: "Could not finish transaction",
|
|
||||||
loading: false,
|
|
||||||
status: false,
|
|
||||||
});
|
|
||||||
toast.success("Opps! something went wrong");
|
|
||||||
}
|
|
||||||
// do something
|
|
||||||
setRequestStatus({
|
|
||||||
message: "Topup successful",
|
|
||||||
loading: false,
|
|
||||||
status: true,
|
|
||||||
});
|
|
||||||
toast.success("Account Topup was sucessful");
|
|
||||||
setTimeout(() => {
|
|
||||||
navigate("/my-wallet", { replace: true });
|
|
||||||
}, 1000);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
// do something
|
|
||||||
setRequestStatus({
|
|
||||||
message: "Opps! An Error Occured",
|
|
||||||
loading: false,
|
|
||||||
status: false,
|
|
||||||
});
|
|
||||||
toast.success("Opps! something went wrong");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
|
|
||||||
tx_ref: Date.now(),
|
|
||||||
amount: state?.amount,
|
|
||||||
currency: "NGN",
|
|
||||||
payment_options: "card,mobilemoney,ussd",
|
|
||||||
customer: {
|
|
||||||
email: `${userDetails.email}`,
|
|
||||||
phone_number: userDetails.phone,
|
|
||||||
name: `${userDetails.lastname} ${userDetails.firstname}`,
|
|
||||||
},
|
|
||||||
customizations: {
|
|
||||||
title: "WrenchBoard",
|
|
||||||
description: "Topup Payment",
|
|
||||||
logo: "https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const fwConfig = {
|
|
||||||
...config,
|
|
||||||
text: "Proceed",
|
|
||||||
callback: (response) => {
|
|
||||||
onSuccessPayment();
|
|
||||||
closePaymentModal(); // this will close the modal programmatically
|
|
||||||
},
|
|
||||||
onClose: () => {},
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// what happens if not state redirect user
|
|
||||||
if (!state) {
|
|
||||||
navigate("/my-wallet/add-fund", { replace: true });
|
|
||||||
} else {
|
|
||||||
setPageLoading(false);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="content-wrapper w-full">
|
|
||||||
{pageLoading ? (
|
|
||||||
<LoadingSpinner size="8" color="sky-blue" />
|
|
||||||
) : (
|
|
||||||
<div className="w-full mb-10">
|
|
||||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
|
||||||
<h2 className="md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
|
|
||||||
Confirm Add Fund To Account
|
|
||||||
</h2>
|
|
||||||
<hr />
|
|
||||||
<div className="px-4 md:px-8 py-4 add-fund-info">
|
|
||||||
<div className="field w-full mb-3">
|
|
||||||
<InputCom
|
|
||||||
fieldClass="px-6"
|
|
||||||
label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
|
|
||||||
type="text"
|
|
||||||
name="amount"
|
|
||||||
value={state.amount || ""}
|
|
||||||
disable={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
|
|
||||||
{
|
|
||||||
state.currency == 'naira' ?
|
|
||||||
<FlutterWaveButton
|
|
||||||
{...fwConfig}
|
|
||||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<button
|
|
||||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
||||||
onClick={()=>console.log('WORKING')}
|
|
||||||
>
|
|
||||||
Continue
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="w-full mb-10">
|
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
|
||||||
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
|
||||||
Recent Activity
|
|
||||||
</h2>
|
|
||||||
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
|
||||||
{payment.loading ? (
|
|
||||||
<LoadingSpinner size="16" color="sky-blue" />
|
|
||||||
) : (
|
|
||||||
<RecentActivityTable payment={payment} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ConfirmAddFund;
|
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
||||||
|
|
||||||
import AddFundDollars from "./AddFundDollars";
|
import AddFundDollars from "./AddFundDollars";
|
||||||
|
|
||||||
function AddFundPop({ _payment }) {
|
function AddFund({ payment }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
// const { currency } = useLocation()?.state; //GETS THE USER CURRENCY FOR ADD FUND
|
const { currency } = useLocation()?.state; //GETS THE USER CURRENCY FOR ADD FUND
|
||||||
|
|
||||||
let { payment, currency } = _payment;
|
|
||||||
|
|
||||||
//STATE FOR CONTROLLED INPUT
|
//STATE FOR CONTROLLED INPUT
|
||||||
let [input, setInput] = useState("");
|
let [input, setInput] = useState("");
|
||||||
@@ -44,18 +42,48 @@ function AddFundPop({ _payment }) {
|
|||||||
|
|
||||||
setInput("");
|
setInput("");
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("walletItem details >>", payment, currency);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[36rem] w-full">
|
<div>
|
||||||
|
{/* heading */}
|
||||||
|
{/* <div className="sm:flex justify-between items-center mb-6">
|
||||||
|
<div className="w-full flex justify-start space-x-3 items-center">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="min-w-[45px] h-auto text-[#374557] border border-sky-blue p-1 rounded-full"
|
||||||
|
onClick={() =>
|
||||||
|
navigate('/my-wallet', { replace: true })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="35"
|
||||||
|
height="35"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="skyblue"
|
||||||
|
>
|
||||||
|
<path d="M19 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H19v-2z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||||
|
Add Credit
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="slider-btns flex space-x-4">
|
||||||
|
<div
|
||||||
|
onClick={() => filterHandler("today")}
|
||||||
|
className="relative"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
|
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
{/*<h2 className='md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Add Credit with Account Deposit</h2>*/}
|
{/*<h2 className='md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Add Credit with Account Deposit</h2>*/}
|
||||||
{/*<hr />*/}
|
{/*<hr />*/}
|
||||||
<form className="md:p-8 p-4 add-fund-info">
|
<form className="md:p-8 p-4 add-fund-info">
|
||||||
<div className="field w-full">
|
<div className="field w-full mb-6">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label={
|
label={
|
||||||
@@ -72,14 +100,11 @@ function AddFundPop({ _payment }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<h1 className="mb-2 text-xl font-bold text-dark-gray dark:text-white px-4 h-5">
|
|
||||||
{currency == "US Dollars" && "Payment Method"}
|
|
||||||
</h1>
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
||||||
{currency == "US Dollars" && (
|
{currency == "US Dollars" && (
|
||||||
<div className="w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl">
|
<div className="w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
<AddFundDollars
|
<AddFundDollars
|
||||||
setInputError={setInputError}
|
setInputError={setInputError}
|
||||||
input={input}
|
input={input}
|
||||||
@@ -105,25 +130,25 @@ function AddFundPop({ _payment }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
|
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
|
||||||
{currency != "US Dollars" &&
|
{currency != "US Dollars" && (
|
||||||
// <div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||||
// <div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||||
// <div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
// <h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||||
// Recent Activity
|
Recent Activity
|
||||||
// </h2>
|
</h2>
|
||||||
// {/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
||||||
// {payment?.loading ? (
|
{payment.loading ? (
|
||||||
// <LoadingSpinner size="16" color="sky-blue" />
|
<LoadingSpinner size="16" color="sky-blue" />
|
||||||
// ) : (
|
) : (
|
||||||
// <RecentActivityTable payment={payment} />
|
<RecentActivityTable payment={payment} />
|
||||||
// )}
|
)}
|
||||||
// </div>
|
</div>
|
||||||
// </div>
|
</div>
|
||||||
// </div>
|
</div>
|
||||||
null}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AddFundPop;
|
export default AddFund;
|
||||||
@@ -0,0 +1,613 @@
|
|||||||
|
import { Form, Formik } from "formik";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import usersService from "../../../services/UsersService";
|
||||||
|
import Icons from "../../Helpers/Icons";
|
||||||
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||||
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
cardNum: Yup.string()
|
||||||
|
.min(6, "not a card number")
|
||||||
|
.max(19, "16 chars max.") //16 chars + 3 spaces
|
||||||
|
.test("luhn-validation", "Invalid Card Number", (value) => {
|
||||||
|
const sanitizedNumber = value?.replace(/\D/g, "");
|
||||||
|
const digits = Array?.from(sanitizedNumber, Number);
|
||||||
|
|
||||||
|
for (let i = digits.length - 2; i >= 0; i -= 2) {
|
||||||
|
digits[i] *= 2;
|
||||||
|
if (digits[i] > 9) {
|
||||||
|
digits[i] -= 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sum = digits.reduce((acc, digit) => acc + digit, 0);
|
||||||
|
|
||||||
|
return sum % 10 === 0;
|
||||||
|
})
|
||||||
|
.required("required"),
|
||||||
|
code: Yup.string()
|
||||||
|
.min(3, "3 chars min.")
|
||||||
|
.max(25, "25 chars max.")
|
||||||
|
.required("required"),
|
||||||
|
state: Yup.string()
|
||||||
|
.min(2, "2 chars min.")
|
||||||
|
.max(25, "25 chars max.")
|
||||||
|
.required("required"),
|
||||||
|
address: Yup.string()
|
||||||
|
.min(3, "3 chars min.")
|
||||||
|
.max(50, "50 chars max.")
|
||||||
|
.required("required"),
|
||||||
|
expirationYear: Yup.string()
|
||||||
|
.min(4, "4 chars min.")
|
||||||
|
.max(4, "4 chars max.")
|
||||||
|
.required("required"),
|
||||||
|
expirationMonth: Yup.string()
|
||||||
|
.min(1, "1 chars min.")
|
||||||
|
.max(2, "2 chars max.")
|
||||||
|
.required("required"),
|
||||||
|
cvv: Yup.string()
|
||||||
|
.min(3, "3 chars min.")
|
||||||
|
.max(4, "4 chars max.")
|
||||||
|
.required("required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
cardNum: "",
|
||||||
|
code: "",
|
||||||
|
state: "",
|
||||||
|
address: "",
|
||||||
|
expirationYear: "",
|
||||||
|
expirationMonth: "",
|
||||||
|
cvv: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
function AddFundDollars(props) {
|
||||||
|
const apiCall = new usersService();
|
||||||
|
let countryWallet = props.walletItem.country;
|
||||||
|
const [tab, setTab] = useState("previous");
|
||||||
|
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||||
|
const [prevCardDetails, setPrevCardDetails] = useState({});
|
||||||
|
const [payListCards, setPayListCards] = useState({ loading: true, data: [] });
|
||||||
|
const [cardIcons, setCardIcons] = useState("atm-card");
|
||||||
|
const [prevCardError, setPrevCardError] = useState("");
|
||||||
|
|
||||||
|
const { firstname, lastname } = userDetails;
|
||||||
|
|
||||||
|
// Handling Card Icons
|
||||||
|
const handleCards = (event) => {
|
||||||
|
const { name, value } = event.target;
|
||||||
|
|
||||||
|
if (name == "cardNum") {
|
||||||
|
// Check if the first character is 4 or 5 and set the card icon accordingly
|
||||||
|
const cardIcon =
|
||||||
|
value.length > 0
|
||||||
|
? value[0] === "4"
|
||||||
|
? "visa-card"
|
||||||
|
: value[0] === "5"
|
||||||
|
? "master-card"
|
||||||
|
: "atm-card"
|
||||||
|
: "atm-card";
|
||||||
|
setCardIcons(cardIcon);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handling card change
|
||||||
|
const handleInputChange = (event) => {
|
||||||
|
const { name, value } = event.target;
|
||||||
|
|
||||||
|
setPrevCardDetails((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
[name]: value,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handling card number grouping
|
||||||
|
const handleCardNumberChange = (value) => {
|
||||||
|
return value
|
||||||
|
?.replace(/\s/g, "") // Remove existing spaces
|
||||||
|
.match(/.{1,4}/g) // Group every four characters
|
||||||
|
?.join(" ");
|
||||||
|
};
|
||||||
|
|
||||||
|
// card slicer
|
||||||
|
const indexOfFirstItem = 0;
|
||||||
|
const indexOfLastItem =
|
||||||
|
indexOfFirstItem + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
|
const currentPreviousCards = payListCards?.data?.slice(
|
||||||
|
indexOfFirstItem,
|
||||||
|
indexOfLastItem
|
||||||
|
);
|
||||||
|
|
||||||
|
// Submission for both prev and new cards
|
||||||
|
const handleSubmit = async (values, helpers) => {
|
||||||
|
props.setInputError("");
|
||||||
|
|
||||||
|
if (!props.input || props.input === "0") {
|
||||||
|
props.setInputError("Please Enter Amount");
|
||||||
|
setTimeout(() => props.setInputError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(props.input)) {
|
||||||
|
props.setInputError("Amount must be a Number");
|
||||||
|
setTimeout(() => props.setInputError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number(props.input) * 100 > Number(props.walletItem?.transfer_limit)) {
|
||||||
|
props.setInputError("Credit limit has been exceeded");
|
||||||
|
setTimeout(() => props.setInputError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tab === "previous") {
|
||||||
|
// To check if card is empty
|
||||||
|
if (Object.keys(prevCardDetails).length === 0) {
|
||||||
|
setPrevCardError("No card selected!");
|
||||||
|
setTimeout(() => setPrevCardError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
props.setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: { awaitConfirm: { loader: true } },
|
||||||
|
}));
|
||||||
|
|
||||||
|
let stateData = {
|
||||||
|
amount: Number(props.input) * 100,
|
||||||
|
currency: props.walletItem?.code,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await apiCall.getStartCredit(stateData);
|
||||||
|
if (res.data.internal_return < 0) {
|
||||||
|
props.setInputError("An Error Occurred");
|
||||||
|
throw new Error("An Error Occurred");
|
||||||
|
}
|
||||||
|
|
||||||
|
const _response = res.data;
|
||||||
|
stateData.amount = Number(props.input);
|
||||||
|
stateData.card =
|
||||||
|
tab === "previous"
|
||||||
|
? prevCardDetails["payment-card"]
|
||||||
|
: { ...values, cvv: values.cvv };
|
||||||
|
stateData.cardType = tab === "previous" ? "prev" : "new";
|
||||||
|
stateData = { ...stateData, ..._response };
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
props.setConfirmCredit({
|
||||||
|
show: {
|
||||||
|
awaitConfirm: { loader: false, state: true },
|
||||||
|
acceptConfirm: { loader: false, state: false },
|
||||||
|
},
|
||||||
|
data: stateData,
|
||||||
|
});
|
||||||
|
}, 1500);
|
||||||
|
} catch (error) {
|
||||||
|
props.setInputError(error.message);
|
||||||
|
setTimeout(() => props.setInputError(""), 5000);
|
||||||
|
props.setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: { awaitConfirm: { loader: false } },
|
||||||
|
}));
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
apiCall
|
||||||
|
.payListCard()
|
||||||
|
.then((res) => {
|
||||||
|
setPayListCards({ loading: false, data: res.data.result_list });
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log("PAYCARDLIST ERROR", err);
|
||||||
|
setPayListCards({ loading: false, data: [] });
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleClose = props.onClose;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="w-full">
|
||||||
|
{/* switch button */}
|
||||||
|
<div className="flex">
|
||||||
|
<form className="add-fund-info flex items-center gap-3">
|
||||||
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
{countryWallet == "US" && "Payment Method"}
|
||||||
|
</h1>
|
||||||
|
<div className="my-1 flex items-center gap-2">
|
||||||
|
<label
|
||||||
|
onClick={() => setTab("previous")}
|
||||||
|
htmlFor="previous"
|
||||||
|
className="cursor-pointer flex items-center gap-1"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
id="previous"
|
||||||
|
name="card-option"
|
||||||
|
checked={tab === "previous"}
|
||||||
|
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
||||||
|
tab == "previous" ? "" : ""
|
||||||
|
} tracking-wide transition duration-200`}
|
||||||
|
/>
|
||||||
|
Previous Cards
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
onClick={() => setTab("new")}
|
||||||
|
htmlFor="new"
|
||||||
|
className="cursor-pointer flex items-center gap-1"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="new"
|
||||||
|
type="radio"
|
||||||
|
name="card-option"
|
||||||
|
checked={tab === "new"}
|
||||||
|
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
||||||
|
tab == "new" ? "" : ""
|
||||||
|
} tracking-wide transition duration-200`}
|
||||||
|
/>
|
||||||
|
Add New Card
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
{/* END OF switch button */}
|
||||||
|
|
||||||
|
{/* previous tab */}
|
||||||
|
{tab === "previous" && (
|
||||||
|
<div className="p-4 previous-details w-full min-h-[16rem] flex flex-col">
|
||||||
|
{payListCards.loading ? (
|
||||||
|
<LoadingSpinner size="10" color="sky-blue" />
|
||||||
|
) : payListCards?.data?.length ? (
|
||||||
|
<select
|
||||||
|
className="my-3 w-full rounded-full p-2 outline-none text-base text-black dark:text-gray-100 bg-[#FAFAFA] dark:bg-[#11131F] border"
|
||||||
|
value={prevCardDetails["payment-card"]?.card_uid}
|
||||||
|
id="payment-card"
|
||||||
|
name="payment-card"
|
||||||
|
onChange={handleInputChange}
|
||||||
|
>
|
||||||
|
<option value="">Select a card</option>
|
||||||
|
{currentPreviousCards.map((item, index) => (
|
||||||
|
<option
|
||||||
|
key={index}
|
||||||
|
className={index !== 0 && "border-t-2"}
|
||||||
|
value={JSON.stringify(item)}
|
||||||
|
>
|
||||||
|
<div className="my-2 flex items-center gap-5">
|
||||||
|
<div className="card-details">
|
||||||
|
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
|
{item.description} Card
|
||||||
|
</h1>
|
||||||
|
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
|
Bank **************{item.digits}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
) : (
|
||||||
|
<div className="w-full flex flex-col items-center">
|
||||||
|
<p className="my-5 text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
|
No Previous Card Found!
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={() => setTab("new")}
|
||||||
|
type="button"
|
||||||
|
className="my-5 px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
|
>
|
||||||
|
<span className="text-white">Add Card</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<p className="text-base italic text-red-500 h-5">
|
||||||
|
{prevCardError && prevCardError}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{tab === "new" && (
|
||||||
|
<div className="new-details w-full max-h-[23rem]">
|
||||||
|
<div className="w-full flex flex-col justify-between">
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form className="md:pl-8">
|
||||||
|
<div className="flex flex-col-reverse sm:flex-row">
|
||||||
|
<div className="flex-1 sm:mr-10">
|
||||||
|
<div className="fields w-full">
|
||||||
|
{/* Inputs */}
|
||||||
|
{/* Name */}
|
||||||
|
<div className="flex items-center field w-full my-2 flex-[0.4] gap-3">
|
||||||
|
<label className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1">
|
||||||
|
Name:
|
||||||
|
</label>
|
||||||
|
<p className="input-label text-[#181c32] dark:text-white text-[16px] leading-[20.9625px] font-semibold flex items-center gap-1">{`${firstname} ${lastname}`}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center flex-1 gap-3 my-2">
|
||||||
|
{/* Card Number */}
|
||||||
|
<div className="field w-full flex-[0.6]">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
spanTag="*"
|
||||||
|
iconName={cardIcons}
|
||||||
|
label="Card Number"
|
||||||
|
type="text"
|
||||||
|
name="cardNum"
|
||||||
|
onInput={handleCards}
|
||||||
|
placeholder="Enter Card Number"
|
||||||
|
value={handleCardNumberChange(
|
||||||
|
props.values.cardNum
|
||||||
|
)}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={props.errors.cardNum}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Expire Year, Year */}
|
||||||
|
<div className="sm:grid gap-5 grid-cols-2 flex-[0.4]">
|
||||||
|
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||||
|
<div className="select-option">
|
||||||
|
<div
|
||||||
|
className={`flex items-center justify-between mb-2.5`}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold line-clamp-3 flex items-center"
|
||||||
|
htmlFor="expiration"
|
||||||
|
>
|
||||||
|
Exp Month{" "}
|
||||||
|
<span className="text-red-700 text-sm italic">
|
||||||
|
*
|
||||||
|
</span>
|
||||||
|
<span className="text-[12px] text-red-500 ml-1">
|
||||||
|
{props.errors.expirationMonth && "**"}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||||
|
value={props.values.expirationMonth}
|
||||||
|
onChange={props.handleChange}
|
||||||
|
onBlur={props.handleBlur}
|
||||||
|
name="expirationMonth"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value=""
|
||||||
|
className="text-dark-gray"
|
||||||
|
>
|
||||||
|
Month
|
||||||
|
</option>
|
||||||
|
{expireMonth?.length &&
|
||||||
|
expireMonth.map((item, index) => (
|
||||||
|
<option
|
||||||
|
key={index}
|
||||||
|
value={
|
||||||
|
Number(item.value) < 10
|
||||||
|
? "0" + item.value
|
||||||
|
: item.value
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||||
|
<div className="select-option">
|
||||||
|
<div
|
||||||
|
className={`flex items-center justify-between mb-2.5`}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center line-clamp-3"
|
||||||
|
htmlFor="expiration"
|
||||||
|
>
|
||||||
|
Exp Year{" "}
|
||||||
|
<span className="text-red-700 text-sm tracking-wide">
|
||||||
|
*
|
||||||
|
</span>
|
||||||
|
<span className="text-[12px] text-red-500 italic">
|
||||||
|
{props.errors.expirationYear && "**"}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||||
|
value={props.values.expirationYear}
|
||||||
|
onChange={props.handleChange}
|
||||||
|
onBlur={props.handleBlur}
|
||||||
|
name="expirationYear"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value=""
|
||||||
|
className="text-dark-gray"
|
||||||
|
>
|
||||||
|
Year
|
||||||
|
</option>
|
||||||
|
{expireYear?.length &&
|
||||||
|
expireYear.map((item, index) => (
|
||||||
|
<option key={index} value={item}>
|
||||||
|
{item}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Address and CVV */}
|
||||||
|
<div className="flex items-center flex-1 gap-3 my-2">
|
||||||
|
<div className="field w-full col-span-1 flex-[0.4]">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
spanTag="*"
|
||||||
|
iconName={cardIcons}
|
||||||
|
label="CVV"
|
||||||
|
type="text"
|
||||||
|
name="cvv"
|
||||||
|
placeholder="CVV"
|
||||||
|
maxLength={3}
|
||||||
|
value={props.values.cvv}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={props.errors.cvv}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="field w-full flex-[0.6]">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
spanTag="*"
|
||||||
|
label="Billing Address"
|
||||||
|
type="text"
|
||||||
|
name="address"
|
||||||
|
placeholder="Billing Address"
|
||||||
|
value={props.values.Address}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={props.errors.address}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Postal Code and State */}
|
||||||
|
<div className="sm:grid gap-5 grid-cols-3 my-2">
|
||||||
|
<div className="field w-full xl:mb-0 col-span-1">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
spanTag="*"
|
||||||
|
label="Postal Code"
|
||||||
|
type="number"
|
||||||
|
name="code"
|
||||||
|
placeholder="Postal Code"
|
||||||
|
value={props.values.code}
|
||||||
|
maxLength={6}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={props.errors.code}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="field w-full col-span-1">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
spanTag="*"
|
||||||
|
label="State"
|
||||||
|
type="text"
|
||||||
|
name="state"
|
||||||
|
placeholder="State"
|
||||||
|
value={props.values.state.toUpperCase()}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={props.errors.state}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="md:px-8 add-fund-btn flex justify-end items-center gap-3">
|
||||||
|
<button
|
||||||
|
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
|
||||||
|
onClick={handleClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
|
>
|
||||||
|
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
|
||||||
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="text-white">Continue</span>{" "}
|
||||||
|
<Icons name="chevron-right" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{tab == "previous" && (
|
||||||
|
<div className="md:py-8 px-[38px] add-fund-btn flex justify-end items-center gap-4 py-4">
|
||||||
|
<button
|
||||||
|
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
|
||||||
|
onClick={props.onClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleSubmit}
|
||||||
|
name="previous"
|
||||||
|
type="button"
|
||||||
|
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
|
>
|
||||||
|
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
|
||||||
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
|
) : (
|
||||||
|
<span className="text-white">Continue</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddFundDollars;
|
||||||
|
|
||||||
|
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
|
||||||
|
const expireYear = [];
|
||||||
|
let currentYear = new Date().getFullYear();
|
||||||
|
for (let i = 0; i <= 6; i++) {
|
||||||
|
expireYear.push(currentYear + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
|
||||||
|
let month = [
|
||||||
|
"January",
|
||||||
|
"February",
|
||||||
|
"March",
|
||||||
|
"April",
|
||||||
|
"May",
|
||||||
|
"June",
|
||||||
|
"July",
|
||||||
|
"August",
|
||||||
|
"September",
|
||||||
|
"October",
|
||||||
|
"November",
|
||||||
|
"December",
|
||||||
|
];
|
||||||
|
const expireMonth = [];
|
||||||
|
for (let i = 0; i < month.length; i++) {
|
||||||
|
expireMonth.push({ name: month[i], value: i + 1 });
|
||||||
|
}
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import usersService from "../../../services/UsersService";
|
||||||
|
import Icons from "../../Helpers/Icons";
|
||||||
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||||
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||||
|
import AddFundDollars from "./AddFundDollars";
|
||||||
|
|
||||||
|
function AddFundPop({
|
||||||
|
_payment,
|
||||||
|
input,
|
||||||
|
setInput,
|
||||||
|
onClose,
|
||||||
|
confirmCredit,
|
||||||
|
setConfirmCredit,
|
||||||
|
walletItem,
|
||||||
|
}) {
|
||||||
|
const apiCall = new usersService();
|
||||||
|
let countryWallet = walletItem?.country;
|
||||||
|
const { currency } = _payment;
|
||||||
|
|
||||||
|
const [inputError, setInputError] = useState("");
|
||||||
|
let __awaitComponent = confirmCredit.show.awaitConfirm;
|
||||||
|
|
||||||
|
const handleChange = ({ target: { name, value } }) => {
|
||||||
|
setInput(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
setInputError("");
|
||||||
|
setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: { awaitConfirm: { loader: true } },
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!input || input === "0") {
|
||||||
|
setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: { awaitConfirm: { loader: false } },
|
||||||
|
}));
|
||||||
|
setInputError("Please Enter Amount");
|
||||||
|
setTimeout(() => setInputError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number(input) * 100 > Number(walletItem?.transfer_limit)) {
|
||||||
|
setInputError("Credit limit has been exceeded");
|
||||||
|
setTimeout(() => setInputError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(input)) {
|
||||||
|
setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: { awaitConfirm: { loader: false } },
|
||||||
|
}));
|
||||||
|
setInputError("Amount must be a Number");
|
||||||
|
setTimeout(() => setInputError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let stateData = {
|
||||||
|
amount: Number(input) * 100,
|
||||||
|
currency: walletItem?.code,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await apiCall.getStartCredit(stateData);
|
||||||
|
if (res.data.internal_return < 0) {
|
||||||
|
setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: { awaitConfirm: { loader: false } },
|
||||||
|
}));
|
||||||
|
setInputError("An Error Occurred");
|
||||||
|
setTimeout(() => setInputError(""), 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _response = res.data;
|
||||||
|
stateData.amount = Number(input);
|
||||||
|
stateData.currency = currency;
|
||||||
|
stateData = { ...stateData, ..._response };
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: {
|
||||||
|
awaitConfirm: { loader: false, state: true },
|
||||||
|
acceptConfirm: { loader: false, state: false },
|
||||||
|
},
|
||||||
|
data: stateData,
|
||||||
|
}));
|
||||||
|
}, 1500);
|
||||||
|
} catch (error) {
|
||||||
|
setConfirmCredit((prev) => ({
|
||||||
|
...prev,
|
||||||
|
show: { awaitConfirm: { loader: false } },
|
||||||
|
}));
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-[33rem] w-full">
|
||||||
|
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||||
|
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||||
|
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
|
||||||
|
<form className="md:px-8 md:pt-4 px-4 pt-2 add-fund-info flex items-center gap-[2.1rem]">
|
||||||
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
Amount({currency})
|
||||||
|
</h1>
|
||||||
|
<div className="field w-full max-w-[250px]">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6 text-right"
|
||||||
|
type="text"
|
||||||
|
name="amount"
|
||||||
|
placeholder="0"
|
||||||
|
value={input}
|
||||||
|
inputHandler={handleChange}
|
||||||
|
/>
|
||||||
|
<p className="text-base text-red-500 italic h-5">
|
||||||
|
{inputError && inputError}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{countryWallet === "US" && (
|
||||||
|
<div className="w-full md:px-8 md:pt-4 px-4 pt-2 bg-white dark:bg-dark-white rounded-2xl">
|
||||||
|
<AddFundDollars
|
||||||
|
setInputError={setInputError}
|
||||||
|
walletItem={walletItem}
|
||||||
|
input={input}
|
||||||
|
setInput={setInput}
|
||||||
|
currency={currency}
|
||||||
|
onClose={onClose}
|
||||||
|
confirmCredit={confirmCredit}
|
||||||
|
setConfirmCredit={setConfirmCredit}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{countryWallet == "NG" && <div className="h-[18rem]"></div>}
|
||||||
|
|
||||||
|
{countryWallet == "NG" && (
|
||||||
|
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
|
||||||
|
<button
|
||||||
|
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleSubmit}
|
||||||
|
type="button"
|
||||||
|
className="px-4 py-1 h-11 flex justify-center space-x-1 items-center btn-gradient text-base rounded-full text-white max-w-[100px] w-full"
|
||||||
|
>
|
||||||
|
{__awaitComponent.loader ? (
|
||||||
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="text-white">Continue</span>{" "}
|
||||||
|
<Icons name="chevron-right" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddFundPop;
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
function CompleteConfirmCredit({ onClose, confirmCredit }) {
|
||||||
|
const { data } = confirmCredit;
|
||||||
|
return (
|
||||||
|
<div className="logout-modal-body w-full flex flex-col items-center">
|
||||||
|
<div className="content-wrapper w-full h-[32rem]">
|
||||||
|
<div className="w-full mb-10">
|
||||||
|
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
|
||||||
|
<div className="px-4 md:p-8 py-4 add-fund-info">
|
||||||
|
<div className="field w-full mb-3 min-h-[45px]">
|
||||||
|
<div
|
||||||
|
className={`flex flex-col gap-4 ${
|
||||||
|
data?.result !== "Charge success" &&
|
||||||
|
"h-[328px] items-center justify-center"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{/* Success Icon for now */}
|
||||||
|
<div className="flex items-center w-full justify-center">
|
||||||
|
{data?.result == "Charge success" ||
|
||||||
|
data?.status == "successful" ? (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="green"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
className="feather feather-check-circle"
|
||||||
|
>
|
||||||
|
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
|
||||||
|
<polyline points="22 4 12 14.01 9 11.01"></polyline>
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
stroke="red"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
className="feather feather-x-circle"
|
||||||
|
>
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<line x1="15" y1="9" x2="9" y2="15"></line>
|
||||||
|
<line x1="9" y1="9" x2="15" y2="15"></line>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={`flex items-center`}>
|
||||||
|
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
{data?.result == "Charge success" ||
|
||||||
|
data?.status == "successful"
|
||||||
|
? "Credit was Successful!"
|
||||||
|
: "Credit was Unsuccessful"}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{data?.internal_return >= 0 ? (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-8">
|
||||||
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
Amount({data?.currency || ""})
|
||||||
|
</h1>
|
||||||
|
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
{`${data?.symbol || ""} ${
|
||||||
|
Number(data?.amount * 0.01).toLocaleString() || ""
|
||||||
|
}`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-8">
|
||||||
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
Wallet Balance
|
||||||
|
</h1>
|
||||||
|
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
{data?.curr_balance}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-8">
|
||||||
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
Confirmation Number
|
||||||
|
</h1>
|
||||||
|
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
{data?.confirmation}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
|
||||||
|
<button
|
||||||
|
className="px-4 h-11 flex justify-center items-center btn-gradient text-white text-base rounded-full w-[100px]"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Ok
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CompleteConfirmCredit;
|
||||||