Compare commits
184 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 24545baad5 | |||
| 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 | |||
| 9475961c2d | |||
| 97ae9dd136 | |||
| ded088c70f | |||
| 4dacee11e8 | |||
| 960579384c | |||
| bcca701a6b | |||
| 6c29f37a60 | |||
| cc22e1a458 | |||
| d274a5c56a | |||
| dfe90fbdc2 | |||
| a2f3c95671 | |||
| 6daa4d6d43 | |||
| 2e25b33110 | |||
| a216ab1098 | |||
| 8b01139b93 | |||
| 8511db6961 | |||
| 99c81fd4ee | |||
| ef545c9714 | |||
| 029a7327a8 | |||
| 5a5d933b24 | |||
| 9f19c930b7 | |||
| 84d7fabae7 | |||
| b245f87556 | |||
| bed5303fa4 | |||
| a5af8ed722 | |||
| ec97d118b2 | |||
| 85213c31a1 | |||
| f9b6c68f99 | |||
| 2a4b77c9a0 | |||
| 97aa5dba21 | |||
| 58a10ca6be | |||
| f3edf1d90b | |||
| 1f7b310b6f | |||
| aecb06ca96 | |||
| d89194f18e | |||
| 03866d666b | |||
| 4224be46bc | |||
| 5dad00096a | |||
| 72da5c707a | |||
| 625928e34b | |||
| 6fd92600b4 | |||
| 133f500849 | |||
| b1f1b34924 | |||
| e80c3528db | |||
| 3eb6960cc7 | |||
| eb01e35c75 | |||
| 0cc70d66b3 | |||
| 7111e81f11 | |||
| 1c64771dcd | |||
| ac1a4f895a | |||
| 22f5bd01d2 | |||
| 467528835a | |||
| e74119983f | |||
| 0be78a2a1b | |||
| 67d5555377 | |||
| 0e65c05505 | |||
| 01d5cdd093 | |||
| 08793ad90d | |||
| e23bdaa0a5 | |||
| 9791d66225 | |||
| 70e6ae20a4 | |||
| 17d1a84792 | |||
| f51ed44463 | |||
| ba45a7bdb9 | |||
| 20909a5b76 | |||
| c1a8fb6cf4 | |||
| a2148aaf3e | |||
| 919338fd3f | |||
| 5594d24ce9 | |||
| f581de6502 | |||
| c89bc0d44b | |||
| 22dc21a79b | |||
| 809db4ded3 | |||
| 1ae67ef3a4 | |||
| d32e8e2c8c | |||
| f635372e31 | |||
| 2913ae5bba | |||
| f4bd4e4c7d | |||
| 6126564547 | |||
| b5573aedd0 | |||
| 2b93b09785 | |||
| c0281f3734 | |||
| ef045e2bc1 | |||
| cf20c38059 | |||
| 6ed1466e2b | |||
| 6c59a24e6e | |||
| 05865c9274 | |||
| a868713ae3 | |||
| e68603d836 | |||
| 67e227c554 | |||
| f6fc004a06 | |||
| 1682a2221f | |||
| b16b356532 | |||
| 62b97d903c | |||
| abef3bec01 | |||
| 626835e1e0 | |||
| a6d68bc856 | |||
| a674688dce | |||
| ef339b163d | |||
| 1ce154cc06 | |||
| 67eb142ae2 | |||
| e784d84699 | |||
| cd6d540c4b | |||
| b2beaa7c2b | |||
| b0db896f6b | |||
| fafea8b1ad | |||
| bbb099d51f | |||
| bfc0521e54 | |||
| 6870c145d7 | |||
| c18373f9db | |||
| 24ac0daf29 | |||
| 4dd58b16d8 | |||
| cc66ebbbde | |||
| 3d61b3259d | |||
| 40b614356f | |||
| dbba6c4014 | |||
| ae93de5f25 | |||
| 4904f1d398 | |||
| 880b084547 | |||
| c807a2657b | |||
| 37a0ffed27 | |||
| 067d9ca5d1 | |||
| 6e3061b9db | |||
| 4f9ca918c9 | |||
| 12f805f0a7 | |||
| 175ac7e2b6 | |||
| bb0796d1e6 | |||
| c0d01e05fe | |||
| 38a888a8a1 | |||
| 8b0aedcbf2 | |||
| dfdccc0287 | |||
| 12512cef97 | |||
| d5d0e64070 | |||
| d55f7ce175 | |||
| f81b687f9f | |||
| 3de1ef71c9 | |||
| fe7d23837c | |||
| bdc000fb8e | |||
| 01f8c7b49b | |||
| 05384fe001 | |||
| 66a43ac636 | |||
| 0ff4e5cf1e | |||
| 6c0a107919 | |||
| 5c8d1e72dd | |||
| 4b11d7ec77 | |||
| baf2ca155f | |||
| fffc51d77a | |||
| c622d73058 | |||
| d0237872ad | |||
| 4403c8650e | |||
| 2afffb1dc9 | |||
| 3a72ebc7a0 | |||
| ecfef0d6e1 | |||
| 7abf4fb7f7 | |||
| 6c601a605a | |||
| 4480e2ebd6 |
@@ -42,9 +42,28 @@ REACT_APP_GOOGLE_CLIENT_SECRET=aozK_2G8UjaCmLgPPkv9abIm
|
||||
REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
||||
REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||
|
||||
REACT_APP_FACEBOOK_CLIENT_ID=390204307987009
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET=19f778e312f2ab96d147bacb612910c2
|
||||
REACT_APP_FACEBOOK_CLIENT_SCOPE="email, public_profile"
|
||||
#Real Account
|
||||
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
|
||||
|
||||
#developenet Account
|
||||
REACT_APP_FACEBOOK_CLIENT_ID=677857427521030
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET=4801375f22072d8a75f64483fdd89829
|
||||
|
||||
#my Account
|
||||
REACT_APP_FACEBOOK_CLIENT_ID3=1598725580610908
|
||||
|
||||
|
||||
REACT_APP_FACEBOOK_CLIENT_SCOPE="email,public_profile"
|
||||
REACT_APP_FACEBOOK_REDIRECT_URL="http://localhost:9082/login/auth/flogin"
|
||||
|
||||
REACT_APP_APPLE_CLIENT_ID='com.wrenchboard.users.client'
|
||||
REACT_APP_APPLE_REDIRECT_URL='http://localhost:9082/login/auth/apple'
|
||||
|
||||
|
||||
# /* 'client_id' => */ 'com.wrenchboard.users.client',
|
||||
# /* 'client_secret' => */ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6Ilc1V1RXQzlEVEoifQ.eyJpc3MiOiJKUjM2M0ZFWThSIiwiaWF0IjoxNjU0MDgzODQxLCJleHAiOjE2NTkyNjc4NDEsImF1ZCI6Imh0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20iLCJzdWIiOiJjb20ud3JlbmNoYm9hcmQudXNlcnMuY2xpZW50In0.TIPMwjS2MgSysqEuw3yu1nrOcrH-6omzerDhx0CadjWn2yCO8wZhQiAlhIFs7F-WPektIJ6h-2BT62yGrILiTA',
|
||||
# /* 'redirect_uri' => */ site_url('login/auth/apple')
|
||||
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
@@ -40,6 +40,11 @@ REACT_APP_GOOGLE_CLIENT_SECRET=aozK_2G8UjaCmLgPPkv9abIm
|
||||
REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
||||
REACT_APP_GOOGLE_REDIRECT_URL=https://users.wrenchboard.com/login/auth/
|
||||
|
||||
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
|
||||
REACT_APP_FACEBOOK_CLIENT_SCOPE="email,public_profile"
|
||||
REACT_APP_FACEBOOK_REDIRECT_URL="https://users.wrenchboard.com/login/auth/flogin"
|
||||
|
||||
DISABLE_ESLINT_PLUGIN=true
|
||||
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"flutterwave-react-v3": "^1.3.0",
|
||||
"formik": "^2.2.9",
|
||||
"react": "^18.2.0",
|
||||
"react-apple-login": "^1.1.6",
|
||||
"react-chartjs-2": "^4.1.0",
|
||||
"react-countup": "^6.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 713 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
@@ -47,6 +47,8 @@ import OffersInterestPage from "./views/OffersInterestPage";
|
||||
import ManageInterestOfferPage from './views/ManageInterestOfferPage'
|
||||
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
||||
import FamilyMarketPage from "./views/FamilyMarketPage";
|
||||
import FacebookRedirect from "./views/FacebookRedirect";
|
||||
import AppleRedirectPage from "./views/AppleRedirectPage";
|
||||
|
||||
export default function Routers() {
|
||||
return (
|
||||
@@ -56,6 +58,8 @@ export default function Routers() {
|
||||
<Route exact path="/login" element={<LoginPage />} />
|
||||
<Route exact path="/signup" element={<SignupPage />} />
|
||||
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
||||
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
||||
<Route exact path="/login/auth/apple" element={<AppleRedirectPage />} />
|
||||
<Route
|
||||
exact
|
||||
path="/forgot-password"
|
||||
|
||||
|
After Width: | Height: | Size: 6.2 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 |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 66 66" id="Account"><path fill="#4687ba" d="M19 36.5c-5.8 0-10.6 4.7-10.6 10.6S13.1 57.6 19 57.6 29.5 52.9 29.5 47 24.8 36.5 19 36.5zm0 19.6c-5 0-9.1-4.1-9.1-9.1s4.1-9 9.1-9 9 4 9 9-4 9.1-9 9.1z" class="color000100 svgShape"></path><path fill="#4687ba" d="M65.7 49.6l-.9-5.4c-1.2-8-7.4-14.3-15.1-15.9 1.3-1.6 2.7-3.9 3.3-7.1.5-.8 2.1-3.5 1.5-5.3-.1-.3-.3-.6-.6-.9.7-2 2.3-9-4.8-12.6C38-3.9 28.7 4.7 30.8 14.6c-.2.3-.5.6-.6 1.1-.3 1.3.1 3 1.3 4.9.2.8 1.5 5 3.9 7.9-3.2.8-6 2.4-8.4 4.6-1.2-.7-2.5-1.2-3.8-1.6l-.8-3.3h-6.8l-.8 3.3c-1.3.4-2.6.9-3.8 1.6l-2.8-1.8-4.8 4.8L5.1 39c-.7 1.2-1.2 2.5-1.6 3.8l-3.3.8v6.8l3.3.8c.4 1.3.9 2.6 1.6 3.8l-1.8 2.9 4.8 4.8 2.8-1.8c1.2.7 2.5 1.2 3.8 1.6l.8 3.3h6.8l.8-3.3c1.3-.4 2.6-.9 3.8-1.6l2.8 1.8 4.8-4.8-.3-.5H59c2 0 3.8-.9 5.1-2.4 1.3-1.4 1.9-3.4 1.6-5.4zM32.9 20.1l-.1-.2c-1.7-2.8-1.3-4.2-.8-4.5l.5-.3c-1.8-6 1.4-11.4 5.6-12.9C43.4.5 57 4.1 52 15.9c.3.1 1 .3 1 .6.3 1-.9 3.3-1.5 4.3-1.1 5.3-4.3 9.7-9.2 9.8-5.1 0-8.1-5.5-9.4-10.5zm-3.3 40.7L27 59.2c-1.1.7-2.4 1.5-5.1 2.1l-.7 3h-4.4l-.7-3c-2.3-.5-3.4-1.1-5.1-2.1l-2.6 1.6-3.1-3.1 1.6-2.6C5.7 53.2 5.2 52 4.7 50l-3-.7v-4.4l3-.7c.3-1.4.7-2.9 2.1-5.2l-1.6-2.6 3.1-3.1 2.6 1.6c1.1-.7 2.4-1.5 5.1-2.1l.7-3h4.4l.7 3c2.3.5 3.4 1.1 5.1 2.1l2.6-1.6 3.1 3.1-1.5 2.6c1.2 1.9 1.6 3.1 2.1 5.1l3 .7v4.4l-3 .7c-.3 1.2-.6 2.8-2.1 5.1l1.6 2.6-3.1 3.2zM63 54.1c-1 1.2-2.4 1.8-4 1.8H33.4l-.5-.9c.7-1.2 1.2-2.5 1.6-3.8l3.3-.8v-6.8l-3.3-.8c-.4-1.3-.9-2.6-1.6-3.8l1.8-2.8-4-4c1.8-1.1 3.8-1.9 6-2.4 1.7 1.5 3.8 2.4 6.2 2.2 2.7-.2 4.4-1.2 5.7-2.4 7.6 1.1 13.7 7.1 14.9 14.8l.8 5.4c.2 1.6-.3 3.1-1.3 4.3z" class="color000100 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="dashboard"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M4 13h6c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1zm0 8h6c.55 0 1-.45 1-1v-4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1zm10 0h6c.55 0 1-.45 1-1v-8c0-.55-.45-1-1-1h-6c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1zM13 4v4c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1h-6c-.55 0-1 .45-1 1z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 503 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="identificationcard"><path fill="#4687ba" d="M0 6v13c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2V6" class="color2d98d4 svgShape"></path><path fill="#ff6699" d="M22 3H2a2 2 0 0 0-2 2v2h24V5a2 2 0 0 0-2-2z" class="color0377be svgShape"></path><path fill="#e6e7f9" d="M22 3H2C.897 3 0 3.897 0 5v.25c0-1.103.897-2 2-2h20c1.103 0 2 .897 2 2V5c0-1.103-.897-2-2-2z" opacity=".2" class="colorffffff svgShape"></path><path fill="#4687ba" d="M22 20.75H2c-1.103 0-2-.897-2-2V19c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2v-.25c0 1.103-.897 2-2 2z" opacity=".1" class="color010101 svgShape"></path><path fill="#e6e7f9" d="M13 17h8v1h-8zM13 14h8v1h-8zM13 11h8v1h-8z" class="colorffffff svgShape"></path><circle cx="7" cy="12" r="2" fill="#e6e7f9" class="colorffffff svgShape"></circle><path fill="#e6e7f9" d="M9.987 15.237C9.288 14.9 8.203 14.5 7 14.5s-2.288.4-2.987.737c-.625.3-1.013.9-1.013 1.566V18h8v-1.197c0-.665-.388-1.265-1.013-1.566z" class="colorffffff svgShape"></path><circle cx="17" cy="5" r="1" fill="#ff6699" class="color0a70b9 svgShape"></circle><path fill="#4687ba" d="M17 4.25a.99.99 0 0 1 .975.875C17.98 5.082 18 5.045 18 5a1 1 0 0 0-2 0c0 .044.02.082.025.125A.99.99 0 0 1 17 4.25z" opacity=".1" class="color010101 svgShape"></path><linearGradient id="a" x1="6.973" x2="21.55" y1="1.973" y2="16.55" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#010101" stop-opacity=".1" class="stopColor010101 svgShape"></stop><stop offset="1" stop-color="#010101" stop-opacity="0" class="stopColor010101 svgShape"></stop></linearGradient><path fill="url(#a)" d="M22 21c1.103 0 2-.897 2-2V7H0l14 14h8z"></path><circle cx="7" cy="5" r="1" fill="#ff6699" class="color0a70b9 svgShape"></circle><path fill="#4687ba" d="M7 4.25a.99.99 0 0 1 .975.875C7.98 5.082 8 5.045 8 5a1 1 0 0 0-2 0c0 .044.02.082.025.125A.99.99 0 0 1 7 4.25z" opacity=".1" class="color010101 svgShape"></path><linearGradient id="b" x1="-.708" x2="24.708" y1="6.074" y2="17.925" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffffff" stop-opacity=".2" class="stopColorffffff svgShape"></stop><stop offset="1" stop-color="#ffffff" stop-opacity="0" class="stopColorffffff svgShape"></stop></linearGradient><path fill="url(#b)" d="M22 3H2a2 2 0 0 0-2 2v14c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2V5a2 2 0 0 0-2-2z"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 128 128" viewBox="0 0 128 128" id="Pin"><path fill="#4687ba" d="M106,13.8L91.7,4.6C86.2,1,78.9,2,74.5,7L41.9,46.9c-9.1,0.4-17.9,3.3-25.4,8.7c-0.7,0.5-0.7,1.6,0.1,2.1
|
||||
l10.2,6.6l0,0L46.4,77l-24,41.4c-1.2,2.1-0.7,4.9,1.4,6.3c2.2,1.6,5.2,1.1,6.7-1.1l28-38.8L78,97.5l0,0l10.2,6.6
|
||||
c0.7,0.5,1.7,0.1,1.9-0.8c1.8-9,0.9-18.3-2.5-26.8l23.1-46C113.6,24.5,111.5,17.4,106,13.8z" class="color2d3e50 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 482 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 32 32" id="Family"><path d="M26.305 22.723a4.972 4.972 0 0 0-3.176-8.71 9.917 9.917 0 0 0-3.438-2.292 6 6 0 1 0-7.382 0 9.917 9.917 0 0 0-3.438 2.292 4.972 4.972 0 0 0-3.171 8.71A8.005 8.005 0 0 0 1 30a1 1 0 0 0 2 0 6 6 0 0 1 12 0 1 1 0 0 0 2 0 6 6 0 0 1 12 0 1 1 0 0 0 2 0 8.005 8.005 0 0 0-4.695-7.277ZM26 19a3 3 0 1 1-3-3 3 3 0 0 1 3 3ZM12 7a4 4 0 1 1 4 4 4 4 0 0 1-4-4ZM6 19a3 3 0 1 1 3 3 3 3 0 0 1-3-3Zm10 7.136a8.04 8.04 0 0 0-3.695-3.413 4.949 4.949 0 0 0-1.05-8.16 7.984 7.984 0 0 1 9.49 0 4.949 4.949 0 0 0-1.05 8.16A8.04 8.04 0 0 0 16 26.136Z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 684 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="Logout"><path d="M4,12a1,1,0,0,0,1,1h7.59l-2.3,2.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l4-4a1,1,0,0,0,.21-.33,1,1,0,0,0,0-.76,1,1,0,0,0-.21-.33l-4-4a1,1,0,1,0-1.42,1.42L12.59,11H5A1,1,0,0,0,4,12ZM17,2H7A3,3,0,0,0,4,5V8A1,1,0,0,0,6,8V5A1,1,0,0,1,7,4H17a1,1,0,0,1,1,1V19a1,1,0,0,1-1,1H7a1,1,0,0,1-1-1V16a1,1,0,0,0-2,0v3a3,3,0,0,0,3,3H17a3,3,0,0,0,3-3V5A3,3,0,0,0,17,2Z" fill="#e07c8a" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 487 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 512 512" id="FindJobs"><path d="M499.22 437.51 433.68 372a23.19 23.19 0 0 0-26.63-4.41l-22.18-22.18A214.71 214.71 0 0 0 62.78 62.78a214.72 214.72 0 0 0 282.6 322.09l22.18 22.18a23.19 23.19 0 0 0 4.44 26.63l65.54 65.54a43.64 43.64 0 0 0 61.71-61.71ZM341.29 369l-.2.18A199.71 199.71 0 0 1 73.39 73.39a199.71 199.71 0 0 1 295.76 267.67l-.22.26q-6.18 7.5-13.14 14.47T341.29 369Zm15.71 6.26c3.21-2.86 6.36-5.8 9.42-8.86s6-6.21 8.86-9.42l20.29 20.3-18.27 18.27Zm131.61 113.35a28.65 28.65 0 0 1-40.49 0l-65.54-65.54a8.22 8.22 0 0 1 0-11.61l28.88-28.88a8.22 8.22 0 0 1 11.61 0l65.54 65.54a28.65 28.65 0 0 1 0 40.49ZM296.08 161h-31v-11.53A21.13 21.13 0 0 0 244 128.36h-58.8a21.13 21.13 0 0 0-21.11 21.11V161h-31a19.82 19.82 0 0 0-19.81 19.81V281a19.83 19.83 0 0 0 19.81 19.82h163A19.84 19.84 0 0 0 315.9 281V180.81A19.83 19.83 0 0 0 296.08 161Zm-117-11.53a6.12 6.12 0 0 1 6.11-6.11H244a6.12 6.12 0 0 1 6.11 6.11V161h-71ZM300.9 281a4.82 4.82 0 0 1-4.82 4.82h-163a4.82 4.82 0 0 1-4.81-4.82v-63.6l63.8 27.77v4.88a14.52 14.52 0 0 0 14.5 14.5h16a14.52 14.52 0 0 0 14.5-14.5v-4.88l63.83-27.77Zm-93.81-31.45v-15h15v15ZM300.9 201l-64.67 28.14a14.5 14.5 0 0 0-13.64-9.63h-16a14.52 14.52 0 0 0-13.59 9.67L128.29 201v-20.19a4.82 4.82 0 0 1 4.81-4.81h163a4.82 4.82 0 0 1 4.82 4.81Zm36.89-109.61c-67.93-67.93-178.47-67.93-246.4 0a174.23 174.23 0 0 0 246.4 246.4 174.23 174.23 0 0 0 0-246.4Zm-10.6 235.8a159.25 159.25 0 1 1 46.63-112.6 158.76 158.76 0 0 1-46.63 112.6Z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 9362 9362" id="jobsact"><path d="M8967 8103l-423 0 0 -856 423 0c181,0 329,193 329,428l0 0c0,235 -148,428 -329,428zm-4636 0l4066 0 0 -856 -4066 0 0 856zm-139 0l-738 -327 -268 0c-43,0 -138,-45 -138,-101 0,-56 95,-101 138,-101l268 0 738 -327 0 428 0 428zm-3982 -8103l6388 0 210 0 0 210 0 809 -420 0 0 -600 -5969 0 0 8523 5969 0 0 -551 420 0 0 761 0 210 -210 0 -6388 0 -210 0 0 -210 0 -8942 0 -210 210 0zm6598 6523l0 436 -420 0 0 -436 420 0zm2554 -3158l0 2557c0,175 -143,317 -317,317l-5224 0c-174,0 -317,-142 -317,-317l0 -2557 2486 0 0 491c0,244 199,443 443,443 244,0 443,-199 443,-443l0 -491 2486 0zm-3843 -2062l1827 0c121,0 219,98 219,219l0 626 -340 0 0 -506 -1585 0 0 506 -340 0 0 -626c0,-121 99,-219 219,-219zm-1698 1011l5224 0c174,0 317,143 317,317l0 568 -2650 0 0 657c0,154 -126,279 -279,279l0 0c-154,0 -280,-125 -280,-279l0 -657 -2649 0 0 -568c0,-174 143,-317 317,-317zm2612 1387c74,0 134,60 134,134 0,74 -60,134 -134,134 -74,0 -134,-60 -134,-134 0,-74 60,-134 134,-134zm-4430 -2741l2801 0 0 420 -2801 0 0 -420zm-806 4786l2023 0 0 176c0,87 19,170 52,244l-2075 0 0 -420zm0 -3657l2366 0c-167,80 -292,235 -330,421l-2036 0 0 -421zm0 914l2023 0 0 421 -2023 0 0 -421zm0 914l2023 0 0 421 -2023 0 0 -421zm0 915l2023 0 0 420 -2023 0 0 -420zm0 1828l1371 0 0 421 -1371 0 0 -421z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" id="Profile"><path fill="#ffffff" d="M108 124H20c-8.8 0-16-7.2-16-16V20c0-8.8 7.2-16 16-16h88c8.8 0 16 7.2 16 16v88c0 8.8-7.2 16-16 16z" class="colorffffff svgShape"></path><path fill="#d2d4d6" d="M4 18.1v21.2h120V18.1c0-7.8-6.3-14.1-14.1-14.1H18.1C10.3 4 4 10.3 4 18.1z" class="colord2d5d6 svgShape"></path><circle cx="20.5" cy="21.1" r="7.1" fill="#7bbaec" class="colorec7bb0 svgShape"></circle><circle cx="59.5" cy="21.1" r="7.1" fill="#4687ba" class="color82cfcd svgShape"></circle><path fill="#57636d" d="M59.5 29.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1 4.4 0 8.1 3.6 8.1 8.1-.1 4.5-3.7 8.1-8.1 8.1zm0-14.1c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1-2.8-6.1-6.1-6.1z" class="color6a576d svgShape"></path><circle cx="40" cy="21.1" r="7.1" fill="#7bbdf1" class="colorf1ed7b svgShape"></circle><path fill="#57636d" d="M20.5 29.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1 4.4 0 8.1 3.6 8.1 8.1s-3.6 8.1-8.1 8.1zm0-14.1c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1-2.7-6.1-6.1-6.1zm39 14.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1 4.4 0 8.1 3.6 8.1 8.1-.1 4.5-3.7 8.1-8.1 8.1zm0-14.1c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1-2.8-6.1-6.1-6.1zM40 29.1c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1s8.1 3.6 8.1 8.1-3.7 8.1-8.1 8.1zM40 15c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1 6.1-2.7 6.1-6.1S43.3 15 40 15zM4 38.3h120v2H4zM108 104.3H20c-.6 0-1-.4-1-1s.4-1 1-1h88c.6 0 1 .4 1 1s-.4 1-1 1zm-48-48H20c-.6 0-1-.4-1-1s.4-1 1-1h40c.6 0 1 .4 1 1s-.4 1-1 1zm0 16H20c-.6 0-1-.4-1-1s.4-1 1-1h40c.6 0 1 .4 1 1s-.4 1-1 1zm0 16H20c-.6 0-1-.4-1-1s.4-1 1-1h40c.6 0 1 .4 1 1s-.4 1-1 1z" class="color6a576d svgShape"></path><path fill="#57636d" d="M108 125H20c-9.4 0-17-7.6-17-17V20c0-9.4 7.6-17 17-17h88c9.4 0 17 7.6 17 17v88c0 9.4-7.6 17-17 17zM20 5C11.7 5 5 11.7 5 20v88c0 8.3 6.7 15 15 15h88c8.3 0 15-6.7 15-15V20c0-8.3-6.7-15-15-15H20z" class="color6a576d svgShape"></path><path fill="#ffffff" d="M108.9 28.1H79.6c-3.9 0-7.1-3.2-7.1-7.1 0-3.9 3.2-7.1 7.1-7.1h29.3c3.9 0 7.1 3.2 7.1 7.1 0 4-3.2 7.1-7.1 7.1z" class="colorffffff svgShape"></path><path fill="#57636d" d="M108.9 29.1H79.6c-4.4 0-8.1-3.6-8.1-8.1 0-4.4 3.6-8.1 8.1-8.1h29.3c4.4 0 8.1 3.6 8.1 8.1s-3.6 8.1-8.1 8.1zM79.6 15c-3.3 0-6.1 2.7-6.1 6.1s2.7 6.1 6.1 6.1h29.3c3.3 0 6.1-2.7 6.1-6.1s-2.7-6.1-6.1-6.1H79.6z" class="color6a576d svgShape"></path><path fill="#5587af" d="M76 55.3h32v32H76z" class="coloraf5655 svgShape"></path><path fill="#57636d" d="M104.8 88.3H79.2c-2.3 0-4.2-1.9-4.2-4.2V58.5c0-2.3 1.9-4.2 4.2-4.2h25.6c2.3 0 4.2 1.9 4.2 4.2v25.6c0 2.3-1.9 4.2-4.2 4.2zm-25.6-32c-1.2 0-2.2 1-2.2 2.2v25.6c0 1.2 1 2.2 2.2 2.2h25.6c1.2 0 2.2-1 2.2-2.2V58.5c0-1.2-1-2.2-2.2-2.2H79.2z" class="color6a576d svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -23,16 +23,16 @@ const validationSchema = Yup.object().shape({
|
||||
})
|
||||
.required("Price is required"),
|
||||
title: Yup.string()
|
||||
.min(25, "Minimum 25 characters")
|
||||
.max(45, "Maximum 45 characters")
|
||||
.min(5, "Minimum 5 characters")
|
||||
.max(149, "Maximum 149 characters")
|
||||
.required("Title is required"),
|
||||
description: Yup.string()
|
||||
.min(25, "Minimum 25 characters")
|
||||
.max(250, "Maximum 250 characters")
|
||||
.min(5, "Minimum 5 characters")
|
||||
.max(299, "Maximum 299 characters")
|
||||
.required("Description is required"),
|
||||
job_detail: Yup.string()
|
||||
.min(25, "Minimum 25 characters")
|
||||
.max(250, "Maximum 250 characters")
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(1440, "Maximum 1440 characters")
|
||||
.required("Details is required"),
|
||||
timeline_days: Yup.number()
|
||||
.typeError("you must specify a number")
|
||||
@@ -78,7 +78,6 @@ function AddJob({ popUpHandler, categories }) {
|
||||
setCurrency({ loading: false, status: true, data: [] });
|
||||
return;
|
||||
}
|
||||
console.log("Res for currency >> ", res);
|
||||
|
||||
setCurrency({
|
||||
loading: false,
|
||||
@@ -221,7 +220,6 @@ function AddJob({ popUpHandler, categories }) {
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
@@ -421,10 +419,3 @@ const publicArray = [
|
||||
{ duration: 21, name: "3 weeks" },
|
||||
{ duration: 28, name: "4 weeks" },
|
||||
];
|
||||
|
||||
// .test("no-e", "Invalid number", (value) => {
|
||||
// if (value && /\d+e/.test(value)) {
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// })
|
||||
|
||||
@@ -4,12 +4,12 @@ import { Link } from "react-router-dom";
|
||||
export default function LoginLayout({ slogan, children }) {
|
||||
return (
|
||||
<div className={`layout-wrapper login`}>
|
||||
<div className={`main-wrapper login-wrapper w-full h-screen overflow-y-auto p-2 sm:p-20`}>
|
||||
<div className={`main-wrapper login-wrapper w-full h-screen overflow-y-auto p-2 sm:px-20 sm:py-5`}>
|
||||
<div className="w-full h-full">
|
||||
<div className="flex-1 flex justify-center items-center">
|
||||
{children && children}
|
||||
</div>
|
||||
<div className="flex-1 flex justify-center items-center p-10">
|
||||
<div className="flex-1 flex justify-center items-center px-10 pt-10">
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href="https://www.wrenchboard.com/about-us"
|
||||
@@ -37,9 +37,9 @@ export default function LoginLayout({ slogan, children }) {
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex justify-center items-center p-10">
|
||||
<p className="text-black text-[15px] px-2 font-medium flex items-center">
|
||||
<span className="text-3xl mt-2 mr-1">©</span> 2023 - {" "}
|
||||
<div className="flex-1 flex justify-center items-center px-10 py-1">
|
||||
<p className="text-black text-[15px] px-2 font-medium flex items-center gap-1">
|
||||
<span className="">© {new Date().getFullYear()} -</span>
|
||||
<Link to="/" className="text-[#009ef7] ml-1">
|
||||
WrenchBoard
|
||||
</Link>{" "}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import { useDispatch } from "react-redux";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function AppleRedirect() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
|
||||
useEffect(()=>{
|
||||
if(!codeResponse){
|
||||
navigate('/login', {state: {error: true}})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse);
|
||||
|
||||
setTimeout(()=>{ // remove LATER
|
||||
navigate('/login', {state: {error: true}})
|
||||
},2000)
|
||||
|
||||
/*
|
||||
POST /token HTTP/1.1
|
||||
Host: oauth2.googleapis.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
|
||||
client_id=your_client_id&
|
||||
client_secret=your_client_secret&
|
||||
redirect_uri=https%3A//oauth2.example.com/code&
|
||||
grant_type=authorization_code
|
||||
*/
|
||||
var reqData = {
|
||||
auth_type: "APPLE",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
};
|
||||
// userApi
|
||||
// .authStart(reqData)
|
||||
// .then((res) => {
|
||||
// if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
// localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
// localStorage.setItem("uid", `${res.data.uid}`);
|
||||
// localStorage.setItem("session_token", `${res.data.session}`);
|
||||
// dispatch(updateUserDetails({...res.data}));
|
||||
// navigate('/', {replace: true})
|
||||
// return
|
||||
// }
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// console.log(error);
|
||||
// });
|
||||
},[])
|
||||
return (
|
||||
<AuthLayout>
|
||||
<div className='min-h-[70vh]'>Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default AppleRedirect
|
||||
@@ -0,0 +1,65 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import { useDispatch } from "react-redux";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function FbookRedirect() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
|
||||
useEffect(()=>{
|
||||
if(!codeResponse){
|
||||
navigate('/login', {state: {error: true}})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse);
|
||||
|
||||
/*
|
||||
POST /token HTTP/1.1
|
||||
Host: oauth2.googleapis.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
|
||||
client_id=your_client_id&
|
||||
client_secret=your_client_secret&
|
||||
redirect_uri=https%3A//oauth2.example.com/code&
|
||||
grant_type=authorization_code
|
||||
*/
|
||||
var reqData = {
|
||||
auth_type: "FACEBOOK",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
};
|
||||
// userApi
|
||||
// .authStart(reqData)
|
||||
// .then((res) => {
|
||||
// if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
// localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
// localStorage.setItem("uid", `${res.data.uid}`);
|
||||
// localStorage.setItem("session_token", `${res.data.session}`);
|
||||
// dispatch(updateUserDetails({...res.data}));
|
||||
// navigate('/', {replace: true})
|
||||
// return
|
||||
// }
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// console.log(error);
|
||||
// });
|
||||
},[])
|
||||
return (
|
||||
<AuthLayout>
|
||||
<div className='min-h-[70vh]'>Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default FbookRedirect
|
||||
@@ -1,23 +1,64 @@
|
||||
import React, {useState, useEffect} from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import { useDispatch } from "react-redux";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function Redirect() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
|
||||
useEffect(()=>{
|
||||
if(!codeResponse){
|
||||
navigate('/login', {replace: true})
|
||||
if(!codeResponse){
|
||||
navigate('/login', {state: {error: true}})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse);
|
||||
/*
|
||||
POST /token HTTP/1.1
|
||||
Host: oauth2.googleapis.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
|
||||
client_id=your_client_id&
|
||||
client_secret=your_client_secret&
|
||||
redirect_uri=https%3A//oauth2.example.com/code&
|
||||
grant_type=authorization_code
|
||||
*/
|
||||
var reqData = {
|
||||
auth_type: "GOOGLE",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
};
|
||||
userApi
|
||||
.authStart(reqData)
|
||||
.then((res) => {
|
||||
if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
dispatch(updateUserDetails({...res.data}));
|
||||
navigate('/', {replace: true})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse)
|
||||
}
|
||||
navigate('/login', {state: {error: true}})
|
||||
})
|
||||
.catch((error) => {
|
||||
navigate('/login', {state: {error: true}})
|
||||
console.log(error);
|
||||
});
|
||||
},[])
|
||||
return (
|
||||
<div>Redirecting ... </div>
|
||||
<AuthLayout>
|
||||
<div className='min-h-[70vh]'>Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default Redirect
|
||||
export default Redirect
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import React, { useEffect, useLayoutEffect, useState } from "react";
|
||||
import { Link, useNavigate, useLocation } from "react-router-dom";
|
||||
import linkedInLogo from "../../../assets/images/Linkedin.png";
|
||||
import appleLogo from "../../../assets/images/apple-black.svg";
|
||||
import facebookLogo from "../../../assets/images/facebook-4.svg";
|
||||
@@ -16,15 +16,15 @@ import { updateUserDetails } from "../../../store/UserDetails";
|
||||
|
||||
export default function Login() {
|
||||
const dispatch = useDispatch();
|
||||
const {state} = useLocation()
|
||||
|
||||
let [loginType, setLoginType] = useState({ full: true, family: false });
|
||||
const [selectedLoginType, setSelectedLoginType] = useState(
|
||||
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
|
||||
);
|
||||
let [loginType, setLoginType] = useState('');
|
||||
|
||||
const [checked, setValue] = useState(false);
|
||||
const [loginLoading, setLoginLoading] = useState(false);
|
||||
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
//login error state
|
||||
const [loginError, setLoginError] = useState(false);
|
||||
// for the catch error
|
||||
@@ -34,13 +34,19 @@ export default function Login() {
|
||||
setValue(!checked);
|
||||
};
|
||||
|
||||
// To Show and Hide Password
|
||||
const togglePasswordVisibility = () => {
|
||||
setShowPassword(!showPassword);
|
||||
};
|
||||
|
||||
//FUNCTION TO DETERMINE/CHANGE LOGIN COMPONENT
|
||||
const handleLoginType = ({ target: { name } }) => {
|
||||
if (name == "full") {
|
||||
setLoginType({ [name]: true, family: false });
|
||||
} else if ((name = "family")) {
|
||||
setLoginType({ [name]: false, family: true });
|
||||
}
|
||||
setLoginType(name);
|
||||
let currentDate = new Date();
|
||||
let expirationDate = new Date(currentDate.getTime() + (24 * 60 * 60 * 1000));
|
||||
// Convert the expiration date to the appropriate format
|
||||
let expirationDateString = expirationDate.toUTCString();
|
||||
document.cookie = `loginType=${name}; expires=${expirationDateString}; path=/;`;
|
||||
};
|
||||
|
||||
// email
|
||||
@@ -71,7 +77,14 @@ export default function Login() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (name == "loginfull") {
|
||||
if (name == "full") {
|
||||
//checks if email is a valid email address
|
||||
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||
if (regEx.test(email) == false) {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(()=>{setMsgError("");},3000)
|
||||
}
|
||||
// Post Data Info for normal Login
|
||||
postData = {
|
||||
username: email,
|
||||
@@ -80,11 +93,7 @@ export default function Login() {
|
||||
login_mode: 1100,
|
||||
action: 11025,
|
||||
};
|
||||
|
||||
// Clear the loginType cookie if the user switches to loginfull
|
||||
document.cookie =
|
||||
"loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
} else if (name == "loginfamily") {
|
||||
} else if (name == "family") {
|
||||
// Post Data Info for family Login
|
||||
postData = {
|
||||
username: email,
|
||||
@@ -93,8 +102,6 @@ export default function Login() {
|
||||
login_mode: 1105,
|
||||
action: 11025,
|
||||
};
|
||||
// Set the loginType cookie to remember the user's selection
|
||||
document.cookie = "loginType=family; expires=Session; path=/;";
|
||||
} else {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Login Type. Consider refreshing the page");
|
||||
@@ -106,7 +113,7 @@ export default function Login() {
|
||||
userApi
|
||||
.logInUser(postData)
|
||||
.then((res) => {
|
||||
if (res.status != 200 || res.data.internal_return < 0) {
|
||||
if (res.status != 200 || res.data.internal_return < 0 || !res.data.member_id || !res.data.uid || !res.data.session) {
|
||||
// setMsgError("Wrong, email/password");
|
||||
setLoginError(true);
|
||||
setLoginLoading(false);
|
||||
@@ -116,7 +123,7 @@ export default function Login() {
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
// localStorage.setItem("session", `${res.data.session}`);
|
||||
dispatch(updateUserDetails(res.data));
|
||||
dispatch(updateUserDetails({...res.data}));
|
||||
setTimeout(() => {
|
||||
navigate("/", { replace: true });
|
||||
setLoginLoading(false);
|
||||
@@ -146,22 +153,57 @@ export default function Login() {
|
||||
});
|
||||
|
||||
// In order to update the selected login type whenever the component renders
|
||||
useEffect(() => {
|
||||
setSelectedLoginType(
|
||||
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
|
||||
);
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// Clear the loginType cookie if the user switches to loginfull
|
||||
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
// }, []);
|
||||
|
||||
useLayoutEffect(()=>{ // checks the cookie in order to set the login type before components mounts
|
||||
// if(document.cookie.includes("loginType=family")){
|
||||
// setLoginType('family')
|
||||
// }else if(document.cookie.includes("loginType=full")){
|
||||
// setLoginType('full')
|
||||
// }else{
|
||||
// setLoginType('full')
|
||||
// }
|
||||
function readCookie(cname) { // checks the cookie in order to set the login type before components mounts
|
||||
let name = cname + "=";
|
||||
let decoded_cookie = decodeURIComponent(document.cookie);
|
||||
let carr = decoded_cookie.split(';');
|
||||
for(let i=0; i<carr.length;i++){
|
||||
let c = carr[i];
|
||||
while(c.charAt(0)==' '){
|
||||
c=c.substring(1);
|
||||
}
|
||||
if(c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return 'full'
|
||||
}
|
||||
let loginValue = readCookie('loginType')
|
||||
setLoginType(loginValue)
|
||||
|
||||
if(state?.error){ //check if the login path has an error state indicating any social handle login with error
|
||||
setMsgError("Unexpected Error, Please try again soon.");
|
||||
setTimeout(()=>{
|
||||
setMsgError("");
|
||||
navigate('/login', {replace: true})
|
||||
},4000)
|
||||
}
|
||||
},[])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
setMail("");
|
||||
setPassword("");
|
||||
}, [loginType.full, loginType.family]);
|
||||
}, [loginType]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AuthLayout slogan="Welcome to WrenchBoard">
|
||||
<div className="w-full">
|
||||
<div className="mb-12">
|
||||
<div className="mb-5">
|
||||
<Link to="#">
|
||||
<img
|
||||
src={WrenchBoard}
|
||||
@@ -170,7 +212,7 @@ export default function Login() {
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
|
||||
<div className="content-wrapper login shadow-md w-full lg:max-w-[530px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
|
||||
<div className="w-full">
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
{/* <h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
@@ -188,11 +230,11 @@ export default function Login() {
|
||||
</div>
|
||||
|
||||
{/* switch login component */}
|
||||
<div className="flex justify-start items-end">
|
||||
<div className="ml-7 flex justify-start items-center gap-3">
|
||||
<button
|
||||
name="full"
|
||||
className={`px-2 py-1 w-[100px] text-left h-[40px] text-lg font-bold text-[#4687ba] hover:text-[#009ef7] tracking-wide transition outline-none border-2 border-b-0 border-r-0 border-[#4687ba] ${
|
||||
loginType.full && "border-r-2 h-[45px]"
|
||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||
loginType=='full' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
onClick={handleLoginType}
|
||||
>
|
||||
@@ -200,12 +242,12 @@ export default function Login() {
|
||||
</button>
|
||||
<button
|
||||
name="family"
|
||||
className={`px-2 py-1 w-[100px] text-left h-[40px] text-lg font-bold text-[#4687ba] hover:text-[#009ef7] tracking-wide transition outline-none border-2 border-b-0 border-l-0 border-[#4687ba] ${
|
||||
loginType.family && "border-l-2 h-[45px]"
|
||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||
loginType=='family' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
onClick={handleLoginType}
|
||||
>
|
||||
Family
|
||||
Family Account
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -213,16 +255,16 @@ export default function Login() {
|
||||
|
||||
{/* for login component */}
|
||||
{
|
||||
loginType.full ? (
|
||||
loginType == 'full' ? (
|
||||
//user login component
|
||||
<div className="p-2 input-area border-2 border-[#4687ba]">
|
||||
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="sm:px-6 px-2"
|
||||
value={email}
|
||||
inputHandler={handleEmail}
|
||||
placeholder="support@mermsemr.com"
|
||||
placeholder="Your Email"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
@@ -239,8 +281,9 @@ export default function Login() {
|
||||
placeholder="● ● ● ● ● ●"
|
||||
label="Password"
|
||||
name="password"
|
||||
type="password"
|
||||
iconName="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
onClick={togglePasswordVisibility}
|
||||
passIcon={showPassword ? "password" : "password"}
|
||||
forgotPassword
|
||||
/>
|
||||
</div>
|
||||
@@ -264,7 +307,7 @@ export default function Login() {
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
name="loginfull"
|
||||
name="full"
|
||||
onClick={doLogin}
|
||||
type="button"
|
||||
disabled={loginLoading}
|
||||
@@ -278,43 +321,51 @@ export default function Login() {
|
||||
</button>
|
||||
</div>
|
||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
<BrandBtn link="#" imgSrc={appleLogo} brand="Apple" />
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
<BrandBtn
|
||||
// link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
|
||||
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
|
||||
imgSrc={appleLogo}
|
||||
brand="Apple"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
/>
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
/>
|
||||
<BrandBtn
|
||||
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
isAnchor={true}
|
||||
/>
|
||||
<BrandBtn
|
||||
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
// END of user login compoenent
|
||||
// family login compoenent
|
||||
<div className="p-2 input-area border-2 border-[#4687ba]">
|
||||
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="px-6"
|
||||
value={email}
|
||||
inputHandler={handleEmail}
|
||||
placeholder="support@mermsemr.com"
|
||||
placeholder="Account ID"
|
||||
label="Username"
|
||||
name="email"
|
||||
type="email"
|
||||
iconName="message"
|
||||
iconName="family-id"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -327,9 +378,9 @@ export default function Login() {
|
||||
placeholder="● ● ● ● ● ●"
|
||||
label="Pin"
|
||||
name="password"
|
||||
type="password"
|
||||
iconName="password"
|
||||
// forgotPassword
|
||||
type={showPassword ? "text" : "password"}
|
||||
onClick={togglePasswordVisibility}
|
||||
passIcon={showPassword ? "family-pin" : "family-pin"}
|
||||
/>
|
||||
</div>
|
||||
{loginError && (
|
||||
@@ -352,7 +403,7 @@ export default function Login() {
|
||||
<div className="signin-area mb-1.5">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
name="loginfamily"
|
||||
name="family"
|
||||
onClick={doLogin}
|
||||
disabled={loginLoading}
|
||||
type="button"
|
||||
@@ -384,7 +435,7 @@ export default function Login() {
|
||||
);
|
||||
}
|
||||
|
||||
const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
||||
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
|
||||
// const doGoogle = async () => {
|
||||
// alert("start google");
|
||||
// };
|
||||
@@ -403,10 +454,23 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
||||
// const doFacebook = async () => {
|
||||
// alert("start facebook");
|
||||
// };
|
||||
|
||||
return (
|
||||
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
|
||||
<button
|
||||
{isAnchor ?
|
||||
(
|
||||
<a
|
||||
href={link}
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
:
|
||||
(
|
||||
<button
|
||||
onClick={onClick}
|
||||
// href="#dd"
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
@@ -416,6 +480,9 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import facebookLogo from "../../../assets/images/facebook-4.svg";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
export default function SignUp() {
|
||||
const [signUpLoading, setSignUpLoading] = useState(false);
|
||||
@@ -64,6 +65,19 @@ export default function SignUp() {
|
||||
last_name !== "" &&
|
||||
country !== ""
|
||||
) {
|
||||
//checks if email is a valid email address
|
||||
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||
if (regEx.test(email) == false) {
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(()=>{setMsgError("");},3000)
|
||||
}
|
||||
|
||||
//checks if terms and condition is checked
|
||||
if (!checked) {
|
||||
setMsgError("Terms and condition required");
|
||||
return setTimeout(()=>{setMsgError("");},3000)
|
||||
}
|
||||
|
||||
setSignUpLoading(true);
|
||||
const reqData = {
|
||||
country: country,
|
||||
@@ -81,7 +95,7 @@ export default function SignUp() {
|
||||
if (res.status === 200) {
|
||||
const { data } = res;
|
||||
if (data && data.acc === "DULPICATE") {
|
||||
setMsgError("This account has been already created");
|
||||
setMsgError("Unable to use this username. Please try another username.");
|
||||
setSignUpLoading(false);
|
||||
}
|
||||
if (data && data.status === "1") {
|
||||
@@ -112,212 +126,159 @@ export default function SignUp() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="layout-wrapper login">
|
||||
<div className="main-wrapper login-wrapper w-full xl:h-screen h-full xl:py-10 py-12 overflow-y-auto">
|
||||
<div className=" h-full">
|
||||
<div className="flex-1 flex justify-center items-center">
|
||||
<div className="w-full">
|
||||
<div className="mb-12">
|
||||
<Link to="#">
|
||||
<img
|
||||
src={WrenchBoard}
|
||||
alt="wrenchboard"
|
||||
className="h-10 mx-auto"
|
||||
/>
|
||||
<AuthLayout slogan="Welcome to WrenchBoard">
|
||||
<div className="w-full">
|
||||
<div className="mb-5">
|
||||
<Link to="#">
|
||||
<img
|
||||
src={WrenchBoard}
|
||||
alt="wrenchboard"
|
||||
className="h-10 mx-auto"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="content-wrapper login relative shadow-md w-full lg:max-w-[530px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5 mb-0">
|
||||
<div>
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
Create Account
|
||||
</h1>
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
Already have an account?{" "}
|
||||
<Link
|
||||
to="/login"
|
||||
className="font-semibold text-[#4687ba] hover:text-[#009ef7] transition"
|
||||
>
|
||||
Sign in here
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div className="w-full flex items-center gap-2">
|
||||
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
|
||||
<span className="text-[#b5b5c3] font-medium text-[0.7rem] w-[2%]">
|
||||
OR
|
||||
</span>
|
||||
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
|
||||
</div>
|
||||
<div className="input-area">
|
||||
<SelectOption
|
||||
label="Country"
|
||||
data={countries}
|
||||
name="country"
|
||||
value={formData.country}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
<div className="input-fl-name mb-5 sm:flex w-full sm:space-x-6 ">
|
||||
<div className="input-item sm:w-1/2 w-full mb-5 sm:mb-0">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="Firstname"
|
||||
label="First Name"
|
||||
name="first_name"
|
||||
type="text"
|
||||
value={formData.first_name}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-item flex-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="Lastname"
|
||||
label="Last Name"
|
||||
name="last_name"
|
||||
type="text"
|
||||
value={formData.last_name}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-wrapper login shadow-md w-full lg:max-w-[600px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5 mb-7">
|
||||
<div>
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
Create Account
|
||||
</h1>
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
Already have an account?{" "}
|
||||
<Link
|
||||
to="/login"
|
||||
className="font-semibold text-[#4687ba] hover:text-[#009ef7] transition"
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="support@mermsemr.com"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
value={formData.email}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="● ● ● ● ● ●"
|
||||
label="Password"
|
||||
name="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
onClick={togglePasswordVisibility}
|
||||
passIcon={
|
||||
showPassword ? "show-password" : "hide-password"
|
||||
}
|
||||
value={formData.password}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
{msgError && (
|
||||
<div className="p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
<div className="forgot-password-area flex justify-between items-center mb-6">
|
||||
<div className="remember-checkbox flex items-center space-x-2.5">
|
||||
<button
|
||||
onClick={rememberMe}
|
||||
type="button"
|
||||
className="w-6 h-6 bg-[#4687ba] text-white flex justify-center items-center border border-light-gray rounded-[.45em]"
|
||||
>
|
||||
{checked && (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-5 w-5"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
Sign in here
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
<span
|
||||
onClick={rememberMe}
|
||||
className="cursor-default text-dark-gray dark:text-white text-[15px]"
|
||||
>
|
||||
I agree with all
|
||||
<Link
|
||||
href="#"
|
||||
className="text-base text-[#4687ba] hover:text-[#009ef7] mx-1 inline-block"
|
||||
>
|
||||
terms and condition
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="signin-area mb-1">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
type="button"
|
||||
className={`rounded-[0.475rem] w-full mb-6 text-[15px] h-[42px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem]`}
|
||||
onClick={handleSignUp}
|
||||
className={`rounded-[0.475rem] mb-6 text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
|
||||
>
|
||||
<img
|
||||
className="mr-3 h-6"
|
||||
src={facebookLogo}
|
||||
alt="logo-icon(s)"
|
||||
/>
|
||||
Sign in with Facebook
|
||||
</button>
|
||||
<div className="w-full flex items-center gap-2">
|
||||
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
|
||||
<span className="text-[#b5b5c3] font-medium text-[0.7rem] w-[2%]">
|
||||
OR
|
||||
</span>
|
||||
<div className="border-b border-[#eff2f5] max-w-[50%] w-full"></div>
|
||||
</div>
|
||||
<div className="input-area">
|
||||
<SelectOption
|
||||
label="Country"
|
||||
data={countries}
|
||||
name="country"
|
||||
value={formData.country}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
<div className="input-fl-name mb-5 sm:flex w-full sm:space-x-6 ">
|
||||
<div className="input-item sm:w-1/2 w-full mb-5 sm:mb-0">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="Firstname"
|
||||
label="First Name"
|
||||
name="first_name"
|
||||
type="text"
|
||||
value={formData.first_name}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-item flex-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="Lastname"
|
||||
label="Last Name"
|
||||
name="last_name"
|
||||
type="text"
|
||||
value={formData.last_name}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="support@mermsemr.com"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
value={formData.email}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="● ● ● ● ● ●"
|
||||
label="Password"
|
||||
name="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
onClick={togglePasswordVisibility}
|
||||
passIcon={
|
||||
showPassword ? "show-password" : "hide-password"
|
||||
}
|
||||
value={formData.password}
|
||||
inputHandler={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">
|
||||
{msgError}
|
||||
</div>
|
||||
{signUpLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<span>Sign Up</span>
|
||||
)}
|
||||
<div className="forgot-password-area flex justify-between items-center mb-6">
|
||||
<div className="remember-checkbox flex items-center space-x-2.5">
|
||||
<button
|
||||
onClick={rememberMe}
|
||||
type="button"
|
||||
className="w-6 h-6 bg-[#4687ba] text-white flex justify-center items-center border border-light-gray rounded-[.45em]"
|
||||
>
|
||||
{checked && (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-5 w-5"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
<span
|
||||
onClick={rememberMe}
|
||||
className="cursor-default text-dark-gray dark:text-white text-[15px]"
|
||||
>
|
||||
I agree with all
|
||||
<Link
|
||||
href="#"
|
||||
className="text-base text-[#4687ba] hover:text-[#009ef7] mx-1 inline-block"
|
||||
>
|
||||
terms and condition
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="signin-area mb-1">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleSignUp}
|
||||
className={`rounded-[0.475rem] mb-6 text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
|
||||
>
|
||||
{signUpLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<span>Sign Up</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex justify-center items-center p-10">
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href="https://www.wrenchboard.com/about-us"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/service"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/contact"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Contact Us
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex justify-center items-center p-10">
|
||||
<p className="text-black text-[15px] px-2 font-medium flex items-center">
|
||||
<span className="text-3xl mt-2 mr-1">©</span> 2023 -{" "}
|
||||
<Link to="/" className="text-[#009ef7] ml-1">
|
||||
WrenchBoard
|
||||
</Link>{" "}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AuthLayout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -343,7 +304,7 @@ const SelectOption = ({
|
||||
<select
|
||||
name={name}
|
||||
id={name}
|
||||
className="input-wrapper border border-[#f5f8fa]] dark:border-[#5e6278] w-full rounded-[0.475rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
|
||||
className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
|
||||
onChange={inputHandler}
|
||||
value={value}
|
||||
>
|
||||
|
||||
@@ -86,11 +86,15 @@ export default function VerifyLink() {
|
||||
const verifyRes = await userApi.verifyEmail(code);
|
||||
if (verifyRes.status === 200) {
|
||||
let { data } = verifyRes;
|
||||
|
||||
console.log('TESTING VERIFY',data)
|
||||
if (
|
||||
data &&
|
||||
data.internal_return >= 0 &&
|
||||
data.status_text === "Link Verfied"
|
||||
data.internal_return >= 0 &&
|
||||
data.status == 0 &&
|
||||
data.pending_id != '' &&
|
||||
data.pending_uid != '' &&
|
||||
data.username != '' &&
|
||||
data.status_text === "Link Verified"
|
||||
) {
|
||||
setPageLoader(false);
|
||||
} else {
|
||||
|
||||
@@ -9,13 +9,13 @@ export default function AvailableJobsCard({
|
||||
className,
|
||||
datas,
|
||||
hidden = false,
|
||||
contentDisplay
|
||||
contentDisplay,
|
||||
}) {
|
||||
//debugger;
|
||||
const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} });
|
||||
const [imageUrl, setImageUrl] = useState("");
|
||||
|
||||
let thePrice = PriceFormatter(
|
||||
let thePrice = PriceFormatter(
|
||||
datas?.price * 0.01,
|
||||
datas?.currency_code,
|
||||
datas?.currency
|
||||
@@ -27,121 +27,136 @@ export default function AvailableJobsCard({
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
{contentDisplay == 'grid' ?
|
||||
<div
|
||||
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col justify-between w-full h-full">
|
||||
<Link to="/shop-details" className="mb-2.5">
|
||||
{contentDisplay == "grid" ? (
|
||||
<div
|
||||
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
className="flex flex-col justify-between w-full h-full"
|
||||
>
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{datas.title}
|
||||
</h1>
|
||||
</Link>
|
||||
|
||||
<div className="card-two-info flex justify-between items-center">
|
||||
<div className="owned-by flex space-x-2 items-center">
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-sm leading-3">Added</p>
|
||||
<p className="text-base text-dark-gray dark:text-white">
|
||||
{datas.offer_added}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-[1px] bg-light-purple dark:bg-dark-light-purple h-7"></div>
|
||||
<div className="created-by flex space-x-2 items-center flex-row-reverse">
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-sm leading-3 text-right">
|
||||
Expires
|
||||
</p>
|
||||
<p className="text-base text-dark-gray dark:text-white text-right">
|
||||
{datas.expire}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="thumbnail-area w-full">
|
||||
<div
|
||||
className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-center bg-cover bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url('${imageUrl}')`,
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-center">{datas.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="details-area">
|
||||
<div className="product-two-options flex justify-between mb-5 relative">
|
||||
{/* <div className="status">*/}
|
||||
{/* {datas.isActive && (*/}
|
||||
{/* <span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">*/}
|
||||
{/* Active*/}
|
||||
{/*</span>*/}
|
||||
{/* )}*/}
|
||||
{/* </div>*/}
|
||||
|
||||
{/*<div className=" review flex space-x-2">*/}
|
||||
{/* <button*/}
|
||||
{/* onClick={favoriteHandler}*/}
|
||||
{/* type="button"*/}
|
||||
{/* className={`w-7 h-7 bg-white rounded-full flex justify-center items-center ${*/}
|
||||
{/* addFavorite ? "text-red-500" : "text-thin-light-gray"*/}
|
||||
{/* }`}*/}
|
||||
{/* >*/}
|
||||
{/* <Icons name="star" />*/}
|
||||
{/* </button>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="card-two-info flex justify-between items-center">
|
||||
<div className="owned-by flex space-x-2 items-center">
|
||||
<div>
|
||||
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
|
||||
{/* {thePrice} | {datas.timeline_days} day(s) */}
|
||||
{thePrice}
|
||||
<p className="text-thin-light-gray text-sm leading-3">
|
||||
Added
|
||||
</p>
|
||||
<p className="text-sm text-lighter-gray">
|
||||
( {datas.offer_code}) |
|
||||
<span className="italic ml-1">
|
||||
{datas.timeline_days} day(s)
|
||||
</span>
|
||||
<p className="text-base text-dark-gray dark:text-white">
|
||||
{datas.offer_added}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
>
|
||||
View
|
||||
</button>
|
||||
<div className="w-[1px] bg-light-purple dark:bg-dark-light-purple h-7"></div>
|
||||
<div className="created-by flex space-x-2 items-center flex-row-reverse">
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-sm leading-3 text-right">
|
||||
Expires
|
||||
</p>
|
||||
<p className="text-base text-dark-gray dark:text-white text-right">
|
||||
{datas.expire}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="thumbnail-area w-full">
|
||||
<div
|
||||
className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-center bg-cover bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url('${imageUrl}')`,
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-center">{datas.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="details-area">
|
||||
<div className="product-two-options flex justify-between mb-5 relative">
|
||||
{/* <div className="status">*/}
|
||||
{/* {datas.isActive && (*/}
|
||||
{/* <span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">*/}
|
||||
{/* Active*/}
|
||||
{/*</span>*/}
|
||||
{/* )}*/}
|
||||
{/* </div>*/}
|
||||
|
||||
{/*<div className=" review flex space-x-2">*/}
|
||||
{/* <button*/}
|
||||
{/* onClick={favoriteHandler}*/}
|
||||
{/* type="button"*/}
|
||||
{/* className={`w-7 h-7 bg-white rounded-full flex justify-center items-center ${*/}
|
||||
{/* addFavorite ? "text-red-500" : "text-thin-light-gray"*/}
|
||||
{/* }`}*/}
|
||||
{/* >*/}
|
||||
{/* <Icons name="star" />*/}
|
||||
{/* </button>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div>
|
||||
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
|
||||
{/* {thePrice} | {datas.timeline_days} day(s) */}
|
||||
{thePrice}
|
||||
</p>
|
||||
<p className="text-sm text-lighter-gray">
|
||||
( {datas.offer_code}) |
|
||||
<span className="italic ml-1">
|
||||
{datas.timeline_days} day(s)
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
|
||||
<div className="flex gap-5 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||
<img src={dataImage2} alt="data" className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<Link to="/shop-details" className="">
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
) : (
|
||||
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
|
||||
<div className="flex gap-5 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||
<img src={dataImage2} alt="data" className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<h1
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize"
|
||||
>
|
||||
{datas?.title}
|
||||
</h1>
|
||||
</Link>
|
||||
|
||||
<div className="my-2">
|
||||
<p className="text-dark-gray dark:text-white">{datas?.description}</p>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
className="my-2"
|
||||
>
|
||||
<p className="text-dark-gray dark:text-white">
|
||||
{datas?.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* <div className="card-two-info flex gap-2 items-center">
|
||||
{/* <div className="card-two-info flex gap-2 items-center">
|
||||
<div className="owned-by flex space-x-2 items-center">
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-sm leading-3">Added</p>
|
||||
@@ -162,40 +177,37 @@ export default function AvailableJobsCard({
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="block sm:flex flex-wrap gap-4">
|
||||
<p className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||
Price: <span className="text-purple">{thePrice}</span>
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple italic">
|
||||
{" "}
|
||||
{datas?.timeline_days} day(s)
|
||||
</span>
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray">
|
||||
Code:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{datas?.offer_code}
|
||||
</span>
|
||||
</p>
|
||||
<div className="block sm:flex flex-wrap gap-4">
|
||||
<p className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||
Price: <span className="text-purple">{thePrice}</span>
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple italic">
|
||||
{" "}
|
||||
{datas?.timeline_days} day(s)
|
||||
</span>
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray">
|
||||
Code:{" "}
|
||||
<span className="text-purple"> {datas?.offer_code}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="">
|
||||
<button
|
||||
type="button"
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="">
|
||||
<button
|
||||
type="button"
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
{marketPopUp.show && (
|
||||
<MarketPopUp
|
||||
details={datas}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import { useState } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import CountDown from "../Helpers/CountDown";
|
||||
import Icons from "../Helpers/Icons";
|
||||
|
||||
export default function FamilyActiveJobsCard({ datas, hidden = false }) {
|
||||
|
||||
let { pathname } = useLocation();
|
||||
|
||||
const [imageUrl, setImageUrl] = useState("");
|
||||
const [addFavorite, setValue] = useState(false);
|
||||
const [options, setOption] = useState(false);
|
||||
const favoriteHandler = () => {
|
||||
if (!addFavorite) {
|
||||
setValue(true);
|
||||
toast.success("Added to Favorite List");
|
||||
} else {
|
||||
setValue(false);
|
||||
toast.warn("Remove to Favorite List");
|
||||
}
|
||||
};
|
||||
//debugger;
|
||||
const bannerName = datas.banner == null ?'default.jpg':datas.banner;
|
||||
return (
|
||||
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
|
||||
<div className="content">
|
||||
{/* thumbnail */}
|
||||
<div className="w-full h-40">
|
||||
{/* thumbnail image */}
|
||||
<div
|
||||
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
|
||||
style={{
|
||||
background: `url(${localImgLoad(
|
||||
`images/taskbanners/${bannerName}`
|
||||
)}) center / contain no-repeat`,
|
||||
}}
|
||||
>
|
||||
{/* <div className="product-options flex justify-between relative">*/}
|
||||
{/*<span*/}
|
||||
{/* onClick={favoriteHandler}*/}
|
||||
{/* className={`w-7 h-7 bg-white rounded-full flex justify-center items-center cursor-pointer ${*/}
|
||||
{/* addFavorite ? "text-pink" : " text-dark-gray"*/}
|
||||
{/* }`}*/}
|
||||
{/*>*/}
|
||||
{/* <Icons name="love" />*/}
|
||||
{/*</span>*/}
|
||||
{/* <span*/}
|
||||
{/* onClick={() => setOption(!options)}*/}
|
||||
{/* className="w-7 h-7 flex justify-center items-center bg-white rounded-full cursor-pointer"*/}
|
||||
{/* >*/}
|
||||
{/* <Icons name="dots" />*/}
|
||||
{/*</span>*/}
|
||||
{/* {options && (*/}
|
||||
{/* <div*/}
|
||||
{/* onClick={() => setOption(!options)}*/}
|
||||
{/* className="w-full h-screen fixed top-0 left-0 z-10"*/}
|
||||
{/* ></div>*/}
|
||||
{/* )}*/}
|
||||
{/* <div*/}
|
||||
{/* style={{ boxShadow: "0px 4px 87px 0px #0000002B" }}*/}
|
||||
{/* className={`drop-down-content w-[80px] bg-white dark:bg-dark-white rounded-[4px] p-2.5 absolute right-0 top-[100%] z-20 ${*/}
|
||||
{/* options ? "active" : ""*/}
|
||||
{/* }`}*/}
|
||||
{/* >*/}
|
||||
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{hidden && (
|
||||
<div className="flex justify-center">
|
||||
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* details */}
|
||||
<div className="details">
|
||||
{/* product title */}
|
||||
<Link
|
||||
to="/manage-active-job"
|
||||
state={{ ...datas, pathname }}
|
||||
className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1"
|
||||
>
|
||||
{datas.title}
|
||||
</Link>
|
||||
{/* countdown */}
|
||||
<div className="w-full h-[54px] flex justify-evenly items-center p-2 rounded-lg border border-[#E3E4FE] dark:border-[#a7a9b533] ">
|
||||
<div className="flex flex-col justify-between">
|
||||
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
|
||||
Task Code
|
||||
</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
{datas.contract}
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-[1px] h-full bg-[#E3E4FE] dark:bg-[#a7a9b533] "></div>
|
||||
<div className="flex flex-col justify-between">
|
||||
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
|
||||
Remaining Time
|
||||
</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
<CountDown lastDate={datas.delivery_date} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-buttons flex justify-end items-center space-x-2">
|
||||
<Link
|
||||
to="/manage-active-job"
|
||||
state={{ ...datas, pathname }}
|
||||
className="btn-shine w-[98px] h-[33px] text-white rounded-full text-sm bg-pink flex justify-center items-center"
|
||||
>
|
||||
View
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,72 +1,78 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import Icons from "../Helpers/Icons";
|
||||
import { useState } from "react";
|
||||
import SuggestTask from "../FamilyPopup/SuggestTask";
|
||||
|
||||
export default function FamilyMarketCard({
|
||||
className,
|
||||
datas,
|
||||
hidden = false,
|
||||
}) {
|
||||
export default function FamilyMarketCard({ className, datas, hidden = false }) {
|
||||
// debugger;
|
||||
const [addFavorite, setValue] = useState(datas.whishlisted);
|
||||
const [options, setOption] = useState(false);
|
||||
const favoriteHandler = () => {
|
||||
if (!addFavorite) {
|
||||
setValue(true);
|
||||
toast.success("Added to Favorite List");
|
||||
} else {
|
||||
setValue(false);
|
||||
toast.warn("Remove to Favorite List");
|
||||
}
|
||||
const [popUp, setPopUp] = useState(false);
|
||||
const popUpHandler = () => {
|
||||
setPopUp((prev) => !prev);
|
||||
};
|
||||
// Image
|
||||
let selectedImage = require(`../../assets/images/family/${
|
||||
datas.banner || "default.jpg"
|
||||
}`);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`card-style-two w-full h-[336px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col justify-between w-full h-full">
|
||||
<div className="thumbnail-area w-full">
|
||||
<div
|
||||
className="w-full h-[236px] p-6 rounded-xl overflow-hidden"
|
||||
style={{
|
||||
background: `url(${`https://blog.float.sg/wp-content/uploads/${datas.meta_value}`}) 0% 0% / cover no-repeat`,
|
||||
}}
|
||||
>
|
||||
<div className="product-two-options flex justify-between mb-5 relative">
|
||||
<div className="status">
|
||||
{datas?.isActive && (
|
||||
<span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">
|
||||
<>
|
||||
<div
|
||||
className={`card-style-two w-full h-[336px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
}`}
|
||||
key={datas?.uid}
|
||||
>
|
||||
<div className="flex flex-col justify-between w-full h-full">
|
||||
<div className="thumbnail-area w-full">
|
||||
<div
|
||||
className="w-full h-[236px] p-6 rounded-xl overflow-hidden"
|
||||
onClick={popUpHandler}
|
||||
style={{
|
||||
// background: `url(${selectedImage}) 0% 0% / cover no-repeat`,
|
||||
background: `url(${selectedImage}) center / contain no-repeat`,
|
||||
}}
|
||||
>
|
||||
<div className="product-two-options flex justify-between mb-5 relative">
|
||||
<div className="status">
|
||||
{/* <span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">
|
||||
Active
|
||||
</span>
|
||||
)}
|
||||
</span> */}
|
||||
</div>
|
||||
</div>
|
||||
{hidden && <div className="flex justify-center"></div>}
|
||||
</div>
|
||||
{hidden && <div className="flex justify-center"></div>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="details-area">
|
||||
{/* title */}
|
||||
<Link to="/shop-details" className="mb-2.5">
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{datas.post_title}
|
||||
</h1>
|
||||
</Link>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center space-x-2"></div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
<div className="details-area mt-12 flex justify-between items-center gap-2">
|
||||
{/* title */}
|
||||
<button onClick={popUpHandler}>
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{datas?.title}
|
||||
</h1>
|
||||
</button>
|
||||
<div className="flex justify-between">
|
||||
{/* <div className="flex items-center space-x-2">
|
||||
<p className="italic text-gray-400">
|
||||
{getTimeAgo(datas?.added)}
|
||||
</p>
|
||||
</div> */}
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={popUpHandler}
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{popUp && (
|
||||
<SuggestTask
|
||||
onClose={popUpHandler}
|
||||
situation={popUp}
|
||||
details={{ ...datas, selectedImage }}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,21 +17,21 @@ export default function HomeBannerOffersCard(props) {
|
||||
return (
|
||||
<Link
|
||||
to={link_result}
|
||||
className="item w-full block group banner-630-340 bg-cover bg-center"
|
||||
className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center"
|
||||
style={{
|
||||
backgroundImage: `url('${imageUrl}')`,
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col justify-between h-full">
|
||||
<div className="w-[80%] h-full mx-auto flex flex-col justify-between">
|
||||
<div className="content flex justify-between items-center">
|
||||
<div className="siderCardHeader">
|
||||
<h1 className="text-2xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
<div className="mb-2">
|
||||
<h1 className="text-2xl lg:text-4xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
<span className="heroSilderTitle">{props.itemData.title}</span>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col justify-around items-center flex-1">
|
||||
<div className="siderCardDescription">
|
||||
<div className="siderCardDescription mb-2">
|
||||
{props.itemData.description}
|
||||
</div>
|
||||
<button className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import CountDown from "../Helpers/CountDown";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
export default function OfferCard({ datas, hidden = false, setOfferPopout }) {
|
||||
let thePrice = PriceFormatter(
|
||||
datas?.price * 0.01,
|
||||
datas?.currency_code,
|
||||
datas?.currency
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
|
||||
<div className="content">
|
||||
{/* thumbnail */}
|
||||
<div className="w-full h-40">
|
||||
{/* thumbnail image */}
|
||||
<div
|
||||
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
|
||||
style={{
|
||||
background: `url(${localImgLoad(
|
||||
`images/taskbanners/${datas.banner}`
|
||||
)}) center / contain no-repeat`,
|
||||
}}
|
||||
>
|
||||
{hidden && <div className="flex justify-center"></div>}
|
||||
</div>
|
||||
</div>
|
||||
{/* details */}
|
||||
<div className="details">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
{datas.title}
|
||||
</h1>
|
||||
{/* countdown */}
|
||||
{/* <div className="w-full h-[54px] flex justify-evenly items-center p-2 rounded-lg border border-[#E3E4FE] dark:border-[#a7a9b533] ">
|
||||
<div className="flex flex-col justify-between">
|
||||
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
|
||||
Task Code
|
||||
</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
{datas.contract}
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-[1px] h-full bg-[#E3E4FE] dark:bg-[#a7a9b533] "></div>
|
||||
<div className="flex flex-col justify-between">
|
||||
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
|
||||
Remaining Time
|
||||
</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
<CountDown lastDate={datas.expire} />
|
||||
</p>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="w-full p-2 rounded-lg border border-[#E3E4FE] dark:border-[#a7a9b533] ">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="flex flex-col justify-between items-center border-r-2">
|
||||
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
|
||||
Task Code
|
||||
</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
{datas.contract}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col justify-between items-center">
|
||||
<p className="text-sm text-red-500 tracking-wide">Expires</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
<CountDown lastDate={datas.expire} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-2" />
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="flex flex-col justify-between items-center border-r-2">
|
||||
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
|
||||
Reward
|
||||
</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
{thePrice}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col justify-between items-center">
|
||||
<p className="text-sm text-thin-light-gray dark:text-white tracking-wide">
|
||||
Timeline
|
||||
</p>
|
||||
<p className="text-base font-bold tracking-wide text-dark-gray dark:text-white">
|
||||
{`${datas.timeline_days} day(s)`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-buttons flex justify-end items-center space-x-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
setOfferPopout({ show: true, data: { ...datas, thePrice } })
|
||||
}
|
||||
className="btn-shine w-[98px] h-[33px] text-white rounded-full text-sm bg-pink flex justify-center items-center"
|
||||
>
|
||||
Start Task
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Layout from "../Partials/Layout";
|
||||
import FamilyManageTabs from "./Tabs/FamilyManageTabs";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import FamilyManageTabs from "./FamilyManageTabs";
|
||||
|
||||
export default function FamilyManage() {
|
||||
const [selectTab, setValue] = useState("today");
|
||||
@@ -11,7 +11,7 @@ export default function FamilyManage() {
|
||||
let location = useLocation();
|
||||
let navigate = useNavigate();
|
||||
let accountDetails = location?.state;
|
||||
|
||||
|
||||
// tab handler
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
import React, {
|
||||
Suspense,
|
||||
lazy,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
useTransition,
|
||||
} from "react";
|
||||
import { useReactToPrint } from "react-to-print";
|
||||
import profile from "../../assets/images/profile-info-profile.png";
|
||||
import usersService from "../../services/UsersService";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
// Lazy Imports for components
|
||||
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
|
||||
const FamilyAccount = lazy(() => import("./Tabs/FamilyAccount"));
|
||||
const FamilyProfile = lazy(() => import("./Tabs/FamilyProfile"));
|
||||
const FamilyTasks = lazy(() => import("./Tabs/FamilyTasks"));
|
||||
const ProfileInfo = lazy(() => import("./Tabs/ProfileInfo"));
|
||||
const FamilyPending = lazy(() => import("./Tabs/FamilyPending"));
|
||||
|
||||
export default function FamilyManageTabs({
|
||||
className,
|
||||
accountDetails,
|
||||
listReload,
|
||||
loader,
|
||||
}) {
|
||||
const [details, setDetails] = useState({
|
||||
familyDetails: { loading: false, data: null },
|
||||
familyTasks: { loading: false, data: null },
|
||||
familyWaitList: { loading: false, data: null },
|
||||
familyPending: { loading: false, data: null },
|
||||
});
|
||||
const [errMsg, setErrMsg] = useState("");
|
||||
const [familyTaskPopout, setFamilyTaskPopout] = useState(false);
|
||||
const [profileImg, setProfileImg] = useState(profile);
|
||||
const profileImgInput = useRef(null);
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
const familyPopUpHandler = () => {
|
||||
setFamilyTaskPopout((prev) => !prev);
|
||||
};
|
||||
|
||||
const browseProfileImg = () => {
|
||||
profileImgInput.current.click();
|
||||
};
|
||||
|
||||
const profileImgChangeHandler = (e) => {
|
||||
if (e.target.value !== "") {
|
||||
const imgReader = new FileReader();
|
||||
imgReader.onload = (event) => {
|
||||
setProfileImg(event.target.result);
|
||||
};
|
||||
imgReader.readAsDataURL(e.target.files[0]);
|
||||
}
|
||||
};
|
||||
|
||||
const manageFamily = useCallback(async () => {
|
||||
try {
|
||||
setDetails((prevDetails) => ({
|
||||
...prevDetails,
|
||||
familyDetails: { loading: true },
|
||||
familyTasks: { loading: true },
|
||||
familyWaitList: { loading: true },
|
||||
familyPending: { loading: true },
|
||||
}));
|
||||
|
||||
const { family_uid } = accountDetails;
|
||||
const reqData = { family_uid };
|
||||
|
||||
const [familyRes, tasksRes, familyWaitRes, familyPending] =
|
||||
await Promise.all([
|
||||
apiCall.ManageFamily(reqData),
|
||||
apiCall.ManageTasks(reqData),
|
||||
apiCall.ManageFamilyWaitlist(),
|
||||
apiCall.ManageFamilyPending(),
|
||||
]);
|
||||
|
||||
const familyData = familyRes.data;
|
||||
const tasksData = tasksRes.data;
|
||||
const familyWaitData = familyWaitRes.data;
|
||||
const familyPendingData = familyPending.data;
|
||||
|
||||
if (
|
||||
familyData?.internal_return < 0 ||
|
||||
tasksData?.internal_return < 0 ||
|
||||
familyWaitData?.internal_return < 0 ||
|
||||
familyPendingData?.internal_return < 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
startTransition(() => {
|
||||
setDetails({
|
||||
familyDetails: { loading: false, data: familyData },
|
||||
familyTasks: { loading: false, data: tasksData },
|
||||
familyWaitList: { loading: false, data: familyWaitData },
|
||||
familyPending: { loading: false, data: familyPendingData },
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
setDetails((prevDetails) => ({
|
||||
...prevDetails,
|
||||
familyDetails: { loading: false },
|
||||
familyTasks: { loading: false },
|
||||
familyWaitList: { loading: false },
|
||||
familyPending: { loading: false },
|
||||
}));
|
||||
setErrMsg("An error occurred");
|
||||
throw new Error(error);
|
||||
}
|
||||
}, [apiCall, accountDetails]);
|
||||
|
||||
const accountRef = useRef();
|
||||
|
||||
const useHandlePrint = useReactToPrint({
|
||||
content: () => accountRef.current,
|
||||
});
|
||||
|
||||
const tabs = [
|
||||
{ id: 1, name: "Tasks" },
|
||||
{ id: 2, name: "Waiting" },
|
||||
{ id: 3, name: "Pending" },
|
||||
];
|
||||
|
||||
const [tab, setTab] = useState(tabs[0].name);
|
||||
|
||||
const tabHandler = (value) => {
|
||||
startTransition(() => {
|
||||
setTab(value);
|
||||
});
|
||||
};
|
||||
|
||||
const tabComponents = {
|
||||
Tasks: (
|
||||
<FamilyTasks
|
||||
className={className}
|
||||
loader={details.familyTasks.loading}
|
||||
familyData={details.familyTasks.data}
|
||||
accountDetails={accountDetails}
|
||||
/>
|
||||
),
|
||||
Waiting: (
|
||||
<FamilyWaitlist
|
||||
familyData={details.familyWaitList.data}
|
||||
accountDetails={accountDetails}
|
||||
loader={details.familyWaitList.loading}
|
||||
/>
|
||||
),
|
||||
Pending: (
|
||||
<FamilyPending
|
||||
familyData={details.familyPending.data}
|
||||
accountDetails={accountDetails}
|
||||
loader={details.familyWaitList.loading}
|
||||
/>
|
||||
),
|
||||
Account: (
|
||||
<FamilyAccount
|
||||
familyData={details.familyDetails.data}
|
||||
myRef={accountRef}
|
||||
loader={details.familyDetails.loading}
|
||||
handlePrint={useHandlePrint}
|
||||
/>
|
||||
),
|
||||
Profile: <FamilyProfile />,
|
||||
};
|
||||
|
||||
const defaultTabComponent = (
|
||||
<FamilyTasks
|
||||
className={className}
|
||||
loader={details.familyTasks.loading}
|
||||
familyData={details.familyTasks.data}
|
||||
accountDetails={accountDetails}
|
||||
/>
|
||||
);
|
||||
|
||||
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
||||
|
||||
useEffect(() => {
|
||||
let __manageFamily = true;
|
||||
if (__manageFamily) {
|
||||
manageFamily();
|
||||
}
|
||||
return () => {
|
||||
__manageFamily = false;
|
||||
};
|
||||
}, [tab, manageFamily]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[520px]">
|
||||
<div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between">
|
||||
<ProfileInfo
|
||||
profileImg={profileImg}
|
||||
profileImgInput={profileImgInput}
|
||||
profileImgChangeHandler={profileImgChangeHandler}
|
||||
browseProfileImg={browseProfileImg}
|
||||
accountDetails={accountDetails}
|
||||
/>
|
||||
<div className="mt-4 flex justify-start items-center gap-2">
|
||||
<button
|
||||
onClick={() => tabHandler("Account")}
|
||||
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
|
||||
>
|
||||
<img
|
||||
src={localImgLoad("images/icons/account.svg")}
|
||||
className="max-w-[30px] w-full"
|
||||
alt="Settings-Icon"
|
||||
/>
|
||||
<p className="text-lg text-sky-blue">Acc.</p>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => tabHandler("Profile")}
|
||||
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
|
||||
>
|
||||
<img
|
||||
src={localImgLoad("images/icons/profile.svg")}
|
||||
className="max-w-[30px] w-full"
|
||||
alt="Settings-Icon"
|
||||
/>
|
||||
<p className="text-lg text-sky-blue">Profile</p>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-3 justify-self-end h-full w-full">
|
||||
<div className="flex flex-col w-full">
|
||||
<div className="w-full pr-8 flex items-center gap-1">
|
||||
<ul className="flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
|
||||
{tabs.map(({ name, id }) => (
|
||||
<li
|
||||
onClick={() => tabHandler(name)}
|
||||
className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl relative top-[2px] ${
|
||||
tab === name
|
||||
? "text-purple border-r"
|
||||
: "text-thin-light-gray"
|
||||
}`}
|
||||
key={id}
|
||||
>
|
||||
<h1>{name}</h1>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<button
|
||||
type="button"
|
||||
onClick={familyPopUpHandler}
|
||||
className="p-1 my-1 w-[100px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Add task
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-[0.9] lg:min-h-[450px] h-full">
|
||||
<div className="h-full p-4 border border-[#dbd9d9] relative overflow-y-auto">
|
||||
<Suspense
|
||||
fallback={<LoadingSpinner size="16" color="sky-blue" />}
|
||||
>
|
||||
{selectedTabComponent}
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
{familyTaskPopout && (
|
||||
<AssignTaskPopout
|
||||
action={familyPopUpHandler}
|
||||
situation={familyTaskPopout}
|
||||
familyDetails={details.familyDetails.data}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,115 +1,95 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import SiteService from "../../services/SiteService";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import DataIteration from "../Helpers/DataIteration";
|
||||
import SearchCom from "../Helpers/SearchCom";
|
||||
import collections from "../../data/collectionplan_data.json";
|
||||
import FamilyMarketCard from "../Cards/FamilyMarketCard";
|
||||
import { Link } from "react-router-dom";
|
||||
import usersService from "../../services/UsersService";
|
||||
import SuggestTask from "../FamilyPopup/SuggestTask";
|
||||
|
||||
export default function FamilyMarket() {
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const [popUp, setPopUp] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [myFamilySampleTasks, setMyFamilySampleTasks] = useState({
|
||||
loading: true,
|
||||
status: false,
|
||||
data: [],
|
||||
});
|
||||
|
||||
const apiCall = useMemo(() => new SiteService(), []);
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
// This is to make sure it's called once and used everywhere
|
||||
let memberId = localStorage.getItem("member_id");
|
||||
let uid = localStorage.getItem("uid");
|
||||
let sessionId = localStorage.getItem("session_token");
|
||||
const getMyFamilySampleTasks = useCallback(async () => {
|
||||
try {
|
||||
setMyFamilySampleTasks({ loading: true, status: false, data: [] });
|
||||
const res = await apiCall.getFamilySampleTasks();
|
||||
setMyFamilySampleTasks({
|
||||
loading: false,
|
||||
status: true,
|
||||
data: res.data.result_list,
|
||||
});
|
||||
} catch (error) {
|
||||
setMyFamilySampleTasks({ loading: false, status: false, data: [] });
|
||||
console.log("Error getting tasks:", error);
|
||||
}
|
||||
}, [apiCall]);
|
||||
|
||||
useEffect(() => {
|
||||
getMyFamilySampleTasks();
|
||||
}, [getMyFamilySampleTasks]);
|
||||
|
||||
const handleSearch = (event) => {
|
||||
setSearchQuery(event.target.value);
|
||||
};
|
||||
|
||||
const filteredTasks =
|
||||
myFamilySampleTasks.data?.filter((task) =>
|
||||
task.title.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
) || [];
|
||||
|
||||
const popUpHandler = () => {
|
||||
setPopUp((prev) => !prev);
|
||||
};
|
||||
|
||||
// tab handler
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
{/*<CommonHead />*/}
|
||||
<div className="notification-page w-full mb-10">
|
||||
<div className="notification-wrapper w-full">
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="mb-5 sm:mb-0">
|
||||
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||
<span
|
||||
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||
>
|
||||
Suggest Task to the Parents
|
||||
</span>
|
||||
<span>Suggest Task to the Parents</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<div
|
||||
onClick={() => filterHandler("today")}
|
||||
className="relative"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Body */}
|
||||
<div className="filter-section w-full items-center sm:flex justify-between mb-6">
|
||||
{/* filter-search */}
|
||||
<div className="sm:w-1/2 w-full sm:pr-20 pr-0 mb-5 sm:mb-0">
|
||||
<SearchCom />
|
||||
<SearchCom
|
||||
placeholder="Search for tasks..."
|
||||
handleSearch={handleSearch}
|
||||
value={searchQuery}
|
||||
/>
|
||||
</div>
|
||||
{/* filer-dropdown */}
|
||||
<div className="flex-1 flex sm:justify-end">
|
||||
<Link
|
||||
to="/upload-product"
|
||||
<button
|
||||
onClick={popUpHandler}
|
||||
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
|
||||
>
|
||||
Any Other Task
|
||||
</Link>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content-section w-full-width">
|
||||
<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-[30px]">
|
||||
<DataIteration
|
||||
datas={collections?.data}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={collections?.data.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<FamilyMarketCard key={datas.id} datas={datas} />
|
||||
)}
|
||||
</DataIteration>
|
||||
{filteredTasks.map((task) => (
|
||||
<FamilyMarketCard key={task.id} datas={task} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{popUp && (
|
||||
<ModalCom action={popUpHandler} situation={popUp}>
|
||||
{/* */}
|
||||
</ModalCom>
|
||||
)}
|
||||
{popUp && <SuggestTask onClose={popUpHandler} situation={popUp} />}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
const CloseIcon = () => (
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -1,222 +1,384 @@
|
||||
import React, {useState, useEffect} from 'react'
|
||||
import ModalCom from '../../Helpers/ModalCom'
|
||||
import Detail from '../../jobPopout/popoutcomponent/Detail'
|
||||
import usersService from '../../../services/UsersService'
|
||||
import LoadingSpinner from '../../Spinners/LoadingSpinner'
|
||||
import { PriceFormatter } from '../../Helpers/PriceFormatter'
|
||||
import React, { useState, useEffect, useTransition } from "react";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import Detail from "../../jobPopout/popoutcomponent/Detail";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import { NewTasks } from "./forms";
|
||||
|
||||
function AssignTaskPopout({action, situation, familyDetails}) {
|
||||
const apiCall = new usersService()
|
||||
const AssignTaskPopout = React.memo(({ action, details, situation, familyDetails }) => {
|
||||
const apiCall = new usersService();
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: ''}) // HOLDS RESPONSE FOR SENDING API REQUEST
|
||||
|
||||
let [familyTask, setFamilyTask] = useState({loading: true, data: []})
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "",
|
||||
}); // HOLDS RESPONSE FOR SENDING API REQUEST
|
||||
|
||||
let [taskType, setTaskType] = useState('select') // SWITCHES BTW SELECT TASK AND NEW TASK
|
||||
let [familyTask, setFamilyTask] = useState({ loading: false, data: [] });
|
||||
|
||||
let [activeTask, setActiveTask] = useState({id: 0, data: {}}) // HOLDS SELECTED TASK
|
||||
let [taskType, setTaskType] = useState(details ? "new" : "select"); // SWITCHES BTW SELECT TASK AND NEW TASK
|
||||
|
||||
const switchTaskType = ({target:{value}}) => { // FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setTaskType(value)
|
||||
let [activeTask, setActiveTask] = useState({ id: 0, data: {} }); // HOLDS SELECTED TASK
|
||||
|
||||
const switchTaskType = ({ target: { value } }) => {
|
||||
// FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setTaskType(value);
|
||||
};
|
||||
|
||||
const handleActiveTask = (id = 0, data = {}) => {
|
||||
// FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setActiveTask({ id, data });
|
||||
};
|
||||
|
||||
// New Task
|
||||
const [formState, setFormState] = useState({
|
||||
// Initialize form state with desired fields
|
||||
banner: details?.banner || "default.jpg",
|
||||
country: details?.country || "",
|
||||
price: details?.price || "",
|
||||
title: details?.title || "",
|
||||
description: details?.description || "",
|
||||
job_detail: details?.job_detail || "",
|
||||
timeline_days: details?.timeline_days || "",
|
||||
category: details?.category || "",
|
||||
});
|
||||
|
||||
const assignFamilyTask = () => {
|
||||
setRequestStatus({ loading: true, status: false, message: "" });
|
||||
let reqData = {};
|
||||
if (taskType == "select") {
|
||||
// RUNS HERE IF TASK TYPE IS SELECT
|
||||
if (!Object.keys(activeTask.data).length) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "No Task is seleted",
|
||||
});
|
||||
return setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 3000);
|
||||
}
|
||||
reqData = {
|
||||
// API PAYLOADS
|
||||
job_id: activeTask.data?.job_id,
|
||||
job_uid: activeTask.data?.job_uid,
|
||||
family_uid: familyDetails.uid,
|
||||
job_description: activeTask.data?.description,
|
||||
assign_mode: 110011,
|
||||
};
|
||||
}
|
||||
|
||||
const handleActiveTask = (id=0, data={}) => { // FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setActiveTask({id, data})
|
||||
if (taskType === "new") {
|
||||
const {
|
||||
banner,
|
||||
category,
|
||||
country,
|
||||
description,
|
||||
job_detail,
|
||||
price,
|
||||
timeline_days,
|
||||
title,
|
||||
} = formState;
|
||||
|
||||
const requiredFields = {
|
||||
banner,
|
||||
// category,
|
||||
country,
|
||||
description,
|
||||
job_detail,
|
||||
price,
|
||||
timeline_days,
|
||||
title,
|
||||
};
|
||||
|
||||
for (let field in requiredFields) {
|
||||
if (requiredFields[field] == "") {
|
||||
// let currencyErrMsg = field == "country" && "currency"
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: `${field} is empty`,
|
||||
});
|
||||
return setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
reqData = {
|
||||
banner,
|
||||
category,
|
||||
country,
|
||||
description,
|
||||
job_detail,
|
||||
price: price * 100,
|
||||
timeline_days,
|
||||
title,
|
||||
assign_mode: 110055,
|
||||
family_uid: details?.family_uid || familyDetails?.uid,
|
||||
};
|
||||
}
|
||||
|
||||
const assignFamilyTask = () => {
|
||||
setRequestStatus({loading: true, status: false, message: ''})
|
||||
let reqData = {}
|
||||
if(taskType == 'select'){ // RUNS HERE IF TASK TYPE IS SELECT
|
||||
if(!Object.keys(activeTask.data).length){
|
||||
setRequestStatus({loading: false, status: false, message: 'No Task is seleted'})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
}, 3000)
|
||||
apiCall
|
||||
.assignFamilyTask(reqData)
|
||||
.then((res) => {
|
||||
if (res.status != 200 || res.data.internal_return < 0) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "failed to assign task",
|
||||
});
|
||||
return setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
}
|
||||
reqData = { // API PAYLOADS
|
||||
job_id: activeTask.data?.job_id,
|
||||
job_uid: activeTask.data?.job_uid,
|
||||
family_uid: familyDetails.uid,
|
||||
job_description: activeTask.data?.description,
|
||||
assign_mode: 110011,
|
||||
}
|
||||
|
||||
apiCall.assignFamilyTask(reqData).then(res => {
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
setRequestStatus({loading: false, status: false, message: 'failed to assign task'})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
}, 5000)
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: true,
|
||||
message: "action successful",
|
||||
});
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
action(); // FUNCTION THAT CLOSES THE MODAL BOX
|
||||
}, 5000);
|
||||
})
|
||||
.catch((err) => {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "An Error occured, try again",
|
||||
});
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let checkFamilyTask = true;
|
||||
const reqData = {
|
||||
limit: 30,
|
||||
offset: 0,
|
||||
job_type: "FAMILY",
|
||||
action: 13005,
|
||||
};
|
||||
|
||||
apiCall
|
||||
.getMyJobList(reqData)
|
||||
.then((res) => {
|
||||
if (checkFamilyTask) {
|
||||
setFamilyTask({ loading: false, data: res?.data?.result_list });
|
||||
if (res?.data?.result_list?.length) {
|
||||
setActiveTask((prev) => ({
|
||||
...prev,
|
||||
data: res?.data?.result_list[0],
|
||||
}));
|
||||
}
|
||||
setRequestStatus({loading: false, status: true, message: 'action successful'})
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
action() // FUNCTION THAT CLOSES THE MODAL BOX
|
||||
}, 5000)
|
||||
}).catch(err => {
|
||||
setRequestStatus({loading: false, status: false, message: 'An Error occured, try again'})
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
}, 5000)
|
||||
})
|
||||
}
|
||||
|
||||
if(taskType == 'new'){ // RUNS HERE IF TASK TYPE IS NEW TASK
|
||||
console.log('TESTING')
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
const reqData = {
|
||||
limit: 30,
|
||||
offset: 0,
|
||||
job_type: 'FAMILY',
|
||||
action: 13005
|
||||
}
|
||||
apiCall.getMyJobList(reqData).then(res => {
|
||||
setFamilyTask({loading: false, data: res?.data?.result_list})
|
||||
if(res?.data?.result_list?.length){
|
||||
setActiveTask(prev => ({...prev, data:res?.data?.result_list[0]}))
|
||||
}
|
||||
}).catch(err => {
|
||||
setFamilyTask({loading: false, data: []})
|
||||
console.log('Error', err)
|
||||
})
|
||||
},[])
|
||||
})
|
||||
.catch((err) => {
|
||||
setFamilyTask({ loading: false, data: [] });
|
||||
console.log("Error", err);
|
||||
});
|
||||
|
||||
return () => {
|
||||
checkFamilyTask = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ModalCom
|
||||
<ModalCom
|
||||
action={action}
|
||||
situation={situation}
|
||||
>
|
||||
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Assign task to {familyDetails?.firstname}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={action}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{familyTask.loading ?
|
||||
<div className='h-[100px] w-full flex justify-center items-center'>
|
||||
<LoadingSpinner color='sky-blue' size='16' />
|
||||
</div>
|
||||
:
|
||||
<>
|
||||
<div className="job-action-modal-body w-full md:grid md:grid-cols-2">
|
||||
<div className="p-4">
|
||||
<div className="mb-2 w-full flex items-center gap-4">
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input type="radio" name='task-type' value='select' className="w-[20px] h-[20px] cursor-pointer" checked={taskType=='select'} onChange={switchTaskType}/>
|
||||
<span>Select Task</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input type="radio" name='task-type' value='new' className="w-[20px] h-[20px] cursor-pointer" checked={taskType=='new'} onChange={switchTaskType}/>
|
||||
<span>New Task</span>
|
||||
</div>
|
||||
className="assign-task-popup"
|
||||
>
|
||||
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Assign task to {familyDetails?.firstname || details.firstName}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={action}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{familyTask.loading ? (
|
||||
<div className="h-[100px] w-full flex justify-center items-center">
|
||||
<LoadingSpinner color="sky-blue" size="16" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
className={`job-action-modal-body w-full md:grid ${
|
||||
taskType !== "new" ? "md:grid-cols-2" : "md:grid-cols-1"
|
||||
}`}
|
||||
>
|
||||
<div className="p-4">
|
||||
<div className="mb-2 w-full flex items-center gap-4">
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input
|
||||
type="radio"
|
||||
name="task-type"
|
||||
value="select"
|
||||
className="w-[20px] h-[20px] cursor-pointer"
|
||||
checked={taskType == "select"}
|
||||
onChange={switchTaskType}
|
||||
/>
|
||||
<span>Select Task</span>
|
||||
</div>
|
||||
<div className='p-4 w-full h-[400px] overflow-y-auto bg-slate-100'>
|
||||
{
|
||||
taskType == 'select' ?
|
||||
familyTask?.data?.length ?
|
||||
familyTask?.data?.map((item, index)=>(
|
||||
<div key={item.job_uid} className="mb-2 flex justify-start items-center gap-2 text-sky-blue text-base cursor-pointer" onClick={()=>handleActiveTask(item.job_uid, item)}>
|
||||
<input
|
||||
type="radio"
|
||||
name='task-list'
|
||||
checked={(activeTask.id == item.job_uid) || (activeTask.id==index)&& true}
|
||||
onChange={()=>handleActiveTask(item.job_uid, item)}
|
||||
className="w-[15px] h-[15px] cursor-pointer"
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input
|
||||
type="radio"
|
||||
name="task-type"
|
||||
value="new"
|
||||
className="w-[20px] h-[20px] cursor-pointer"
|
||||
checked={taskType == "new"}
|
||||
onChange={switchTaskType}
|
||||
/>
|
||||
<span>New Task</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Task Type === select */}
|
||||
{taskType == "select" && (
|
||||
<div className="p-4 w-full h-[400px] overflow-y-auto bg-slate-100">
|
||||
{familyTask?.data?.length ? (
|
||||
familyTask?.data?.map((item, index) => (
|
||||
<div
|
||||
key={item.job_uid}
|
||||
className="mb-2 flex justify-start items-center gap-2 text-sky-blue text-base cursor-pointer"
|
||||
onClick={() => handleActiveTask(item.job_uid, item)}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="task-list"
|
||||
checked={
|
||||
activeTask.id == item.job_uid ||
|
||||
(activeTask.id == index && true)
|
||||
}
|
||||
onChange={() =>
|
||||
handleActiveTask(item.job_uid, item)
|
||||
}
|
||||
className="w-[15px] h-[15px] cursor-pointer"
|
||||
/>
|
||||
<p className="w-full text-dark-gray tracking-wide">{item?.title}</p>
|
||||
<p className="w-full text-dark-gray tracking-wide">
|
||||
{item?.title}
|
||||
</p>
|
||||
</div>
|
||||
))
|
||||
:
|
||||
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center">No Task found!</p>
|
||||
:
|
||||
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center">SPACE FOR NEW TASK</p>
|
||||
}
|
||||
))
|
||||
) : (
|
||||
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center cursor-default">
|
||||
No Task found!
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{taskType == "new" && (
|
||||
<div className="p-4 w-full h-[400px]">
|
||||
<NewTasks
|
||||
formState={formState}
|
||||
setFormState={setFormState}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{familyTask?.data?.length > 0 ?
|
||||
<div className="p-4">
|
||||
<div className="w-full">
|
||||
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">{activeTask?.data?.title}</p>
|
||||
<div className="my-3">
|
||||
<Detail label="Description" value={activeTask?.data?.description} />
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className='text-slate-900 dark:text-white tracking-wide font-semibold'>Price</label>
|
||||
<p className='p-1 text-sm text-slate-900 dark:text-white'>{PriceFormatter(activeTask?.data?.price*0.01, activeTask?.data?.currency, activeTask?.data?.curreny_code)}</p>
|
||||
</div>
|
||||
{/*Right Hand Side for details && Task Type === select */}
|
||||
{taskType == "select" && (
|
||||
<>
|
||||
{familyTask?.data?.length > 0 ? (
|
||||
<div className="p-4">
|
||||
<div className="w-full">
|
||||
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">
|
||||
{activeTask?.data?.title}
|
||||
</p>
|
||||
<div className="my-3">
|
||||
<Detail
|
||||
label="Description"
|
||||
value={activeTask?.data?.description}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Price
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">
|
||||
{PriceFormatter(
|
||||
activeTask?.data?.price * 0.01,
|
||||
activeTask?.data?.currency,
|
||||
activeTask?.data?.curreny_code
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className='text-slate-900 dark:text-white tracking-wide font-semibold'>Timeline</label>
|
||||
<p className='p-1 text-sm text-slate-900 dark:text-white'>{`${activeTask?.data?.timeline_days} day(s)`}</p>
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Timeline
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">{`${activeTask?.data?.timeline_days} day(s)`}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="my-3 sm:flex items-center">
|
||||
<Detail
|
||||
label="Created"
|
||||
value={`Dummy, no value found for created!`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="my-3">
|
||||
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Delivery Detail
|
||||
</label>
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
|
||||
rows="5"
|
||||
style={{ resize: "none" }}
|
||||
value={activeTask?.data?.job_detail}
|
||||
readOnly
|
||||
// onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="my-3 sm:flex items-center">
|
||||
<Detail
|
||||
label="Created"
|
||||
value={`Dummy, no value found for created!`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="my-3">
|
||||
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Delivery Detail
|
||||
</label>
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
|
||||
rows="5"
|
||||
style={{ resize: "none" }}
|
||||
value={activeTask?.data?.job_detail}
|
||||
readOnly
|
||||
// onChange={handleInputChange}
|
||||
/>
|
||||
{/* <p>{}</p> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<></>
|
||||
}
|
||||
</div>
|
||||
|
||||
{/* BTN */}
|
||||
<div className='p-2 border-t-2 flex justify-end items-center gap-3'>
|
||||
{/* error or success display */}
|
||||
{/* BTN */}
|
||||
<div className="py-2 px-4 border-t-2 flex justify-between items-center">
|
||||
{/* error or success display */}
|
||||
<div className="w-auto h-auto flex items-center">
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-2 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
className={`relative p-2 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px] self-start`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
@@ -229,35 +391,51 @@ function AssignTaskPopout({action, situation, familyDetails}) {
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
<button
|
||||
disabled={requestStatus.loading}
|
||||
onClick={action} type="button"
|
||||
</div>
|
||||
|
||||
{/* End of error or success display */}
|
||||
<div className="w-auto h-auto flex items-center gap-3">
|
||||
<button
|
||||
disabled={requestStatus.loading}
|
||||
onClick={action}
|
||||
type="button"
|
||||
className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
<span className='text-gradient'>Close</span>
|
||||
<span className="text-gradient">Close</span>
|
||||
</button>
|
||||
<div className=''>
|
||||
{requestStatus.loading ?
|
||||
<LoadingSpinner color='sky-blue' size='8' />
|
||||
:
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
Assign
|
||||
</button>
|
||||
}
|
||||
<div className="">
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner color="sky-blue" size="8" />
|
||||
) : taskType == "select" ? (
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
Assign
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
{`Assign to ${
|
||||
familyDetails?.firstname || details?.firstName
|
||||
}`}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</ModalCom>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</ModalCom>
|
||||
</>
|
||||
)
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
export default AssignTaskPopout
|
||||
export default AssignTaskPopout;
|
||||
@@ -0,0 +1,232 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import usersService from "../../../../services/UsersService";
|
||||
import InputCom from "../../../Helpers/Inputs/InputCom";
|
||||
|
||||
export default function NewTasks({ formState, setFormState }) {
|
||||
let [currency, setCurrency] = useState({
|
||||
loading: true,
|
||||
status: false,
|
||||
data: null,
|
||||
});
|
||||
|
||||
const selectImage = require(`../../../../assets/images/taskbanners/${
|
||||
formState.banner || "default.jpg"
|
||||
}`);
|
||||
const ApiCall = new usersService();
|
||||
|
||||
// FUNCTION TO GET Currency
|
||||
const getUserCurrency = () => {
|
||||
setCurrency((prev) => ({ ...prev, loading: true }));
|
||||
ApiCall.getUserWallets()
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setCurrency({ loading: false, status: true, data: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
setCurrency({
|
||||
loading: false,
|
||||
status: true,
|
||||
data: res.data.result_list,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setCurrency({ loading: false, status: false, data: [] });
|
||||
});
|
||||
};
|
||||
|
||||
const handleInputChange = (event) => {
|
||||
const { name, value } = event.target;
|
||||
setFormState((prevState) => ({
|
||||
...prevState,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUserCurrency();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<form className="w-full flex justify-between items-start">
|
||||
<div className="flex flex-col gap-3 max-w-[77%]">
|
||||
{/* inputs starts here */}
|
||||
<div className="grid md:grid-cols-3 grid-cols-1 gap-6 mb-[5px]">
|
||||
{/* Currency */}
|
||||
<div className="field w-full mb-6 xl:mb-0">
|
||||
<label
|
||||
htmlFor="country"
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex item-center gap-1"
|
||||
>
|
||||
Currency
|
||||
{/* {props.errors.country && props.touched.country && <span className="text-[12px] text-red-500">{props.errors.country}</span>} */}
|
||||
</label>
|
||||
<select
|
||||
id="country"
|
||||
name="country"
|
||||
value={formState.country}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
>
|
||||
{currency.loading ? (
|
||||
<option className="text-slate-500 text-[13.975px]" value="">
|
||||
Loading...
|
||||
</option>
|
||||
) : currency.data.length ? (
|
||||
<>
|
||||
<option className="text-slate-500 text-[13.975px]" value="">
|
||||
Currency
|
||||
</option>
|
||||
{currency.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item?.country}
|
||||
>
|
||||
{item?.description}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
No Options Found! Try Again
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Price */}
|
||||
<div className="field w-full">
|
||||
<InputCom
|
||||
fieldClass="px-6 text-right"
|
||||
label="Price"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="number"
|
||||
name="price"
|
||||
placeholder="0"
|
||||
value={formState.price}
|
||||
inputHandler={handleInputChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
// error={props.errors.price && props.touched.price && props.errors.price}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Duration */}
|
||||
<div className="field w-full mb-6 xl:mb-0">
|
||||
<label
|
||||
htmlFor="timeline_days"
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex item-center gap-1"
|
||||
>
|
||||
Timeline
|
||||
{/* {props.errors.country && props.touched.country && <span className="text-[12px] text-red-500">{props.errors.country}</span>} */}
|
||||
</label>
|
||||
<select
|
||||
id="timeline_days"
|
||||
name="timeline_days"
|
||||
value={formState.timeline_days}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
>
|
||||
{publicArray.length && (
|
||||
<>
|
||||
<option className="text-slate-500 text-[13.975px]" value="">
|
||||
Duration
|
||||
</option>
|
||||
{publicArray.map(({ name, duration }, idx) => (
|
||||
<option
|
||||
className="text-slate-500 text-[13.975px]"
|
||||
value={duration}
|
||||
>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Title"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="title"
|
||||
value={formState.title}
|
||||
inputHandler={handleInputChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
// error={props.errors.title && props.touched.title && props.errors.title}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Description"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="description"
|
||||
value={formState.description}
|
||||
inputHandler={handleInputChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
// error={props.errors.description && props.touched.description && props.errors.description}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="Job Delivery Details"
|
||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1'
|
||||
>
|
||||
Job Delivery Details
|
||||
{/* {props.errors.job_detail && props.touched.job_detail && <span className="text-[12px] text-red-500">{props.errors.job_detail}</span>} */}
|
||||
</label>
|
||||
<textarea
|
||||
id="Job Delivery Details"
|
||||
rows="5"
|
||||
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px]`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={formState.job_detail}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Banner Image */}
|
||||
<div className="max-w-[20%] w-full">
|
||||
<div className="h-32 w-full">
|
||||
<img
|
||||
src={selectImage}
|
||||
alt="task_banner_img"
|
||||
className="w-full h-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
const publicArray = [
|
||||
{ duration: 1, name: "1 day" },
|
||||
{ duration: 2, name: "2 days" },
|
||||
{ duration: 3, name: "3 days" },
|
||||
{ duration: 4, name: "4 days" },
|
||||
{ duration: 5, name: "5 days" },
|
||||
{ duration: 6, name: "6 days" },
|
||||
{ duration: 7, name: "1 week" },
|
||||
{ duration: 14, name: "2 weeks" },
|
||||
{ duration: 21, name: "3 weeks" },
|
||||
{ duration: 28, name: "4 weeks" },
|
||||
];
|
||||
@@ -0,0 +1,3 @@
|
||||
import NewTasks from "./NewTasks";
|
||||
|
||||
export {NewTasks}
|
||||
@@ -1,17 +1,14 @@
|
||||
import React, { useState } from "react";
|
||||
import dataImage1 from "../../assets/images/data-table-user-1.png";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { useNavigate, useLocation, Link } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
|
||||
import familyImage from '../../assets/images/no-family-side.png'
|
||||
|
||||
export default function FamilyTable({ className, familyList, loader, popUpHandler }) {
|
||||
const filterCategories = ["All Categories", "Explore", "Featured"];
|
||||
const [selectedCategory, setCategory] = useState(filterCategories[0]);
|
||||
const navigate = useNavigate();
|
||||
// let location = useLocation();
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { forwardRef } from "react";
|
||||
import QRCode from "react-qr-code";
|
||||
|
||||
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
||||
return (
|
||||
<div
|
||||
className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center"
|
||||
ref={myRef}
|
||||
>
|
||||
<div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
|
||||
<div className="flex items-center justify-around h-[380px]">
|
||||
<div className="flex flex-col">
|
||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
Username:{" "}
|
||||
<span className="ml-2 normal-case">
|
||||
{familyData?.username ? familyData?.username : "please wait..."}
|
||||
</span>
|
||||
</h2>
|
||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
Pin:{" "}
|
||||
<span className="ml-2 normal-case">
|
||||
{familyData?.pin ? familyData?.pin : "please wait..."}
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<span className="text-5xl text-gray-400 opacity-20 font-bold">
|
||||
or
|
||||
</span>
|
||||
|
||||
<div className="max-w-[200px]">
|
||||
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
|
||||
Scan the code from mobile app
|
||||
</p>
|
||||
<QRCode
|
||||
size={256}
|
||||
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
|
||||
value={`https://www.google.com`}
|
||||
viewBox={`0 0 256 256`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] w-full flex justify-center items-center">
|
||||
<button
|
||||
className="btn-shine w-[116px] h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center"
|
||||
onClick={handlePrint}
|
||||
>
|
||||
Print
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default FamilyAccount;
|
||||
@@ -1,342 +0,0 @@
|
||||
import React, {
|
||||
Suspense,
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import QRCode from "react-qr-code";
|
||||
import { useReactToPrint } from "react-to-print";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import profile from "../../../assets/images/profile-info-profile.png";
|
||||
import FamilyTasks from "./FamilyTasks";
|
||||
|
||||
import AssignTaskPopout from '../FamilyPopout/AssignTaskPopout'
|
||||
|
||||
|
||||
export default function FamilyManageTabs({
|
||||
className,
|
||||
accountDetails,
|
||||
listReload,
|
||||
loader,
|
||||
}) {
|
||||
const [details, setDetails] = useState({
|
||||
familyDetails: {
|
||||
loading: false,
|
||||
data: null,
|
||||
},
|
||||
familyTasks: {
|
||||
loading: false,
|
||||
data: null,
|
||||
},
|
||||
});
|
||||
const [errMsg, setErrMsg] = useState("");
|
||||
// List of tabs
|
||||
const tabs = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Tasks",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Account",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Profile",
|
||||
},
|
||||
];
|
||||
const [tab, setTab] = useState(tabs[0].name);
|
||||
const tabHandler = (value) => {
|
||||
setTab(value);
|
||||
};
|
||||
|
||||
let [familyTaskPopout, setFamilyTaskPopout] = useState(false) // DETERMINES WHEN FAMILY ADD TASK POPOUT DISPLAYS
|
||||
|
||||
const familyPopUpHandler = () => { // FUNCTION TO CHANGE THE FAMILY ADD TASK POPOIUT STATE
|
||||
setFamilyTaskPopout(prev => !prev)
|
||||
}
|
||||
|
||||
// For profile uploads
|
||||
const [profileImg, setProfileImg] = useState(profile);
|
||||
// profile img
|
||||
const profileImgInput = useRef(null);
|
||||
const browseProfileImg = () => {
|
||||
profileImgInput.current.click();
|
||||
};
|
||||
const profileImgChangHandler = (e) => {
|
||||
if (e.target.value !== "") {
|
||||
const imgReader = new FileReader();
|
||||
imgReader.onload = (event) => {
|
||||
setProfileImg(event.target.result);
|
||||
};
|
||||
imgReader.readAsDataURL(e.target.files[0]);
|
||||
}
|
||||
};
|
||||
|
||||
// Api call
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
// function for manage family
|
||||
const manageFamily = useCallback(async () => {
|
||||
try {
|
||||
setDetails({
|
||||
familyDetails: { loading: true },
|
||||
familyTasks: { loading: true },
|
||||
});
|
||||
let { family_uid } = accountDetails;
|
||||
let reqData = { family_uid };
|
||||
|
||||
// the family response
|
||||
const familyRes = await apiCall.ManageFamily(reqData);
|
||||
const familyData = familyRes.data;
|
||||
|
||||
// the tasks response
|
||||
const tasksRes = await apiCall.ManageTasks(reqData);
|
||||
const tasksData = tasksRes.data;
|
||||
|
||||
// checking the internal return
|
||||
if (familyData?.internal_return < 0 || tasksData?.internal_return < 0)
|
||||
return;
|
||||
|
||||
setDetails({
|
||||
familyDetails: { loading: false, data: familyData },
|
||||
familyTasks: { loading: false, data: tasksData },
|
||||
});
|
||||
} catch (error) {
|
||||
setDetails({
|
||||
familyDetails: { loading: false },
|
||||
familyTasks: { loading: false },
|
||||
});
|
||||
setErrMsg("An error occurred");
|
||||
throw new Error(error);
|
||||
}
|
||||
}, [apiCall, accountDetails]);
|
||||
|
||||
useEffect(() => {
|
||||
manageFamily();
|
||||
}, [tab, manageFamily]);
|
||||
|
||||
const accountRef = useRef();
|
||||
// to handle printing
|
||||
const useHandlePrint = useReactToPrint({
|
||||
content: () => accountRef.current,
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[520px]">
|
||||
<div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full">
|
||||
<ProfileInfo
|
||||
profileImg={profileImg}
|
||||
profileImgInput={profileImgInput}
|
||||
profileImgChangHandler={profileImgChangHandler}
|
||||
browseProfileImg={browseProfileImg}
|
||||
accountDetails={accountDetails}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 justify-self-end h-full w-full">
|
||||
<div className="flex flex-col w-full">
|
||||
<div className="w-full pr-8 flex items-center gap-1">
|
||||
<ul className="flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
|
||||
{tabs.map(({ name, id }) => (
|
||||
<li
|
||||
onClick={() => tabHandler(name)}
|
||||
className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl ${
|
||||
tab === name
|
||||
? "text-purple border-r"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
key={id}
|
||||
>
|
||||
<h1>{name}</h1>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<button
|
||||
type="button"
|
||||
onClick={familyPopUpHandler}
|
||||
className="p-1 my-1 w-[100px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Add task
|
||||
{/* {accountDetails?.firstname} */}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-[0.9] lg:min-h-[450px] h-full">
|
||||
{/* Your content here */}
|
||||
{tabs.map(({ name, id }) => {
|
||||
return (
|
||||
<div
|
||||
className={`${
|
||||
tab === name ? "block" : "hidden"
|
||||
} h-full p-4 border border-[#dbd9d9] relative overflow-y-auto`}
|
||||
key={id}
|
||||
>
|
||||
{name === "Tasks" && (
|
||||
<FamilyTasks
|
||||
className={className}
|
||||
loader={details.familyTasks.loading}
|
||||
familyData={details.familyTasks.data}
|
||||
accountDetails={accountDetails}
|
||||
/>
|
||||
)}
|
||||
{name === "Account" && (
|
||||
<Account
|
||||
familyData={details.familyDetails.data}
|
||||
myRef={accountRef}
|
||||
loader={details.familyDetails.loading}
|
||||
handlePrint={useHandlePrint}
|
||||
/>
|
||||
)}
|
||||
{name === "Profile" && <Profile />}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
{/* FAMILY ADD TASK POPOUT */}
|
||||
{familyTaskPopout &&
|
||||
<AssignTaskPopout
|
||||
action={familyPopUpHandler}
|
||||
situation={familyTaskPopout}
|
||||
familyDetails={details.familyDetails.data}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ProfileInfo({
|
||||
profileImg,
|
||||
profileImgInput,
|
||||
profileImgChangHandler,
|
||||
browseProfileImg,
|
||||
accountDetails,
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-6">
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={profileImg}
|
||||
alt=""
|
||||
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
<div
|
||||
onClick={browseProfileImg}
|
||||
className="w-[32px] h-[32px] absolute bottom-7 sm:right-2 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col justify-center gap-3 items-center">
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{accountDetails?.firstname}
|
||||
</h1>
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{accountDetails?.lastname}
|
||||
</h1>
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{accountDetails?.age}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const Account = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
||||
return (
|
||||
<div
|
||||
className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center"
|
||||
ref={myRef}
|
||||
>
|
||||
<div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
|
||||
<div className="flex items-center justify-around h-[380px]">
|
||||
<div className="flex flex-col">
|
||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
Username:{" "}
|
||||
<span className="ml-2 normal-case">
|
||||
{familyData?.username ? familyData?.username : "please wait..."}
|
||||
</span>
|
||||
</h2>
|
||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
Pin:{" "}
|
||||
<span className="ml-2 normal-case">
|
||||
{familyData?.pin ? familyData?.pin : "please wait..."}
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<span className="text-5xl text-gray-400 opacity-20 font-bold">
|
||||
or
|
||||
</span>
|
||||
|
||||
<div className="max-w-[200px]">
|
||||
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
|
||||
Scan the code from mobile app
|
||||
</p>
|
||||
<QRCode
|
||||
size={256}
|
||||
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
|
||||
value={`https://www.google.com`}
|
||||
viewBox={`0 0 256 256`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] w-full flex justify-center items-center">
|
||||
<button
|
||||
className="btn-shine w-[116px] h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center"
|
||||
onClick={handlePrint}
|
||||
>
|
||||
Print
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
function Profile() {
|
||||
return <>Profile</>;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import dataImage2 from "../../../assets/images/data-table-user-2.png";
|
||||
import PendingJobsPopout from "../../jobPopout/PendingJobsPopout";
|
||||
import localImgLoad from "../../../lib/localImgLoad";
|
||||
|
||||
export default function FamilyPending({
|
||||
familyData,
|
||||
className,
|
||||
accountDetails,
|
||||
loader,
|
||||
}) {
|
||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||
|
||||
let filteredFamilyData = useMemo(
|
||||
() =>
|
||||
familyData?.result_list?.filter(
|
||||
(data) => data?.family_uid === accountDetails?.family_uid
|
||||
),
|
||||
[accountDetails?.family_uid, familyData?.result_list]
|
||||
);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentPendingTasks = filteredFamilyData?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
{filteredFamilyData && (
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{
|
||||
<>
|
||||
{currentPendingTasks.length > 0 ? (
|
||||
currentPendingTasks.map((value, index) => {
|
||||
let deliveryDate = value?.expire?.split(" ")[0];
|
||||
let thePrice = PriceFormatter(
|
||||
value?.price * 0.01,
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
let image = value.banner ? value.banner : "default.jpg";
|
||||
return (
|
||||
<tr
|
||||
key={index}
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
>
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={localImgLoad(
|
||||
`images/taskbanners/${image}`
|
||||
)}
|
||||
alt="data"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
{value.title}
|
||||
</h1>
|
||||
<div>{value.description}</div>
|
||||
<span className="text-sm text-thin-light-gray flex items-start gap-1">
|
||||
Price:{" "}
|
||||
<span className="text-purple">
|
||||
{thePrice}
|
||||
</span>
|
||||
</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value.timeline_days} day(s)
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Expire:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{deliveryDate}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Sent to:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value.job_to}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td className="text-right py-4 px-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setJobPopout({ show: true, data: value });
|
||||
}}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
<td className="p-2">No Pending Task!</td>
|
||||
</tr>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0}
|
||||
next={currentPage + itemsPerPage >= filteredFamilyData.length}
|
||||
data={filteredFamilyData}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Active Job Popout */}
|
||||
{jobPopout.show && (
|
||||
<PendingJobsPopout
|
||||
details={jobPopout.data}
|
||||
onClose={() => {
|
||||
setJobPopout({ show: false, data: {} });
|
||||
}}
|
||||
situation={jobPopout.show}
|
||||
/>
|
||||
)}
|
||||
{/* End of Active Job Popout */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function FamilyProfile() {
|
||||
return <>Profile</>;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import Icons from "../../Helpers/Icons";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import Detail from "../../jobPopout/popoutcomponent/Detail";
|
||||
import localImgLoad from "../../../lib/localImgLoad";
|
||||
|
||||
|
||||
export default function FamilyTasks({ familyData, className, loader, accountDetails }) {
|
||||
@@ -55,6 +56,7 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
let image = value.banner ? value.banner : 'default.jpg'
|
||||
return (
|
||||
<tr
|
||||
key={index}
|
||||
@@ -62,11 +64,11 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
|
||||
>
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px] min-w-[60px]">
|
||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage2}
|
||||
src={localImgLoad(`images/taskbanners/${image}`)}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
import { memo, useMemo, useState } from "react";
|
||||
import SuggestTask from "../../FamilyPopup/SuggestTask";
|
||||
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import AssignTaskPopout from "../FamilyPopout/AssignTaskPopout";
|
||||
|
||||
const FamilyWaitlist = memo(
|
||||
({ familyData, className, accountDetails, loader }) => {
|
||||
const [popUp, setPopUp] = useState({ show: false, data: {} });
|
||||
const [continueTaskPopup, setContinueTaskPopup] = useState({
|
||||
show: false,
|
||||
data: {},
|
||||
});
|
||||
const filteredFamilyData = useMemo(
|
||||
() =>
|
||||
familyData?.result_list?.filter(
|
||||
(data) => data?.family_uid === accountDetails?.family_uid
|
||||
),
|
||||
[familyData, accountDetails]
|
||||
);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const indexOfFirstItem = currentPage;
|
||||
const indexOfLastItem = currentPage + itemsPerPage;
|
||||
const currentTask = useMemo(
|
||||
() => filteredFamilyData?.slice(indexOfFirstItem, indexOfLastItem),
|
||||
[filteredFamilyData, indexOfFirstItem, indexOfLastItem]
|
||||
);
|
||||
|
||||
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
||||
|
||||
const openPopUp = (value) => {
|
||||
setPopUp({ show: true, data: { ...value } });
|
||||
};
|
||||
|
||||
const closePopUp = () => {
|
||||
setPopUp({ show: false, data: {} });
|
||||
};
|
||||
|
||||
const openContinueTaskPopup = (value) => {
|
||||
setContinueTaskPopup({ show: true, data: { ...value } });
|
||||
};
|
||||
|
||||
const closeContinueTaskPopup = () => {
|
||||
setContinueTaskPopup({ show: false, data: {} });
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
{loader ? (
|
||||
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
|
||||
<LoadingSpinner size={16} color="sky-blue" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{filteredFamilyData && (
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{currentTask.map((value) => {
|
||||
const addedDate = value?.added.split(" ")[0];
|
||||
const selectedImage = require(`../../../assets/images/family/${
|
||||
value?.banner || "default.jpg"
|
||||
}`);
|
||||
return (
|
||||
<tr
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
key={value.uid}
|
||||
>
|
||||
<td className="py-4">
|
||||
<div className="w-full flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img
|
||||
src={selectedImage}
|
||||
alt="task_img"
|
||||
className="w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="">
|
||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
{value.title}
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
{value.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-2 flex flex-col items-center justify-center">
|
||||
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
||||
{addedDate}
|
||||
</p>
|
||||
<p className="text-xs py-1.5 w-[70px] cursor-default tracking-wide rounded-full bg-gold text-white flex justify-center items-center">
|
||||
{value.status_text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-right py-4 px-2">
|
||||
<button
|
||||
onClick={() => openPopUp(value)}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage === 0}
|
||||
next={
|
||||
currentPage + itemsPerPage >= filteredFamilyData?.length
|
||||
}
|
||||
data={filteredFamilyData}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{popUp.show && (
|
||||
<SuggestTask
|
||||
details={popUp.data}
|
||||
onClose={closePopUp}
|
||||
continuePopupData={openContinueTaskPopup}
|
||||
situation={popUp.show}
|
||||
/>
|
||||
)}
|
||||
|
||||
{continueTaskPopup.show && (
|
||||
<AssignTaskPopout
|
||||
details={continueTaskPopup.data}
|
||||
action={closeContinueTaskPopup}
|
||||
situation={continueTaskPopup.show}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default FamilyWaitlist;
|
||||
@@ -0,0 +1,61 @@
|
||||
import React from "react";
|
||||
|
||||
export default function ProfileInfo({
|
||||
profileImg,
|
||||
profileImgInput,
|
||||
profileImgChangHandler,
|
||||
browseProfileImg,
|
||||
accountDetails,
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={profileImg}
|
||||
alt=""
|
||||
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
<div
|
||||
onClick={browseProfileImg}
|
||||
className="w-[32px] h-[32px] absolute bottom-7 sm:right-2 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col justify-center gap-3 items-center">
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{accountDetails?.firstname}
|
||||
</h1>
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{accountDetails?.lastname}
|
||||
</h1>
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{accountDetails?.age}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import FamilyAccount from "./FamilyAccount";
|
||||
import FamilyProfile from "./FamilyProfile";
|
||||
import FamilyTasks from "./FamilyTasks";
|
||||
import FamilyWaitlist from "./FamilyWaitlist";
|
||||
import FamilyPending from "./FamilyPending";
|
||||
import ProfileInfo from "./ProfileInfo";
|
||||
|
||||
export {
|
||||
FamilyAccount,
|
||||
FamilyProfile,
|
||||
FamilyTasks,
|
||||
FamilyWaitlist,
|
||||
FamilyPending,
|
||||
ProfileInfo,
|
||||
};
|
||||
@@ -1,9 +1,16 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import React, {
|
||||
Suspense,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import FamilyTable from "./FamilyTable";
|
||||
import SiteService from "../../services/SiteService";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
export default function FamilyAcc() {
|
||||
const [selectTab, setValue] = useState("today");
|
||||
@@ -20,60 +27,50 @@ export default function FamilyAcc() {
|
||||
|
||||
const apiCall = useMemo(() => new SiteService(), []);
|
||||
|
||||
// This is to make sure it's called once and used everywhere
|
||||
let memberId = localStorage.getItem("member_id");
|
||||
let uid = localStorage.getItem("uid");
|
||||
let sessionId = localStorage.getItem("session_token");
|
||||
|
||||
const popUpHandler = () => {
|
||||
setPopUp((prev) => !prev);
|
||||
};
|
||||
|
||||
// tab handler
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
|
||||
// For the age drop down
|
||||
let startAge = 5;
|
||||
let endAge = 16;
|
||||
// creates an array of age values ranging from 16 to 70
|
||||
const ageRange = Array.from(
|
||||
{ length: endAge - startAge + 1 },
|
||||
(_, index) => startAge + index
|
||||
);
|
||||
// age handler
|
||||
const ageRange = useMemo(() => {
|
||||
const startAge = 5;
|
||||
const endAge = 16;
|
||||
return Array.from(
|
||||
{ length: endAge - startAge + 1 },
|
||||
(_, index) => startAge + index
|
||||
);
|
||||
}, []);
|
||||
|
||||
const handleAgeSelect = (event) => {
|
||||
setSelectedAge(parseInt(event.target.value));
|
||||
};
|
||||
// Input handler
|
||||
|
||||
const handleInputChange = (event) => {
|
||||
const { name, value } = event?.target;
|
||||
setFormData({ ...formData, [name]: value });
|
||||
setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
|
||||
};
|
||||
|
||||
// Add member
|
||||
const addMember = async () => {
|
||||
const { first_name, last_name } = formData;
|
||||
setLoader(true);
|
||||
try {
|
||||
if (first_name !== "" && last_name !== "") {
|
||||
let reqData = {
|
||||
member_id: memberId,
|
||||
uid: uid,
|
||||
session_id: sessionId,
|
||||
const reqData = {
|
||||
firstname: first_name,
|
||||
lastname: last_name,
|
||||
age: selectedAge,
|
||||
};
|
||||
|
||||
let res = await apiCall.addFamily(reqData);
|
||||
const res = await apiCall.addFamily(reqData);
|
||||
const { data } = res;
|
||||
|
||||
if (data?.internal_return > 0 && data?.status == "OK") {
|
||||
if (data?.internal_return > 0 && data?.status === "OK") {
|
||||
setLoader(false);
|
||||
setListReload((prev) => !prev);
|
||||
popUpHandler()
|
||||
popUpHandler();
|
||||
} else {
|
||||
setLoader(false);
|
||||
setMsgErr("Sorry, something went wrong");
|
||||
@@ -94,38 +91,42 @@ export default function FamilyAcc() {
|
||||
first_name: "",
|
||||
last_name: "",
|
||||
});
|
||||
setSelectedAge("")
|
||||
setSelectedAge("");
|
||||
}
|
||||
};
|
||||
|
||||
// member listing
|
||||
const memberList = useCallback(async () => {
|
||||
setLoader(true);
|
||||
try {
|
||||
let reqData = {
|
||||
member_id: memberId,
|
||||
uid: uid,
|
||||
session_id: sessionId,
|
||||
const reqData = {
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
action: 22010,
|
||||
};
|
||||
|
||||
let res = await apiCall.familyListings(reqData);
|
||||
const res = await apiCall.familyListings(reqData);
|
||||
const { data } = res;
|
||||
if (data?.internal_return >= 0 && data?.status == "OK") {
|
||||
let { result_list } = data;
|
||||
if (data?.internal_return >= 0 && data?.status === "OK") {
|
||||
const { result_list } = data;
|
||||
setFamilyList(result_list);
|
||||
setLoader(false);
|
||||
} else return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
setLoader(false);
|
||||
throw new Error(error);
|
||||
}
|
||||
}, [apiCall, memberId, sessionId, uid]);
|
||||
}, [apiCall]);
|
||||
|
||||
useEffect(() => {
|
||||
memberList();
|
||||
let checkMemberList = true;
|
||||
if (checkMemberList) {
|
||||
memberList();
|
||||
}
|
||||
return () => {
|
||||
checkMemberList = false;
|
||||
};
|
||||
}, [listReload, memberList]);
|
||||
|
||||
return (
|
||||
@@ -158,7 +159,13 @@ export default function FamilyAcc() {
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<FamilyTable familyList={familyList} loader={loader} popUpHandler={popUpHandler} />
|
||||
<Suspense fallback={<LoadingSpinner color="sky-blue" size="16" />}>
|
||||
<FamilyTable
|
||||
familyList={familyList}
|
||||
loader={loader}
|
||||
popUpHandler={popUpHandler}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
{popUp && (
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
import { useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import { Form, Formik } from "formik";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import usersService from "../../services/UsersService";
|
||||
import Icons from "../Helpers/Icons";
|
||||
|
||||
const DEFAULT_IMAGE = require("../../assets/images/family/default.jpg");
|
||||
const SuggestTask = ({ details, onClose, situation, continuePopupData }) => {
|
||||
const { pathname, state } = useLocation();
|
||||
const [submitTask, setSubmitTask] = useState({
|
||||
loading: false,
|
||||
msg: "",
|
||||
state: "",
|
||||
});
|
||||
const [suggestedNextStep, setSuggestedNextStep] = useState("Send Task");
|
||||
|
||||
const switchNextStep = ({ target: value }) => {
|
||||
setSuggestedNextStep(value);
|
||||
};
|
||||
|
||||
const selectedImage = details?.selectedImage || DEFAULT_IMAGE;
|
||||
const initialValues = {
|
||||
title: details?.title || "",
|
||||
description: details?.description || "",
|
||||
banner: details?.banner,
|
||||
};
|
||||
|
||||
const apiCall = new usersService();
|
||||
|
||||
const handleSuggestedTask = async (values) => {
|
||||
if (!values.title && !values.description) return;
|
||||
|
||||
try {
|
||||
setSubmitTask({ loading: true });
|
||||
const reqData = { ...values };
|
||||
const res = await apiCall.sendFamilySuggestedTasks(reqData);
|
||||
if (res.internal_return < 0) {
|
||||
setSubmitTask({ loading: false, msg: res.status, state: "bad" });
|
||||
return;
|
||||
}
|
||||
setSubmitTask({ loading: false, msg: res.status, state: "success" });
|
||||
setTimeout(() => {
|
||||
onClose();
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
setSubmitTask({ loading: false, msg: error, state: "bad" });
|
||||
throw new Error("Error Occurred", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleParentSuggestion = (values) => {
|
||||
if (suggestedNextStep == "Send Task") {
|
||||
let firstName = state?.firstname;
|
||||
let family_uid = state?.family_uid;
|
||||
continuePopupData({ ...details, firstName, family_uid });
|
||||
}
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation}>
|
||||
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-base md:text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
{pathname === "/manage-family"
|
||||
? `${state?.firstname}'s Suggested Task`
|
||||
: "Suggest to Parent"}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={onClose}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
onSubmit={
|
||||
pathname !== "/manage-family"
|
||||
? handleSuggestedTask
|
||||
: handleParentSuggestion
|
||||
}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form>
|
||||
<div className="p-5 w-full bg-white rounded-md flex justify-between">
|
||||
{/* Image Section */}
|
||||
<div className="p-4 w-full md:w-2/4 md:border-r-2">
|
||||
<div
|
||||
className="w-full h-[236px] p-6 bg-gray-400 rounded-xl overflow-hidden"
|
||||
style={{
|
||||
background: `url(${selectedImage}) center / contain no-repeat`,
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
|
||||
{/* ACTION SECTION */}
|
||||
<div className="p-4 w-full md:w-2/4 h-full">
|
||||
{/* Title */}
|
||||
<div className="field w-full mb-[15px]">
|
||||
<InputCom
|
||||
fieldClass={
|
||||
pathname === "/manage-family" ? "px-2" : "px-6"
|
||||
}
|
||||
label="Title"
|
||||
labelClass="tracking-wide"
|
||||
inputBg={
|
||||
pathname === "/manage-family"
|
||||
? "bg-white"
|
||||
: "bg-slate-100"
|
||||
}
|
||||
inputClass="disabled:cursor-default"
|
||||
type="text"
|
||||
name="title"
|
||||
disable={details?.title}
|
||||
value={props.values.title}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={
|
||||
props.errors.title &&
|
||||
props.touched.title &&
|
||||
props.errors.title
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<label
|
||||
htmlFor="description"
|
||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1'
|
||||
>
|
||||
Description
|
||||
{props.errors.description &&
|
||||
props.touched.description && (
|
||||
<span className="text-[12px] text-red-500">
|
||||
{props.errors.description}
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
<textarea
|
||||
id="description"
|
||||
rows="5"
|
||||
className={`input-field pt-2 placeholder:text-base text-dark-gray dark:text-white w-full ${
|
||||
pathname === "/manage-family"
|
||||
? "px-2 h-[110px]"
|
||||
: "bg-slate-100 px-3 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px] h-[130px]"
|
||||
}`}
|
||||
style={{ resize: "none" }}
|
||||
name="description"
|
||||
value={props.values.description}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Radio buttons for family */}
|
||||
{pathname === "/manage-family" ? (
|
||||
<div className="h-[20px] w-full border-t dark:border-[#5356fb29] border-light-purple relative">
|
||||
<div id="my-radio-group" className="sr-only">
|
||||
Parent suggested next step
|
||||
</div>
|
||||
<div
|
||||
role="group"
|
||||
className="flex items-center justify-between py-2"
|
||||
aria-labelledby="parent-suggested-radio-group"
|
||||
>
|
||||
{[
|
||||
{ title: "Send Task" },
|
||||
{ title: "Duplicate" },
|
||||
{ title: "Not Now" },
|
||||
].map(({ title }, idx) => (
|
||||
<label
|
||||
role="group"
|
||||
key={idx}
|
||||
htmlFor={`parent-suggested-${idx}`}
|
||||
className={`transition duration-150 ease-in-out parent-suggest group cursor-pointer`}
|
||||
onClick={() => setSuggestedNextStep(title)}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="parent-suggested"
|
||||
value={title}
|
||||
checked={suggestedNextStep === title}
|
||||
onChange={switchNextStep}
|
||||
className={`transition duration-150 ease-in-out parent-suggest pointer-events-none`}
|
||||
/>
|
||||
<span
|
||||
onClick={() => setSuggestedNextStep(title)}
|
||||
id={`parent-suggested-${idx}`}
|
||||
name="parent-suggested"
|
||||
className={`ml-1 ${
|
||||
title == "Not Now"
|
||||
? "text-red-500"
|
||||
: title == "Duplicate"
|
||||
? "text-purple"
|
||||
: "text-black"
|
||||
} font-semibold`}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full h-[70px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||
<div className="flex items-center space-x-4 mr-9">
|
||||
<button
|
||||
type="button"
|
||||
className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
onClick={onClose}
|
||||
>
|
||||
<span className="text-gradient"> Cancel</span>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={props.isSubmitting}
|
||||
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full transition duration-150 ease-in-out flex items-center"
|
||||
>
|
||||
{pathname !== "/manage-family" ? (
|
||||
<>
|
||||
{submitTask.loading
|
||||
? "Submitting Task"
|
||||
: submitTask.state == "success"
|
||||
? "Task Submitted"
|
||||
: submitTask.state == "bad"
|
||||
? "An Error Occurred"
|
||||
: "Send to Parents"}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{suggestedNextStep == "Send Task" ? (
|
||||
<>
|
||||
Continue <Icons name="chevron-right" />
|
||||
</>
|
||||
) : (
|
||||
"Complete"
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
</ModalCom>
|
||||
);
|
||||
};
|
||||
|
||||
export default SuggestTask;
|
||||
@@ -1,8 +1,9 @@
|
||||
import React from "react";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
import ATMCard from '../../assets/images/card.svg'
|
||||
import VisaCard from '../../assets/images/visa.svg'
|
||||
import MasterCard from '../../assets/images/master.svg'
|
||||
import ATMCard from "../../assets/images/card.svg";
|
||||
import VisaCard from "../../assets/images/visa.svg";
|
||||
import MasterCard from "../../assets/images/master.svg";
|
||||
|
||||
export default function Icons({ name }) {
|
||||
return (
|
||||
@@ -472,6 +473,21 @@ export default function Icons({ name }) {
|
||||
>
|
||||
<rect y="0.823242" width="20" height="2.35294" rx="1.17647" />
|
||||
</svg>
|
||||
) : name === "chevron-right" ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8.25 4.5l7.5 7.5-7.5 7.5"
|
||||
/>
|
||||
</svg>
|
||||
) : name === "right-arrow" ? (
|
||||
<svg
|
||||
width="24"
|
||||
@@ -493,7 +509,21 @@ export default function Icons({ name }) {
|
||||
<img className="w-[20px]" src={VisaCard} alt="card" />
|
||||
) : name === "master-card" ? (
|
||||
<img className="w-[20px]" src={MasterCard} alt="card" />
|
||||
) : (
|
||||
) : name === "new-dashboard" ? (
|
||||
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/dashboard.svg')} alt="dashboard" />
|
||||
) : name === "new-family" ? (
|
||||
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/family.svg')} alt="family" />
|
||||
) : name === "new-logout" ? (
|
||||
<img className="w-[45px] rounded-full bg-white p-1" src={localImgLoad('images/icons/logout.svg')} alt="logout" />
|
||||
) : name === "new-market" ? (
|
||||
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/market.svg')} alt="market" />
|
||||
) : name === "new-mytask" ? (
|
||||
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/my-task.svg')} alt="task" />
|
||||
) : name === "family-id" ? (
|
||||
<img className="w-[20px] h-[20px]" src={localImgLoad('images/icons/family-id.svg')} alt="family-id" />
|
||||
) : name === "family-pin" ? (
|
||||
<img className="w-[20px] h-[20px]" src={localImgLoad('images/icons/family-pin.svg')} alt="family-pin" />
|
||||
): (
|
||||
""
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -76,7 +76,7 @@ export default function InputCom({
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border 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 ${inputClass}`}
|
||||
className={`input-wrapper w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-base ${inputClass ? inputClass : "text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] border"}`}
|
||||
>
|
||||
<input
|
||||
placeholder={placeholder}
|
||||
@@ -97,7 +97,7 @@ export default function InputCom({
|
||||
dir={direction}
|
||||
/>
|
||||
{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) => (
|
||||
<Icons key={index} name={item} />
|
||||
))}
|
||||
@@ -105,7 +105,7 @@ export default function InputCom({
|
||||
)}
|
||||
{passIcon && (
|
||||
<div
|
||||
className="absolute right-6 bottom-[10px] z-10"
|
||||
className="absolute right-6 bottom-3 z-10"
|
||||
onClick={onClick}
|
||||
>
|
||||
<Icons name={passIcon} />
|
||||
@@ -126,7 +126,9 @@ const inputConfigs = {
|
||||
province: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
||||
city: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
||||
amount: { minLength: 1, maxLength: 9, pattern: "[0-9]+" },
|
||||
description: { minLength: 5, maxLength: 250 },
|
||||
description: { minLength: 5, maxLength: 299 },
|
||||
title: { minLength: 5, maxLength: 149 },
|
||||
job_detail: { minLength: 4, maxLength: 1440 }
|
||||
};
|
||||
|
||||
/* Numbers Only: <input type="text" pattern="[0-9]*" /> strictly numbers
|
||||
|
||||
@@ -20,7 +20,8 @@ import React from "react";
|
||||
export const PriceFormatter = (
|
||||
price = "00",
|
||||
currency = "",
|
||||
currencyName = ""
|
||||
currencyName = "",
|
||||
priceClass
|
||||
) => {
|
||||
// Convert the number to a string
|
||||
let numStr = String(price);
|
||||
@@ -44,7 +45,7 @@ export const PriceFormatter = (
|
||||
return (
|
||||
<span className="text-sm flex items-center">
|
||||
<sup>{currency || currencyName || ""}</sup>
|
||||
<span className="px-1 font-bold text-lg">{formattedInteger || ""}</span>
|
||||
<span className={`px-1 font-bold ${priceClass ? priceClass : "text-lg"}`}>{formattedInteger || ""}</span>
|
||||
<sup>{formattedDecimal || ""}</sup>
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import Icons from "./Icons";
|
||||
|
||||
export default function SearchCom({ className, inputClasses, placeholder }) {
|
||||
export default function SearchCom({
|
||||
className,
|
||||
inputClasses,
|
||||
placeholder,
|
||||
handleSearch,
|
||||
value,
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`w-full h-[48px] pl-8 flex rounded-full overflow-hidden bg-white dark:bg-dark-white ${
|
||||
@@ -17,7 +23,9 @@ export default function SearchCom({ className, inputClasses, placeholder }) {
|
||||
inputClasses || ""
|
||||
}`}
|
||||
type="text"
|
||||
placeholder={placeholder || 'Search items, collections...'}
|
||||
onInput={handleSearch}
|
||||
value={value}
|
||||
placeholder={placeholder || "Search items, collections..."}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import React, { useRef } from "react";
|
||||
import ProductCardStyleOne from "../Cards/ProductCardStyleOne";
|
||||
//import ProductCardStyleOne from "../Cards/ProductCardStyleOne";
|
||||
import Icons from "../Helpers/Icons";
|
||||
import SliderCom from "../Helpers/SliderCom";
|
||||
import FamilyActiveJobsCard from "../Cards/FamilyActiveJobsCard";
|
||||
|
||||
export default function FamilyActiveLSlde({ className, trending }) {
|
||||
const settings = {
|
||||
arrows: false,
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
infinite: true,
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
infinite: trending?.length > 3,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1025,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
infinite: trending?.length > 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -22,6 +24,7 @@ export default function FamilyActiveLSlde({ className, trending }) {
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
infinite: trending?.length > 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -29,6 +32,7 @@ export default function FamilyActiveLSlde({ className, trending }) {
|
||||
settings: {
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
infinite: trending?.length > 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -89,12 +93,12 @@ export default function FamilyActiveLSlde({ className, trending }) {
|
||||
</div>
|
||||
</div>
|
||||
{/* trending products */}
|
||||
<div className="trending-products relative w-full">
|
||||
<div className="trending-products slider-left relative w-full rounded-2xl p-[10px] bg-alice-blue">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{trending &&
|
||||
trending.length > 0 &&
|
||||
trending.map((item) => (
|
||||
<ProductCardStyleOne key={item.id} datas={item} />
|
||||
<FamilyActiveJobsCard key={item.id} datas={item} />
|
||||
))}
|
||||
</SliderCom>
|
||||
</div>
|
||||
|
||||
@@ -6,16 +6,21 @@ import FamilyActiveLSlde from "./FamilyActiveLSlde";
|
||||
import ParentWaiting from "../MyPendingJobs/ParentWaiting";
|
||||
import MyOffersFamilyTable from "../MyTasks/MyOffersFamilyTable";
|
||||
|
||||
export default function FamilyDash(props) {
|
||||
console.log("PROPS IN FAMILY DASH->", props);
|
||||
export default function FamilyDash({familyOffers, MyActiveJobList}) {
|
||||
console.log("PROPS IN FAMILY DASH->", familyOffers);
|
||||
|
||||
const trending = datas.datas;
|
||||
const trending = MyActiveJobList;
|
||||
return (
|
||||
<div>
|
||||
<div className="home-page-wrapper">
|
||||
<CommonHead commonHeadData={props.commonHeadData} />
|
||||
<MyOffersFamilyTable MyActiveOffersList={trending} className="mb-10" />
|
||||
{/* <CommonHead commonHeadData={props.commonHeadData} /> */}
|
||||
{familyOffers && familyOffers.length > 0 &&
|
||||
<MyOffersFamilyTable familyOffers={familyOffers} className="mb-10" />
|
||||
}
|
||||
{trending && trending.length > 0 &&
|
||||
<FamilyActiveLSlde trending={trending} className="mb-10" />
|
||||
}
|
||||
|
||||
{/*<TopSellerTopBuyerSliderSection className="mb-10" />*/}
|
||||
<ParentWaiting className="mb-10" />
|
||||
</div>
|
||||
|
||||
@@ -11,12 +11,6 @@ import HomeActivities from "./HomeActivities";
|
||||
|
||||
export default function FullAccountDash(props) {
|
||||
console.log("PROPS IN HOME->", props);
|
||||
|
||||
const trending = datas.datas;
|
||||
const jobData = datas.datas; // api calls or cache
|
||||
|
||||
const userApi = new usersService();
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import heroBg from "../../assets/images/hero-bg.svg";
|
||||
import heroBg from "../../assets/images/bg-sky-blue.jpg"; //hero-bg.svg";
|
||||
import heroUser from "../../assets/images/hero-user.png";
|
||||
import CountDown from "../Helpers/CountDown";
|
||||
import HomeSliders from "./HomeSliders";
|
||||
@@ -24,7 +24,7 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`w-full lg:h-[444px] h-full lg:flex lg:p-8 p-4 justify-between items-center lg:space-x-28 rounded-2xl overflow-hidden ${
|
||||
className={`w-full min-h-[400px] md:grid grid-cols-2 lg:p-8 p-4 justify-between items-center gap-2 rounded-2xl overflow-hidden ${
|
||||
className || ""
|
||||
}`}
|
||||
style={{
|
||||
@@ -33,7 +33,7 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
||||
backgroundSize: "cover",
|
||||
}}
|
||||
>
|
||||
<div className="flex-1 h-[330px] lg:h-full flex flex-col justify-between mb-5 lg:mb-0">
|
||||
<div className="h-full flex flex-col justify-between mb-5 lg:mb-0">
|
||||
{/* heading */}
|
||||
<div>
|
||||
<h1 className="lg:text-2xl text-xl font-medium text-white tracking-wide">
|
||||
@@ -56,8 +56,8 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
||||
</div>
|
||||
</div>
|
||||
{/* countdown */}
|
||||
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length && (
|
||||
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border border-white-opacity">
|
||||
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && (
|
||||
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
|
||||
<div className="flex flex-col justify-between">
|
||||
<p className="text-base text-white tracking-wide">Current Task</p>
|
||||
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||
@@ -84,7 +84,7 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
||||
)}
|
||||
{/* action */}
|
||||
<div className="flex lg:space-x-3 space-x-1 items-center">
|
||||
<Link to="/mytask" className="text-white text-base sm:block hidden">
|
||||
<Link to="/mytask" className="text-white text-base">
|
||||
<span className=" border-b dark:border-[#5356fb29] border-white">
|
||||
{" "}
|
||||
View All Task(s)
|
||||
|
||||
@@ -6,7 +6,7 @@ export default function HomeSliders(props) {
|
||||
// debugger;
|
||||
return (
|
||||
<>
|
||||
<div className="hero-slider relative 2xl:w-[600px] xl:w-[400px] lg:w-[420px] w-full mb-2 lg:mb-0 ">
|
||||
<div className="hero-slider relative h-full w-full mb-2 lg:mb-0">
|
||||
<div className="w-full">
|
||||
<SliderCom settings={props.settings}>
|
||||
{props.bannerList?.length <= 0 && (
|
||||
|
||||
@@ -8,14 +8,26 @@ import FullAccountDash from "./FullAccountDash";
|
||||
|
||||
export default function Home(props) {
|
||||
console.log("PROPS IN HOME->", props);
|
||||
const userApi = new usersService();
|
||||
const { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
||||
|
||||
let [nextDueTask, setNextDueTask] = useState({});
|
||||
|
||||
const userApi = new usersService();
|
||||
const [MyOffersList, setMyOffersList] = useState([]);
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
|
||||
const { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
||||
const [MyActiveJobList, setMyActiveJobList] = useState([]); // STATE TO HOLD ACTIVE/CURRENT TASKS
|
||||
|
||||
const getMyActiveJobList = async () => { // FUNCTION TO POPULATE ACTIVE/CURRENT TASK LIST
|
||||
try {
|
||||
const res = await userApi.getMyActiveTaskList();
|
||||
setMyActiveJobList(res?.data?.result_list);
|
||||
} catch (error) {
|
||||
setMyActiveJobList([]);
|
||||
console.log("Error getting tasks");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// FUNCTION TO GET DASH DATA TO DETERMINE CURRENT TASK DUE TIME
|
||||
const getHomeDate = () => {
|
||||
@@ -32,15 +44,37 @@ export default function Home(props) {
|
||||
});
|
||||
};
|
||||
|
||||
const getMyOffersList = async () => {
|
||||
try {
|
||||
const res = await userApi.getOffersList();
|
||||
setMyOffersList(res.data?.result_list);
|
||||
} catch (error) {
|
||||
console.log("Error getting offers", error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getHomeDate();
|
||||
const fetchData = async () => {
|
||||
await Promise.all([getHomeDate(), getMyOffersList()]);
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
getMyActiveJobList();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="home-page-wrapper">
|
||||
{userDetails && userDetails?.account_type == "FAMILY" ? (
|
||||
<FamilyDash account={userDetails} commonHeadData={props.bannerList} />
|
||||
<FamilyDash
|
||||
account={userDetails}
|
||||
commonHeadData={props.bannerList}
|
||||
familyOffers={MyOffersList}
|
||||
MyActiveJobList={MyActiveJobList}
|
||||
/>
|
||||
) : userDetails && userDetails?.account_type == "FULL" ? (
|
||||
<FullAccountDash
|
||||
nextDueTask={nextDueTask}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import DataIteration from "../Helpers/DataIteration";
|
||||
import AvailableJobsCard from "../Cards/AvailableJobsCard";
|
||||
import ListView from '../../assets/images/list-view.png'
|
||||
import GridView from '../../assets/images/grid-view.svg'
|
||||
import ListView from "../../assets/images/list-view.png";
|
||||
import GridView from "../../assets/images/grid-view.svg";
|
||||
import SelectBox from "../Helpers/SelectBox";
|
||||
|
||||
export default function MainSection({
|
||||
@@ -17,7 +17,7 @@ export default function MainSection({
|
||||
);
|
||||
const [tab, setTab] = useState(Object.keys(marketCategories)[0]);
|
||||
|
||||
let [contentDisplay, setContentDisplay] = useState('grid') // STATE TO HOLD LIST VIEW STYLE
|
||||
let [contentDisplay, setContentDisplay] = useState("grid"); // STATE TO HOLD LIST VIEW STYLE
|
||||
|
||||
// Convert to array in order to map
|
||||
const mappedArray = Object.entries(marketCategories).map(([key, value]) => {
|
||||
@@ -29,8 +29,8 @@ export default function MainSection({
|
||||
setTab(value);
|
||||
};
|
||||
|
||||
// Handles the category selection on mobile view
|
||||
const handleSetCategory = (value) => {
|
||||
// Handles the category selection on mobile view
|
||||
const handleSetCategory = (value) => {
|
||||
for (let i in marketCategories) {
|
||||
if (marketCategories[i] == value) {
|
||||
setTab(i);
|
||||
@@ -57,7 +57,7 @@ export default function MainSection({
|
||||
<div className="hidden lg:flex md:space-x-8 space-x-2">
|
||||
{mappedArray.map(({ key, value }) => (
|
||||
<span
|
||||
key={key}
|
||||
key={key}
|
||||
onClick={() => tabHandler(key)}
|
||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||
tab === key
|
||||
@@ -76,30 +76,43 @@ export default function MainSection({
|
||||
datas={Object.values(marketCategories)}
|
||||
className="Update-table-dropdown"
|
||||
contentBodyClasses="w-auto min-w-max"
|
||||
position='left'
|
||||
position="left"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* contentDisplay toggler */}
|
||||
<div className="p-2 w-[35px] h-[35px] bg-white dark:bg-slate-200 rounded-lg">
|
||||
<img
|
||||
title={contentDisplay=='grid'? 'list view' : 'grid view'}
|
||||
onClick={()=>setContentDisplay((prev)=>prev=='grid'? 'list' : 'grid')}
|
||||
src={contentDisplay=='grid'? ListView : GridView}
|
||||
className="w-full h-full cursor-pointer" alt="view"
|
||||
/>
|
||||
<img
|
||||
title={contentDisplay == "grid" ? "list view" : "grid view"}
|
||||
onClick={() =>
|
||||
setContentDisplay((prev) => (prev == "grid" ? "list" : "grid"))
|
||||
}
|
||||
src={contentDisplay == "grid" ? ListView : GridView}
|
||||
className="w-full h-full cursor-pointer"
|
||||
alt="view"
|
||||
/>
|
||||
</div>
|
||||
{/* end of contentDisplay toggler */}
|
||||
</div>
|
||||
<div className="filter-navigate-content w-full min-h-screen">
|
||||
<div className={contentDisplay == 'grid' ? 'grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]' : 'w-full'}>
|
||||
<div
|
||||
className={
|
||||
contentDisplay == "grid"
|
||||
? "grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]"
|
||||
: "w-full"
|
||||
}
|
||||
>
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<AvailableJobsCard contentDisplay={contentDisplay} key={datas.id} datas={datas} />
|
||||
<AvailableJobsCard
|
||||
contentDisplay={contentDisplay}
|
||||
key={datas.id}
|
||||
datas={datas}
|
||||
/>
|
||||
)}
|
||||
</DataIteration>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
|
||||
function CurrentJobAction() {
|
||||
return (
|
||||
<div className='job-action bg-white dark:bg-black'>
|
||||
<div className='job-action dark:bg-black'>
|
||||
<p className="my-3 py-1 text-base active-owner">
|
||||
<table className="w-full text-sm text-left text-gray-500">
|
||||
<tbody>
|
||||
|
||||
@@ -60,7 +60,7 @@ function CurrentTaskAction({jobDetails}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='job-action bg-white dark:bg-black'>
|
||||
<div className='job-action dark:bg-black'>
|
||||
|
||||
<table className="w-full text-sm text-left text-gray-500 active-worker">
|
||||
<tbody>
|
||||
|
||||
@@ -101,7 +101,7 @@ function PastDueJobAction({jobDetails}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='job-action bg-white dark:bg-black'>
|
||||
<div className='job-action dark:bg-black'>
|
||||
|
||||
<table className="w-full text-sm text-left text-gray-500 owner-pastdue">
|
||||
<tbody>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
|
||||
function PastDueTaskAction() {
|
||||
return (
|
||||
<div className='job-action bg-white dark:bg-black'>
|
||||
<div className='job-action dark:bg-black'>
|
||||
|
||||
<table className="w-full text-sm text-left text-gray-500 worker-pastdue">
|
||||
<tbody>
|
||||
|
||||
@@ -90,7 +90,7 @@ function ReviewJobAction({jobDetails}) {
|
||||
})
|
||||
}
|
||||
return (
|
||||
<div className='job-action bg-white dark:bg-black'>
|
||||
<div className='job-action dark:bg-black'>
|
||||
<div className="my-3 py-1 text-base">
|
||||
<table className="w-full text-sm text-left text-gray-500 review-owner">
|
||||
<tbody>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
|
||||
function ReviewTaskAction() {
|
||||
return (
|
||||
<div className='job-action bg-white dark:bg-black'>
|
||||
<div className='job-action dark:bg-black'>
|
||||
<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
|
||||
</p>
|
||||
|
||||
@@ -4,6 +4,7 @@ import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
const navigate = useNavigate();
|
||||
@@ -56,11 +57,11 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
>
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px]">
|
||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage2}
|
||||
src={localImgLoad(`images/taskbanners/${value.banner}`)}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
|
||||
@@ -13,6 +13,7 @@ import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
import EditIcon from '../../assets/images/icon-edit.svg'
|
||||
import DeleteIcon from '../../assets/images/icon-delete.svg'
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
// Getting the categories
|
||||
@@ -114,8 +115,8 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
<td className="py-9">
|
||||
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
|
||||
<div className="flex space-x-2 items-center job-items w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||
<img src={dataImage2} alt="data" className="w-full h-full" />
|
||||
<div 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" />
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
|
||||
@@ -4,6 +4,7 @@ import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
export default function MyPendingJobTable({ MyJobList, className }) {
|
||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||
@@ -55,11 +56,11 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
||||
>
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px]">
|
||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage2}
|
||||
src={localImgLoad(`images/taskbanners/${value.banner}`)}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
|
||||
@@ -2,8 +2,6 @@ import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import activeAidsBanner from "../../assets/images/kids-waiting.jpg";
|
||||
import HeroUser from "../../assets/images/hero-user.png";
|
||||
import CountDown from "../Helpers/CountDown";
|
||||
import ParentWaitingTable from "./ParentWaitingTable";
|
||||
|
||||
export default function ParentWaiting({ className }) {
|
||||
@@ -20,21 +18,28 @@ export default function ParentWaiting({ className }) {
|
||||
return (
|
||||
<>
|
||||
<div className={`overview-section w-full ${className || ""}`}>
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
<div className="w-full mb-3 flex justify-between items-center gap-1">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Waiting for Parent to Get Started...
|
||||
</h1>
|
||||
<Link
|
||||
to='/familymarket'
|
||||
className="px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
More Task
|
||||
</Link>
|
||||
</div>
|
||||
<div className="overview-section-wrapper lg:flex lg:h-[494px] lg:pace-x-2 flex-1 lg:gap-8">
|
||||
<div className=" w-full h-full bg-white dark:bg-dark-white flex-[50%] rounded-2xl overflow-hidden mb-10">
|
||||
{/* <div className="overview-section-wrapper py-2 min-h-[450px] lg:flex lg:space-x-2 flex-1 lg:gap-8"> */}
|
||||
<div className="overview-section-wrapper py-2 min-h-[400px] lg:grid grid-cols-2 gap-4">
|
||||
<div className="mb-10 lg:mb-0 h-full w-full bg-white dark:bg-dark-white rounded-2xl overflow-hidden">
|
||||
<img
|
||||
src={activeAidsBanner}
|
||||
alt="banner"
|
||||
className="w-full lg:h-full h-[400px]"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="overview-countdown lg:w-2/5 w-full h-full flex flex-col justify-between lg:p-8 rounded-2xl bg-white dark:bg-dark-white flex-[50%] ">
|
||||
<div className="overview-countdown h-full w-full flex flex-col justify-between p-4 rounded-2xl bg-white dark:bg-dark-white">
|
||||
{<ParentWaitingTable />}
|
||||
|
||||
{/* <div className="lg:mb-0 mb-3">*/}
|
||||
|
||||
@@ -1,35 +1,64 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import transaction1 from "../../assets/images/recent-transation-1.png";
|
||||
import transaction2 from "../../assets/images/recent-transation-2.png";
|
||||
import transaction3 from "../../assets/images/recent-transation-3.png";
|
||||
|
||||
export default function ParentWaitingTable() {
|
||||
const transationFilterData = [
|
||||
{
|
||||
id: 1,
|
||||
name: "all",
|
||||
uniqueId: Math.random(),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "send",
|
||||
uniqueId: Math.random(),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "recent",
|
||||
uniqueId: Math.random(),
|
||||
},
|
||||
];
|
||||
const [filterActive, setValue] = useState(transationFilterData[0].id);
|
||||
const filterHander = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
return (
|
||||
<div className="rounded-2xl bg-white dark:bg-dark-white ">
|
||||
{/* heading */}
|
||||
<div className="heading sm:flex justify-between items-center">
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import usersService from "../../services/UsersService";
|
||||
|
||||
|
||||
export default function ParentWaitingTable() {
|
||||
// const transationFilterData = [
|
||||
// {
|
||||
// id: 1,
|
||||
// name: "all",
|
||||
// uniqueId: Math.random(),
|
||||
// },
|
||||
// {
|
||||
// id: 2,
|
||||
// name: "send",
|
||||
// uniqueId: Math.random(),
|
||||
// },
|
||||
// {
|
||||
// id: 3,
|
||||
// name: "recent",
|
||||
// uniqueId: Math.random(),
|
||||
// },
|
||||
// ];
|
||||
// const [filterActive, setValue] = useState(transationFilterData[0].id);
|
||||
// const filterHander = (value) => {
|
||||
// setValue(value);
|
||||
// };
|
||||
|
||||
const apiCall = new usersService()
|
||||
|
||||
let [familySuggestList, setFamilySuggestList] = useState({loading: true, data:[]})
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentList = familySuggestList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
apiCall.getFamilySuggestList().then(res => {
|
||||
setFamilySuggestList({loading: false, data:res.data?.result_list})
|
||||
}).catch(err => {
|
||||
setFamilySuggestList({loading: false, data:[]})
|
||||
console.log('ERROR==>Familysuggestlist', err)
|
||||
})
|
||||
},[])
|
||||
|
||||
return (
|
||||
<div className="rounded-2xl bg-white dark:bg-dark-white flex flex-col justify-between">
|
||||
{/* heading */}
|
||||
{/* <div className="heading sm:flex justify-between items-center">
|
||||
<div>
|
||||
<ul className="flex space-x-5 items-center">
|
||||
{transationFilterData.map((value) => (
|
||||
@@ -43,297 +72,74 @@ export default function ParentWaitingTable() {
|
||||
{value.name}
|
||||
</li>
|
||||
))}
|
||||
{/* <li className="text-base text-thin-light-gray hover:text-purple border-b dark:border-[#5356fb29] border-transparent hover:border-purple uppercase">
|
||||
All
|
||||
</li>
|
||||
<li className="text-base text-thin-light-gray hover:text-purple border-b dark:border-[#5356fb29] border-transparent hover:border-purple uppercase">
|
||||
SEND
|
||||
</li>
|
||||
<li className="text-base text-thin-light-gray hover:text-purple border-b dark:border-[#5356fb29] border-transparent hover:border-purple uppercase">
|
||||
recent
|
||||
</li> */}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/* content */}
|
||||
</div> */}
|
||||
|
||||
{filterActive === 2 ? (
|
||||
<div className="content">
|
||||
{/* content */}
|
||||
<div className="content min-h-[400px]">
|
||||
{familySuggestList.loading ?
|
||||
<div className="h-full flex justify-center items-center">
|
||||
<LoadingSpinner size='16' color='sky-blue' />
|
||||
</div>
|
||||
:
|
||||
familySuggestList && familySuggestList.length != 0?
|
||||
<ul>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
{currentList.map((item)=>{
|
||||
// Image
|
||||
let Image = require(`../../assets/images/family/${
|
||||
item.banner || "default.jpg"
|
||||
}`);
|
||||
return (
|
||||
<li key={item.uid} className="content-item py-2 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple">
|
||||
<div className="w-full flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={Image} alt="" className="w-full h-full" />
|
||||
</div>
|
||||
<div className="time">
|
||||
<div className="">
|
||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
{item.title}
|
||||
</p>
|
||||
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction2} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add BTC from Coinbase Wallet
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-2 self-end">
|
||||
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
||||
{new Date(item.added).toLocaleString().split(',')[0]}
|
||||
|
||||
</p>
|
||||
<p className="text-xs py-1.5 w-[50px] tracking-wide rounded-full bg-gold text-white flex justify-center items-center">{item.status_text}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-824.78
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction3} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Buy Nft art from LTC
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-924.54
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
) : filterActive === 3 ? (
|
||||
<div className="content">
|
||||
<ul>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction2} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add BTC from Coinbase Wallet
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-824.78
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
) : (
|
||||
<div className="content">
|
||||
<ul>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction2} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add BTC from Coinbase Wallet
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-824.78
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction3} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Buy Nft art from LTC
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-924.54
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
:
|
||||
<p className="w-full flex items-center justify-center text-xl text-dark-gray dark:text-white">No List Found!</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
familySuggestList?.data?.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={familySuggestList?.data}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
const noTasksBg = require("../../assets/images/no-task-background.jpg");
|
||||
const noFamilyTasksBg = require("../../assets/images/family-no-task-background.jpg");
|
||||
@@ -52,7 +53,7 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
>
|
||||
{/* Adding this dark overlay in order to see the texts properly */}
|
||||
{!ActiveJobList?.data.length && accountType && (
|
||||
<div class="absolute inset-0 bg-black opacity-30"></div>
|
||||
<div className="absolute inset-0 bg-black opacity-30"></div>
|
||||
)}
|
||||
{ActiveJobList?.data.length > 0 && ActiveJobList.loading && (
|
||||
<div className="w-full h-[520px] flex items-center justify-center">
|
||||
@@ -80,7 +81,7 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
<div className="flex space-x-2 items-center">
|
||||
<div className="w-full min-w-[60px] max-w-[60px] flex-[0.1] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage1}
|
||||
src={localImgLoad(`images/taskbanners/${task?.banner}`)}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
@@ -145,21 +146,21 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
>
|
||||
<div
|
||||
className={`p-2 font-bold text-3xl ${
|
||||
accountType ? "text-white" : "text-purple"
|
||||
accountType ? "text-white" : "text-sky-blue"
|
||||
} whitespace-nowrap`}
|
||||
>
|
||||
You currently have {accountType ? '"0"' : "no"} task
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
!accountType &&
|
||||
"bg-black opacity-30 h-[17rem] p-5 rounded-md -translate-x-20"
|
||||
}
|
||||
className={`
|
||||
${!accountType &&
|
||||
"bg-[#f0f8ff] h-[17rem] p-5 rounded-md -translate-x-20"}
|
||||
`}
|
||||
>
|
||||
<button
|
||||
className={`${
|
||||
!accountType
|
||||
? "w-[130px] h-20 bg-[#19a706] text-lg font-semibold rounded-md py-2 px-4"
|
||||
? "w-[150px] h-20 bg-[#22b14c] text-lg font-semibold rounded-md py-2 px-4"
|
||||
: "w-[115px] h-11 btn-gradient rounded-full"
|
||||
} flex justify-center items-center text-base text-white`}
|
||||
onClick={navigateMarket}
|
||||
@@ -169,7 +170,7 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
) : accountType ? (
|
||||
"Find Task"
|
||||
) : (
|
||||
"Ask Parent For New Task"
|
||||
"Suggest tasks to your parent"
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,160 +1,127 @@
|
||||
import { useRef, useState } from "react";
|
||||
import OfferCard from "../Cards/OfferCard";
|
||||
import Icons from "../Helpers/Icons";
|
||||
import SliderCom from "../Helpers/SliderCom";
|
||||
|
||||
import OfferJobPopout from "../jobPopout/OfferJobPopout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
export default function MyOffersFamilyTable({ className, MyActiveOffersList }) {
|
||||
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
|
||||
const settings = {
|
||||
arrows: false,
|
||||
dots: false,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 4,
|
||||
autoplay: true,
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 1,
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
infinite: familyOffers?.length > 3,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 426,
|
||||
breakpoint: 1025,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
infinite: familyOffers?.length > 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 769,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
infinite: familyOffers?.length > 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 619,
|
||||
settings: {
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 2,
|
||||
infinite: familyOffers?.length > 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
console.log("YES WE SEE OFFERS", MyActiveOffersList);
|
||||
const sellSlider = useRef(null);
|
||||
//const buySlider = useRef(null);
|
||||
const prevHandler = (value) => {
|
||||
if (value === "sell") {
|
||||
sellSlider.current.slickPrev();
|
||||
}
|
||||
// if (value === "buy") {
|
||||
// buySlider.current.slickPrev();
|
||||
// }
|
||||
console.log("YES WE SEE OFFERS", familyOffers);
|
||||
|
||||
const trendingSlider = useRef(null);
|
||||
const prevHandler = () => {
|
||||
trendingSlider.current.slickPrev();
|
||||
};
|
||||
const nextHandler = (value) => {
|
||||
if (value === "sell") {
|
||||
sellSlider.current.slickNext();
|
||||
}
|
||||
// if (value === "buy") {
|
||||
// buySlider.current.slickNext();
|
||||
// }
|
||||
const nextHandler = () => {
|
||||
trendingSlider.current.slickNext();
|
||||
};
|
||||
|
||||
if (!MyActiveOffersList || MyActiveOffersList?.result_list?.length == 0) {
|
||||
if (!familyOffers || familyOffers?.result_list?.length == 0) {
|
||||
return ""; // want blank or no appear when no items
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`top-seller-top-buyer-wrapper ${className || ""}`}>
|
||||
<div className="top-seller-top-buyer-wrapper-container">
|
||||
<div className="main-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0 sm:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
|
||||
<div className="heading flex justify-between items-center mb-4">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
You Have Task(s) Waiting For You
|
||||
</h1>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button
|
||||
onClick={() => nextHandler("sell")}
|
||||
type="button"
|
||||
className="transform rotate-180 text-dark-gray dark:text-white dark:opacity-25"
|
||||
>
|
||||
<Icons name="arrows" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => prevHandler("sell")}
|
||||
type="button"
|
||||
className="transform rotate-180"
|
||||
>
|
||||
<div className=" text-dark-gray dark:text-white">
|
||||
<svg
|
||||
width="11"
|
||||
height="19"
|
||||
viewBox="0 0 11 19"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.09766 1.1499L1.13307 9.11449L9.09766 17.0791"
|
||||
stroke="url(#paint0_linear_220_23410)"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_220_23410"
|
||||
x1="9.09766"
|
||||
y1="1.1499"
|
||||
x2="-4.2474"
|
||||
y2="7.96749"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#F539F8" />
|
||||
<stop offset="0.416763" stopColor="#C342F9" />
|
||||
<stop offset="1" stopColor="#5356FB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="slider-content">
|
||||
<SliderCom settings={settings} selector={sellSlider}>
|
||||
{MyActiveOffersList &&
|
||||
MyActiveOffersList?.result_list?.length > 0 &&
|
||||
MyActiveOffersList?.result_list?.map((value, index) => {
|
||||
let thePrice = PriceFormatter(
|
||||
value?.price * 0.01,
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
return (
|
||||
<div className="item" key={index}>
|
||||
<div className="offer-slide-item flex flex-col justify-between items-center">
|
||||
{/* title */}
|
||||
<div className="flex justify-center">
|
||||
<p className="text-xl text-dark-gray dark:text-white font-bold mb-2">
|
||||
{value.title}
|
||||
</p>
|
||||
</div>
|
||||
{/* username */}
|
||||
<div className="flex flex-col justify-center my-1">
|
||||
<p className="text-xs text-thin-light-gray">
|
||||
{value.timeline_days} Days
|
||||
</p>
|
||||
<div className="my-2 flex space-x-1 items-center text-purple text-xs">
|
||||
<span>{thePrice}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setOfferPopout({
|
||||
show: true,
|
||||
data: {...value, thePrice },
|
||||
});
|
||||
}}
|
||||
className="w-20 h-11 self-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Start Task
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</SliderCom>
|
||||
</div>
|
||||
<div
|
||||
className={`trending-section w-full px-2 sm:px-0 ${className || ""}`}
|
||||
>
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Ready to Start?
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-3">
|
||||
<button onClick={nextHandler} type="button">
|
||||
<div className="trending-slider-left-btn relative text-white w-10 h-10 flex justify-center items-center rounded-full overflow-hidden">
|
||||
<svg
|
||||
width="11"
|
||||
height="19"
|
||||
viewBox="0 0 11 19"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.09766 1.1499L1.13307 9.11449L9.09766 17.0791"
|
||||
stroke="url(#paint0_linear_220_23410)"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_220_23410"
|
||||
x1="9.09766"
|
||||
y1="1.1499"
|
||||
x2="-4.2474"
|
||||
y2="7.96749"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#F539F8" />
|
||||
<stop offset="0.416763" stopColor="#C342F9" />
|
||||
<stop offset="1" stopColor="#5356FB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
<button onClick={prevHandler} type="button">
|
||||
<div className="trending-slider-right-btn primary-gradient text-white w-10 h-10 relative flex justify-center items-center rounded-full ">
|
||||
<Icons name="arrows" />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/* trending products */}
|
||||
<div className="trending-products slider-left relative w-full rounded-2xl p-[10px] bg-alice-blue">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{familyOffers &&
|
||||
familyOffers.length > 0 &&
|
||||
familyOffers.map((item) => {
|
||||
return (
|
||||
<OfferCard
|
||||
key={item.id}
|
||||
datas={item}
|
||||
setOfferPopout={setOfferPopout}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</SliderCom>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,35 +1,45 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import top from "../../assets/images/top-buyer-1png.png";
|
||||
import top2 from "../../assets/images/top-buyer-2.png";
|
||||
import top3 from "../../assets/images/top-buyer-3.png";
|
||||
import top4 from "../../assets/images/top-buyer-4.png";
|
||||
import Icons from "../Helpers/Icons";
|
||||
import SliderCom from "../Helpers/SliderCom";
|
||||
|
||||
import OfferCard from "../Cards/OfferCard";
|
||||
import OfferJobPopout from "../jobPopout/OfferJobPopout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
export default function MyOffersTable({ className, MyActiveOffersList }) {
|
||||
let [offerPopout, setOfferPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||
|
||||
const settings = {
|
||||
arrows: false,
|
||||
dots: false,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 4,
|
||||
autoplay: true,
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 1,
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 3,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 426,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 1,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 2,
|
||||
{
|
||||
breakpoint: 1025,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 769,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 619,
|
||||
settings: {
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
infinite: MyActiveOffersList?.result_list?.length > 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
console.log("YES WE SEE OFFERS", MyActiveOffersList);
|
||||
const sellSlider = useRef(null);
|
||||
@@ -58,344 +68,64 @@ export default function MyOffersTable({ className, MyActiveOffersList }) {
|
||||
return (
|
||||
<>
|
||||
<div className={`top-seller-top-buyer-wrapper ${className || ""}`}>
|
||||
<div className="top-seller-top-buyer-wrapper-container">
|
||||
<div className="main-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0 sm:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
|
||||
<div className="heading flex justify-between items-center mb-4">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Offers
|
||||
</h1>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button
|
||||
onClick={() => nextHandler("sell")}
|
||||
type="button"
|
||||
className="transform rotate-180 text-dark-gray dark:text-white dark:opacity-25"
|
||||
>
|
||||
<Icons name="arrows" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => prevHandler("sell")}
|
||||
type="button"
|
||||
className="transform rotate-180"
|
||||
>
|
||||
<div className=" text-dark-gray dark:text-white">
|
||||
<svg
|
||||
width="11"
|
||||
height="19"
|
||||
viewBox="0 0 11 19"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.09766 1.1499L1.13307 9.11449L9.09766 17.0791"
|
||||
stroke="url(#paint0_linear_220_23410)"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_220_23410"
|
||||
x1="9.09766"
|
||||
y1="1.1499"
|
||||
x2="-4.2474"
|
||||
y2="7.96749"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
<div className={`trending-section w-full px-2 sm:px-0 ${className || ""}`}>
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Ready to Start?</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-3">
|
||||
<button onClick={() => nextHandler("sell")} type="button">
|
||||
<div className="trending-slider-left-btn relative text-white w-10 h-10 flex justify-center items-center rounded-full overflow-hidden">
|
||||
<svg
|
||||
width="11"
|
||||
height="19"
|
||||
viewBox="0 0 11 19"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<stop stopColor="#F539F8" />
|
||||
<stop offset="0.416763" stopColor="#C342F9" />
|
||||
<stop offset="1" stopColor="#5356FB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
<path
|
||||
d="M9.09766 1.1499L1.13307 9.11449L9.09766 17.0791"
|
||||
stroke="url(#paint0_linear_220_23410)"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_220_23410"
|
||||
x1="9.09766"
|
||||
y1="1.1499"
|
||||
x2="-4.2474"
|
||||
y2="7.96749"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#F539F8" />
|
||||
<stop offset="0.416763" stopColor="#C342F9" />
|
||||
<stop offset="1" stopColor="#5356FB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
<button onClick={() => prevHandler("sell")} type="button">
|
||||
<div className="trending-slider-right-btn primary-gradient text-white w-10 h-10 relative flex justify-center items-center rounded-full ">
|
||||
<Icons name="arrows" />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="slider-content">
|
||||
<SliderCom settings={settings} selector={sellSlider}>
|
||||
</div>
|
||||
{/* trending products */}
|
||||
<div className="trending-products slider-left relative w-full rounded-2xl p-[10px] bg-alice-blue">
|
||||
<SliderCom selector={sellSlider} settings={settings}>
|
||||
{MyActiveOffersList &&
|
||||
MyActiveOffersList?.result_list?.length > 0 &&
|
||||
MyActiveOffersList?.result_list?.map((value, index) => {
|
||||
let thePrice = PriceFormatter(
|
||||
value?.price * 0.01,
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
return (
|
||||
<div className="item" key={index}>
|
||||
<div className="offer-slide-item flex flex-col justify-between items-center">
|
||||
{/* title */}
|
||||
<div className="flex justify-center">
|
||||
<p className="text-xl text-dark-gray dark:text-white font-bold mb-2">
|
||||
{value.title}
|
||||
</p>
|
||||
</div>
|
||||
{/* username */}
|
||||
<div className="flex flex-col justify-center my-1">
|
||||
<p className="text-xs text-thin-light-gray">
|
||||
{value.timeline_days} Days
|
||||
</p>
|
||||
<div className="my-2 flex space-x-1 items-center text-purple text-xs">
|
||||
<span>{thePrice}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setOfferPopout({
|
||||
show: true,
|
||||
data: {...value, thePrice },
|
||||
});
|
||||
}}
|
||||
className="w-20 h-11 self-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Start Task
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* <div className="item">*/}
|
||||
{/* /!* img *!/*/}
|
||||
{/* <div className="flex justify-center mb-4">*/}
|
||||
{/* <div className=" w-14 h-14 relative">*/}
|
||||
{/* <img src={top2} alt="top" className="w-full h-full" />*/}
|
||||
{/* <div className="absolute right-0 top-0">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="18"*/}
|
||||
{/* height="17"*/}
|
||||
{/* viewBox="0 0 18 17"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M13.3341 14.7394C12.8954 14.7394 12.4564 14.7416 12.0177 14.7375C11.9347 14.7367 11.8877 14.7647 11.8451 14.835C11.4401 15.4977 11.0288 16.1565 10.6273 16.8213C10.5678 16.9196 10.5247 16.9134 10.444 16.8631C9.84979 16.4937 9.25283 16.1283 8.65967 15.7566C8.58338 15.7089 8.53208 15.708 8.45471 15.755C7.84092 16.1275 7.22251 16.4926 6.60872 16.865C6.51805 16.9202 6.48086 16.9117 6.42548 16.8178C6.03646 16.1562 5.63903 15.4993 5.24757 14.8391C5.20251 14.7628 5.15066 14.7373 5.06297 14.7375C4.23961 14.7408 3.41652 14.7397 2.59315 14.7392C2.38765 14.7392 2.41561 14.7563 2.41561 14.5549C2.4148 13.7182 2.41371 12.8812 2.41724 12.0446C2.41778 11.9479 2.39145 11.892 2.30539 11.8396C1.59985 11.4093 0.899185 10.9712 0.193637 10.5406C0.10921 10.4891 0.0950937 10.4578 0.149387 10.3707C0.541931 9.74279 0.926874 9.11 1.31969 8.48236C1.36855 8.40445 1.36611 8.35423 1.31969 8.27768C0.968138 7.69863 0.624187 7.11497 0.272634 6.5362C0.221055 6.45151 0.238972 6.41974 0.317427 6.37332C0.985783 5.97779 1.65088 5.57656 2.31978 5.18157C2.39905 5.13488 2.41751 5.08167 2.41724 4.99697C2.41452 4.12855 2.41778 3.26012 2.41317 2.39169C2.41262 2.27306 2.43624 2.23152 2.566 2.23261C3.39371 2.23912 4.22142 2.23478 5.0494 2.23777C5.13627 2.23804 5.18459 2.21388 5.23183 2.13651C5.64989 1.44996 6.07501 0.767762 6.49497 0.0823035C6.54574 -0.000494485 6.57994 -0.0284558 6.6793 0.0339821C7.333 0.444986 7.99321 0.845131 8.64799 1.25423C8.73351 1.30771 8.79459 1.30799 8.87874 1.25695C9.44231 0.914355 10.01 0.57882 10.5727 0.23514C10.6764 0.171888 10.7209 0.179218 10.7855 0.289706C11.1428 0.901868 11.512 1.50697 11.8725 2.11723C11.9244 2.20492 11.98 2.23939 12.0853 2.23885C12.9402 2.23369 13.795 2.23804 14.6499 2.23342C14.7604 2.23288 14.7943 2.25948 14.7935 2.37404C14.7886 3.21994 14.7921 4.06557 14.7889 4.91146C14.7886 5.0024 14.8133 5.0548 14.895 5.10475C15.5699 5.51575 16.2391 5.93653 16.9156 6.34509C17.0269 6.41241 17.0179 6.45965 16.9596 6.55276C16.5741 7.16927 16.1956 7.79012 15.8085 8.40554C15.742 8.51114 15.7417 8.58742 15.808 8.69574C16.1799 9.3041 16.5396 9.92006 16.9115 10.5287C16.9756 10.6335 16.959 10.6747 16.8597 10.7331C16.2062 11.1186 15.5574 11.5114 14.9037 11.8964C14.8179 11.9468 14.7881 12.0011 14.7886 12.0991C14.7924 12.9315 14.7889 13.7635 14.7932 14.5958C14.7938 14.7074 14.7645 14.7432 14.6499 14.7416C14.2117 14.7359 13.7728 14.7397 13.3341 14.7394ZM6.15184 8.14086C6.10596 8.18103 6.07881 8.20356 6.05329 8.22745C5.80979 8.45685 5.56655 8.68651 5.32358 8.91644C5.15283 9.07824 5.15093 9.08068 5.3111 9.25143C6.0723 10.062 6.8354 10.871 7.59551 11.6824C7.65577 11.7468 7.69975 11.7546 7.75703 11.6854C7.78282 11.6545 7.81676 11.6306 7.84662 11.6026C8.54565 10.9473 9.24522 10.2922 9.94399 9.63665C10.788 8.84477 11.6304 8.05154 12.4765 7.26184C12.5436 7.1994 12.5257 7.16954 12.4735 7.11497C12.2488 6.87934 12.0234 6.64398 11.8087 6.39965C11.7205 6.29921 11.67 6.30926 11.5777 6.3964C10.3569 7.54661 9.13148 8.69194 7.91014 9.84161C7.83223 9.9149 7.79395 9.91246 7.72201 9.83509C7.22034 9.29568 6.71323 8.76116 6.20857 8.2242C6.18713 8.20194 6.17301 8.17262 6.15184 8.14086Z"*/}
|
||||
{/* fill="#3897EF"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* title *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <p className="text-base font-bold text-dark-gray dark:text-white">*/}
|
||||
{/* Brokln Simons*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* username *!/*/}
|
||||
{/* <div className="flex justify-center mb-1">*/}
|
||||
{/* <p className="text-xs text-thin-light-gray">*/}
|
||||
{/* @broklinslam_75*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* items *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <div className="flex space-x-1 items-center text-purple text-xs">*/}
|
||||
{/*<span>*/}
|
||||
{/* <svg*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* width="13"*/}
|
||||
{/* height="11"*/}
|
||||
{/* viewBox="0 0 13 11"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path d="M6.49948 11.0002C6.45633 10.9222 6.44195 10.8402 6.41935 10.7642C5.68171 8.2937 4.94614 5.82125 4.20645 3.35081C4.18385 3.27679 4.19001 3.25879 4.27836 3.25879C5.71459 3.28079 7.15287 3.2968 8.5891 3.3168C8.698 3.3188 8.698 3.3188 8.66923 3.42482C7.9542 5.92527 7.23917 8.42573 6.52414 10.9242C6.51797 10.9462 6.50975 10.9682 6.49948 11.0002Z" />*/}
|
||||
{/* <path d="M13.0002 3.25468C10.9619 5.75913 8.93804 8.24759 6.91418 10.736C6.88952 10.71 6.91007 10.69 6.91623 10.67C7.60866 8.24959 8.30109 5.82715 8.99352 3.40671C9.00585 3.3607 9.04489 3.34269 9.07776 3.31469C9.20515 3.19867 9.34898 3.25868 9.48048 3.25868C10.6147 3.25268 11.7489 3.25468 12.883 3.25468C12.9159 3.25468 12.9467 3.25468 13.0002 3.25468Z" />*/}
|
||||
{/* <path d="M0 3.25444C0.0472578 3.25444 0.0739687 3.25444 0.10068 3.25444C1.32322 3.25444 2.5437 3.25444 3.76624 3.25244C3.82994 3.25244 3.86281 3.26444 3.88336 3.33046C4.59428 5.72089 5.30725 8.11132 6.01818 10.5018C6.02845 10.5338 6.04694 10.5638 6.03667 10.6078C4.02513 8.15933 2.01976 5.71489 0 3.25444Z" />*/}
|
||||
{/* <path d="M8.66592 2.93668C7.16189 2.93668 5.67224 2.93668 4.18054 2.93668C4.17438 2.90268 4.20314 2.88867 4.21753 2.86867C4.94899 1.96651 5.68046 1.06434 6.40988 0.160178C6.44275 0.120171 6.45919 0.0821637 6.51261 0.150176C7.21942 1.06634 7.93034 1.98051 8.63921 2.89668C8.64743 2.90668 8.65154 2.91668 8.66592 2.93668Z" />*/}
|
||||
{/* <path d="M2.70399 0.129883C3.0615 1.07205 3.41491 2.00222 3.77037 2.93639C2.52729 2.93639 1.29448 2.93639 0.0390625 2.93639C0.930796 1.99622 1.81226 1.06805 2.70399 0.129883Z" />*/}
|
||||
{/* <path d="M12.9687 2.9386C12.7324 2.9386 12.5166 2.9386 12.3009 2.9386C11.3126 2.9386 10.3263 2.9386 9.33803 2.9386C9.28255 2.9386 9.25173 2.9406 9.2805 2.86859C9.63185 1.97642 9.98115 1.08226 10.3304 0.190099C10.3366 0.174096 10.3387 0.154092 10.3633 0.14209C11.2263 1.06826 12.0913 1.99643 12.9687 2.9386Z" />*/}
|
||||
{/* <path d="M8.97094 2.81832C8.24152 1.87815 7.52238 0.947984 6.79297 0.0078125C7.89223 0.0078125 8.9771 0.0078125 10.0702 0.0078125C9.70651 0.939982 9.34283 1.87015 8.97094 2.81832Z" />*/}
|
||||
{/* <path d="M3.99333 2.65048C3.66252 1.78032 3.33994 0.930169 3.01735 0.0780142C2.99886 0.0320058 2.97626 0 3.0605 0C4.07962 0.00200036 5.09875 0.00200036 6.13842 0.00200036C5.42133 0.888161 4.71247 1.76432 3.99333 2.65048Z" />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* <span>3435 Items</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="item">*/}
|
||||
{/* /!* img *!/*/}
|
||||
{/* <div className="flex justify-center mb-4">*/}
|
||||
{/* <div className=" w-14 h-14 relative">*/}
|
||||
{/* <img src={top3} alt="top" className="w-full h-full" />*/}
|
||||
{/* <div className="absolute right-0 top-0">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="18"*/}
|
||||
{/* height="17"*/}
|
||||
{/* viewBox="0 0 18 17"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M13.3341 14.7394C12.8954 14.7394 12.4564 14.7416 12.0177 14.7375C11.9347 14.7367 11.8877 14.7647 11.8451 14.835C11.4401 15.4977 11.0288 16.1565 10.6273 16.8213C10.5678 16.9196 10.5247 16.9134 10.444 16.8631C9.84979 16.4937 9.25283 16.1283 8.65967 15.7566C8.58338 15.7089 8.53208 15.708 8.45471 15.755C7.84092 16.1275 7.22251 16.4926 6.60872 16.865C6.51805 16.9202 6.48086 16.9117 6.42548 16.8178C6.03646 16.1562 5.63903 15.4993 5.24757 14.8391C5.20251 14.7628 5.15066 14.7373 5.06297 14.7375C4.23961 14.7408 3.41652 14.7397 2.59315 14.7392C2.38765 14.7392 2.41561 14.7563 2.41561 14.5549C2.4148 13.7182 2.41371 12.8812 2.41724 12.0446C2.41778 11.9479 2.39145 11.892 2.30539 11.8396C1.59985 11.4093 0.899185 10.9712 0.193637 10.5406C0.10921 10.4891 0.0950937 10.4578 0.149387 10.3707C0.541931 9.74279 0.926874 9.11 1.31969 8.48236C1.36855 8.40445 1.36611 8.35423 1.31969 8.27768C0.968138 7.69863 0.624187 7.11497 0.272634 6.5362C0.221055 6.45151 0.238972 6.41974 0.317427 6.37332C0.985783 5.97779 1.65088 5.57656 2.31978 5.18157C2.39905 5.13488 2.41751 5.08167 2.41724 4.99697C2.41452 4.12855 2.41778 3.26012 2.41317 2.39169C2.41262 2.27306 2.43624 2.23152 2.566 2.23261C3.39371 2.23912 4.22142 2.23478 5.0494 2.23777C5.13627 2.23804 5.18459 2.21388 5.23183 2.13651C5.64989 1.44996 6.07501 0.767762 6.49497 0.0823035C6.54574 -0.000494485 6.57994 -0.0284558 6.6793 0.0339821C7.333 0.444986 7.99321 0.845131 8.64799 1.25423C8.73351 1.30771 8.79459 1.30799 8.87874 1.25695C9.44231 0.914355 10.01 0.57882 10.5727 0.23514C10.6764 0.171888 10.7209 0.179218 10.7855 0.289706C11.1428 0.901868 11.512 1.50697 11.8725 2.11723C11.9244 2.20492 11.98 2.23939 12.0853 2.23885C12.9402 2.23369 13.795 2.23804 14.6499 2.23342C14.7604 2.23288 14.7943 2.25948 14.7935 2.37404C14.7886 3.21994 14.7921 4.06557 14.7889 4.91146C14.7886 5.0024 14.8133 5.0548 14.895 5.10475C15.5699 5.51575 16.2391 5.93653 16.9156 6.34509C17.0269 6.41241 17.0179 6.45965 16.9596 6.55276C16.5741 7.16927 16.1956 7.79012 15.8085 8.40554C15.742 8.51114 15.7417 8.58742 15.808 8.69574C16.1799 9.3041 16.5396 9.92006 16.9115 10.5287C16.9756 10.6335 16.959 10.6747 16.8597 10.7331C16.2062 11.1186 15.5574 11.5114 14.9037 11.8964C14.8179 11.9468 14.7881 12.0011 14.7886 12.0991C14.7924 12.9315 14.7889 13.7635 14.7932 14.5958C14.7938 14.7074 14.7645 14.7432 14.6499 14.7416C14.2117 14.7359 13.7728 14.7397 13.3341 14.7394ZM6.15184 8.14086C6.10596 8.18103 6.07881 8.20356 6.05329 8.22745C5.80979 8.45685 5.56655 8.68651 5.32358 8.91644C5.15283 9.07824 5.15093 9.08068 5.3111 9.25143C6.0723 10.062 6.8354 10.871 7.59551 11.6824C7.65577 11.7468 7.69975 11.7546 7.75703 11.6854C7.78282 11.6545 7.81676 11.6306 7.84662 11.6026C8.54565 10.9473 9.24522 10.2922 9.94399 9.63665C10.788 8.84477 11.6304 8.05154 12.4765 7.26184C12.5436 7.1994 12.5257 7.16954 12.4735 7.11497C12.2488 6.87934 12.0234 6.64398 11.8087 6.39965C11.7205 6.29921 11.67 6.30926 11.5777 6.3964C10.3569 7.54661 9.13148 8.69194 7.91014 9.84161C7.83223 9.9149 7.79395 9.91246 7.72201 9.83509C7.22034 9.29568 6.71323 8.76116 6.20857 8.2242C6.18713 8.20194 6.17301 8.17262 6.15184 8.14086Z"*/}
|
||||
{/* fill="#3897EF"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* title *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <p className="text-base font-bold text-dark-gray dark:text-white">*/}
|
||||
{/* Brokln Simons*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* username *!/*/}
|
||||
{/* <div className="flex justify-center mb-1">*/}
|
||||
{/* <p className="text-xs text-thin-light-gray">*/}
|
||||
{/* @broklinslam_75*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* items *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <div className="flex space-x-1 items-center text-purple text-xs">*/}
|
||||
{/*<span>*/}
|
||||
{/* <svg*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* width="13"*/}
|
||||
{/* height="11"*/}
|
||||
{/* viewBox="0 0 13 11"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path d="M6.49948 11.0002C6.45633 10.9222 6.44195 10.8402 6.41935 10.7642C5.68171 8.2937 4.94614 5.82125 4.20645 3.35081C4.18385 3.27679 4.19001 3.25879 4.27836 3.25879C5.71459 3.28079 7.15287 3.2968 8.5891 3.3168C8.698 3.3188 8.698 3.3188 8.66923 3.42482C7.9542 5.92527 7.23917 8.42573 6.52414 10.9242C6.51797 10.9462 6.50975 10.9682 6.49948 11.0002Z" />*/}
|
||||
{/* <path d="M13.0002 3.25468C10.9619 5.75913 8.93804 8.24759 6.91418 10.736C6.88952 10.71 6.91007 10.69 6.91623 10.67C7.60866 8.24959 8.30109 5.82715 8.99352 3.40671C9.00585 3.3607 9.04489 3.34269 9.07776 3.31469C9.20515 3.19867 9.34898 3.25868 9.48048 3.25868C10.6147 3.25268 11.7489 3.25468 12.883 3.25468C12.9159 3.25468 12.9467 3.25468 13.0002 3.25468Z" />*/}
|
||||
{/* <path d="M0 3.25444C0.0472578 3.25444 0.0739687 3.25444 0.10068 3.25444C1.32322 3.25444 2.5437 3.25444 3.76624 3.25244C3.82994 3.25244 3.86281 3.26444 3.88336 3.33046C4.59428 5.72089 5.30725 8.11132 6.01818 10.5018C6.02845 10.5338 6.04694 10.5638 6.03667 10.6078C4.02513 8.15933 2.01976 5.71489 0 3.25444Z" />*/}
|
||||
{/* <path d="M8.66592 2.93668C7.16189 2.93668 5.67224 2.93668 4.18054 2.93668C4.17438 2.90268 4.20314 2.88867 4.21753 2.86867C4.94899 1.96651 5.68046 1.06434 6.40988 0.160178C6.44275 0.120171 6.45919 0.0821637 6.51261 0.150176C7.21942 1.06634 7.93034 1.98051 8.63921 2.89668C8.64743 2.90668 8.65154 2.91668 8.66592 2.93668Z" />*/}
|
||||
{/* <path d="M2.70399 0.129883C3.0615 1.07205 3.41491 2.00222 3.77037 2.93639C2.52729 2.93639 1.29448 2.93639 0.0390625 2.93639C0.930796 1.99622 1.81226 1.06805 2.70399 0.129883Z" />*/}
|
||||
{/* <path d="M12.9687 2.9386C12.7324 2.9386 12.5166 2.9386 12.3009 2.9386C11.3126 2.9386 10.3263 2.9386 9.33803 2.9386C9.28255 2.9386 9.25173 2.9406 9.2805 2.86859C9.63185 1.97642 9.98115 1.08226 10.3304 0.190099C10.3366 0.174096 10.3387 0.154092 10.3633 0.14209C11.2263 1.06826 12.0913 1.99643 12.9687 2.9386Z" />*/}
|
||||
{/* <path d="M8.97094 2.81832C8.24152 1.87815 7.52238 0.947984 6.79297 0.0078125C7.89223 0.0078125 8.9771 0.0078125 10.0702 0.0078125C9.70651 0.939982 9.34283 1.87015 8.97094 2.81832Z" />*/}
|
||||
{/* <path d="M3.99333 2.65048C3.66252 1.78032 3.33994 0.930169 3.01735 0.0780142C2.99886 0.0320058 2.97626 0 3.0605 0C4.07962 0.00200036 5.09875 0.00200036 6.13842 0.00200036C5.42133 0.888161 4.71247 1.76432 3.99333 2.65048Z" />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* <span>3435 Items</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="item">*/}
|
||||
{/* /!* img *!/*/}
|
||||
{/* <div className="flex justify-center mb-4">*/}
|
||||
{/* <div className=" w-14 h-14 relative">*/}
|
||||
{/* <img src={top4} alt="top" className="w-full h-full" />*/}
|
||||
{/* <div className="absolute right-0 top-0">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="18"*/}
|
||||
{/* height="17"*/}
|
||||
{/* viewBox="0 0 18 17"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M13.3341 14.7394C12.8954 14.7394 12.4564 14.7416 12.0177 14.7375C11.9347 14.7367 11.8877 14.7647 11.8451 14.835C11.4401 15.4977 11.0288 16.1565 10.6273 16.8213C10.5678 16.9196 10.5247 16.9134 10.444 16.8631C9.84979 16.4937 9.25283 16.1283 8.65967 15.7566C8.58338 15.7089 8.53208 15.708 8.45471 15.755C7.84092 16.1275 7.22251 16.4926 6.60872 16.865C6.51805 16.9202 6.48086 16.9117 6.42548 16.8178C6.03646 16.1562 5.63903 15.4993 5.24757 14.8391C5.20251 14.7628 5.15066 14.7373 5.06297 14.7375C4.23961 14.7408 3.41652 14.7397 2.59315 14.7392C2.38765 14.7392 2.41561 14.7563 2.41561 14.5549C2.4148 13.7182 2.41371 12.8812 2.41724 12.0446C2.41778 11.9479 2.39145 11.892 2.30539 11.8396C1.59985 11.4093 0.899185 10.9712 0.193637 10.5406C0.10921 10.4891 0.0950937 10.4578 0.149387 10.3707C0.541931 9.74279 0.926874 9.11 1.31969 8.48236C1.36855 8.40445 1.36611 8.35423 1.31969 8.27768C0.968138 7.69863 0.624187 7.11497 0.272634 6.5362C0.221055 6.45151 0.238972 6.41974 0.317427 6.37332C0.985783 5.97779 1.65088 5.57656 2.31978 5.18157C2.39905 5.13488 2.41751 5.08167 2.41724 4.99697C2.41452 4.12855 2.41778 3.26012 2.41317 2.39169C2.41262 2.27306 2.43624 2.23152 2.566 2.23261C3.39371 2.23912 4.22142 2.23478 5.0494 2.23777C5.13627 2.23804 5.18459 2.21388 5.23183 2.13651C5.64989 1.44996 6.07501 0.767762 6.49497 0.0823035C6.54574 -0.000494485 6.57994 -0.0284558 6.6793 0.0339821C7.333 0.444986 7.99321 0.845131 8.64799 1.25423C8.73351 1.30771 8.79459 1.30799 8.87874 1.25695C9.44231 0.914355 10.01 0.57882 10.5727 0.23514C10.6764 0.171888 10.7209 0.179218 10.7855 0.289706C11.1428 0.901868 11.512 1.50697 11.8725 2.11723C11.9244 2.20492 11.98 2.23939 12.0853 2.23885C12.9402 2.23369 13.795 2.23804 14.6499 2.23342C14.7604 2.23288 14.7943 2.25948 14.7935 2.37404C14.7886 3.21994 14.7921 4.06557 14.7889 4.91146C14.7886 5.0024 14.8133 5.0548 14.895 5.10475C15.5699 5.51575 16.2391 5.93653 16.9156 6.34509C17.0269 6.41241 17.0179 6.45965 16.9596 6.55276C16.5741 7.16927 16.1956 7.79012 15.8085 8.40554C15.742 8.51114 15.7417 8.58742 15.808 8.69574C16.1799 9.3041 16.5396 9.92006 16.9115 10.5287C16.9756 10.6335 16.959 10.6747 16.8597 10.7331C16.2062 11.1186 15.5574 11.5114 14.9037 11.8964C14.8179 11.9468 14.7881 12.0011 14.7886 12.0991C14.7924 12.9315 14.7889 13.7635 14.7932 14.5958C14.7938 14.7074 14.7645 14.7432 14.6499 14.7416C14.2117 14.7359 13.7728 14.7397 13.3341 14.7394ZM6.15184 8.14086C6.10596 8.18103 6.07881 8.20356 6.05329 8.22745C5.80979 8.45685 5.56655 8.68651 5.32358 8.91644C5.15283 9.07824 5.15093 9.08068 5.3111 9.25143C6.0723 10.062 6.8354 10.871 7.59551 11.6824C7.65577 11.7468 7.69975 11.7546 7.75703 11.6854C7.78282 11.6545 7.81676 11.6306 7.84662 11.6026C8.54565 10.9473 9.24522 10.2922 9.94399 9.63665C10.788 8.84477 11.6304 8.05154 12.4765 7.26184C12.5436 7.1994 12.5257 7.16954 12.4735 7.11497C12.2488 6.87934 12.0234 6.64398 11.8087 6.39965C11.7205 6.29921 11.67 6.30926 11.5777 6.3964C10.3569 7.54661 9.13148 8.69194 7.91014 9.84161C7.83223 9.9149 7.79395 9.91246 7.72201 9.83509C7.22034 9.29568 6.71323 8.76116 6.20857 8.2242C6.18713 8.20194 6.17301 8.17262 6.15184 8.14086Z"*/}
|
||||
{/* fill="#3897EF"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* title *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <p className="text-base font-bold text-dark-gray dark:text-white">*/}
|
||||
{/* Brokln Simons*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* username *!/*/}
|
||||
{/* <div className="flex justify-center mb-1">*/}
|
||||
{/* <p className="text-xs text-thin-light-gray">*/}
|
||||
{/* @broklinslam_75*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* items *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <div className="flex space-x-1 items-center text-purple text-xs">*/}
|
||||
{/*<span>*/}
|
||||
{/* <svg*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* width="13"*/}
|
||||
{/* height="11"*/}
|
||||
{/* viewBox="0 0 13 11"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path d="M6.49948 11.0002C6.45633 10.9222 6.44195 10.8402 6.41935 10.7642C5.68171 8.2937 4.94614 5.82125 4.20645 3.35081C4.18385 3.27679 4.19001 3.25879 4.27836 3.25879C5.71459 3.28079 7.15287 3.2968 8.5891 3.3168C8.698 3.3188 8.698 3.3188 8.66923 3.42482C7.9542 5.92527 7.23917 8.42573 6.52414 10.9242C6.51797 10.9462 6.50975 10.9682 6.49948 11.0002Z" />*/}
|
||||
{/* <path d="M13.0002 3.25468C10.9619 5.75913 8.93804 8.24759 6.91418 10.736C6.88952 10.71 6.91007 10.69 6.91623 10.67C7.60866 8.24959 8.30109 5.82715 8.99352 3.40671C9.00585 3.3607 9.04489 3.34269 9.07776 3.31469C9.20515 3.19867 9.34898 3.25868 9.48048 3.25868C10.6147 3.25268 11.7489 3.25468 12.883 3.25468C12.9159 3.25468 12.9467 3.25468 13.0002 3.25468Z" />*/}
|
||||
{/* <path d="M0 3.25444C0.0472578 3.25444 0.0739687 3.25444 0.10068 3.25444C1.32322 3.25444 2.5437 3.25444 3.76624 3.25244C3.82994 3.25244 3.86281 3.26444 3.88336 3.33046C4.59428 5.72089 5.30725 8.11132 6.01818 10.5018C6.02845 10.5338 6.04694 10.5638 6.03667 10.6078C4.02513 8.15933 2.01976 5.71489 0 3.25444Z" />*/}
|
||||
{/* <path d="M8.66592 2.93668C7.16189 2.93668 5.67224 2.93668 4.18054 2.93668C4.17438 2.90268 4.20314 2.88867 4.21753 2.86867C4.94899 1.96651 5.68046 1.06434 6.40988 0.160178C6.44275 0.120171 6.45919 0.0821637 6.51261 0.150176C7.21942 1.06634 7.93034 1.98051 8.63921 2.89668C8.64743 2.90668 8.65154 2.91668 8.66592 2.93668Z" />*/}
|
||||
{/* <path d="M2.70399 0.129883C3.0615 1.07205 3.41491 2.00222 3.77037 2.93639C2.52729 2.93639 1.29448 2.93639 0.0390625 2.93639C0.930796 1.99622 1.81226 1.06805 2.70399 0.129883Z" />*/}
|
||||
{/* <path d="M12.9687 2.9386C12.7324 2.9386 12.5166 2.9386 12.3009 2.9386C11.3126 2.9386 10.3263 2.9386 9.33803 2.9386C9.28255 2.9386 9.25173 2.9406 9.2805 2.86859C9.63185 1.97642 9.98115 1.08226 10.3304 0.190099C10.3366 0.174096 10.3387 0.154092 10.3633 0.14209C11.2263 1.06826 12.0913 1.99643 12.9687 2.9386Z" />*/}
|
||||
{/* <path d="M8.97094 2.81832C8.24152 1.87815 7.52238 0.947984 6.79297 0.0078125C7.89223 0.0078125 8.9771 0.0078125 10.0702 0.0078125C9.70651 0.939982 9.34283 1.87015 8.97094 2.81832Z" />*/}
|
||||
{/* <path d="M3.99333 2.65048C3.66252 1.78032 3.33994 0.930169 3.01735 0.0780142C2.99886 0.0320058 2.97626 0 3.0605 0C4.07962 0.00200036 5.09875 0.00200036 6.13842 0.00200036C5.42133 0.888161 4.71247 1.76432 3.99333 2.65048Z" />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* <span>3435 Items</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="item">*/}
|
||||
{/* /!* img *!/*/}
|
||||
{/* <div className="flex justify-center mb-4">*/}
|
||||
{/* <div className=" w-14 h-14 relative">*/}
|
||||
{/* <img src={top3} alt="top" className="w-full h-full" />*/}
|
||||
{/* <div className="absolute right-0 top-0">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="18"*/}
|
||||
{/* height="17"*/}
|
||||
{/* viewBox="0 0 18 17"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M13.3341 14.7394C12.8954 14.7394 12.4564 14.7416 12.0177 14.7375C11.9347 14.7367 11.8877 14.7647 11.8451 14.835C11.4401 15.4977 11.0288 16.1565 10.6273 16.8213C10.5678 16.9196 10.5247 16.9134 10.444 16.8631C9.84979 16.4937 9.25283 16.1283 8.65967 15.7566C8.58338 15.7089 8.53208 15.708 8.45471 15.755C7.84092 16.1275 7.22251 16.4926 6.60872 16.865C6.51805 16.9202 6.48086 16.9117 6.42548 16.8178C6.03646 16.1562 5.63903 15.4993 5.24757 14.8391C5.20251 14.7628 5.15066 14.7373 5.06297 14.7375C4.23961 14.7408 3.41652 14.7397 2.59315 14.7392C2.38765 14.7392 2.41561 14.7563 2.41561 14.5549C2.4148 13.7182 2.41371 12.8812 2.41724 12.0446C2.41778 11.9479 2.39145 11.892 2.30539 11.8396C1.59985 11.4093 0.899185 10.9712 0.193637 10.5406C0.10921 10.4891 0.0950937 10.4578 0.149387 10.3707C0.541931 9.74279 0.926874 9.11 1.31969 8.48236C1.36855 8.40445 1.36611 8.35423 1.31969 8.27768C0.968138 7.69863 0.624187 7.11497 0.272634 6.5362C0.221055 6.45151 0.238972 6.41974 0.317427 6.37332C0.985783 5.97779 1.65088 5.57656 2.31978 5.18157C2.39905 5.13488 2.41751 5.08167 2.41724 4.99697C2.41452 4.12855 2.41778 3.26012 2.41317 2.39169C2.41262 2.27306 2.43624 2.23152 2.566 2.23261C3.39371 2.23912 4.22142 2.23478 5.0494 2.23777C5.13627 2.23804 5.18459 2.21388 5.23183 2.13651C5.64989 1.44996 6.07501 0.767762 6.49497 0.0823035C6.54574 -0.000494485 6.57994 -0.0284558 6.6793 0.0339821C7.333 0.444986 7.99321 0.845131 8.64799 1.25423C8.73351 1.30771 8.79459 1.30799 8.87874 1.25695C9.44231 0.914355 10.01 0.57882 10.5727 0.23514C10.6764 0.171888 10.7209 0.179218 10.7855 0.289706C11.1428 0.901868 11.512 1.50697 11.8725 2.11723C11.9244 2.20492 11.98 2.23939 12.0853 2.23885C12.9402 2.23369 13.795 2.23804 14.6499 2.23342C14.7604 2.23288 14.7943 2.25948 14.7935 2.37404C14.7886 3.21994 14.7921 4.06557 14.7889 4.91146C14.7886 5.0024 14.8133 5.0548 14.895 5.10475C15.5699 5.51575 16.2391 5.93653 16.9156 6.34509C17.0269 6.41241 17.0179 6.45965 16.9596 6.55276C16.5741 7.16927 16.1956 7.79012 15.8085 8.40554C15.742 8.51114 15.7417 8.58742 15.808 8.69574C16.1799 9.3041 16.5396 9.92006 16.9115 10.5287C16.9756 10.6335 16.959 10.6747 16.8597 10.7331C16.2062 11.1186 15.5574 11.5114 14.9037 11.8964C14.8179 11.9468 14.7881 12.0011 14.7886 12.0991C14.7924 12.9315 14.7889 13.7635 14.7932 14.5958C14.7938 14.7074 14.7645 14.7432 14.6499 14.7416C14.2117 14.7359 13.7728 14.7397 13.3341 14.7394ZM6.15184 8.14086C6.10596 8.18103 6.07881 8.20356 6.05329 8.22745C5.80979 8.45685 5.56655 8.68651 5.32358 8.91644C5.15283 9.07824 5.15093 9.08068 5.3111 9.25143C6.0723 10.062 6.8354 10.871 7.59551 11.6824C7.65577 11.7468 7.69975 11.7546 7.75703 11.6854C7.78282 11.6545 7.81676 11.6306 7.84662 11.6026C8.54565 10.9473 9.24522 10.2922 9.94399 9.63665C10.788 8.84477 11.6304 8.05154 12.4765 7.26184C12.5436 7.1994 12.5257 7.16954 12.4735 7.11497C12.2488 6.87934 12.0234 6.64398 11.8087 6.39965C11.7205 6.29921 11.67 6.30926 11.5777 6.3964C10.3569 7.54661 9.13148 8.69194 7.91014 9.84161C7.83223 9.9149 7.79395 9.91246 7.72201 9.83509C7.22034 9.29568 6.71323 8.76116 6.20857 8.2242C6.18713 8.20194 6.17301 8.17262 6.15184 8.14086Z"*/}
|
||||
{/* fill="#3897EF"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* title *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <p className="text-base font-bold text-dark-gray dark:text-white">*/}
|
||||
{/* Brokln Simons*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* username *!/*/}
|
||||
{/* <div className="flex justify-center mb-1">*/}
|
||||
{/* <p className="text-xs text-thin-light-gray">*/}
|
||||
{/* @broklinslam_75*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* items *!/*/}
|
||||
{/* <div className="flex justify-center">*/}
|
||||
{/* <div className="flex space-x-1 items-center text-purple text-xs">*/}
|
||||
{/*<span>*/}
|
||||
{/* <svg*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* width="13"*/}
|
||||
{/* height="11"*/}
|
||||
{/* viewBox="0 0 13 11"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path d="M6.49948 11.0002C6.45633 10.9222 6.44195 10.8402 6.41935 10.7642C5.68171 8.2937 4.94614 5.82125 4.20645 3.35081C4.18385 3.27679 4.19001 3.25879 4.27836 3.25879C5.71459 3.28079 7.15287 3.2968 8.5891 3.3168C8.698 3.3188 8.698 3.3188 8.66923 3.42482C7.9542 5.92527 7.23917 8.42573 6.52414 10.9242C6.51797 10.9462 6.50975 10.9682 6.49948 11.0002Z" />*/}
|
||||
{/* <path d="M13.0002 3.25468C10.9619 5.75913 8.93804 8.24759 6.91418 10.736C6.88952 10.71 6.91007 10.69 6.91623 10.67C7.60866 8.24959 8.30109 5.82715 8.99352 3.40671C9.00585 3.3607 9.04489 3.34269 9.07776 3.31469C9.20515 3.19867 9.34898 3.25868 9.48048 3.25868C10.6147 3.25268 11.7489 3.25468 12.883 3.25468C12.9159 3.25468 12.9467 3.25468 13.0002 3.25468Z" />*/}
|
||||
{/* <path d="M0 3.25444C0.0472578 3.25444 0.0739687 3.25444 0.10068 3.25444C1.32322 3.25444 2.5437 3.25444 3.76624 3.25244C3.82994 3.25244 3.86281 3.26444 3.88336 3.33046C4.59428 5.72089 5.30725 8.11132 6.01818 10.5018C6.02845 10.5338 6.04694 10.5638 6.03667 10.6078C4.02513 8.15933 2.01976 5.71489 0 3.25444Z" />*/}
|
||||
{/* <path d="M8.66592 2.93668C7.16189 2.93668 5.67224 2.93668 4.18054 2.93668C4.17438 2.90268 4.20314 2.88867 4.21753 2.86867C4.94899 1.96651 5.68046 1.06434 6.40988 0.160178C6.44275 0.120171 6.45919 0.0821637 6.51261 0.150176C7.21942 1.06634 7.93034 1.98051 8.63921 2.89668C8.64743 2.90668 8.65154 2.91668 8.66592 2.93668Z" />*/}
|
||||
{/* <path d="M2.70399 0.129883C3.0615 1.07205 3.41491 2.00222 3.77037 2.93639C2.52729 2.93639 1.29448 2.93639 0.0390625 2.93639C0.930796 1.99622 1.81226 1.06805 2.70399 0.129883Z" />*/}
|
||||
{/* <path d="M12.9687 2.9386C12.7324 2.9386 12.5166 2.9386 12.3009 2.9386C11.3126 2.9386 10.3263 2.9386 9.33803 2.9386C9.28255 2.9386 9.25173 2.9406 9.2805 2.86859C9.63185 1.97642 9.98115 1.08226 10.3304 0.190099C10.3366 0.174096 10.3387 0.154092 10.3633 0.14209C11.2263 1.06826 12.0913 1.99643 12.9687 2.9386Z" />*/}
|
||||
{/* <path d="M8.97094 2.81832C8.24152 1.87815 7.52238 0.947984 6.79297 0.0078125C7.89223 0.0078125 8.9771 0.0078125 10.0702 0.0078125C9.70651 0.939982 9.34283 1.87015 8.97094 2.81832Z" />*/}
|
||||
{/* <path d="M3.99333 2.65048C3.66252 1.78032 3.33994 0.930169 3.01735 0.0780142C2.99886 0.0320058 2.97626 0 3.0605 0C4.07962 0.00200036 5.09875 0.00200036 6.13842 0.00200036C5.42133 0.888161 4.71247 1.76432 3.99333 2.65048Z" />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* <span>3435 Items</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
</SliderCom>
|
||||
</div>
|
||||
</div>
|
||||
MyActiveOffersList?.result_list?.length > 0 &&
|
||||
MyActiveOffersList.result_list.map((item) => {
|
||||
return (
|
||||
<OfferCard key={item.id} datas={item} setOfferPopout={setOfferPopout} />
|
||||
)
|
||||
})}
|
||||
</SliderCom>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import CommonHead from "../UserHeader/CommonHead";
|
||||
// import TopSellerTopBuyerSliderSection from "../Home/TopSellerTopBuyerSliderSection";
|
||||
import MyOffersTable from "./MyOffersTable";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function MyTasks({
|
||||
MyActiveOffersList,
|
||||
@@ -15,6 +16,8 @@ export default function MyTasks({
|
||||
(state) => state?.userDetails
|
||||
);
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
@@ -26,12 +29,16 @@ export default function MyTasks({
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<CommonHead commonHeadData={commonHeadData} />
|
||||
{userDetails?.account_type == 'FULL' &&
|
||||
<CommonHead commonHeadData={commonHeadData} />
|
||||
}
|
||||
|
||||
<div className="notification-page w-full mb-10">
|
||||
<div className="notification-wrapper w-full">
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="mb-5 sm:mb-0">
|
||||
{/* <div className="w-full mb-5 sm:mb-0 flex justify-between items-center gap-1">
|
||||
{userDetails.account_type == 'FAMILY' &&
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
<span
|
||||
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||
@@ -39,7 +46,19 @@ export default function MyTasks({
|
||||
My Tasks
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
}
|
||||
{ActiveJobList?.data?.length > 0 && userDetails.account_type == 'FAMILY' &&
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
navigate("/familymarket");
|
||||
}}
|
||||
className="px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
More Task
|
||||
</button>
|
||||
}
|
||||
</div> */}
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<div
|
||||
onClick={() => filterHandler("today")}
|
||||
@@ -54,6 +73,27 @@ export default function MyTasks({
|
||||
className="mb-10"
|
||||
/>
|
||||
)}
|
||||
<div className="w-full mb-5 flex justify-between items-center gap-1">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
<span
|
||||
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||
>
|
||||
My Tasks
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
{ActiveJobList?.data?.length > 0 && userDetails.account_type == 'FAMILY' &&
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
navigate("/familymarket");
|
||||
}}
|
||||
className="px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
More Task
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<MyJobTable ActiveJobList={ActiveJobList} Account={userDetails} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
export default function MyWaitingJobTable({ MyJobList, className }) {
|
||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||
@@ -43,6 +44,7 @@ export default function MyWaitingJobTable({ MyJobList, className }) {
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
let image = value.banner ? value.banner : 'default.jpg'
|
||||
return (
|
||||
<tr
|
||||
key={index}
|
||||
@@ -50,11 +52,11 @@ export default function MyWaitingJobTable({ MyJobList, className }) {
|
||||
>
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px]">
|
||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage2}
|
||||
src={localImgLoad(`images/taskbanners/${image}`)}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
|
||||
@@ -42,7 +42,7 @@ function AddFund({payment}) {
|
||||
return (
|
||||
<div>
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
{/* <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"
|
||||
@@ -71,7 +71,7 @@ function AddFund({payment}) {
|
||||
className="relative"
|
||||
></div>
|
||||
</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">
|
||||
|
||||
@@ -1,402 +1,494 @@
|
||||
import React,{useEffect, useState} from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import InputCom from '../Helpers/Inputs/InputCom';
|
||||
import PaginatedList from '../Pagination/PaginatedList';
|
||||
import { handlePagingFunc } from '../Pagination/HandlePagination';
|
||||
import LoadingSpinner from '../Spinners/LoadingSpinner';
|
||||
import usersService from '../../services/UsersService';
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import usersService from "../../services/UsersService";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
import { Form, Formik } from "formik";
|
||||
import { useSelector } from "react-redux";
|
||||
import * as Yup from "yup";
|
||||
import Icons from "../Helpers/Icons";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
.min(3, "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"),
|
||||
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: ''
|
||||
};
|
||||
|
||||
name: "",
|
||||
cardNum: "",
|
||||
code: "",
|
||||
state: "",
|
||||
address: "",
|
||||
expirationYear: "",
|
||||
expirationMonth: "",
|
||||
cvv: "",
|
||||
};
|
||||
|
||||
function AddFundDollars(props) {
|
||||
const navigate = useNavigate()
|
||||
let apiCall = new usersService()
|
||||
const navigate = useNavigate();
|
||||
let apiCall = new usersService();
|
||||
|
||||
let [tab, setTab] = useState("previous"); //STATE FOR SWITCHING BETWEEN TABS
|
||||
let [tab, setTab] = useState("previous"); //STATE FOR SWITCHING BETWEEN TABS
|
||||
const [loader, setLoader] = useState(false);
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
let { firstname, lastname } = userDetails;
|
||||
let [prevCardDetails, setPrevCardDetails] = useState({}); // STATE TO HOLD PREVIOUS CARD SELECTED
|
||||
let [payListCards, setPayListCards] = useState({ loading: true, data: [] }); //USER PREVIOUS CARDS
|
||||
// const [payListCard, setPayListCard] = useState({ data: "" }); //USER PAYLIST
|
||||
|
||||
let [prevCardDetails, setPrevCardDetails] = useState(null) // STATE TO HOLD PREVIOUS CARD SELECTED
|
||||
const handleInputChange = (event) => {
|
||||
const { name, value } = event.target;
|
||||
setPrevCardDetails((prevState) => ({
|
||||
...prevState,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
let [payListCard, setPayListCard] = useState({loading: true, data:[]}) //USER PREVIOUS CARDS
|
||||
const indexOfFirstItem = 0;
|
||||
const indexOfLastItem =
|
||||
indexOfFirstItem + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentPreviousCards = payListCards?.data?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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('')
|
||||
if (isNaN(props.input)) {
|
||||
props.setInputError("Amount must be a Number");
|
||||
return setTimeout(() => {
|
||||
props.setInputError("");
|
||||
}, 5000);
|
||||
}
|
||||
if (tab == "previous") {
|
||||
if (!prevCardDetails) {
|
||||
// return setTimeout(() => {
|
||||
// props.setInputError("");
|
||||
// }, 5000);
|
||||
return;
|
||||
}
|
||||
setLoader(true);
|
||||
const stateData = {
|
||||
amount: Number(props.input),
|
||||
currency: props.currency,
|
||||
card: prevCardDetails["payment-card"],
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
apiCall.payListCard().then(res => {
|
||||
setPayListCard({loading: false, data: res.data.result_list})
|
||||
}).catch(err => {
|
||||
console.log('PAYCARDLIST ERROR', err)
|
||||
setPayListCard({loading: false, data: []})
|
||||
})
|
||||
}, [])
|
||||
setTimeout(() => {
|
||||
props.setConfirmCredit({ show: true, data: stateData });
|
||||
setLoader(false);
|
||||
}, 1500);
|
||||
// navigate("confirm-add-fund", { state: stateData }); // State will change later dummy for now
|
||||
}
|
||||
if (tab == "new") {
|
||||
const stateData = {
|
||||
amount: Number(props.input),
|
||||
currency: props.currency,
|
||||
values,
|
||||
};
|
||||
// navigate("confirm-add-fund", { state: stateData }); // State will change later dummy for now
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
apiCall
|
||||
.payListCard()
|
||||
.then((res) => {
|
||||
setPayListCards({ loading: false, data: res.data.result_list });
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("PAYCARDLIST ERROR", err);
|
||||
setPayListCards({ loading: false, data: [] });
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className='mb-2 text-xl font-bold text-dark-gray dark:text-white'>Payment Method</h1>
|
||||
<div className="w-full">
|
||||
{/* switch button */}
|
||||
<div className="my-1 flex items-center border-b border-slate-300">
|
||||
<button
|
||||
name="previous"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "previous" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
<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">
|
||||
{props.currency == "US Dollars" && "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
|
||||
</button>
|
||||
<button
|
||||
name="new"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "new" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
</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 justify-between items-center">
|
||||
{payListCards.loading ? (
|
||||
<LoadingSpinner size="10" color="sky-blue" />
|
||||
) : payListCards?.data?.length ? (
|
||||
<select
|
||||
className="my-3 w-full rounded-full p-4 outline-none border-none text-base text-black dark:text-gray-100 bg-[#dce2e6] dark:bg-[#5e6278] 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">
|
||||
{/* <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>
|
||||
</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>
|
||||
{/* END OF switch button */}
|
||||
|
||||
{/* previous tab */}
|
||||
{tab == 'previous' ?
|
||||
<div className="p-4 previous-details w-full border min-h-[300px] flex flex-col justify-between items-center">
|
||||
{ payListCard.loading ?
|
||||
<LoadingSpinner size='10' color='sky-blue' />
|
||||
:
|
||||
payListCard?.data?.length ?
|
||||
<table className="my-3 w-full">
|
||||
<tbody>
|
||||
{currentPreviousCards.map((item, index)=>(
|
||||
<tr key={index} className={index != 0 && 'border-t-2'}>
|
||||
<td>
|
||||
<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>
|
||||
<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>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
:
|
||||
<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 min-h-[300px] border-t">
|
||||
<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>
|
||||
) : (
|
||||
<div className="new-details w-full max-h-[23rem] 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="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="w-full">
|
||||
{/* <div className="field w-full my-2 flex-[0.4]">
|
||||
<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> */}
|
||||
|
||||
<div className="flex items-center flex-1 gap-3 my-3">
|
||||
{/* CARD NUMBER */}
|
||||
<div className="field w-full flex-[0.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 */}
|
||||
<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 block"
|
||||
htmlFor="expiration"
|
||||
>
|
||||
Exp 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-[#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={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"
|
||||
>
|
||||
Exp 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-[#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>
|
||||
{props.errors.expirationYear &&
|
||||
props.touched.expirationYear && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.expirationYear}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-1 gap-3 my-3">
|
||||
{/* Address AND CVV */}
|
||||
<div className="field w-full col-span-1 flex-[0.4]">
|
||||
<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 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}
|
||||
/>
|
||||
{props.errors.address &&
|
||||
props.touched.address && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.address}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* postal code and state */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 my-3">
|
||||
<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 ${
|
||||
@@ -431,50 +523,73 @@ function AddFundDollars(props) {
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||
<button
|
||||
type="submit"
|
||||
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>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
<div className="md:px-8 md:pt-4 px-4 pt-2 add-fund-btn flex justify-end items-center">
|
||||
<button
|
||||
type="submit"
|
||||
className="py-1 px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white gap-1"
|
||||
>
|
||||
<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}
|
||||
type="button"
|
||||
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
{loader ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
) : (
|
||||
<span className="text-white">Continue</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{ tab == 'previous' &&
|
||||
<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>
|
||||
}
|
||||
)}
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default AddFundDollars
|
||||
|
||||
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)
|
||||
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})
|
||||
}
|
||||
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,139 @@
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
|
||||
import AddFundDollars from "./AddFundDollars";
|
||||
|
||||
function AddFundPop({ _payment, input, setInput, onClose, setConfirmCredit }) {
|
||||
const navigate = useNavigate();
|
||||
// const { currency } = useLocation()?.state; //GETS THE USER CURRENCY FOR ADD FUND
|
||||
|
||||
let { payment, currency } = _payment;
|
||||
|
||||
//STATE FOR CONTROLLED INPUT
|
||||
let [inputError, setInputError] = useState("");
|
||||
|
||||
// FUNCTION TO HANDLE INPUT CHANGE
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
setInput(value);
|
||||
};
|
||||
|
||||
//FUNCTION TO HANDLE SUBMIT
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
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);
|
||||
}
|
||||
|
||||
if (input) return;
|
||||
// setTimeout(
|
||||
// () =>
|
||||
// setConfirmCredit({
|
||||
// show: true,
|
||||
// data: { amount: Number(input), currency: "naira" },
|
||||
// }),
|
||||
// 1500
|
||||
// );
|
||||
|
||||
// const stateData = { amount: Number(input), currency: "naira" };
|
||||
// navigate("confirm-add-fund", { state: stateData });
|
||||
|
||||
// setInput("");
|
||||
};
|
||||
|
||||
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">
|
||||
{/*<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: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">
|
||||
{currency == "US Dollars" ? "Amount (USD)" : "Amount (Naira)"}
|
||||
</h1>
|
||||
<div className="field w-full max-w-[250px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
type="text"
|
||||
name="amount"
|
||||
placeholder="0"
|
||||
value={input}
|
||||
inputHandler={handleChange}
|
||||
/>
|
||||
<p className="text-base text-red-500 h-5">
|
||||
{inputError && inputError}
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
||||
{currency == "US Dollars" && (
|
||||
<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}
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
currency={currency}
|
||||
onClose={onClose}
|
||||
setConfirmCredit={setConfirmCredit}
|
||||
/>
|
||||
</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 gap-4">
|
||||
<button
|
||||
className="px-2 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-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>
|
||||
null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddFundPop;
|
||||
@@ -1,16 +1,14 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { 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 }) {
|
||||
function ConfirmAddFund({ confirmCredit, onClose, walletItem }) {
|
||||
let { userDetails } = useSelector((state) => state.userDetails); // TO GET LOGGEDIN USER DETAILS
|
||||
|
||||
let [pageLoading, setPageLoading] = useState(true);
|
||||
@@ -24,12 +22,10 @@ function ConfirmAddFund({ payment }) {
|
||||
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" };
|
||||
let reqData = { amount: confirmCredit?.data?.account, currency: "NGN" };
|
||||
apiURL
|
||||
.startTopUp(reqData)
|
||||
.then((res) => {
|
||||
@@ -66,7 +62,7 @@ function ConfirmAddFund({ payment }) {
|
||||
const config = {
|
||||
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
|
||||
tx_ref: Date.now(),
|
||||
amount: state?.amount,
|
||||
amount: confirmCredit?.data?.amount,
|
||||
currency: "NGN",
|
||||
payment_options: "card,mobilemoney,ussd",
|
||||
customer: {
|
||||
@@ -91,73 +87,127 @@ function ConfirmAddFund({ payment }) {
|
||||
onClose: () => {},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// what happens if not state redirect user
|
||||
if (!state) {
|
||||
navigate("/my-wallet/add-fund", { replace: true });
|
||||
} else {
|
||||
setPageLoading(false);
|
||||
}
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// // what happens if not data redirect user
|
||||
// if (!data) {
|
||||
// navigate("/my-wallet/add-fund", { replace: true });
|
||||
// } else {
|
||||
// setPageLoading(false);
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
let __confirmCard = JSON.parse(confirmCredit?.data.card);
|
||||
const ThePaymentText = ({ value }) => (
|
||||
<div className="my-2 flex items-center gap-5">
|
||||
<div className="card-details flex items-center gap-3">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{value.description} Card
|
||||
</h1>
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Bank **************{value.digits}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
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">
|
||||
<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">
|
||||
{/* <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">
|
||||
<hr /> */}
|
||||
<div className="px-4 md:p-8 py-4 add-fund-info">
|
||||
<div className="field w-full mb-3 min-h-[45px]">
|
||||
{confirmCredit?.show ? (
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{confirmCredit?.data?.currency == "naira"
|
||||
? "Amount (Naira):"
|
||||
: "Amount (Dollars):"}
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{`${walletItem?.symbol} ${
|
||||
Number(confirmCredit?.data?.amount).toLocaleString() ||
|
||||
""
|
||||
}`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
{/* <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1"> */}
|
||||
<label
|
||||
htmlFor="payment"
|
||||
className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1"
|
||||
>
|
||||
{confirmCredit?.data?.currency && "Payment Method:"}
|
||||
</label>
|
||||
<span className="text-[#181c32] dark:text-white ">
|
||||
{__confirmCard && (
|
||||
<ThePaymentText value={__confirmCard} />
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
|
||||
label={
|
||||
confirmCredit?.data?.currency == "naira"
|
||||
? "Amount (Naira):"
|
||||
: "Amount (Dollars):"
|
||||
}
|
||||
type="text"
|
||||
name="amount"
|
||||
value={state.amount || ""}
|
||||
value={confirmCredit?.data?.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
|
||||
</div>
|
||||
{/* <h1 className="mb-2 text-xl font-bold text-dark-gray dark:text-white px-4 h-5">
|
||||
{confirmCredit?.data?.currency && "Payment Method"}
|
||||
</h1> */}
|
||||
{/* <hr /> */}
|
||||
<div className="min-h-[220px]"></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 border-gradient text-base rounded-full"
|
||||
onClick={onClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
{confirmCredit?.data?.currency == "naira" ? (
|
||||
<FlutterWaveButton
|
||||
{...fwConfig}
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
onClick={()=>console.log('WORKING')}
|
||||
/>
|
||||
) : (
|
||||
<button
|
||||
className="px-4 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>
|
||||
|
||||
<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">
|
||||
{/* <div className="w-full mb-10">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full 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> */}
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||