Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1916bc1a65 | |||
| 1103127cae | |||
| 751369071c | |||
| 4cc8f27c14 | |||
| aab455c2c3 | |||
| 21843c4bc7 | |||
| 8702728ffa | |||
| 79dcd0f2b5 | |||
| 47b25f3dfe | |||
| 89925a6af9 | |||
| 3c0f951b6e | |||
| ffbfb1da35 | |||
| a8416a8433 | |||
| 70c9d1778c | |||
| 930559c96b | |||
| c4af2dfcc8 | |||
| b186549b8d | |||
| ab191b6a72 | |||
| d130687cf9 | |||
| 5e9a442eac | |||
| 1093c25207 | |||
| 0623227807 | |||
| 3a05790125 | |||
| 85b0456011 | |||
| 6ddd16ee24 | |||
| d034f9be45 | |||
| 2f3940f99c | |||
| 5e998e5e42 | |||
| e113f40c5c | |||
| 42a3df2d65 | |||
| 3fb996887b | |||
| 6d2794dd2f | |||
| 8e683f12a2 | |||
| 1910ea2bb6 | |||
| 5f6471a16e | |||
| 98a4baddab | |||
| 67f8de325f | |||
| 594d2a4224 | |||
| edd48e72ec | |||
| 47c9e1bb6e | |||
| 2fe80ecbe3 | |||
| 1640f25d9d | |||
| 28f3bbcad1 | |||
| c4eca264b1 | |||
| 89a9e77380 | |||
| 349b524151 | |||
| 084370b641 | |||
| c2a6cff3eb | |||
| d45e533d91 | |||
| c89de2559a | |||
| a5a267927a | |||
| 557e0acba4 | |||
| 3e4dfadb41 | |||
| b480d49096 | |||
| ece7bf41d3 | |||
| 250dd0b171 | |||
| f2475ddd88 | |||
| f302ca80d7 | |||
| 11b96e56da | |||
| daad9d18ec | |||
| 3c842f6606 | |||
| 23ef007bb1 | |||
| a9b9a17381 | |||
| d5e66618aa | |||
| 2e89f07ee2 | |||
| 1a51bcf0b5 | |||
| f1ee5150a9 | |||
| 9db7f5c985 | |||
| d56363276b | |||
| 5a9b49559b | |||
| fbc8228977 | |||
| a1140f7006 | |||
| f3561ff0fb | |||
| 42b792ab9d | |||
| 1e3a166172 | |||
| e1c6cb357e | |||
| 1aa64fba1f | |||
| 4f0a6f67c3 | |||
| 4f863f7b1d | |||
| b66f9d7ced | |||
| 493f209162 | |||
| 0aa109e280 | |||
| b0a287c6a8 | |||
| 8c00b157ad | |||
| 85bbd25bbb | |||
| 4d7e42fba8 | |||
| f91e8e9910 | |||
| 9e9b0b5557 | |||
| bfcfcdbf16 | |||
| 7e99e7ccab | |||
| fd9adb1c08 | |||
| 7f2448efff | |||
| 82ec224d66 | |||
| 35ea200de5 | |||
| 7cdd387045 | |||
| 6b568ff56c | |||
| 8808a2f81c | |||
| 1991bab675 | |||
| f650097db2 | |||
| c427521ac3 | |||
| 2412059fd0 | |||
| 34dc467e8b | |||
| 9fa16278ab | |||
| cae02d1dc6 | |||
| abbd7b3993 | |||
| 5523511524 | |||
| 35db8ca7ec | |||
| 51e0482a16 | |||
| a615e25fcb | |||
| addede388e | |||
| 76474bb3b5 | |||
| 6337c82374 | |||
| a970411719 | |||
| 10967acf9e | |||
| fb6831d44f | |||
| 7dcae39320 | |||
| a0ba60a2bc | |||
| f377326b48 | |||
| feb8bd718d | |||
| a2a2dbfc24 | |||
| 1c0cb6c97f | |||
| 41c9c60fd1 | |||
| ba5646fe2c | |||
| 1f9ab45206 | |||
| 0ffa1123d2 | |||
| 9420a201e4 | |||
| 1b7ea7321e | |||
| b3e273d712 | |||
| 7fa74d6fd3 | |||
| 02c195500a | |||
| ca8e56c6dd | |||
| c265e9db33 | |||
| 2861473ea3 | |||
| a598aa3898 | |||
| 9d190916a8 | |||
| eca9455f0f | |||
| a1bf0bad0f | |||
| e236ad20f7 | |||
| 330f47baa7 | |||
| 5088aa3ead | |||
| 07a443d082 | |||
| 59a370d763 | |||
| 68e709f34b | |||
| b1bb730c7d | |||
| 20a86f4802 |
@@ -24,7 +24,6 @@ REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
|
||||
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
|
||||
|
||||
REACT_APP_FLUTTERWAVE_APIKEY=FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X
|
||||
|
||||
# Had to change the error time to 3sec cause it took too long
|
||||
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
|
||||
@@ -64,12 +63,31 @@ 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')
|
||||
#SOCIALS Links Display
|
||||
REACT_APP_APPLE_SOCIAL_LOGIN=0
|
||||
REACT_APP_LINKEDIN_SOCIAL_LOGIN=0
|
||||
|
||||
#File Handling
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
#Auth Text(s)
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
|
||||
|
||||
#apigate.lotus.g1.wrenchboard.com:76.209.103.227
|
||||
#apigate.orion.g1.wrenchboard.com:76.209.103.227
|
||||
|
||||
#Cards Handling
|
||||
REACT_APP_MAX_CREDIT_CARDS=4
|
||||
REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
|
||||
#Family
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
@@ -24,7 +24,6 @@ REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
|
||||
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
|
||||
|
||||
REACT_APP_FLUTTERWAVE_APIKEY=FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X
|
||||
|
||||
# Had to change the error time to 3sec cause it took too long
|
||||
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
|
||||
@@ -43,4 +42,20 @@ REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
|
||||
REACT_APP_APPLE_SOCIAL_LOGIN=0
|
||||
REACT_APP_LINKEDIN_SOCIAL_LOGIN=0
|
||||
|
||||
REACT_APP_MAX_CREDIT_CARDS=4
|
||||
REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
@@ -24,7 +24,6 @@ REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
|
||||
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
|
||||
|
||||
REACT_APP_FLUTTERWAVE_APIKEY=FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X
|
||||
|
||||
# Had to change the error time to 3sec cause it took too long
|
||||
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
|
||||
@@ -50,4 +49,19 @@ DISABLE_ESLINT_PLUGIN=true
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
REACT_APP_APPLE_SOCIAL_LOGIN=0
|
||||
REACT_APP_LINKEDIN_SOCIAL_LOGIN=0
|
||||
|
||||
REACT_APP_MAX_CREDIT_CARDS=4
|
||||
REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"react-chartjs-2": "^4.1.0",
|
||||
"react-countup": "^6.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
"react-qr-code": "^2.0.11",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.0.2",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
@@ -57,6 +57,7 @@ export default function Routers() {
|
||||
{/* guest routes */}
|
||||
<Route exact path="/login" element={<LoginPage />} />
|
||||
<Route exact path="/eoffer" element={<LoginPage />} />
|
||||
<Route exact path="/invite" element={<LoginPage />} />
|
||||
|
||||
<Route exact path="/signup" element={<SignupPage />} />
|
||||
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" id="files"><circle cx="64" cy="64" r="64" fill="#EF4C45"></circle><path fill="#CD2E30" d="M128 64v-2L92.4 26.5l-63.1 74 27.2 27c2.4.3 4.9.4 7.4.4C99.3 128 128 99.3 128 64z"></path><path fill="#E5E8EC" d="M93.5 78.4V29c0-1.9-1.5-3.4-3.4-3.4H41.8c-1.9 0-3.4 1.5-3.4 3.4v49.4h55.1z"></path><path fill="#FFF" d="M89.5 78.4V44.6H78.1c-1.9 0-3.4-1.5-3.4-3.4V29.9H37.8c-1.9 0-3.4 1.5-3.4 3.4v45.1h55.1z"></path><path fill="#FFCC04" d="m79.3 65.9-1.5 4c-.5 1.2-1.6 2-2.9 2H53.1c-1.3 0-2.4-.8-2.9-2l-1.5-4c-.5-1.3-1.7-2.2-3.1-2.2H30.9c-1.9 0-3.4 1.5-3.4 3.4v28.8c0 3.5 2.9 6.4 6.4 6.4H94c3.5 0 6.4-2.9 6.4-6.4V67.1c0-1.9-1.5-3.4-3.4-3.4H82.5c-1.4 0-2.7.9-3.2 2.2z"></path><path fill="#CED4DF" d="m74.9 45.8-.1-.1.1.1z"></path><path fill="#22D2FC" d="M74.7 29.9v11.4c0 1.9 1.5 3.4 3.4 3.4h11.4L74.7 29.9z"></path><path fill="#FFF" d="M74.1 81.6H53.9c-2 0-3.7 1.6-3.7 3.7 0 2 1.6 3.7 3.7 3.7h20.2c2 0 3.7-1.6 3.7-3.7 0-2-1.7-3.7-3.7-3.7z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1003 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 51 51" id="jpg"><circle cx="25.5" cy="25.5" r="24" fill="#FED000"></circle><path fill="#F39F03" d="M37.462 16.607v4.741a.924.924 0 0 1-.877.924v16.361c0 1.027-.84 1.867-1.867 1.867H18.282a1.866 1.866 0 0 1-1.867-1.867V22.272a.924.924 0 0 1-.877-.924v-4.741c0-.495.392-.906.877-.924v-1.316a1.86 1.86 0 0 1 1.867-1.867h16.436c1.027 0 1.867.83 1.867 1.867v1.316c.485.018.877.43.877.924z"></path><path fill="#FFF" d="M35.585 13.367v24.266c0 1.031-.836 1.867-1.867 1.867H17.282a1.867 1.867 0 0 1-1.867-1.867V13.367c0-1.031.836-1.867 1.867-1.867h16.436c1.03 0 1.867.836 1.867 1.867z" opacity=".96"></path><path fill="#33ACFE" d="M18.143 25.5h14.715v9.894H18.143z"></path><path fill="#273E56" d="M32.859 35.394h-7.622l3.959-4.357z"></path><path fill="#334861" d="M29.048 35.394H18.143l5.664-7.357z"></path><circle cx="27.697" cy="28.037" r="1.094" fill="#FED000"></circle><path fill="#EB4B33" d="M35.462 21.28H15.538a1 1 0 0 1-1-1v-4.604a1 1 0 0 1 1-1h19.924a1 1 0 0 1 1 1v4.605a1 1 0 0 1-1 1z"></path><path fill="#FFF" d="M22.511 18.797c0 .57-.155 1.499-1.475 1.499-.737 0-1.456-.403-1.456-1.37v-.384h.88v.199c0 .427.105.737.564.737.514 0 .514-.409.514-.725v-2.987h.973v3.03zm.857-3.031h1.996c1.109 0 1.53.7 1.53 1.42 0 .718-.421 1.418-1.53 1.418H24.34v1.587h-.973v-4.425zm.973 2.082h.756c.446 0 .855-.099.855-.663 0-.564-.409-.663-.855-.663h-.756v1.326zm6.36 1.84a1.49 1.49 0 0 1-1.214.608c-1.364 0-2.176-1.023-2.176-2.299 0-1.314.812-2.336 2.176-2.336.905 0 1.766.552 1.865 1.561h-.93c-.117-.496-.47-.743-.935-.743-.874 0-1.202.743-1.202 1.518 0 .738.328 1.48 1.202 1.48.638 0 .997-.334 1.053-.953h-.98V17.8h1.86v2.392h-.62l-.099-.502z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 512 512" id="mp4-file"><circle cx="256" cy="256" r="256" fill="#8ABE4F"></circle><path fill="#7BA840" d="M511.9 262.5 346.6 96.8c-1.1-1.1-3.1-1.1-4.3 0l-37.4 43.4c-.6.6-.8 1.2-.7 1.9l-3.4-6.1H159.2c-13.1 0-23.7 10.6-23.7 23.7v145.6l7.9 5.9h-16.2v66.6l8.3 7.9v6.6c0 7.6 3.5 14.3 9 18.6.7.9 58.1 58.3 100.6 100.9 3.6.1 7.2.2 10.8.2 139.3 0 252.5-111.1 256-249.5z"></path><g fill="#FFF"><path d="M169.1 193.7h145.4V206H169.1zM169.1 213.5h145.4v12.3H169.1zM169.1 233.4h145.4v12.3H169.1zM169.1 253.3h145.4v12.3H169.1zM169.1 273.1H282v12.3H169.1zM384.1 140.2l-37.4-43.4c-1.1-1.1-3.1-1.1-4.3 0L305 140.2c-1.7 1.6-.4 4.3 2.1 4.3h17.6v34h39.8v-34h17.6c2.3 0 3.6-2.6 2-4.3zM324.6 184.7h39.8v15.5h-39.8zM324.6 212c0 1.4 1.3 2.6 2.9 2.6h34c1.6 0 2.9-1.1 2.9-2.6v-5.7h-39.8v5.7z"></path><path d="M339.7 389.3c0 10.1-8.2 18.3-18.3 18.3H162.2c-10.1 0-18.3-8.2-18.3-18.3v-5.6h-8.4v8.6c0 13.1 10.6 23.7 23.7 23.7h165.2c13.1 0 23.7-10.6 23.7-23.7V220.4h-8.4v168.9zM143.9 162.7c0-10.1 8.2-18.3 18.3-18.3h136.4c-.9-2.8-.2-6 1.9-8.2l.2-.3H159.2c-13.1 0-23.7 10.6-23.7 23.7v145.6h8.4V162.7z"></path><path d="M313.2 344.5c0-18.4-14.9-33.3-33.3-33.3H127.2v66.6h152.7c18.4 0 33.3-14.9 33.3-33.3zm-109 19.2h-6.4v-27.6h-.2L187 363.7h-4.4l-10.8-28.1-.2.1v28.1h-6.4v-38.4h8.4l11 29.5h.2l11.1-29.5h8.2v38.3zm34.4-17.8c-2.4 2.2-5.7 3.3-10 3.3h-8.3v14.6h-6.4v-38.4h14.7c4.2 0 7.6 1.1 10 3.3 2.4 2.2 3.6 5.1 3.6 8.6s-1.2 6.4-3.6 8.6zm36.5 9.3h-4.9v8.5h-6.4v-8.5h-16.1l-.2-3.9 16-26h6.6V350h4.9v5.2z"></path><path d="m263.1 335.8-9.2 14.2h9.9v-15.7h-.1zM228.6 330.4h-8.3V344h8.3c2.4 0 4.2-.6 5.4-1.9 1.2-1.3 1.8-2.9 1.8-4.8s-.6-3.6-1.8-4.9c-1.2-1.3-3-2-5.4-2z"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 90 90" viewBox="0 0 90 90" id="pdf"><circle cx="45" cy="45" r="44.5" fill="#84D2ED"></circle><polygon fill="#EFC41C" stroke="#010101" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.978" points="35.6 18.8 35.6 31.9 22.5 31.9 22.5 71.2 62.8 71.2 62.8 18.8"></polygon><polygon fill="#8CC749" stroke="#010101" stroke-miterlimit="10" stroke-width="1.978" points="22.5 31.9 22.5 31.9 22.5 31.9"></polygon><polygon fill="#EB665F" stroke="#010101" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.978" points="35.6 18.8 22.5 31.9 22.5 31.9 35.6 31.9"></polygon><rect width="35.9" height="15.7" x="31.6" y="40.2" fill="#F2DFD5" stroke="#010101" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.978"></rect><path fill="#010101" d="M43 44c.7.6 1 1.5 1 2.7 0 1.2-.4 2.1-1.1 2.7-.7.6-1.8.9-3.3.9h-1.3v2.8h-2.2v-9.9h3.5C41.2 43.1 42.3 43.4 43 44zM41.4 47.9c.3-.3.4-.7.4-1.3 0-.6-.2-1-.5-1.2C41 45.2 40.4 45 39.7 45h-1.3v3.3h1.5C40.6 48.4 41.2 48.2 41.4 47.9zM53.4 44.4c.9.9 1.4 2.1 1.4 3.6 0 1.5-.5 2.8-1.4 3.7-.9.9-2.3 1.3-4.2 1.3h-3.4v-9.9h3.5C51.1 43.1 52.5 43.6 53.4 44.4zM51.8 50.3c.5-.5.8-1.3.8-2.2s-.3-1.7-.8-2.3c-.5-.5-1.4-.8-2.5-.8H48v6h1.4C50.5 51.1 51.2 50.9 51.8 50.3zM63.6 43.1v1.9H59v2.1h4.4v1.9H59v3.9h-2.2v-9.9H63.6z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="655.359" height="655.359" fill-rule="evenodd" clip-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 6.827 6.827" id="png-file"><circle cx="3.413" cy="3.413" r="3.413" fill="#42a5f5"></circle><path fill="#fffffe" d="M1.744 4.074h.27V1.75a.164.164 0 0 1 .164-.164H4.3l.023.022.544.545.023.023v1.898h.191a.198.198 0 0 1 .198.199v.77a.198.198 0 0 1-.198.198H1.744a.198.198 0 0 1-.198-.199v-.769a.198.198 0 0 1 .198-.199zm.425 0h2.567V2.24l-.004-.004h-.498v-.495H2.178a.009.009 0 0 0-.007.003.009.009 0 0 0-.002.006v2.324zm.389-.7h1.789v.156h-1.79v-.156zm0-.544h1.789v.156h-1.79V2.83zm.07 2.094V4.37h.179c.068 0 .112.003.132.009a.145.145 0 0 1 .08.054.172.172 0 0 1 .032.107.18.18 0 0 1-.018.086.152.152 0 0 1-.047.055.162.162 0 0 1-.058.026.637.637 0 0 1-.116.008h-.073v.209h-.111zm.111-.46v.157H2.8a.29.29 0 0 0 .089-.009.074.074 0 0 0 .034-.027.075.075 0 0 0 .013-.043.072.072 0 0 0-.018-.05.077.077 0 0 0-.044-.024.532.532 0 0 0-.08-.004h-.055zm.405.46V4.37h.109l.226.37v-.37h.104v.554h-.112l-.223-.361v.36h-.104zm.814-.204v-.093H4.2v.22a.372.372 0 0 1-.237.086.304.304 0 0 1-.15-.036.232.232 0 0 1-.098-.105.337.337 0 0 1-.032-.147.32.32 0 0 1 .036-.154.244.244 0 0 1 .106-.102.285.285 0 0 1 .132-.028.26.26 0 0 1 .161.043.195.195 0 0 1 .075.12l-.111.02a.118.118 0 0 0-.044-.064.133.133 0 0 0-.08-.024.152.152 0 0 0-.117.047c-.029.03-.043.077-.043.138 0 .065.014.114.044.147.029.033.067.05.114.05a.194.194 0 0 0 .07-.014.244.244 0 0 0 .061-.034v-.07h-.128z"></path><path fill="none" d="M1.547 1.547H5.28V5.28H1.547z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 101 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="1200" height="1227" viewBox="0 0 1200 1227" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 430 B |
@@ -1,6 +1,6 @@
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import * as Yup from "yup";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
@@ -11,7 +11,7 @@ const validationSchema = Yup.object().shape({
|
||||
country: Yup.string()
|
||||
.min(1, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Country is required"),
|
||||
.required("Currency is required"),
|
||||
price: Yup.string()
|
||||
.typeError("Invalid number")
|
||||
.min(1, "Price must be greater than 0")
|
||||
@@ -32,7 +32,7 @@ const validationSchema = Yup.object().shape({
|
||||
.required("Description is required"),
|
||||
job_detail: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(1440, "Maximum 1440 characters")
|
||||
.max(499, "Maximum 499 characters")
|
||||
.required("Details is required"),
|
||||
timeline_days: Yup.number()
|
||||
.typeError("you must specify a number")
|
||||
@@ -43,15 +43,9 @@ const validationSchema = Yup.object().shape({
|
||||
|
||||
function AddJob({ popUpHandler, categories }) {
|
||||
const ApiCall = new usersService();
|
||||
|
||||
const { walletDetails } = useSelector((state) => state.walletDetails);
|
||||
let dispatch = useDispatch();
|
||||
|
||||
let [currency, setCurrency] = useState({
|
||||
loading: true,
|
||||
status: false,
|
||||
data: null,
|
||||
}); // To Hold the array of currency getUserCurrency returns
|
||||
|
||||
let initialValues = {
|
||||
// initial values for formik
|
||||
country: "",
|
||||
@@ -69,30 +63,15 @@ function AddJob({ popUpHandler, categories }) {
|
||||
message: "",
|
||||
}); // Holds state when submit button is pressed
|
||||
|
||||
// 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 getWalletDetail = (country) => { // A FUNCTION TO GET USER BALANCE BASED ON COUNTRY SELECTED
|
||||
const walletChecker = walletDetails?.data.find(
|
||||
(item) => item.country === country
|
||||
);
|
||||
return walletChecker ? walletChecker.amount : 0;
|
||||
};
|
||||
|
||||
// FUNCTION TO HANDLE ADD JOB FORM
|
||||
const handleAddJob = (values, helpers) => {
|
||||
let reqData = {
|
||||
const handleAddJob = async (values, helpers) => {
|
||||
const reqData = {
|
||||
country: values?.country,
|
||||
price: Number(values.price) * 100,
|
||||
title: values?.title,
|
||||
@@ -102,20 +81,35 @@ function AddJob({ popUpHandler, categories }) {
|
||||
category: values.category?.join("@"),
|
||||
};
|
||||
|
||||
const walletAmount = getWalletDetail(reqData.country); // GETTING USER BALANCE BASED ON COUNTRY SELECTED
|
||||
|
||||
if (reqData.price > walletAmount) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Insufficient Balance",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 1500);
|
||||
return;
|
||||
}
|
||||
|
||||
setRequestStatus({ loading: true, status: false, message: "" });
|
||||
ApiCall.jobManagerCreateJob(reqData)
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 1) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Could not complete your request at the moment",
|
||||
});
|
||||
setTimeout(() => {
|
||||
popUpHandler();
|
||||
}, 1500);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await ApiCall.jobManagerCreateJob(reqData);
|
||||
if (res.data.internal_return < 1) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Could not complete your request at the moment",
|
||||
});
|
||||
setTimeout(() => {
|
||||
popUpHandler();
|
||||
}, 1500);
|
||||
} else {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: true,
|
||||
@@ -125,27 +119,22 @@ function AddJob({ popUpHandler, categories }) {
|
||||
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||
popUpHandler();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Opps! something went wrong. Try Again",
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
}
|
||||
} catch (err) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Oops! Something went wrong. Try Again",
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUserCurrency();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
|
||||
<div className="add-job p-5 w-full bg-white dark:bg-dark-white dark:text-white rounded-md flex flex-col justify-between">
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
@@ -164,26 +153,30 @@ function AddJob({ popUpHandler, categories }) {
|
||||
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>}
|
||||
{props.errors.country && props.touched.country && (
|
||||
<span className="text-[12px] text-red-500">
|
||||
{props.errors.country}
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
<select
|
||||
id="country"
|
||||
name="country"
|
||||
value={props.values.country}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
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 border`}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
>
|
||||
{currency.loading ? (
|
||||
{walletDetails.loading ? (
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
Loading...
|
||||
</option>
|
||||
) : currency.data.length ? (
|
||||
) : walletDetails.data.length ? (
|
||||
<>
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
Select a currency
|
||||
</option>
|
||||
{currency.data?.map((item, index) => (
|
||||
{walletDetails.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
@@ -207,14 +200,17 @@ function AddJob({ popUpHandler, categories }) {
|
||||
fieldClass="px-6 text-right"
|
||||
label="Price"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="number"
|
||||
name="price"
|
||||
placeholder="0"
|
||||
value={props.values.price}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.price && props.touched.price && props.errors.price}
|
||||
error={
|
||||
props.errors.price &&
|
||||
props.touched.price &&
|
||||
props.errors.price
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -225,13 +221,16 @@ function AddJob({ popUpHandler, categories }) {
|
||||
fieldClass="px-6"
|
||||
label="Title"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="title"
|
||||
value={props.values.title}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.title && props.touched.title && props.errors.title}
|
||||
error={
|
||||
props.errors.title &&
|
||||
props.touched.title &&
|
||||
props.errors.title
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -241,13 +240,16 @@ function AddJob({ popUpHandler, categories }) {
|
||||
fieldClass="px-6"
|
||||
label="Description"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="description"
|
||||
value={props.values.description}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.description && props.touched.description && props.errors.description}
|
||||
error={
|
||||
props.errors.description &&
|
||||
props.touched.description &&
|
||||
props.errors.description
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -259,12 +261,17 @@ function AddJob({ popUpHandler, categories }) {
|
||||
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>}
|
||||
{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]`}
|
||||
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] border`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={props.values.job_detail}
|
||||
@@ -286,19 +293,28 @@ function AddJob({ popUpHandler, categories }) {
|
||||
role="group"
|
||||
aria-labelledby="checked-group"
|
||||
>
|
||||
{Object?.entries(categories).map(([key, value]) => (
|
||||
<label
|
||||
key={key}
|
||||
className="flex gap-1 w-full items-center"
|
||||
>
|
||||
<Field
|
||||
type="checkbox"
|
||||
name="category"
|
||||
value={key}
|
||||
/>
|
||||
<span className="text-[13.975px]">{value}</span>
|
||||
{categories ? (
|
||||
<>
|
||||
{Object?.entries(categories).map(([key, value]) => (
|
||||
<label
|
||||
key={key}
|
||||
className="flex gap-1 w-full items-center"
|
||||
>
|
||||
<Field
|
||||
type="checkbox"
|
||||
name="category"
|
||||
value={key}
|
||||
/>
|
||||
<span className="text-[13.975px]">{value}</span>
|
||||
</label>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<label className="flex gap-1 w-full items-center">
|
||||
<Field type="checkbox" name="category" />
|
||||
<span className="text-[13.975px]">null</span>
|
||||
</label>
|
||||
))}
|
||||
)}
|
||||
<span className="h-5 text-sm italic text-[#cf3917]">
|
||||
{props.errors.category &&
|
||||
props.touched.category &&
|
||||
@@ -324,7 +340,7 @@ function AddJob({ popUpHandler, categories }) {
|
||||
<Field
|
||||
component="select"
|
||||
name="timeline_days"
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none ${
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none border ${
|
||||
props.errors.timeline_days &&
|
||||
props.touched.timeline_days
|
||||
? "border-[#ff0a0a63] shadow-red-500 border-[0.5px] animate-shake"
|
||||
@@ -335,6 +351,7 @@ function AddJob({ popUpHandler, categories }) {
|
||||
<option value="">Select Duration</option>
|
||||
{publicArray.map(({ name, duration }, idx) => (
|
||||
<option
|
||||
key={idx}
|
||||
className="text-slate-500 text-lg"
|
||||
value={duration}
|
||||
>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import React, { useEffect } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import { updateUserDetails } from "../../../store/UserDetails";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function Redirect() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
|
||||
useEffect(()=>{
|
||||
if(!codeResponse){
|
||||
navigate('/login', {state: {error: true}})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse);
|
||||
/*
|
||||
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
|
||||
@@ -31,34 +31,40 @@ function Redirect() {
|
||||
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
|
||||
}
|
||||
navigate('/login', {state: {error: true}})
|
||||
})
|
||||
.catch((error) => {
|
||||
navigate('/login', {state: {error: true}})
|
||||
console.log(error);
|
||||
});
|
||||
},[])
|
||||
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;
|
||||
}
|
||||
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>
|
||||
)
|
||||
<div className="min-h-[70vh]">Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Redirect
|
||||
export default Redirect;
|
||||
|
||||
@@ -7,6 +7,8 @@ import AuthLayout from "../AuthLayout";
|
||||
import EmailValidator from "../../../lib/EmailValidator";
|
||||
import ForgetPwdResponse from "../ForgetPwdResponse";
|
||||
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
|
||||
export default function ForgotPassword() {
|
||||
const [checked, setValue] = useState(false);
|
||||
const [resetLoading, setResetLoading] = useState(false);
|
||||
@@ -22,9 +24,18 @@ export default function ForgotPassword() {
|
||||
setMail(e?.target.value);
|
||||
};
|
||||
|
||||
const humanChecker = () => {
|
||||
setValue(!checked);
|
||||
};
|
||||
// const humanChecker = () => {
|
||||
// setValue(!checked);
|
||||
// };
|
||||
|
||||
function humanChecker(value) {
|
||||
// console.log("Captcha value:", value);
|
||||
if(value){
|
||||
setValue(true)
|
||||
}else{
|
||||
setValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
const resetHandler = async () => {
|
||||
if (email == "") {
|
||||
@@ -113,10 +124,16 @@ export default function ForgotPassword() {
|
||||
/>
|
||||
</div>
|
||||
{/* hCaptha clone for the time being */}
|
||||
<div className="mb-10">
|
||||
<div className="mb-10 flex justify-center w-full">
|
||||
<ReCAPTCHA
|
||||
sitekey={process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY}
|
||||
onChange={humanChecker}
|
||||
/>
|
||||
</div>
|
||||
{/* <div className="mb-10">
|
||||
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
|
||||
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
|
||||
{/* Checkbox */}
|
||||
|
||||
<div className="h-full relative inline-block">
|
||||
<div className="relative table top-0 h-full">
|
||||
<div className="table-cell align-middle">
|
||||
@@ -148,18 +165,25 @@ export default function ForgotPassword() {
|
||||
<div className="h-full relative inline-block w-16"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center items-center gap-2">
|
||||
<div className="flex justify-center items-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`rounded-full mb-6 text-[15px] font-semibold text-white hover:text-white flex justify-center bg-red-500 hover:bg-red-600 transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetHandler}
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
className={`rounded-full mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
{resetLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
@@ -167,13 +191,6 @@ export default function ForgotPassword() {
|
||||
<span>Send Code</span>
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -320,7 +320,7 @@ export default function Login() {
|
||||
onClick={doLogin}
|
||||
type="button"
|
||||
disabled={loginLoading}
|
||||
className={`btn-login rounded-[0.475rem] mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
className={`btn-login rounded-full mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
@@ -329,34 +329,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={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
|
||||
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
|
||||
imgSrc={appleLogo}
|
||||
brand="Apple"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||
<BrandBtn
|
||||
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
isAnchor={true}
|
||||
/>
|
||||
<BrandBtn
|
||||
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
isAnchor={true}
|
||||
/>
|
||||
<div className="sm:grid grid-cols-2 gap-1">
|
||||
<div className="w-full">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`w-full ${
|
||||
process.env.REACT_APP_APPLE_SOCIAL_LOGIN !== 0 &&
|
||||
"hidden"
|
||||
}`}
|
||||
>
|
||||
<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}
|
||||
// style={{visibility: 'hidden'}}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<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}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`w-full ${
|
||||
process.env.REACT_APP_LINKEDIN_SOCIAL_LOGIN !== 0 &&
|
||||
"hidden"
|
||||
}`}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
@@ -416,7 +433,7 @@ export default function Login() {
|
||||
onClick={doLogin}
|
||||
disabled={loginLoading}
|
||||
type="button"
|
||||
className={`btn-login rounded-[0.475rem] text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
className={`btn-login rounded-full text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
@@ -432,12 +449,12 @@ export default function Login() {
|
||||
}
|
||||
{/* END of login component */}
|
||||
|
||||
{loginType == "full" &&
|
||||
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
||||
This site is protected by hCaptcha and the our Privacy Policy
|
||||
and Terms of Service apply.
|
||||
</div>
|
||||
}
|
||||
{loginType == "full" && (
|
||||
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
||||
This site is protected by hCaptcha and the our Privacy Policy
|
||||
and Terms of Service apply.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -446,7 +463,14 @@ export default function Login() {
|
||||
);
|
||||
}
|
||||
|
||||
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor = false }) => {
|
||||
const BrandBtn = ({
|
||||
link,
|
||||
imgSrc,
|
||||
brand,
|
||||
onClick,
|
||||
isAnchor = false,
|
||||
style = { visibility: "visible" },
|
||||
}) => {
|
||||
// const doGoogle = async () => {
|
||||
// alert("start google");
|
||||
// };
|
||||
@@ -466,7 +490,7 @@ const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor = false }) => {
|
||||
// alert("start facebook");
|
||||
// };
|
||||
return (
|
||||
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
|
||||
<div className="w-full flex justify-center bottomMargin" style={style}>
|
||||
{isAnchor ? (
|
||||
<a
|
||||
href={link}
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
export default function SignUp() {
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const country = queryParams.get("cnt")?.toUpperCase();
|
||||
|
||||
const {pathname} = useLocation()
|
||||
const currentPath = country ? `${pathname}?cnt=${country.toLowerCase()}`:pathname // Determines the new pathname is country query params exist
|
||||
|
||||
const [signUpLoading, setSignUpLoading] = useState(false);
|
||||
const [checked, setValue] = useState(false);
|
||||
// for the catch error
|
||||
const [msgError, setMsgError] = useState("");
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [countries, setCountries] = useState([]);
|
||||
const [countries, setCountries] = useState({loading:true, data:[]});
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
country: "",
|
||||
country: country? country : "",
|
||||
first_name: "",
|
||||
last_name: "",
|
||||
email: "",
|
||||
@@ -45,9 +51,18 @@ export default function SignUp() {
|
||||
try {
|
||||
if (res.status === 200) {
|
||||
const { signup_country } = await res.data;
|
||||
setCountries(signup_country);
|
||||
// setCountries(signup_country);
|
||||
if(country){ // IF LINK/PATHNAME HAS CNT QUERY VALUE
|
||||
let cnt = signup_country.filter(item => item[0]==country) // test to see country passed in query param exist from list of countries supplied by API
|
||||
if(!cnt.length){ // IF CNT EMPTY, SET FORMDATA COUNTRY BACK TO EMPTY STRING: RE: THIS IS BCOS WE INITAIL SET COUNTRY VALUE IN FORMDATA, IF COUNTRY PARAM IS PRESENT IN LINK
|
||||
setFormData(prev => ({...prev, country: ''}))
|
||||
return setCountries({loading: false, data: signup_country});
|
||||
}
|
||||
return setCountries({loading: false, data: cnt});
|
||||
}
|
||||
setCountries({loading: false, data:signup_country});
|
||||
} else if (res.data.result !== 100) {
|
||||
setCountries("Nothing see here!");
|
||||
setCountries({loading: false, data:[]});
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
@@ -134,7 +149,7 @@ export default function SignUp() {
|
||||
<AuthLayout slogan="Welcome to WrenchBoard">
|
||||
<div className="w-full">
|
||||
<div className="mb-5">
|
||||
<Link to="#">
|
||||
<Link to={currentPath}>
|
||||
<img
|
||||
src={WrenchBoard}
|
||||
alt="wrenchboard"
|
||||
@@ -172,6 +187,7 @@ export default function SignUp() {
|
||||
name="country"
|
||||
value={formData.country}
|
||||
inputHandler={handleInputChange}
|
||||
disable={country && countries?.data?.length <= 1 ? true : false}
|
||||
/>
|
||||
<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">
|
||||
@@ -306,9 +322,10 @@ export default function SignUp() {
|
||||
<div className="signin-area mb-1">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
disabled={countries.loading}
|
||||
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`}
|
||||
className={`rounded-full 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>
|
||||
@@ -333,6 +350,7 @@ const SelectOption = ({
|
||||
inputHandler,
|
||||
value,
|
||||
data, // passing the data from parent
|
||||
disable
|
||||
}) => {
|
||||
return (
|
||||
<div className="input-com mb-7">
|
||||
@@ -346,19 +364,39 @@ const SelectOption = ({
|
||||
</div>
|
||||
<div>
|
||||
<select
|
||||
disabled={disable}
|
||||
name={name}
|
||||
id={name}
|
||||
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}
|
||||
>
|
||||
<option value={""}>Select your Country</option>
|
||||
{data?.length > 0 &&
|
||||
data?.map((item, idx) => (
|
||||
{data?.data?.length > 1 ?
|
||||
<>
|
||||
<option value={""}>Select your Country</option>
|
||||
{data?.data?.map((item, idx) => (
|
||||
<option value={item[0]} key={idx}>
|
||||
{item[1]}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
:
|
||||
data?.data?.length == 1 ?
|
||||
data?.data?.map((item, idx) => (
|
||||
<option value={item[0]} key={idx}>
|
||||
{item[1]}
|
||||
</option>
|
||||
))
|
||||
:
|
||||
data?.data?.length < 1 && data.loading ?
|
||||
<option value=''>
|
||||
Loading...
|
||||
</option>
|
||||
:
|
||||
<option value=''>
|
||||
No Country Found!
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import { useEffect, useState } from "react";
|
||||
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
|
||||
|
||||
export default function AvailableJobsCard({
|
||||
className,
|
||||
@@ -156,27 +154,6 @@ export default function AvailableJobsCard({
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* <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>
|
||||
<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="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>
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
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 profile from "../../assets/images/icons/family.svg";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import usersService from "../../services/UsersService";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
@@ -29,113 +27,113 @@ export default function FamilyManageTabs({
|
||||
listReload,
|
||||
loader,
|
||||
}) {
|
||||
// Initial state for family details
|
||||
const initialDetailState = {
|
||||
loading: false,
|
||||
data: null,
|
||||
};
|
||||
|
||||
// State for family details, tasks, waitlist, and pending
|
||||
const [details, setDetails] = useState({
|
||||
familyDetails: { loading: false, data: null },
|
||||
familyTasks: { loading: false, data: null },
|
||||
familyWaitList: { loading: false, data: null },
|
||||
familyPending: { loading: false, data: null },
|
||||
familyDetails: { ...initialDetailState },
|
||||
familyTasks: { ...initialDetailState },
|
||||
familyWaitList: { ...initialDetailState },
|
||||
familyPending: { ...initialDetailState },
|
||||
});
|
||||
|
||||
// Function to reset family details, tasks, waitlist, and pending
|
||||
const resetDetails = () => {
|
||||
setDetails({
|
||||
familyDetails: { ...initialDetailState },
|
||||
familyTasks: { ...initialDetailState },
|
||||
familyWaitList: { ...initialDetailState },
|
||||
familyPending: { ...initialDetailState },
|
||||
});
|
||||
};
|
||||
|
||||
const [updatePage, setUpdatePage] = useState(false) // State to determine when to update the page
|
||||
|
||||
// State for family task data
|
||||
const [familyTask, setFamilyTask] = useState({ loading: false, data: [] });
|
||||
|
||||
// State for active task
|
||||
const [activeTask, setActiveTask] = useState({ id: 0, data: {} });
|
||||
|
||||
// State for error messages
|
||||
const [errMsg, setErrMsg] = useState("");
|
||||
|
||||
// State for family task popout
|
||||
const [familyTaskPopout, setFamilyTaskPopout] = useState(false);
|
||||
|
||||
// State for profile image
|
||||
const [profileImg, setProfileImg] = useState(profile);
|
||||
|
||||
// Ref for profile image input
|
||||
const profileImgInput = useRef(null);
|
||||
const [isPending, startTransition] = useTransition();
|
||||
|
||||
// Create an instance of the usersService class
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
// Function to handle toggling the family task popout
|
||||
const familyPopUpHandler = () => {
|
||||
setFamilyTaskPopout((prev) => !prev);
|
||||
};
|
||||
|
||||
// Function to trigger a click on the hidden profile image input
|
||||
const browseProfileImg = () => {
|
||||
profileImgInput.current.click();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the change event of the profile image input field.
|
||||
* Checks if the selected file exceeds the maximum file size limit and displays an alert if it does.
|
||||
* If the file is within the size limit, it reads the file using the FileReader API and sets the profile image state with the result.
|
||||
*/
|
||||
const profileImgChangeHandler = (e) => {
|
||||
if (e.target.value !== "") {
|
||||
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
||||
|
||||
const file = e.target.files[0];
|
||||
if (file && file.size > MAX_FILE_SIZE) {
|
||||
alert("File size exceeds the limit.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
const imgReader = new FileReader();
|
||||
imgReader.onload = (event) => {
|
||||
setProfileImg(event.target.result);
|
||||
imgReader.onload = () => {
|
||||
const imageDataUrl = imgReader.result;
|
||||
|
||||
// Set the profile image
|
||||
setProfileImg(imageDataUrl);
|
||||
};
|
||||
imgReader.readAsDataURL(e.target.files[0]);
|
||||
imgReader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
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]);
|
||||
|
||||
// Ref for the account section
|
||||
const accountRef = useRef();
|
||||
|
||||
// React-to-Print hook for handling printing
|
||||
const useHandlePrint = useReactToPrint({
|
||||
content: () => accountRef.current,
|
||||
});
|
||||
|
||||
// Array of tab names
|
||||
const tabs = [
|
||||
{ id: 1, name: "Tasks" },
|
||||
{ id: 2, name: "Waiting" },
|
||||
{ id: 3, name: "Pending" },
|
||||
];
|
||||
|
||||
// State for the currently selected tab
|
||||
const [tab, setTab] = useState(tabs[0].name);
|
||||
|
||||
// Function to handle tab changes
|
||||
const tabHandler = (value) => {
|
||||
startTransition(() => {
|
||||
setTab(value);
|
||||
});
|
||||
setTab(value);
|
||||
};
|
||||
|
||||
// Object that maps tab names to their corresponding components
|
||||
const tabComponents = {
|
||||
Tasks: (
|
||||
<FamilyTasks
|
||||
@@ -156,7 +154,7 @@ export default function FamilyManageTabs({
|
||||
<FamilyPending
|
||||
familyData={details.familyPending.data}
|
||||
accountDetails={accountDetails}
|
||||
loader={details.familyWaitList.loading}
|
||||
loader={details.familyPending.loading}
|
||||
/>
|
||||
),
|
||||
Account: (
|
||||
@@ -170,6 +168,7 @@ export default function FamilyManageTabs({
|
||||
Profile: <FamilyProfile />,
|
||||
};
|
||||
|
||||
// Default tab component
|
||||
const defaultTabComponent = (
|
||||
<FamilyTasks
|
||||
className={className}
|
||||
@@ -179,17 +178,101 @@ export default function FamilyManageTabs({
|
||||
/>
|
||||
);
|
||||
|
||||
// Selected tab component based on the current 'tab'
|
||||
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
||||
|
||||
// Effect to manage family details and related data
|
||||
useEffect(() => {
|
||||
let __manageFamily = true;
|
||||
if (__manageFamily) {
|
||||
manageFamily();
|
||||
}
|
||||
return () => {
|
||||
__manageFamily = false;
|
||||
const manageFamily = async () => {
|
||||
try {
|
||||
resetDetails();
|
||||
|
||||
setDetails({
|
||||
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;
|
||||
|
||||
// Function to check for errors in data
|
||||
const checkDataError = (data) => data?.internal_return < 0;
|
||||
|
||||
if (
|
||||
checkDataError(familyData) ||
|
||||
checkDataError(tasksData) ||
|
||||
checkDataError(familyWaitData) ||
|
||||
checkDataError(familyPendingData)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDetails({
|
||||
familyDetails: { loading: false, data: familyData },
|
||||
familyTasks: { loading: false, data: tasksData },
|
||||
familyWaitList: { loading: false, data: familyWaitData },
|
||||
familyPending: { loading: false, data: familyPendingData },
|
||||
});
|
||||
} catch (error) {
|
||||
resetDetails();
|
||||
setErrMsg("An error occurred");
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
}, [tab, manageFamily]);
|
||||
|
||||
// Invoke the manageFamily function when the component mounts
|
||||
manageFamily();
|
||||
}, [updatePage]);
|
||||
|
||||
// Effect to manage family tasks
|
||||
useEffect(() => {
|
||||
let checkFamilyTask = true;
|
||||
const reqData = {
|
||||
limit: 30,
|
||||
offset: 0,
|
||||
job_type: "FAMILY",
|
||||
action: 13005,
|
||||
};
|
||||
|
||||
if (checkFamilyTask) {
|
||||
setFamilyTask({ loading: true });
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
// Cleanup function to prevent memory leaks
|
||||
return () => {
|
||||
checkFamilyTask = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -265,7 +348,7 @@ export default function FamilyManageTabs({
|
||||
Add task
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex-[0.9] h-full">
|
||||
<div className="h-full relative overflow-y-auto">
|
||||
<Suspense
|
||||
@@ -285,7 +368,12 @@ export default function FamilyManageTabs({
|
||||
<AssignTaskPopout
|
||||
action={familyPopUpHandler}
|
||||
situation={familyTaskPopout}
|
||||
familyDetails={details.familyDetails.data}
|
||||
familyTask={familyTask}
|
||||
setFamilyTask={setFamilyTask}
|
||||
setActiveTask={setActiveTask}
|
||||
activeTask={activeTask}
|
||||
familyDetailsData={details.familyDetails.data}
|
||||
setUpdatePage={setUpdatePage}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,441 +1,420 @@
|
||||
import React, { useState, useEffect, useTransition } from "react";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import Detail from "../../jobPopout/popoutcomponent/Detail";
|
||||
import React, { useState } from "react";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import Detail from "../../jobPopout/popoutcomponent/Detail";
|
||||
import { NewTasks } from "./forms";
|
||||
|
||||
const AssignTaskPopout = React.memo(({ action, details, situation, familyDetails }) => {
|
||||
const apiCall = new usersService();
|
||||
const AssignTaskPopout = React.memo(
|
||||
({
|
||||
action,
|
||||
details,
|
||||
situation,
|
||||
familyDetailsData,
|
||||
familyTask,
|
||||
activeTask,
|
||||
setActiveTask,
|
||||
setUpdatePage
|
||||
}) => {
|
||||
const apiCall = new usersService();
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "",
|
||||
}); // HOLDS RESPONSE FOR SENDING API REQUEST
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "",
|
||||
}); // HOLDS RESPONSE FOR SENDING API REQUEST
|
||||
|
||||
let [familyTask, setFamilyTask] = useState({ loading: false, data: [] });
|
||||
let [taskType, setTaskType] = useState(details ? "new" : "select"); // SWITCHES BTW SELECT TASK AND NEW TASK
|
||||
|
||||
let [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 handleActiveTask = (id = 0, data = {}) => {
|
||||
// FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setActiveTask({ id, data });
|
||||
};
|
||||
|
||||
const switchTaskType = ({ target: { value } }) => {
|
||||
// FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setTaskType(value);
|
||||
};
|
||||
// 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 handleActiveTask = (id = 0, data = {}) => {
|
||||
// FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setActiveTask({ id, data });
|
||||
};
|
||||
|
||||
// New Task
|
||||
const [formState, setFormState] = useState({
|
||||
// Initialize form state with desired fields
|
||||
banner: details?.banner || "default.jpg",
|
||||
country: details?.country || "",
|
||||
price: details?.price || "",
|
||||
title: details?.title || "",
|
||||
description: details?.description || "",
|
||||
job_detail: details?.job_detail || "",
|
||||
timeline_days: details?.timeline_days || "",
|
||||
category: details?.category || "",
|
||||
});
|
||||
|
||||
const assignFamilyTask = () => {
|
||||
setRequestStatus({ loading: true, status: false, message: "" });
|
||||
let reqData = {};
|
||||
if (taskType == "select") {
|
||||
// RUNS HERE IF TASK TYPE IS SELECT
|
||||
if (!Object.keys(activeTask.data).length) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "No Task is seleted",
|
||||
});
|
||||
return setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 3000);
|
||||
}
|
||||
reqData = {
|
||||
// API PAYLOADS
|
||||
job_id: activeTask.data?.job_id,
|
||||
job_uid: activeTask.data?.job_uid,
|
||||
family_uid: familyDetails?.uid || details?.family_uid,
|
||||
job_description: activeTask.data?.description,
|
||||
assign_mode: 110011,
|
||||
};
|
||||
}
|
||||
|
||||
if (taskType === "new") {
|
||||
const {
|
||||
banner,
|
||||
category,
|
||||
country,
|
||||
description,
|
||||
job_detail,
|
||||
price,
|
||||
timeline_days,
|
||||
title,
|
||||
} = formState;
|
||||
|
||||
const requiredFields = {
|
||||
banner,
|
||||
// category,
|
||||
country,
|
||||
description,
|
||||
job_detail,
|
||||
price,
|
||||
timeline_days,
|
||||
title,
|
||||
};
|
||||
|
||||
for (let field in requiredFields) {
|
||||
if (requiredFields[field] == "") {
|
||||
// let currencyErrMsg = field == "country" && "currency"
|
||||
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: `${field} is empty`,
|
||||
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: familyDetailsData?.uid || details?.family_uid,
|
||||
job_description: activeTask.data?.description,
|
||||
assign_mode: 110011,
|
||||
};
|
||||
}
|
||||
|
||||
reqData = {
|
||||
banner,
|
||||
category,
|
||||
country,
|
||||
description,
|
||||
job_detail,
|
||||
price: price * 100,
|
||||
timeline_days,
|
||||
title,
|
||||
assign_mode: 110055,
|
||||
family_uid: details?.family_uid || familyDetails?.uid,
|
||||
};
|
||||
}
|
||||
if (taskType === "new") {
|
||||
const {
|
||||
banner,
|
||||
category,
|
||||
country,
|
||||
description,
|
||||
job_detail,
|
||||
price,
|
||||
timeline_days,
|
||||
title,
|
||||
} = formState;
|
||||
|
||||
apiCall
|
||||
.assignFamilyTask(reqData)
|
||||
.then((res) => {
|
||||
if (res.status != 200 || res.data.internal_return < 0) {
|
||||
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 || familyDetailsData?.uid,
|
||||
};
|
||||
}
|
||||
|
||||
apiCall
|
||||
.assignFamilyTask(reqData)
|
||||
.then((res) => {
|
||||
if (res.status != 200 || res.data.internal_return < 0) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "failed to assign task",
|
||||
});
|
||||
return setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
}
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: true,
|
||||
message: "action successful",
|
||||
});
|
||||
setUpdatePage(prev => !prev) // Updates family task page by calling the useeffect hook
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
action(); // FUNCTION THAT CLOSES THE MODAL BOX
|
||||
}, 5000);
|
||||
})
|
||||
.catch((err) => {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "failed to assign task",
|
||||
message: "An Error occured, try again",
|
||||
});
|
||||
return setTimeout(() => {
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
}
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: true,
|
||||
message: "action successful",
|
||||
});
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
action(); // FUNCTION THAT CLOSES THE MODAL BOX
|
||||
}, 5000);
|
||||
})
|
||||
.catch((err) => {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "An Error occured, try again",
|
||||
});
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let checkFamilyTask = true;
|
||||
const reqData = {
|
||||
limit: 30,
|
||||
offset: 0,
|
||||
job_type: "FAMILY",
|
||||
action: 13005,
|
||||
};
|
||||
|
||||
apiCall
|
||||
.getMyJobList(reqData)
|
||||
.then((res) => {
|
||||
if (checkFamilyTask) {
|
||||
setFamilyTask({ loading: false, data: res?.data?.result_list });
|
||||
if (res?.data?.result_list?.length) {
|
||||
setActiveTask((prev) => ({
|
||||
...prev,
|
||||
data: res?.data?.result_list[0],
|
||||
}));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
setFamilyTask({ loading: false, data: [] });
|
||||
console.log("Error", err);
|
||||
});
|
||||
|
||||
return () => {
|
||||
checkFamilyTask = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ModalCom
|
||||
action={action}
|
||||
situation={situation}
|
||||
className="assign-task-popup"
|
||||
>
|
||||
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Assign task to {familyDetails?.firstname || details.firstName}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={action}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
return (
|
||||
<>
|
||||
<ModalCom
|
||||
action={action}
|
||||
situation={situation}
|
||||
className="assign-task-popup"
|
||||
>
|
||||
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Assign task to{" "}
|
||||
{familyDetailsData?.firstname || details?.firstName}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={action}
|
||||
>
|
||||
<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" />
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
className={`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>
|
||||
{familyTask.loading ? (
|
||||
<div className="h-[100px] w-full flex justify-center items-center">
|
||||
<LoadingSpinner color="sky-blue" size="16" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
className={`job-action-modal-body w-full md:grid ${
|
||||
taskType !== "new" ? "md:grid-cols-2" : "md:grid-cols-1"
|
||||
}`}
|
||||
>
|
||||
<div className="p-4">
|
||||
<div className="mb-2 w-full flex items-center gap-4">
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input
|
||||
type="radio"
|
||||
name="task-type"
|
||||
value="select"
|
||||
className="w-[20px] h-[20px] cursor-pointer"
|
||||
checked={taskType == "select"}
|
||||
onChange={switchTaskType}
|
||||
/>
|
||||
<span>Select Task</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input
|
||||
type="radio"
|
||||
name="task-type"
|
||||
value="new"
|
||||
className="w-[20px] h-[20px] cursor-pointer"
|
||||
checked={taskType == "new"}
|
||||
onChange={switchTaskType}
|
||||
/>
|
||||
<span>New Task</span>
|
||||
</div>
|
||||
</div>
|
||||
<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={() =>
|
||||
{/* Task Type === select */}
|
||||
{taskType == "select" && (
|
||||
<div className="p-4 w-full h-[400px] overflow-y-auto bg-slate-100 rounded-md dark:bg-[#11131f] dark:text-white">
|
||||
{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)
|
||||
}
|
||||
className="w-[15px] h-[15px] cursor-pointer"
|
||||
/>
|
||||
<p className="w-full text-dark-gray tracking-wide">
|
||||
{item?.title}
|
||||
>
|
||||
<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 dark:text-white tracking-wide">
|
||||
{item?.title}
|
||||
</p>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center cursor-default">
|
||||
No Task found!
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{taskType == "new" && (
|
||||
<div className="p-4 w-full h-[400px]">
|
||||
<NewTasks
|
||||
formState={formState}
|
||||
setFormState={setFormState}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/*Right Hand Side for details && Task Type === select */}
|
||||
{taskType == "select" && (
|
||||
<>
|
||||
{familyTask?.data?.length > 0 ? (
|
||||
<div className="p-4">
|
||||
<div className="w-full">
|
||||
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">
|
||||
{activeTask?.data?.title}
|
||||
</p>
|
||||
<div className="my-3">
|
||||
<Detail
|
||||
label="Description"
|
||||
value={activeTask?.data?.description}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Price
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">
|
||||
{PriceFormatter(
|
||||
activeTask?.data?.price * 0.01,
|
||||
activeTask?.data?.currency,
|
||||
activeTask?.data?.curreny_code
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Timeline
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">{`${activeTask?.data?.timeline_days} day(s)`}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="my-3 sm:flex items-center">
|
||||
<Detail
|
||||
label="Created"
|
||||
value={`Dummy, no value found for created!`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="my-3">
|
||||
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Delivery Detail
|
||||
</label>
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
|
||||
rows="5"
|
||||
style={{ resize: "none" }}
|
||||
value={activeTask?.data?.job_detail}
|
||||
readOnly
|
||||
// onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
</div>
|
||||
) : (
|
||||
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center cursor-default">
|
||||
No Task found!
|
||||
</p>
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{taskType == "new" && (
|
||||
<div className="p-4 w-full h-[400px]">
|
||||
<NewTasks
|
||||
formState={formState}
|
||||
setFormState={setFormState}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/*Right Hand Side for details && Task Type === select */}
|
||||
{taskType == "select" && (
|
||||
<>
|
||||
{familyTask?.data?.length > 0 ? (
|
||||
<div className="p-4">
|
||||
<div className="w-full">
|
||||
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">
|
||||
{activeTask?.data?.title}
|
||||
</p>
|
||||
<div className="my-3">
|
||||
<Detail
|
||||
label="Description"
|
||||
value={activeTask?.data?.description}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Price
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">
|
||||
{PriceFormatter(
|
||||
activeTask?.data?.price * 0.01,
|
||||
activeTask?.data?.currency,
|
||||
activeTask?.data?.curreny_code
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className="text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Timeline
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">{`${activeTask?.data?.timeline_days} day(s)`}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="my-3 sm:flex items-center">
|
||||
<Detail
|
||||
label="Created"
|
||||
value={`Dummy, no value found for created!`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="my-3">
|
||||
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||
Delivery Detail
|
||||
</label>
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
|
||||
rows="5"
|
||||
style={{ resize: "none" }}
|
||||
value={activeTask?.data?.job_detail}
|
||||
readOnly
|
||||
// onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* BTN */}
|
||||
<div className="py-2 px-4 border-t-2 flex justify-between items-center">
|
||||
{/* error or success display */}
|
||||
<div className="w-auto h-auto flex items-center">
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-2 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px] self-start`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
{/* 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-green-700 bg-slate-200 border-slate-800 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>
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
<div
|
||||
className={`relative p-2 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* End of error or success display */}
|
||||
<div className="w-auto h-auto flex items-center gap-3">
|
||||
<button
|
||||
disabled={requestStatus.loading}
|
||||
onClick={action}
|
||||
type="button"
|
||||
className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
<span className="text-gradient">Close</span>
|
||||
</button>
|
||||
<div className="">
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner color="sky-blue" size="8" />
|
||||
) : taskType == "select" ? (
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
Assign
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
{`Assign to ${
|
||||
familyDetails?.firstname || details?.firstName
|
||||
}`}
|
||||
</button>
|
||||
)}
|
||||
{/* End of error or success display */}
|
||||
<div className="w-auto h-auto flex items-center gap-3">
|
||||
<button
|
||||
disabled={requestStatus.loading}
|
||||
onClick={action}
|
||||
type="button"
|
||||
className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
<span className="text-gradient">Close</span>
|
||||
</button>
|
||||
<div className="">
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner color="sky-blue" size="8" />
|
||||
) : taskType == "select" ? (
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
Assign
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
{`Assign to ${
|
||||
familyDetailsData?.firstname || details?.firstName
|
||||
}`}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</ModalCom>
|
||||
</>
|
||||
);
|
||||
})
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</ModalCom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default AssignTaskPopout;
|
||||
export default AssignTaskPopout;
|
||||
|
||||
@@ -1,29 +1,124 @@
|
||||
import React, { useState } from "react";
|
||||
import dataImage1 from "../../assets/images/data-table-user-1.png";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
import familyImage from '../../assets/images/no-family-side.png'
|
||||
import familyImage from "../../assets/images/no-family-side.png";
|
||||
import { formatDateString } from "../../lib";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
export default function FamilyTable({ className, familyList, loader, popUpHandler }) {
|
||||
const navigate = useNavigate();
|
||||
/**
|
||||
* Renders a list of family members that can be managed.
|
||||
* It has its current maximum members at 8 and it comes with pagination and loading spinner functionality.
|
||||
|
||||
* @returns {JSX.Element} - The rendered component.
|
||||
*/
|
||||
export default function FamilyTable({
|
||||
className,
|
||||
familyList,
|
||||
loader,
|
||||
popUpHandler,
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
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 currentFamilyList = familyList?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
const currentFamilyList = familyList?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
const handleManageClick = (familyMember) => {
|
||||
navigate("/manage-family", { state: familyMember });
|
||||
};
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a table row for a family member.
|
||||
* @returns {JSX.Element} - The table row component.
|
||||
*/
|
||||
const FamilyRow = ({
|
||||
firstname,
|
||||
lastname,
|
||||
age,
|
||||
added,
|
||||
last_login,
|
||||
task_count,
|
||||
family_uid,
|
||||
banner,
|
||||
}) => {
|
||||
// Check for valid dates
|
||||
const addedDate = added ? added.split(" ")[0] : "N/A";
|
||||
const loginDate = last_login ? formatDateString(last_login) : "N/A";
|
||||
|
||||
return (
|
||||
<tr
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
key={family_uid}
|
||||
>
|
||||
<td className="py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1]">
|
||||
<img
|
||||
src={localImgLoad(`images/icons/${banner}`)}
|
||||
alt={`Avatar of ${firstname} ${lastname}`}
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
{`${firstname} ${lastname} (${age})`}
|
||||
</h1>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Added: <span className="text-purple ml-1">{addedDate}</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Last Login:{" "}
|
||||
<span className="text-purple ml-1">{loginDate}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
||||
{task_count}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-right py-4 px-2 flex items-center justify-center">
|
||||
<button
|
||||
onClick={() =>
|
||||
handleManageClick({
|
||||
firstname,
|
||||
lastname,
|
||||
age,
|
||||
added,
|
||||
last_login,
|
||||
task_count,
|
||||
family_uid,
|
||||
banner,
|
||||
})
|
||||
}
|
||||
type="button"
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] ${
|
||||
className={`update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] flex flex-col justify-between ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
@@ -32,125 +127,51 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
|
||||
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
</div>
|
||||
)
|
||||
:
|
||||
familyList?.length > 0 ?
|
||||
(
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 relative">
|
||||
<thead className="sticky top-0">
|
||||
<tr className="text-base text-thin-light-gray whitespace-nowrap border-b dark:border-[#5356fb29] default-border-bottom ">
|
||||
<th className="py-4">Name</th>
|
||||
<th className="py-4 text-center">Last Login</th>
|
||||
<th className="py-4 text-center">No of Tasks</th>
|
||||
<th className="py-4 text-right"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="h-full">
|
||||
{currentFamilyList?.map((props, idx) => {
|
||||
let {
|
||||
firstname,
|
||||
lastname,
|
||||
age,
|
||||
added,
|
||||
last_login,
|
||||
task_count,
|
||||
family_uid,
|
||||
banner
|
||||
} = props;
|
||||
let addedDate = added?.split(" ")[0];
|
||||
let LoginDate = last_login?.split(" ")[0];
|
||||
return (
|
||||
<tr
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
key={family_uid}
|
||||
>
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1]">
|
||||
<img
|
||||
// src={dataImage1}
|
||||
src={localImgLoad(`images/icons/${banner}`)}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
{`${firstname} ${lastname} (${age})`}
|
||||
</h1>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Added:{" "}
|
||||
<span className="text-purple ml-1">
|
||||
{addedDate}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
||||
{LoginDate}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
||||
{task_count}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-right py-4 px-2 flex items-center justify-center">
|
||||
<button
|
||||
onClick={() => {
|
||||
navigate("/manage-family", {
|
||||
state: { ...props },
|
||||
});
|
||||
}}
|
||||
type="button"
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
:
|
||||
(
|
||||
<div className="font-bold text-center text-xl md:text-2xl lg:text-4xl text-dark-gray md:flex items-center justify-between">
|
||||
<div className="p-2 w-full md:w-1/2">
|
||||
<p className="mb-4 p-3 md:p-16">Add your family, assign tasks, and get the whole team engaged.</p>
|
||||
<button
|
||||
onClick={popUpHandler}
|
||||
type="button"
|
||||
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
|
||||
>
|
||||
Add Family
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-2 w-full md:w-1/2">
|
||||
<img className='w-full' src={familyImage} alt="Add Family" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
) : (
|
||||
<>
|
||||
{familyList?.length > 0 ? (
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 relative">
|
||||
<thead className="sticky top-0">
|
||||
<tr className="text-base text-thin-light-gray whitespace-nowrap border-b dark:border-[#5356fb29] default-border-bottom ">
|
||||
<th className="py-4">Name</th>
|
||||
<th className="py-4 text-center">No of Tasks</th>
|
||||
<th className="py-4 text-right"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="h-full">
|
||||
{currentFamilyList?.map((familyMember) => {
|
||||
return <FamilyRow {...familyMember} />;
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
) : (
|
||||
<div className="font-bold text-center text-xl md:text-2xl lg:text-4xl text-dark-gray md:flex items-center justify-between">
|
||||
<div className="p-2 w-full md:w-1/2">
|
||||
<p className="mb-4 p-3 md:p-16">
|
||||
Add your family, assign tasks, and get the whole team
|
||||
engaged.
|
||||
</p>
|
||||
<button
|
||||
onClick={popUpHandler}
|
||||
type="button"
|
||||
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
|
||||
>
|
||||
Add Family
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-2 w-full md:w-1/2">
|
||||
<img className="w-full" src={familyImage} alt="Add Family" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
familyList?.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
prev={currentPage == 0}
|
||||
next={currentPage + itemsPerPage >= familyList.length}
|
||||
data={familyList}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { forwardRef } from "react";
|
||||
import QRCode from "react-qr-code";
|
||||
import { useSelector } from "react-redux";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
|
||||
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
||||
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint, loader }, ref) => {
|
||||
const { userDetails } = useSelector((state) => state.userDetails);
|
||||
return (
|
||||
<div
|
||||
className="w-full lg:min-h-[538px] p-3 h-full flex flex-col items-center justify-center"
|
||||
@@ -32,12 +35,19 @@ const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
||||
<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>
|
||||
{loader ?
|
||||
<div className="w-full">
|
||||
<LoadingSpinner size='8' color='sky-blue' />
|
||||
</div>
|
||||
:
|
||||
<QRCode
|
||||
size={256}
|
||||
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
|
||||
value={`https://www.google.com`}
|
||||
// value={`https://www.google.com`}
|
||||
value={`${userDetails?.uid}@${familyData?.username}@${familyData?.uid}`}
|
||||
viewBox={`0 0 256 256`}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] w-full flex justify-center items-center">
|
||||
|
||||
@@ -90,7 +90,7 @@ export default function FamilyTasks({
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
{value.title}
|
||||
</h1>
|
||||
<div className="flex gap-4 items-center">
|
||||
<div className="flex flex-col sm:flex-row items-start gap-1 md:gap-4 md:items-center">
|
||||
<span className="text-sm text-thin-light-gray flex flex-start gap-1">
|
||||
Price:{" "}
|
||||
<span className="text-purple">
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
import React from "react";
|
||||
import localImgLoad from "../../../lib/localImgLoad";
|
||||
|
||||
|
||||
export default function ProfileInfo({
|
||||
profileImg,
|
||||
profileImgInput,
|
||||
profileImgChangHandler,
|
||||
profileImgChangeHandler,
|
||||
browseProfileImg,
|
||||
accountDetails,
|
||||
}) {
|
||||
// console.log(accountDetails.banner)
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={localImgLoad(`images/icons/${accountDetails.banner}`)}
|
||||
alt=""
|
||||
src={
|
||||
profileImg
|
||||
? profileImg
|
||||
: localImgLoad(`images/icons/${accountDetails.banner}`)
|
||||
}
|
||||
alt="profile"
|
||||
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
accept="image/*"
|
||||
onChange={profileImgChangeHandler}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
|
||||
@@ -5,16 +5,18 @@ import React, {
|
||||
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 InputCom from "../Helpers/Inputs/InputCom";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import FamilyTable from "./FamilyTable";
|
||||
|
||||
export default function FamilyAcc() {
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const [selectedAge, setSelectedAge] = useState(undefined);
|
||||
// State to store the selected year and month
|
||||
const [selectedYear, setSelectedYear] = useState("");
|
||||
const [selectedMonth, setSelectedMonth] = useState("");
|
||||
const [familyList, setFamilyList] = useState([]);
|
||||
const [loader, setLoader] = useState(false);
|
||||
const [popUp, setPopUp] = useState(false);
|
||||
@@ -35,17 +37,14 @@ export default function FamilyAcc() {
|
||||
setValue(value);
|
||||
};
|
||||
|
||||
const ageRange = useMemo(() => {
|
||||
const startAge = 5;
|
||||
const endAge = 16;
|
||||
return Array.from(
|
||||
{ length: endAge - startAge + 1 },
|
||||
(_, index) => startAge + index
|
||||
);
|
||||
}, []);
|
||||
// Handle year selection
|
||||
const handleYearChange = (e) => {
|
||||
setSelectedYear(e.target.value);
|
||||
};
|
||||
|
||||
const handleAgeSelect = (event) => {
|
||||
setSelectedAge(parseInt(event.target.value));
|
||||
// Handle month selection
|
||||
const handleMonthChange = (e) => {
|
||||
setSelectedMonth(e.target.value);
|
||||
};
|
||||
|
||||
const handleInputChange = (event) => {
|
||||
@@ -53,6 +52,13 @@ export default function FamilyAcc() {
|
||||
setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
|
||||
};
|
||||
|
||||
// use the useEffect hook to clear the selected month if the year changes (to ensure consistency)
|
||||
useEffect(() => {
|
||||
if (selectedYear === "" && selectedMonth !== "") {
|
||||
setSelectedMonth("");
|
||||
}
|
||||
}, [selectedYear]);
|
||||
|
||||
const addMember = async () => {
|
||||
const { first_name, last_name } = formData;
|
||||
setLoader(true);
|
||||
@@ -61,7 +67,8 @@ export default function FamilyAcc() {
|
||||
const reqData = {
|
||||
firstname: first_name,
|
||||
lastname: last_name,
|
||||
age: selectedAge,
|
||||
year: +selectedYear,
|
||||
month: +selectedMonth,
|
||||
};
|
||||
|
||||
const res = await apiCall.addFamily(reqData);
|
||||
@@ -91,7 +98,8 @@ export default function FamilyAcc() {
|
||||
first_name: "",
|
||||
last_name: "",
|
||||
});
|
||||
setSelectedAge("");
|
||||
setSelectedMonth("");
|
||||
setSelectedYear("");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -143,13 +151,16 @@ export default function FamilyAcc() {
|
||||
>
|
||||
Family Accounts
|
||||
</span>
|
||||
<button
|
||||
onClick={popUpHandler}
|
||||
type="button"
|
||||
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
{familyList.length < process.env.REACT_APP_MAX_FAMILY_MEMBERS &&
|
||||
!loader && (
|
||||
<button
|
||||
onClick={popUpHandler}
|
||||
type="button"
|
||||
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
)}
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
@@ -173,9 +184,10 @@ export default function FamilyAcc() {
|
||||
<FamilyForm
|
||||
popUpHandler={popUpHandler}
|
||||
value={formData}
|
||||
ageHandler={handleAgeSelect}
|
||||
ageRange={ageRange}
|
||||
ageValue={selectedAge}
|
||||
selectedYear={selectedYear}
|
||||
selectedMonth={selectedMonth}
|
||||
monthHandler={handleMonthChange}
|
||||
yearHandler={handleYearChange}
|
||||
inputHandler={handleInputChange}
|
||||
msgErr={msgErr}
|
||||
onClick={addMember}
|
||||
@@ -191,8 +203,10 @@ const FamilyForm = ({
|
||||
value: { first_name, last_name },
|
||||
ageValue,
|
||||
inputHandler,
|
||||
ageHandler,
|
||||
ageRange,
|
||||
selectedMonth,
|
||||
selectedYear,
|
||||
monthHandler,
|
||||
yearHandler,
|
||||
msgErr,
|
||||
loader,
|
||||
onClick,
|
||||
@@ -237,33 +251,22 @@ const FamilyForm = ({
|
||||
value={last_name}
|
||||
inputHandler={inputHandler}
|
||||
/>
|
||||
<div className="input-com mb-7 flex gap-1 items-center w-full justify-between">
|
||||
<div className="input-com mb-7 flex flex-col gap-1 w-full">
|
||||
{/* Age dropdown */}
|
||||
<div className="flex items-center justify-between flex-[0.3]">
|
||||
<div className="">
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[15px] font-semibold"
|
||||
htmlFor="age-selection"
|
||||
>
|
||||
Select your age:
|
||||
Birthday: (Year/Month)
|
||||
</label>
|
||||
</div>
|
||||
<div className=" flex-[0.7] max-w-[150px]">
|
||||
<select
|
||||
name="age-selection"
|
||||
id="age-selection"
|
||||
className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-[35px] 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 px-4"
|
||||
onChange={ageHandler}
|
||||
value={ageValue}
|
||||
>
|
||||
<option value={""}>Select age</option>
|
||||
{ageRange?.length > 0 &&
|
||||
ageRange?.map((age) => (
|
||||
<option value={age} key={age}>
|
||||
{age}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<YearMonthDropdowns
|
||||
handleMonthChange={monthHandler}
|
||||
handleYearChange={yearHandler}
|
||||
selectedMonth={selectedMonth}
|
||||
selectedYear={selectedYear}
|
||||
/>
|
||||
</div>
|
||||
{msgErr && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-xs font-light leading-[19.5px]">
|
||||
@@ -312,3 +315,66 @@ const CloseIcon = () => (
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
function YearMonthDropdowns({
|
||||
selectedMonth,
|
||||
selectedYear,
|
||||
handleMonthChange,
|
||||
handleYearChange,
|
||||
}) {
|
||||
// Get the current year
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
// Generate an array of years from the current year to (currentYear - 19)
|
||||
const years = Array.from({ length: 17 }, (_, index) => currentYear - index);
|
||||
|
||||
// Array of month names
|
||||
const months = [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex max-w-[330px] w-full self-end gap-4">
|
||||
<select
|
||||
id="yearDropdown"
|
||||
value={selectedYear}
|
||||
onChange={handleYearChange}
|
||||
className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-56 rounded-[35px] h-10 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 px-4"
|
||||
// size="5"
|
||||
>
|
||||
<option value="">Select a Year</option>
|
||||
{years.map((year) => (
|
||||
<option key={year} value={year}>
|
||||
{year}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<select
|
||||
id="monthDropdown"
|
||||
value={selectedMonth}
|
||||
onChange={handleMonthChange}
|
||||
className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-56 rounded-[35px] h-10 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 px-4"
|
||||
// size="5"
|
||||
>
|
||||
<option value="">Select a Month</option>
|
||||
{months.map((month, index) => (
|
||||
<option key={month} value={index + 1}>
|
||||
{month}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ export default function InputCom({
|
||||
maxLength = 45,
|
||||
minLength = 0,
|
||||
direction,
|
||||
tabIndex,
|
||||
error,
|
||||
}) {
|
||||
const inputRef = useRef(null);
|
||||
@@ -92,14 +93,15 @@ export default function InputCom({
|
||||
value={value}
|
||||
onChange={inputHandler}
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full ${
|
||||
inputBg ? inputBg : "bg-[#FAFAFA] tracking-wide"
|
||||
} dark:bg-[#11131F] focus:ring-0 focus:outline-none ${fieldClass}`}
|
||||
inputBg ? inputBg : "bg-[#FAFAFA] dark:bg-[#11131F] dark:text-white tracking-wide"
|
||||
} focus:ring-0 focus:outline-none ${fieldClass}`}
|
||||
type={type}
|
||||
id={name}
|
||||
name={name}
|
||||
onInput={onInput}
|
||||
minLength={minLengthValidation()}
|
||||
maxLength={maxLengthValidation()}
|
||||
tabIndex={tabIndex}
|
||||
// pattern={inputPatterns()}
|
||||
ref={inputRef}
|
||||
readOnly={disable}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import React from "react";
|
||||
import datas from "../../data/product_data.json";
|
||||
import TopSellerTopBuyerSliderSection from "./TopSellerTopBuyerSliderSection";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import FamilyActiveLSlde from "./FamilyActiveLSlde";
|
||||
import ParentWaiting from "../MyPendingJobs/ParentWaiting";
|
||||
import MyOffersFamilyTable from "../MyTasks/MyOffersFamilyTable";
|
||||
import FamilyActiveLSlde from "./FamilyActiveLSlde";
|
||||
|
||||
export default function FamilyDash({familyOffers, MyActiveJobList}) {
|
||||
export default function FamilyDash({ familyOffers, MyActiveJobList }) {
|
||||
console.log("PROPS IN FAMILY DASH->", familyOffers);
|
||||
|
||||
const trending = MyActiveJobList;
|
||||
@@ -14,13 +11,13 @@ export default function FamilyDash({familyOffers, MyActiveJobList}) {
|
||||
<div>
|
||||
<div className="home-page-wrapper">
|
||||
{/* <CommonHead commonHeadData={props.commonHeadData} /> */}
|
||||
{familyOffers && familyOffers.length > 0 &&
|
||||
<MyOffersFamilyTable familyOffers={familyOffers} className="mb-10" />
|
||||
}
|
||||
{trending && trending.length > 0 &&
|
||||
<FamilyActiveLSlde trending={trending} className="mb-10" />
|
||||
}
|
||||
|
||||
{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>
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
import React from "react";
|
||||
import datas from "../../data/product_data.json";
|
||||
import Hero from "./Hero";
|
||||
// import HomeTaskDisplay from "./HomeTaskDisplay";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { useSelector } from "react-redux";
|
||||
// import SellHistoryMarketVisitorAnalytic from './SellHistoryMarketVisitorAnalytic';
|
||||
// import TopSellerTopBuyerSliderSection from "./TopSellerTopBuyerSliderSection";
|
||||
//import UpdateTable from "./UpdateTable";
|
||||
import MyJobTable from "../MyTasks/MyJobTable";
|
||||
import MyOffersTable from "../MyTasks/MyOffersTable";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import Hero from "./Hero";
|
||||
import HomeActivities from "./HomeActivities";
|
||||
|
||||
export default function FullAccountDash(props) {
|
||||
console.log("PROPS IN HOME->", props);
|
||||
// console.log("PROPS IN HOME->", props);
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
<div className="home-page-wrapper">
|
||||
<Hero
|
||||
className="mb-10"
|
||||
@@ -22,7 +19,31 @@ export default function FullAccountDash(props) {
|
||||
bannerList={props.bannerList}
|
||||
nextDueTask={props.nextDueTask}
|
||||
/>
|
||||
<HomeActivities className="mb-10" />
|
||||
{props.offersList?.data?.result_list?.length ? (
|
||||
<MyOffersTable
|
||||
MyActiveOffersList={props.offersList?.data}
|
||||
className="mb-10"
|
||||
/>
|
||||
) : props.MyActiveJobList?.data?.length ? (
|
||||
<>
|
||||
<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>My Tasks</span>
|
||||
</h1>
|
||||
</div>
|
||||
<MyJobTable
|
||||
ActiveJobList={props.MyActiveJobList}
|
||||
Account={userDetails}
|
||||
/>
|
||||
</>
|
||||
) : !props.offersList?.loading && !props.MyActiveJobList?.loading ? (
|
||||
<HomeActivities className="mb-10" />
|
||||
) : (
|
||||
<div className="w-full h-[220px] flex items-center justify-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/*<UpdateTable className="mb-10"/>*/}
|
||||
{/*<SellHistoryMarketVisitorAnalytic className="mb-10"/>*/}
|
||||
{/*<TopSellerTopBuyerSliderSection className="mb-10" />*/}
|
||||
@@ -33,24 +54,6 @@ export default function FullAccountDash(props) {
|
||||
{/* bannerList={props.bannerList}*/}
|
||||
{/*/>*/}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
// /*
|
||||
// <Layout>
|
||||
// <div className="home-page-wrapper">
|
||||
// <Hero className="mb-10" data={userDetails} />
|
||||
// {/* <CreateNft />
|
||||
// <TrendingSection trending={trending} className="mb-10" />*/}
|
||||
// <HomeTaskDisplay
|
||||
// jobData={jobData}
|
||||
// className="mb-10"
|
||||
// bannerList={props.bannerList}
|
||||
// />
|
||||
{
|
||||
/* <SellHistoryMarketVisitorAnalytic className="mb-10"/>
|
||||
<TopSellerTopBuyerSliderSection className="mb-10" />
|
||||
<UpdateTable className="mb-10"/>*/
|
||||
}
|
||||
// </div>
|
||||
// </Layout>
|
||||
|
||||
@@ -1,267 +1,133 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import dataImage1 from "../../assets/images/data-table-user-1.png";
|
||||
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||
import dataImage3 from "../../assets/images/data-table-user-3.png";
|
||||
import dataImage4 from "../../assets/images/data-table-user-4.png";
|
||||
import SelectBox from "../Helpers/SelectBox";
|
||||
import usersService from "../../services/UsersService";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
export default function HomeActivities({ className }) {
|
||||
const filterCategories = ["All Categories", "Explore", "Featured"];
|
||||
const [selectedCategory, setCategory] = useState(filterCategories[0]);
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow relative min-h-[520px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div className="header w-full sm:flex justify-between items-center mb-5">
|
||||
<div className="flex space-x-2 items-center mb-2 sm:mb-0">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Recent Activities
|
||||
</h1>
|
||||
const [recentActivitiesData, setRecentActivitiesData] = useState({
|
||||
loading: false,
|
||||
status: false,
|
||||
msg: "",
|
||||
data: null,
|
||||
});
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{/* table heading */}
|
||||
{/*<tr className="text-base text-thin-light-gray whitespace-nowrap px-2 border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
|
||||
{/* <td className="py-4 w-[300px] block whitespace-nowrap">*/}
|
||||
{/* All Product*/}
|
||||
{/* </td>*/}
|
||||
{/* <td className="py-4 whitespace-nowrap text-center">.</td>*/}
|
||||
{/* <td className="py-4 whitespace-nowrap text-center"></td>*/}
|
||||
const _apiCall = new usersService();
|
||||
|
||||
{/* <td className="py-4 whitespace-nowrap text-right"></td>*/}
|
||||
{/*</tr>*/}
|
||||
<tr className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage1}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
Mullican Computer Joy
|
||||
</h1>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Owned by <span className="text-purple">Xoeyam</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
|
||||
fill="#627EEA"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
|
||||
fill="white"
|
||||
fillOpacity="0.2"
|
||||
/>
|
||||
<path
|
||||
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
||||
7473 ETH
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
|
||||
fill="#FEFEFE"
|
||||
/>
|
||||
<path
|
||||
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium">
|
||||
6392.99$
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
const getRecentActivities = async () => {
|
||||
setRecentActivitiesData((prev) => ({ ...prev, loading: true }));
|
||||
let res;
|
||||
try {
|
||||
res = await _apiCall.getRecentActivities(null);
|
||||
res = res.data;
|
||||
if (res?.internal_return >= 0) {
|
||||
setRecentActivitiesData((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
status: true,
|
||||
data: res.result_list,
|
||||
}));
|
||||
} else {
|
||||
setRecentActivitiesData((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
status: false,
|
||||
msg: "Something went wrong",
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
setRecentActivitiesData((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
status: false,
|
||||
msg: "Unable to see this",
|
||||
}));
|
||||
throw new Error(`Unable to see this because: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
<td className="text-right py-4">
|
||||
<button
|
||||
type="button"
|
||||
className="text-sm text-white bg-purple px-2.5 py-1.5 rounded-full"
|
||||
>
|
||||
Active
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage2}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
Mullican Computer Joy
|
||||
</h1>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Owned by <span className="text-purple">Xoeyam</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
|
||||
fill="#627EEA"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
|
||||
fill="white"
|
||||
fillOpacity="0.2"
|
||||
/>
|
||||
<path
|
||||
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
||||
7473 ETH
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
|
||||
fill="#FEFEFE"
|
||||
/>
|
||||
<path
|
||||
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium">
|
||||
6392.99$
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
useEffect(() => {
|
||||
getRecentActivities();
|
||||
}, []);
|
||||
|
||||
<td className="text-right py-4">
|
||||
<button
|
||||
type="button"
|
||||
className="text-sm text-white bg-light-green px-2.5 py-1.5 rounded-full"
|
||||
>
|
||||
Complated
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
console.log(recentActivitiesData);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow relative min-h-[520px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div className="header w-full sm:flex justify-between items-center mb-5">
|
||||
<div className="flex space-x-2 items-center mb-4 sm:mb-0">
|
||||
<h1 className="text-center text-2xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Recent Activities
|
||||
</h1>
|
||||
</div>
|
||||
);
|
||||
</div>
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{/* table heading */}
|
||||
{/*<tr className="text-base text-thin-light-gray whitespace-nowrap px-2 border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
|
||||
{/* <td className="py-4 w-[300px] block whitespace-nowrap">*/}
|
||||
{/* All Product*/}
|
||||
{/* </td>*/}
|
||||
{/* <td className="py-4 whitespace-nowrap text-center">.</td>*/}
|
||||
{/* <td className="py-4 whitespace-nowrap text-center"></td>*/}
|
||||
|
||||
{/* <td className="py-4 whitespace-nowrap text-right"></td>*/}
|
||||
{/*</tr>*/}
|
||||
|
||||
{recentActivitiesData.loading ? (
|
||||
<tr>
|
||||
<td>
|
||||
<div className="h-[100px] w-full flex justify-center items-center">
|
||||
<LoadingSpinner color="sky-blue" size="16" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
) : recentActivitiesData.data ? (
|
||||
recentActivitiesData.data?.map((item) => {
|
||||
let addedDate = item?.added?.split(" ")[0];
|
||||
return (
|
||||
<tr
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
key={item.uid}
|
||||
>
|
||||
<td className="py-3">
|
||||
<div className="flex space-x-2 items-center">
|
||||
{/* <div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage1}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div> */}
|
||||
<div className="flex flex-col">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
{item.title ? item.title : "Title"}
|
||||
</h1>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
{item.description ? item.description : ""}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td className="text-right py-3">
|
||||
<div className="flex space-x-1 items-center justify-end">
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium">
|
||||
{item.added ? addedDate : ""}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
) : null}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,28 +7,30 @@ import FamilyDash from "./FamilyDash";
|
||||
import FullAccountDash from "./FullAccountDash";
|
||||
|
||||
export default function Home(props) {
|
||||
console.log("PROPS IN HOME->", props);
|
||||
// console.log("PROPS IN HOME->", props);
|
||||
const userApi = new usersService();
|
||||
const { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
||||
|
||||
let [nextDueTask, setNextDueTask] = useState({});
|
||||
const [MyOffersList, setMyOffersList] = useState([]);
|
||||
const [MyOffersList, setMyOffersList] = useState({loading: true, data: []});
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
|
||||
const [MyActiveJobList, setMyActiveJobList] = useState([]); // STATE TO HOLD ACTIVE/CURRENT TASKS
|
||||
const [MyActiveJobList, setMyActiveJobList] = useState({loading:true, data:[]}); // STATE TO HOLD ACTIVE/CURRENT TASKS
|
||||
// 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);
|
||||
setMyActiveJobList({loading:false, data:res?.data?.result_list});
|
||||
// setMyActiveJobList(res?.data?.result_list);
|
||||
} catch (error) {
|
||||
setMyActiveJobList([]);
|
||||
setMyActiveJobList({loading:false, data:[]});
|
||||
// setMyActiveJobList([]);
|
||||
console.log("Error getting tasks");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// FUNCTION TO GET DASH DATA TO DETERMINE CURRENT TASK DUE TIME
|
||||
const getHomeDate = () => {
|
||||
userApi
|
||||
@@ -47,8 +49,9 @@ export default function Home(props) {
|
||||
const getMyOffersList = async () => {
|
||||
try {
|
||||
const res = await userApi.getOffersList();
|
||||
setMyOffersList(res.data?.result_list);
|
||||
setMyOffersList({loading:false, data:res.data});
|
||||
} catch (error) {
|
||||
setMyOffersList({loading:false, data:[]});
|
||||
console.log("Error getting offers", error);
|
||||
}
|
||||
};
|
||||
@@ -72,13 +75,15 @@ export default function Home(props) {
|
||||
<FamilyDash
|
||||
account={userDetails}
|
||||
commonHeadData={props.bannerList}
|
||||
familyOffers={MyOffersList}
|
||||
MyActiveJobList={MyActiveJobList}
|
||||
familyOffers={MyOffersList?.data?.result_list}
|
||||
MyActiveJobList={MyActiveJobList?.data}
|
||||
/>
|
||||
) : userDetails && userDetails?.account_type == "FULL" ? (
|
||||
<FullAccountDash
|
||||
nextDueTask={nextDueTask}
|
||||
bannerList={props.bannerList}
|
||||
offersList={MyOffersList}
|
||||
MyActiveJobList={MyActiveJobList}
|
||||
/>
|
||||
) : (
|
||||
<div>
|
||||
|
||||
@@ -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 AvailableJobsCard from "../Cards/AvailableJobsCard";
|
||||
import DataIteration from "../Helpers/DataIteration";
|
||||
import SelectBox from "../Helpers/SelectBox";
|
||||
|
||||
export default function MainSection({
|
||||
|
||||
@@ -125,10 +125,10 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
<CloseIcon onClose={onClose} />
|
||||
</div>
|
||||
|
||||
<div className="md:flex bg-white rounded-lg">
|
||||
<div className="md:flex bg-white dark:bg-dark-white text-slate-900 dark:text-white rounded-lg">
|
||||
<div className="p-4 w-full md:w-[75%] md:border-r-1">
|
||||
<div className="min-h-[263px]">
|
||||
<h2 className="font-semibold text-slate-900 dark:text-black tracking-wide">
|
||||
<h2 className="font-semibold text-slate-900 dark:text-white tracking-wide">
|
||||
{details?.title}
|
||||
</h2>
|
||||
|
||||
@@ -152,11 +152,11 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
},
|
||||
].map(({ name, content, danger }, idx) => (
|
||||
<div className={`my-3 md:flex items-center`} key={idx}>
|
||||
<label className="w-full md:w-[19%] text-slate-900 tracking-wide font-semibold whitespace-pre-wrap">
|
||||
<label className="w-full md:w-[19%] tracking-wide font-semibold whitespace-pre-wrap">
|
||||
{name}
|
||||
</label>
|
||||
<div
|
||||
className={`w-full md:w-3/4 text-slate-900 market-pop ${
|
||||
className={`w-full md:w-3/4 text-slate-900 dark:text-white market-pop ${
|
||||
name !== "Delivery Detail"
|
||||
? " h-full max-h-28 flex items-center"
|
||||
: " overflow-y-auto max-h-[100px]"
|
||||
@@ -164,20 +164,20 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
>
|
||||
{danger ? (
|
||||
<p
|
||||
className={``}
|
||||
className={`dark:text-white`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: danger && content,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<p className={`w-full text-slate-900`}>
|
||||
<p className={`w-full text-slate-900 dark:text-white`}>
|
||||
{name !== "Delivery Detail" ? (
|
||||
<>
|
||||
{typeof content !== "object" ? content : null}
|
||||
{typeof content === "object" && (
|
||||
<>
|
||||
<hr className="mb-1" />
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="flex items-center gap-2 dark:text-white">
|
||||
{content?.text}
|
||||
<strong>{thePrice}</strong>
|
||||
</span>
|
||||
@@ -197,11 +197,11 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
<hr />
|
||||
<div className="my-3 w-full flex flex-col gap-3">
|
||||
<div className="w-full">
|
||||
<label className="w-full text-slate-900 tracking-wide">
|
||||
<label className="w-full text-slate-900 dark:text-white tracking-wide">
|
||||
If you have any questions about this task:
|
||||
</label>
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
|
||||
className={`p-1 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
|
||||
rows="5"
|
||||
style={{ resize: "none" }}
|
||||
placeholder="Enter message here ..."
|
||||
@@ -226,7 +226,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</div>
|
||||
|
||||
<div className="w-full md:w-[23%] h-full ">
|
||||
<div className="mx-auto bg-[#f1f8ff] p-4 rounded-md md:min-h-[498px] flex flex-col justify-between">
|
||||
<div className="mx-auto bg-[#f1f8ff] dark:bg-[#C2C8D3] p-4 rounded-md md:min-h-[498px] flex flex-col justify-between">
|
||||
<div className="w-full flex flex-col justify-center py-4 gap-2">
|
||||
<p className="w-full text-slate-900 tracking-wide my-1">
|
||||
Interested in the task?
|
||||
@@ -261,7 +261,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="text-slate-900">
|
||||
<p className="flex items-center tracking-wide">
|
||||
Interest: <b className="ml-1">{details.interest_count}</b>
|
||||
</p>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Layout from "../Partials/Layout";
|
||||
import MainSection from "./MainSection";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import { useSelector } from "react-redux";
|
||||
import Layout from "../Partials/Layout";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import MainSection from "./MainSection";
|
||||
|
||||
export default function MarketPlace({ commonHeadData }) {
|
||||
let { jobLists } = useSelector((state) => state.jobLists);
|
||||
@@ -20,4 +20,4 @@ export default function MarketPlace({ commonHeadData }) {
|
||||
</Layout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,11 @@ export default function ActiveJobMessage({ activeJobMesList }) {
|
||||
<td>
|
||||
<div className={`msg_box ${item.who}`}>
|
||||
<div className="msg_header">{item.msg_date} {item.msg_firstname}</div>
|
||||
{item.msg_type == 'FILE' ?
|
||||
<a href='' className="p-2" dangerouslySetInnerHTML={{__html: item.message}}></a>
|
||||
:
|
||||
<span className="p-2" dangerouslySetInnerHTML={{__html: item.message}}></span>
|
||||
}
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import Layout from "../Partials/Layout";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import ActiveJobMessage from "./ActiveJobMessage";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import CountDown from "../Helpers/CountDown";
|
||||
import IndexJobActions from "./JobActions/IndexJobActions";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import { useReactToPrint } from "react-to-print";
|
||||
import CountDown from "../Helpers/CountDown";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import ActiveJobMessage from "./ActiveJobMessage";
|
||||
import IndexJobActions from "./JobActions/IndexJobActions";
|
||||
|
||||
import usersService from "../../services/UsersService";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
function ActiveJobs(props) {
|
||||
const ApiCall = new usersService();
|
||||
let navigate = useNavigate();
|
||||
const navigate = useNavigate();
|
||||
|
||||
let { userDetails } = useSelector((state) => state.userDetails);
|
||||
const { userDetails } = useSelector((state) => state.userDetails);
|
||||
|
||||
let [passDue, setPassDue] = useState(
|
||||
const [passDue, setPassDue] = useState(
|
||||
new Date() > new Date(props.details?.delivery_date)
|
||||
); // STATE TO KNOW IF TASK IS PASSED DUE TIME
|
||||
|
||||
let [messageToSend, setMessageToSend] = useState(""); // State to hold the value of message to be sent
|
||||
const [messageToSend, setMessageToSend] = useState(""); // State to hold the value of message to be sent
|
||||
|
||||
let [filesToSend, setFilesToSend] = useState([]); // State to hold the value of files to be sent
|
||||
const [filesToSend, setFilesToSend] = useState([]); // State to hold the value of files to be sent
|
||||
|
||||
let [tab, setTab] = useState("message");
|
||||
const [tab, setTab] = useState("message");
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
const [requestStatus, setRequestStatus] = useState({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "",
|
||||
@@ -248,7 +249,11 @@ function ActiveJobs(props) {
|
||||
}
|
||||
}, [passDue]);
|
||||
|
||||
console.log("AC JOBS >>", props);
|
||||
let thePrice = PriceFormatter(
|
||||
props.details?.price * 0.01,
|
||||
props.details?.currency_code,
|
||||
props.details?.currency
|
||||
);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
@@ -259,14 +264,17 @@ function ActiveJobs(props) {
|
||||
<button
|
||||
type="button"
|
||||
className="min-w-[45px] h-auto text-[#374557] border border-sky-blue p-1 rounded-full"
|
||||
onClick={() =>{
|
||||
if(props.details.pathname == '/manage-family'){
|
||||
navigate(props.details.pathname, {state: { ...props.details.accountDetails }}, { replace: true })
|
||||
}else{
|
||||
navigate(props.details.pathname, { replace: true })
|
||||
}
|
||||
onClick={() => {
|
||||
if (props.details.pathname == "/manage-family") {
|
||||
navigate(
|
||||
props.details.pathname,
|
||||
{ state: { ...props.details.accountDetails } },
|
||||
{ replace: true }
|
||||
);
|
||||
} else {
|
||||
navigate(props.details.pathname, { replace: true });
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -308,10 +316,11 @@ function ActiveJobs(props) {
|
||||
<span className="font-semibold">Due: </span>
|
||||
{props?.details && props.details.delivery_date.split(" ")[0]}
|
||||
</p>
|
||||
<p className="py-2 text-base text-slate-700">
|
||||
{props?.delivery_date &&
|
||||
props.details.delivery_date.split(" ")[1]}
|
||||
</p>
|
||||
{props?.delivery_date && (
|
||||
<p className="py-2 text-base text-slate-700">
|
||||
{props.details.delivery_date.split(" ")[1]}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="my-1 flex items-start gap-3">
|
||||
@@ -331,6 +340,13 @@ function ActiveJobs(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="my-1 text-base text-slate-700 tracking-wide flex items-center gap-3">
|
||||
<span className="font-semibold text-black dark:text-white">
|
||||
Price:{" "}
|
||||
</span>
|
||||
<span className="">{thePrice}</span>
|
||||
</div>
|
||||
|
||||
<div className="my-1 text-base text-slate-700 tracking-wide flex items-center gap-3">
|
||||
<span className="font-semibold text-black dark:text-white">
|
||||
Duration:{" "}
|
||||
@@ -367,15 +383,17 @@ function ActiveJobs(props) {
|
||||
{/* TEXTAREA SECTION */}
|
||||
<div className="mt-5">
|
||||
<div className="">
|
||||
<div
|
||||
<div
|
||||
className="pl-7 my-2 flex items-center border-b border-slate-300 gap-3"
|
||||
// className='ml-7 flex justify-start items-center gap-3'
|
||||
>
|
||||
>
|
||||
<button
|
||||
name="message"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`px-4 py-1 rounded-t-2xl ${
|
||||
tab == "message" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
tab == "message"
|
||||
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||
: "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
>
|
||||
Send Message
|
||||
@@ -384,7 +402,9 @@ function ActiveJobs(props) {
|
||||
name="files"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`px-4 py-1 rounded-t-2xl ${
|
||||
tab == "files" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
tab == "files"
|
||||
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||
: "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
>
|
||||
Send Files
|
||||
@@ -398,6 +418,7 @@ function ActiveJobs(props) {
|
||||
name="message"
|
||||
onChange={handleMessageChange}
|
||||
value={messageToSend}
|
||||
autoFocus
|
||||
/>
|
||||
) : (
|
||||
<div className="p-4 w-full h-[300px] text-base text-slate-600 border border-slate-300">
|
||||
@@ -471,7 +492,7 @@ function ActiveJobs(props) {
|
||||
<button
|
||||
onClick={sendFile}
|
||||
type="button"
|
||||
className='btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center'
|
||||
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
@@ -495,7 +516,7 @@ function ActiveJobs(props) {
|
||||
<button
|
||||
onClick={sendTaskMessage}
|
||||
type="button"
|
||||
className='btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer'
|
||||
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
|
||||
>
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import React, { useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
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();
|
||||
@@ -25,7 +24,7 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
||||
className={`update-table w-full p-3 sm:p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
@@ -33,11 +32,6 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
<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>
|
||||
{/*<tr className="text-base text-thin-light-gray border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
|
||||
{/* <td className="py-4">All Product</td>*/}
|
||||
{/* <td className="py-4 text-right">.</td>*/}
|
||||
{/*</tr>*/}
|
||||
|
||||
{
|
||||
<>
|
||||
{MyJobList &&
|
||||
@@ -59,7 +53,9 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={localImgLoad(`images/taskbanners/${value.banner}`)}
|
||||
src={localImgLoad(
|
||||
`images/taskbanners/${value.banner}`
|
||||
)}
|
||||
alt="data"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
@@ -75,7 +71,7 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
{thePrice}
|
||||
</span>
|
||||
</span>
|
||||
<div className="flex gap-4 items-center">
|
||||
<div className="flex flex-col sm:flex-row items-start gap-1 md:gap-4 md:items-center">
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple">
|
||||
@@ -113,9 +109,11 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
state: { ...value, pathname },
|
||||
});
|
||||
}}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
{value.owner_status == "OWNER"
|
||||
? "Manage"
|
||||
: "Send Updates"}
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -1,42 +1,39 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import MyActiveJobTable from "./MyActiveJobTable";
|
||||
|
||||
export default function MyReviewDueJobs(props) {
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
return (
|
||||
<Layout>
|
||||
<CommonHead
|
||||
commonHeadData={props.commonHeadData}
|
||||
/>
|
||||
<div className="notification-page w-full mb-10">
|
||||
<div className="notification-wrapper w-full">
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="mb-5 sm:mb-0">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
return (
|
||||
<Layout>
|
||||
<CommonHead commonHeadData={props.commonHeadData} />
|
||||
<div className="notification-page w-full mb-10">
|
||||
<div className="notification-wrapper w-full">
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="mb-5 sm:mb-0">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
<span
|
||||
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||
>
|
||||
Review Due Job(s)
|
||||
Review Due Job(s)
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<div
|
||||
onClick={() => filterHandler("today")}
|
||||
className="relative"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<MyActiveJobTable MyJobList={props.MyJobList} />
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<div
|
||||
onClick={() => filterHandler("today")}
|
||||
className="relative"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<MyActiveJobTable MyJobList={props.myJobList} />
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ const CouponPopup = ({ popUpHandler, data }) => {
|
||||
setStatusMsg({ error: "An error occurred" });
|
||||
else setStatusMsg({ success: res.data?.status_text });
|
||||
|
||||
dispatch(tableReload({ type: "COUPONTABLE" }));
|
||||
// dispatch(tableReload({ type: "COUPONTABLE" }));
|
||||
dispatch(tableReload({ type: "WALLETTABLE" }));
|
||||
setTimeout(() => {
|
||||
popUpHandler();
|
||||
setLoader(false);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useSelector } from "react-redux";
|
||||
|
||||
export default function MyCoupons() {
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
const {couponTable} = useSelector(state => state.tableReload)
|
||||
const {couponTable, walletTable} = useSelector(state => state.tableReload)
|
||||
let [couponHistory, setCouponHistory] = useState({
|
||||
// FOR COUPON HISTORY
|
||||
loading: true,
|
||||
@@ -38,7 +38,7 @@ export default function MyCoupons() {
|
||||
|
||||
useEffect(() => {
|
||||
getCouponHistory();
|
||||
}, [couponTable]);
|
||||
}, [couponTable, walletTable]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
import React, { useState } from "react";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import usersService from "../../services/UsersService";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
|
||||
function DeleteTaskModal({ details, onClose, situation, setReloadList }) {
|
||||
let dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const ApiCall = new usersService();
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
laoding: false,
|
||||
status: false,
|
||||
message: "",
|
||||
}); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
|
||||
|
||||
// FUNCTION TO DELETE TASK
|
||||
const deleteTask = () => {
|
||||
setRequestStatus({loading:true, status:false, message: ''})
|
||||
|
||||
let reqData = { // REQUEST PAYLOAD
|
||||
suggest_uid: details.uid,
|
||||
suggest_action: 555,
|
||||
offset: 0
|
||||
}
|
||||
ApiCall.suggestStatus(reqData).then((response)=>{ // API CALL TO DELETE SUGGESTED TASK
|
||||
let {data} = response
|
||||
if(data.internal_return < 0){
|
||||
setRequestStatus({loading:false, status:false, message: 'Unable to delete, Try again'})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading:false, status:false, message: ''})
|
||||
},3000)
|
||||
}
|
||||
setRequestStatus({loading:false, status:true, message: 'Family Suggest Deleted'})
|
||||
setReloadList(prev => !prev) // RELOADS THE FAMILY SUGGEST LIST TABLE
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading:false, status:false, message: ''})
|
||||
onClose()
|
||||
},3000)
|
||||
}).catch(error => {
|
||||
setRequestStatus({loading:false, status:false, message: 'Unable to delete, Try again'})
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading:false, status:false, message: ''})
|
||||
},3000)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation}>
|
||||
<div className="logout-modal-wrapper lg:w-[500px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b border-light-purple dark:border-[#5356fb29] ">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Delete Task
|
||||
</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>
|
||||
<div className="logout-modal-body w-full flex flex-col items-center px-10 py-8">
|
||||
<div className="what-icon mb-6 cursor-pointer">
|
||||
<svg
|
||||
width="136"
|
||||
height="136"
|
||||
viewBox="0 0 136 136"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="68" cy="68" r="68" fill="#4687ba" />
|
||||
<path
|
||||
d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M67.485 100.21C66.1617 99.9268 64.9041 99.5091 63.803 98.6787C61.3804 96.8484 60.2877 93.7699 61.0386 90.7888C61.7726 87.8747 64.2138 85.6703 67.2089 85.2157C71.273 84.6 75.2024 87.3681 75.8135 91.277C76.4937 95.6153 73.8202 99.3782 69.544 100.103C69.4429 100.12 69.3487 100.172 69.2527 100.209C68.6635 100.21 68.0742 100.21 67.485 100.21Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white">
|
||||
{details.title}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex space-x-2.5">
|
||||
<button
|
||||
onClick={onClose}
|
||||
type="button"
|
||||
className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
<span className="text-gradient">Cancel</span>
|
||||
</button>
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<button
|
||||
onClick={() => deleteTask(details)}
|
||||
type="button"
|
||||
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
Confirm Delete
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
</div>
|
||||
</div>
|
||||
</ModalCom>
|
||||
);
|
||||
}
|
||||
|
||||
export default DeleteTaskModal;
|
||||
@@ -18,7 +18,7 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
@@ -33,11 +33,6 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
||||
<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>
|
||||
{/*<tr className="text-base text-thin-light-gray border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
|
||||
{/* <td className="py-4">All Product</td>*/}
|
||||
{/* <td className="py-4 text-right">.</td>*/}
|
||||
{/*</tr>*/}
|
||||
|
||||
{
|
||||
<>
|
||||
{MyJobList &&
|
||||
@@ -108,9 +103,9 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
||||
onClick={() => {
|
||||
setJobPopout({ show: true, data: value });
|
||||
}}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
{value.owner_status == 'OWNER' ? 'Manage' : 'Send Updates'}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -7,7 +7,9 @@ import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import usersService from "../../services/UsersService";
|
||||
|
||||
import DeleteIcon from '../../assets/images/icon-delete.svg'
|
||||
import DeleteTaskModal from "./DeleteTaskModal";
|
||||
import SendReminderModal from "./SendReminderModal";
|
||||
|
||||
export default function ParentWaitingTable() {
|
||||
// const transationFilterData = [
|
||||
@@ -34,6 +36,11 @@ export default function ParentWaitingTable() {
|
||||
|
||||
const apiCall = new usersService()
|
||||
|
||||
let [reloadList, setReloadList] = useState(false) // STATE TO DETERMINE WHEN TO RELOAD THE FAMILY SUGGEST LIST
|
||||
|
||||
let [deleteTaskPopout, setDeleteTaskPopout] = useState({show:false, data:{}}) // HOLDS THE INFO OF DELETE TASK POPOUT
|
||||
let [sendReminderPopout, setSendReminderPopout] = useState({show:false, data:{}}) // HOLDS THE INFO OF SEND REMINDER POPOUT
|
||||
|
||||
let [familySuggestList, setFamilySuggestList] = useState({loading: true, data:[]})
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
@@ -53,7 +60,7 @@ export default function ParentWaitingTable() {
|
||||
setFamilySuggestList({loading: false, data:[]})
|
||||
console.log('ERROR==>Familysuggestlist', err)
|
||||
})
|
||||
},[])
|
||||
},[reloadList])
|
||||
|
||||
return (
|
||||
<div className="rounded-2xl bg-white dark:bg-dark-white flex flex-col justify-between">
|
||||
@@ -97,7 +104,7 @@ export default function ParentWaitingTable() {
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={Image} alt="" className="w-full h-full" />
|
||||
</div>
|
||||
<div className="">
|
||||
<div className="w-full">
|
||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
{item.title}
|
||||
</p>
|
||||
@@ -107,12 +114,35 @@ export default function ParentWaitingTable() {
|
||||
</p>
|
||||
</div>
|
||||
</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 className="min-w-[120px] flex justify-start items-end px-2 gap-1">
|
||||
<button
|
||||
type="button"
|
||||
className="p-1 border-2 border-red-400 rounded-md"
|
||||
onClick={() => {
|
||||
setDeleteTaskPopout({
|
||||
show: true,
|
||||
data: { ...item },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<img className="min-w-[21px] h-[21px]" src={DeleteIcon} alt='delete-icon' />
|
||||
</button>
|
||||
|
||||
<div className="">
|
||||
<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 cursor-pointer"
|
||||
onClick={() => {
|
||||
setSendReminderPopout({
|
||||
show: true,
|
||||
data: { ...item },
|
||||
});
|
||||
}}
|
||||
>{item.status_text}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -122,6 +152,32 @@ export default function ParentWaitingTable() {
|
||||
:
|
||||
<p className="w-full flex items-center justify-center text-xl text-dark-gray dark:text-white">No List Found!</p>
|
||||
}
|
||||
|
||||
{/* Delete Task Popout */}
|
||||
{deleteTaskPopout.show && (
|
||||
<DeleteTaskModal
|
||||
details={deleteTaskPopout.data}
|
||||
onClose={() => {
|
||||
setDeleteTaskPopout({ show: false, data: {} });
|
||||
}}
|
||||
situation={deleteTaskPopout.show}
|
||||
setReloadList={setReloadList}
|
||||
/>
|
||||
)}
|
||||
{/* END of Delete Task Popout */}
|
||||
|
||||
{/* Send Reminder Popout */}
|
||||
{sendReminderPopout.show && (
|
||||
<SendReminderModal
|
||||
details={sendReminderPopout.data}
|
||||
onClose={() => {
|
||||
setSendReminderPopout({ show: false, data: {} });
|
||||
}}
|
||||
situation={sendReminderPopout.show}
|
||||
setReloadList={setReloadList}
|
||||
/>
|
||||
)}
|
||||
{/* END of Send Reminder Popout */}
|
||||
</div>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
import React, { useState } from "react";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import usersService from "../../services/UsersService";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
|
||||
function SendReminderModal({ details, onClose, situation, setReloadList }) {
|
||||
let dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const ApiCall = new usersService();
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
laoding: false,
|
||||
status: false,
|
||||
message: "",
|
||||
}); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
|
||||
|
||||
// FUNCTION TO SEND REMINDER
|
||||
const sendReminder = () => {
|
||||
setRequestStatus({loading:true, status:false, message: ''})
|
||||
|
||||
let reqData = { // REQUEST PAYLOAD
|
||||
suggest_uid: details.uid,
|
||||
suggest_action: 222,
|
||||
offset: 0
|
||||
}
|
||||
ApiCall.suggestStatus(reqData).then((response)=>{ // API CALL TO DELETE SUGGESTED TASK
|
||||
let {data} = response
|
||||
if(data.internal_return < 0){
|
||||
setRequestStatus({loading:false, status:false, message: 'Unable to send reminder, Try again1111'})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading:false, status:false, message: ''})
|
||||
},3000)
|
||||
}
|
||||
setRequestStatus({loading:false, status:true, message: 'Reminder Sent'})
|
||||
setReloadList(prev => !prev) // RELOADS THE FAMILY SUGGEST LIST TABLE
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading:false, status:false, message: ''})
|
||||
onClose()
|
||||
},3000)
|
||||
}).catch(error => {
|
||||
setRequestStatus({loading:false, status:false, message: 'Unable to send reminder, Try againNETWORK'})
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading:false, status:false, message: ''})
|
||||
},3000)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation}>
|
||||
<div className="logout-modal-wrapper lg:w-[500px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b border-light-purple dark:border-[#5356fb29] ">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Send Reminder
|
||||
</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>
|
||||
<div className="logout-modal-body w-full flex flex-col items-center p-8">
|
||||
|
||||
<div className="mb-6 w-full flex gap-4 items-center">
|
||||
<div className="icon max-w-[150px] min-w-[150px] max-h-[150px] min-h-[150px] flex justify-center items-center">
|
||||
<img src={require(`../../assets/images/family/${details.banner || "default.jpg"}`)} alt="" className="w-full h-full" />
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
{details.title}
|
||||
</p>
|
||||
|
||||
<p className="text-sm mb-2 text-thin-light-gray font-medium">
|
||||
{details.description}
|
||||
</p>
|
||||
{
|
||||
details.remind &&
|
||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
Last Remind: {new Date(details.remind).toLocaleString().split(',')[0]}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex justify-end">
|
||||
{/* <button
|
||||
onClick={onClose}
|
||||
type="button"
|
||||
className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
<span className="text-gradient">Cancel</span>
|
||||
</button> */}
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<button
|
||||
onClick={() => sendReminder(details)}
|
||||
type="button"
|
||||
className="text-white bg-sky-blue text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
Send Reminder
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
</div>
|
||||
</div>
|
||||
</ModalCom>
|
||||
);
|
||||
}
|
||||
|
||||
export default SendReminderModal;
|
||||
@@ -55,15 +55,14 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
{!ActiveJobList?.data.length && accountType && (
|
||||
<div className="absolute inset-0 bg-black opacity-30"></div>
|
||||
)}
|
||||
{ActiveJobList?.data.length > 0 && ActiveJobList.loading && (
|
||||
{ActiveJobList.loading ?
|
||||
<div className="w-full h-[520px] flex items-center justify-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
:
|
||||
<div className="relative w-full sm:rounded-lg">
|
||||
<div className="h-auto w-full">
|
||||
{ActiveJobList?.data?.length > 0 &&
|
||||
{ActiveJobList?.data?.length > 0 ?
|
||||
currentTask?.map((task, idx) => {
|
||||
// find due date
|
||||
const dueDate = task?.delivery_date.split(" ")[0];
|
||||
@@ -97,7 +96,7 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
Price:
|
||||
<span className="text-purple ml-1">{thePrice}</span>
|
||||
</span>
|
||||
<div className="flex gap-4 items-center">
|
||||
<div className="flex flex-col sm:flex-row items-start gap-1 md:gap-4 md:items-center">
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Duration:
|
||||
<span className="text-purple ml-1">
|
||||
@@ -129,16 +128,15 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
state: { ...task, pathname },
|
||||
});
|
||||
}}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Manage
|
||||
{task.owner_status == 'OWNER' ? 'Manage' : 'Send Updates'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{ActiveJobList?.data?.length <= 0 && (
|
||||
})
|
||||
:
|
||||
<div
|
||||
className={`flex flex-col ${
|
||||
accountType ? "items-center" : "items-end"
|
||||
@@ -175,12 +173,12 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ActiveJobList?.internal_return < 0 && (
|
||||
}
|
||||
{/* {ActiveJobList?.internal_return < 0 && (
|
||||
<div className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
<p className="p-2">Error Occurred! Unable to display Tasks!</p>
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
@@ -199,6 +197,7 @@ export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -38,8 +38,7 @@ export default function MyOffersFamilyTable({ className, familyOffers }) {
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
console.log("YES WE SEE OFFERS", familyOffers);
|
||||
// console.log("YES WE SEE OFFERS", familyOffers);
|
||||
|
||||
const trendingSlider = useRef(null);
|
||||
const prevHandler = () => {
|
||||
|
||||
@@ -64,6 +64,8 @@ const initialValues = {
|
||||
};
|
||||
|
||||
function AddFundDollars(props) {
|
||||
let MaxNoOfCards = process.env.REACT_APP_MAX_CREDIT_CARDS // HOLDS THE VALUE OF THE MAX NUMBER OF CARDS USER CAN ADD
|
||||
|
||||
const apiCall = new usersService();
|
||||
let countryWallet = props.walletItem.country;
|
||||
const [tab, setTab] = useState("previous");
|
||||
@@ -240,7 +242,7 @@ function AddFundDollars(props) {
|
||||
<label
|
||||
onClick={() => setTab("new")}
|
||||
htmlFor="new"
|
||||
className="cursor-pointer flex items-center gap-1"
|
||||
className={`cursor-pointer flex items-center gap-1 ${payListCards.data.length >= MaxNoOfCards ? 'pointer-events-none':''}`}
|
||||
>
|
||||
<input
|
||||
id="new"
|
||||
@@ -251,7 +253,7 @@ function AddFundDollars(props) {
|
||||
tab == "new" ? "" : ""
|
||||
} tracking-wide transition duration-200`}
|
||||
/>
|
||||
Add New Card
|
||||
Add New Card {payListCards.data.length >= MaxNoOfCards && <span className="text-[14px] text-red-500">Max Reached</span>}
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
@@ -314,245 +316,253 @@ function AddFundDollars(props) {
|
||||
|
||||
{tab === "new" && (
|
||||
<div className="new-details w-full max-h-[22rem]">
|
||||
<div className="w-full flex flex-col justify-between">
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="md:pl-8">
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="flex-1 sm:mr-10">
|
||||
<div className="fields w-full">
|
||||
{/* Inputs */}
|
||||
{/* Name */}
|
||||
<div className="flex items-center field w-full my-2 flex-[0.4] gap-3">
|
||||
<label className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1">
|
||||
Name:
|
||||
</label>
|
||||
<p className="input-label text-[#181c32] dark:text-white text-[16px] leading-[20.9625px] font-semibold flex items-center gap-1">{`${firstname} ${lastname}`}</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-1 gap-3 my-2">
|
||||
{/* Card Number */}
|
||||
<div className="field w-full flex-[0.6]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
iconName={cardIcons}
|
||||
label="Card Number"
|
||||
type="text"
|
||||
name="cardNum"
|
||||
onInput={handleCards}
|
||||
placeholder="Enter Card Number"
|
||||
value={handleCardNumberChange(
|
||||
props.values.cardNum
|
||||
)}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.cardNum}
|
||||
/>
|
||||
{payListCards.loading ?
|
||||
<div className="pt-10 flex w-full h-full justify-center items-center">
|
||||
<LoadingSpinner size='10' color='sky-blue' />
|
||||
</div>
|
||||
:payListCards.data.length < MaxNoOfCards ?
|
||||
<div className="w-full flex flex-col justify-between">
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="md:pl-8">
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="flex-1 sm:mr-10">
|
||||
<div className="fields w-full">
|
||||
{/* Inputs */}
|
||||
{/* Name */}
|
||||
<div className="flex items-center field w-full my-2 flex-[0.4] gap-3">
|
||||
<label className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1">
|
||||
Name:
|
||||
</label>
|
||||
<p className="input-label text-[#181c32] dark:text-white text-[16px] leading-[20.9625px] font-semibold flex items-center gap-1">{`${firstname} ${lastname}`}</p>
|
||||
</div>
|
||||
|
||||
{/* Expire Year, Year */}
|
||||
<div className="sm:grid gap-5 grid-cols-2 flex-[0.4]">
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div
|
||||
className={`flex items-center justify-between mb-2.5`}
|
||||
>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold line-clamp-3 flex items-center"
|
||||
htmlFor="expiration"
|
||||
>
|
||||
Exp Month{" "}
|
||||
<span className="text-red-700 text-sm italic">
|
||||
*
|
||||
</span>
|
||||
<span className="text-[12px] text-red-500 ml-1">
|
||||
{props.errors.expirationMonth && "**"}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationMonth}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name="expirationMonth"
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
className="text-dark-gray"
|
||||
>
|
||||
Month
|
||||
</option>
|
||||
{expireMonth?.length &&
|
||||
expireMonth.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
value={
|
||||
Number(item.value) < 10
|
||||
? "0" + item.value
|
||||
: item.value
|
||||
}
|
||||
>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center flex-1 gap-3 my-2">
|
||||
{/* Card Number */}
|
||||
<div className="field w-full flex-[0.6]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
iconName={cardIcons}
|
||||
label="Card Number"
|
||||
type="text"
|
||||
name="cardNum"
|
||||
onInput={handleCards}
|
||||
placeholder="Enter Card Number"
|
||||
value={handleCardNumberChange(
|
||||
props.values.cardNum
|
||||
)}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.cardNum}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div
|
||||
className={`flex items-center justify-between mb-2.5`}
|
||||
>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center line-clamp-3"
|
||||
htmlFor="expiration"
|
||||
{/* 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`}
|
||||
>
|
||||
Exp Year{" "}
|
||||
<span className="text-red-700 text-sm tracking-wide">
|
||||
*
|
||||
</span>
|
||||
<span className="text-[12px] text-red-500 italic">
|
||||
{props.errors.expirationYear && "**"}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationYear}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name="expirationYear"
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
className="text-dark-gray"
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold line-clamp-3 flex items-center"
|
||||
htmlFor="expiration"
|
||||
>
|
||||
Year
|
||||
</option>
|
||||
{expireYear?.length &&
|
||||
expireYear.map((item, index) => (
|
||||
<option key={index} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
Exp Month{" "}
|
||||
<span className="text-red-700 text-sm italic">
|
||||
*
|
||||
</span>
|
||||
<span className="text-[12px] text-red-500 ml-1">
|
||||
{props.errors.expirationMonth && "**"}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationMonth}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name="expirationMonth"
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
className="text-dark-gray"
|
||||
>
|
||||
Month
|
||||
</option>
|
||||
{expireMonth?.length &&
|
||||
expireMonth.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
value={
|
||||
Number(item.value) < 10
|
||||
? "0" + item.value
|
||||
: item.value
|
||||
}
|
||||
>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div
|
||||
className={`flex items-center justify-between mb-2.5`}
|
||||
>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center line-clamp-3"
|
||||
htmlFor="expiration"
|
||||
>
|
||||
Exp Year{" "}
|
||||
<span className="text-red-700 text-sm tracking-wide">
|
||||
*
|
||||
</span>
|
||||
<span className="text-[12px] text-red-500 italic">
|
||||
{props.errors.expirationYear && "**"}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationYear}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name="expirationYear"
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
className="text-dark-gray"
|
||||
>
|
||||
Year
|
||||
</option>
|
||||
{expireYear?.length &&
|
||||
expireYear.map((item, index) => (
|
||||
<option key={index} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Address and CVV */}
|
||||
<div className="flex items-center flex-1 gap-3 my-2">
|
||||
<div className="field w-full col-span-1 flex-[0.4]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
iconName={cardIcons}
|
||||
label="CVV"
|
||||
type="text"
|
||||
name="cvv"
|
||||
placeholder="CVV"
|
||||
maxLength={3}
|
||||
value={props.values.cvv}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.cvv}
|
||||
/>
|
||||
{/* Address and CVV */}
|
||||
<div className="flex items-center flex-1 gap-3 my-2">
|
||||
<div className="field w-full col-span-1 flex-[0.4]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
iconName={cardIcons}
|
||||
label="CVV"
|
||||
type="text"
|
||||
name="cvv"
|
||||
placeholder="CVV"
|
||||
maxLength={3}
|
||||
value={props.values.cvv}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.cvv}
|
||||
/>
|
||||
</div>
|
||||
<div className="field w-full flex-[0.6]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="Billing Address"
|
||||
type="text"
|
||||
name="address"
|
||||
placeholder="Billing Address"
|
||||
value={props.values.Address}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.address}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field w-full flex-[0.6]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="Billing Address"
|
||||
type="text"
|
||||
name="address"
|
||||
placeholder="Billing Address"
|
||||
value={props.values.Address}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.address}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Postal Code and State */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 my-2">
|
||||
<div className="field w-full xl:mb-0 col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="Postal Code"
|
||||
type="number"
|
||||
name="code"
|
||||
placeholder="Postal Code"
|
||||
value={props.values.code}
|
||||
maxLength={6}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.code}
|
||||
/>
|
||||
</div>
|
||||
<div className="field w-full col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="State"
|
||||
type="text"
|
||||
name="state"
|
||||
placeholder="State"
|
||||
value={props.values.state.toUpperCase()}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.state}
|
||||
/>
|
||||
{/* Postal Code and State */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 my-2">
|
||||
<div className="field w-full xl:mb-0 col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="Postal Code"
|
||||
type="number"
|
||||
name="code"
|
||||
placeholder="Postal Code"
|
||||
value={props.values.code}
|
||||
maxLength={6}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.code}
|
||||
/>
|
||||
</div>
|
||||
<div className="field w-full col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="State"
|
||||
type="text"
|
||||
name="state"
|
||||
placeholder="State"
|
||||
value={props.values.state.toUpperCase()}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.state}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="add-fund-btn flex justify-end items-center gap-2 mt-4">
|
||||
<button
|
||||
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center bg-[#f5a430] text-black items-center text-base rounded-full"
|
||||
onClick={handleClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
) : (
|
||||
<>
|
||||
<span className="text-white">Continue</span>{" "}
|
||||
<Icons name="chevron-right" />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
<div className="add-fund-btn flex justify-end items-center gap-2 mt-4">
|
||||
<button
|
||||
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center bg-[#f5a430] text-black items-center text-base rounded-full"
|
||||
onClick={handleClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
) : (
|
||||
<>
|
||||
<span className="text-white">Continue</span>{" "}
|
||||
<Icons name="chevron-right" />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -26,46 +26,59 @@ function AddFundPop({
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
setInputError("");
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: true } },
|
||||
}));
|
||||
|
||||
if (!input || input === "0") {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("Please Enter Amount");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Number(input) * 100 > Number(walletItem?.transfer_limit)) {
|
||||
setInputError("Credit limit has been exceeded");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNaN(input)) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("Amount must be a Number");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
let stateData = {
|
||||
amount: Number(input) * 100,
|
||||
currency: walletItem?.code,
|
||||
};
|
||||
|
||||
try {
|
||||
// Clear any previous input error and set the loading spinner to be shown
|
||||
setInputError("");
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: true } },
|
||||
}));
|
||||
|
||||
// Perform validation checks on the input amount
|
||||
if (!input || input === "0") {
|
||||
// Handle input validation error
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("Please Enter Amount");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Number(input) * 100 > Number(walletItem?.transfer_limit)) {
|
||||
// Handle credit limit exceeded error
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("Credit limit has been exceeded");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNaN(input)) {
|
||||
// Handle invalid input error
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("Amount must be a Number");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare state data for API call
|
||||
let stateData = {
|
||||
amount: Number(input) * 100,
|
||||
currency: walletItem?.code,
|
||||
};
|
||||
|
||||
// Make API call to start credit process
|
||||
const res = await apiCall.getStartCredit(stateData);
|
||||
|
||||
if (res.data.internal_return < 0) {
|
||||
// Handle API error
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
@@ -75,6 +88,7 @@ function AddFundPop({
|
||||
return;
|
||||
}
|
||||
|
||||
// Update state with response data
|
||||
const _response = res.data;
|
||||
stateData.amount = Number(input);
|
||||
stateData.currency = currency;
|
||||
@@ -91,6 +105,7 @@ function AddFundPop({
|
||||
}));
|
||||
}, 1500);
|
||||
} catch (error) {
|
||||
// Handle API call error
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
@@ -116,6 +131,7 @@ function AddFundPop({
|
||||
placeholder="0"
|
||||
value={input}
|
||||
inputHandler={handleChange}
|
||||
tabIndex={0}
|
||||
/>
|
||||
<p className="text-base text-red-500 italic h-5">
|
||||
{inputError && inputError}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
/**
|
||||
* Renders a modal with information about a credit transaction.
|
||||
* @returns {JSX.Element} - The rendered modal component.
|
||||
*/
|
||||
function CompleteConfirmCredit({ onClose, confirmCredit }) {
|
||||
const { data } = confirmCredit;
|
||||
const isSuccess =
|
||||
data?.result === "Charge success" || data?.status === "successful";
|
||||
|
||||
return (
|
||||
<div className="logout-modal-body w-full flex flex-col items-center">
|
||||
<div className="content-wrapper w-full h-[32rem]">
|
||||
@@ -11,91 +16,80 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
|
||||
<div className="field w-full mb-3 min-h-[45px]">
|
||||
<div
|
||||
className={`flex flex-col gap-4 ${
|
||||
data?.result !== "Charge success" &&
|
||||
"h-[328px] items-center justify-center"
|
||||
!isSuccess && "h-[328px] items-center justify-center"
|
||||
}`}
|
||||
>
|
||||
{/* Success Icon for now */}
|
||||
<div className="flex items-center w-full justify-center">
|
||||
{data?.result == "Charge success" ||
|
||||
data?.status == "successful" ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100"
|
||||
height="100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="green"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="feather feather-check-circle"
|
||||
>
|
||||
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
|
||||
<polyline points="22 4 12 14.01 9 11.01"></polyline>
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
width="100"
|
||||
height="100"
|
||||
stroke="red"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="feather feather-x-circle"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<line x1="15" y1="9" x2="9" y2="15"></line>
|
||||
<line x1="9" y1="9" x2="15" y2="15"></line>
|
||||
</svg>
|
||||
)}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100"
|
||||
height="100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke={isSuccess ? "green" : "red"}
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className={`feather ${
|
||||
isSuccess ? "feather-check-circle" : "feather-x-circle"
|
||||
}`}
|
||||
>
|
||||
{isSuccess ? (
|
||||
<>
|
||||
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
|
||||
<polyline points="22 4 12 14.01 9 11.01"></polyline>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<line x1="15" y1="9" x2="9" y2="15"></line>
|
||||
<line x1="9" y1="9" x2="15" y2="15"></line>
|
||||
</>
|
||||
)}
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div className={`flex items-center`}>
|
||||
<div className="flex items-center">
|
||||
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.result == "Charge success" ||
|
||||
data?.status == "successful"
|
||||
{isSuccess
|
||||
? "Credit was Successful!"
|
||||
: "Credit was Unsuccessful"}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{data?.internal_return >= 0 &&
|
||||
data?.result !== "Charge failed" ? (
|
||||
<>
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Amount({data?.currency || ""})
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{`${data?.symbol || ""} ${
|
||||
Number(data?.amount * 0.01).toLocaleString() || ""
|
||||
}`}
|
||||
</span>
|
||||
</div>
|
||||
data?.result !== "Charge failed" && (
|
||||
<>
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Amount({data?.currency || ""})
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{`${data?.symbol || ""} ${
|
||||
Number(data?.amount * 0.01).toLocaleString() || ""
|
||||
}`}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Wallet Balance
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.curr_balance}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Wallet Balance
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.curr_balance * 0.01}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Confirmation Number
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.confirmation}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Confirmation Number
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.confirmation}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,84 +1,102 @@
|
||||
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
|
||||
import React, { useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useSelector } from "react-redux";
|
||||
import { toast } from "react-toastify";
|
||||
import debounce from "../../../hooks/debounce";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import { tableReload } from "../../../store/TableReloads";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
|
||||
/**
|
||||
* Renders a React component that displays the description and last four digits of a payment card.
|
||||
*/
|
||||
function ThePaymentText({ value, type }) {
|
||||
const cardDetails = value;
|
||||
value.description =
|
||||
type === "new"
|
||||
? cardDetails.cardNum[0] === "4"
|
||||
? "Visa"
|
||||
: cardDetails.cardNum[0] == "5"
|
||||
? "Master"
|
||||
: "ATM"
|
||||
: value.description;
|
||||
value.digits = type === "new" ? cardDetails.cardNum.slice(-4) : value.digits;
|
||||
const { cardNum } = value;
|
||||
let description = value.description;
|
||||
let digits = value.digits;
|
||||
|
||||
if (type === "new") {
|
||||
const firstDigit = cardNum[0];
|
||||
if (firstDigit === "4") {
|
||||
description = "Visa";
|
||||
} else if (firstDigit === "5") {
|
||||
description = "Master";
|
||||
} else {
|
||||
description = "ATM";
|
||||
}
|
||||
digits = cardNum.slice(-4);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="my-2 flex items-center gap-5">
|
||||
<div className="card-details flex items-center gap-3">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1 space-x-1">
|
||||
{value.description} Card
|
||||
<h1 className="text-xl font-normal text-dark-gray dark:text-white tracking-tighter my-1 space-x-1">
|
||||
{description} Card
|
||||
</h1>
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Bank **************{value.digits}
|
||||
<p className="text-xl font-normal text-dark-gray dark:text-white tracking-wide">
|
||||
Bank **************{digits}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the amount of a transaction in a specific currency.
|
||||
* @returns {JSX.Element} - The rendered component.
|
||||
*/
|
||||
function AmountSection({ currency, amount, country }) {
|
||||
const formattedAmount = Number(amount).toFixed(2);
|
||||
const formattedAmount = amount?.toFixed(2);
|
||||
const gapClassName = country === "US" ? "gap-14" : "gap-4";
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center ${country == "US" ? "gap-14" : "gap-4"}`}
|
||||
>
|
||||
<div className={`flex items-center ${gapClassName}`}>
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Amount({currency})
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
<span className="text-xl font-normal text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{formattedAmount}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the transaction fee for a payment.
|
||||
* @returns {JSX.Element} - Rendered JSX displaying the transaction fee with the label "Transaction Fee".
|
||||
*/
|
||||
function TransactionFeeSection({ currency, fee, country }) {
|
||||
const formattedFee = Number(fee).toFixed(2);
|
||||
const formattedFee = (+fee).toFixed(2);
|
||||
const gapClass = country === "US" ? "gap-[2.7rem]" : "gap-4";
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center border-b border-gray-600 ${
|
||||
country == "US" ? "gap-[2.7rem]" : "gap-4"
|
||||
}`}
|
||||
>
|
||||
<div className={`flex items-center border-b border-gray-600 ${gapClass}`}>
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Transaction Fee
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
<span className="text-xl font-normal text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{formattedFee}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total amount by adding the `amount` and `fee` values together.
|
||||
* Formats the total amount to two decimal places and displays it.
|
||||
* @returns {JSX.Element} - The TotalSection component.
|
||||
*/
|
||||
function TotalSection({ currency, amount, fee, country }) {
|
||||
const total = Number(amount) + Number(fee);
|
||||
const formattedTotal = total.toFixed(2);
|
||||
const formattedTotal = total?.toFixed(2);
|
||||
|
||||
const gap = country === "US" ? "gap-[8rem]" : "gap-[6.3rem]";
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center ${
|
||||
country == "US" ? "gap-[8rem]" : "gap-[6.3rem]"
|
||||
}`}
|
||||
>
|
||||
<div className={`flex items-center ${gap}`}>
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Total
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
<span className="text-xl font-normal text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{formattedTotal}
|
||||
</span>
|
||||
</div>
|
||||
@@ -102,8 +120,6 @@ function ConfirmAddFund({
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [requestStatus, setRequestStatus] = useState({
|
||||
message: "",
|
||||
loading: false,
|
||||
@@ -127,7 +143,7 @@ function ConfirmAddFund({
|
||||
logo: "https://www.wrenchboard.com/assets/images/wrench-500-500-icon.png",
|
||||
},
|
||||
};
|
||||
//debugger;
|
||||
|
||||
const fwConfig = {
|
||||
...config,
|
||||
text: "Proceed",
|
||||
@@ -162,8 +178,6 @@ function ConfirmAddFund({
|
||||
status: false,
|
||||
});
|
||||
}
|
||||
|
||||
return dispatch(tableReload({ type: "WALLETTABLE" }));
|
||||
})
|
||||
.catch((err) => {
|
||||
setRequestStatus({
|
||||
@@ -188,27 +202,40 @@ function ConfirmAddFund({
|
||||
|
||||
const debouncedSuccessPayment = debounce(onSuccessPayment, 5000);
|
||||
|
||||
/**
|
||||
* Handles the process of making a payment using a previously saved card.
|
||||
* Updates the state to show a loader while the payment is being processed,
|
||||
* sends a request to the server to make the payment, and updates the state with the response.
|
||||
* If the payment is successful, it also dispatches an action to reload the wallet table.
|
||||
*/
|
||||
const handlePrevCard = async () => {
|
||||
const { amount, credit_reference, currency } = __confirmData;
|
||||
const { card_uid } = __confirmCardDetails;
|
||||
|
||||
const reqData = {
|
||||
amount: amount * 100,
|
||||
card_uid,
|
||||
credit_reference,
|
||||
currency,
|
||||
};
|
||||
|
||||
try {
|
||||
// Show loader while the payment is being processed
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
acceptConfirm: { loader: true },
|
||||
},
|
||||
}));
|
||||
|
||||
// Extract necessary data from confirmCredit and confirmCardDetails objects
|
||||
const { amount, credit_reference, currency } = __confirmData;
|
||||
const { card_uid } = __confirmCardDetails;
|
||||
|
||||
// Create request data object with required parameters for making the payment
|
||||
const reqData = {
|
||||
amount: amount * 100,
|
||||
card_uid,
|
||||
credit_reference,
|
||||
currency,
|
||||
};
|
||||
|
||||
// Send request to server to make the payment using getPaidPrevCard method of usersService
|
||||
const res = await apiURL.getPaidPrevCard(reqData);
|
||||
const _response = res.data;
|
||||
if (res.data.internal_return < 0) {
|
||||
|
||||
// If internal_return value in the response is less than 0, hide the loader and return
|
||||
if (_response.internal_return < 0) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
@@ -218,6 +245,7 @@ function ConfirmAddFund({
|
||||
return;
|
||||
}
|
||||
|
||||
// Update state to show the acceptConfirm state and the response data
|
||||
setTimeout(() => {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
@@ -227,9 +255,9 @@ function ConfirmAddFund({
|
||||
},
|
||||
data: _response,
|
||||
}));
|
||||
dispatch(tableReload({ type: "WALLETTABLE" }));
|
||||
}, 1500);
|
||||
} catch (error) {
|
||||
// Handle error and hide the loader
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
@@ -240,45 +268,45 @@ function ConfirmAddFund({
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the payment process when a new card is used.
|
||||
* @async
|
||||
*/
|
||||
const handleNewCard = async () => {
|
||||
const { amount, credit_reference, uid } = __confirmData;
|
||||
const { address, cardNum, cvv, expirationMonth, expirationYear } =
|
||||
__confirmCardDetails;
|
||||
|
||||
const reqData = {
|
||||
amount: amount * 100,
|
||||
cardnumber: cardNum.replace(/\s/g, ""),
|
||||
credit_reference,
|
||||
cvc: cvv,
|
||||
description: address,
|
||||
exp_month: expirationMonth,
|
||||
exp_year: expirationYear,
|
||||
paymenttype: 100,
|
||||
uid,
|
||||
};
|
||||
|
||||
try {
|
||||
// Extract necessary data from __confirmData and __confirmCardDetails
|
||||
const { amount, credit_reference, uid } = __confirmData;
|
||||
const { address, cardNum, cvv, expirationMonth, expirationYear } =
|
||||
__confirmCardDetails;
|
||||
|
||||
// Set loading state to indicate payment is being processed
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
acceptConfirm: { loader: true },
|
||||
},
|
||||
}));
|
||||
|
||||
// Prepare request data
|
||||
const reqData = {
|
||||
amount: amount * 100,
|
||||
cardnumber: cardNum.replace(/\s/g, ""),
|
||||
credit_reference,
|
||||
cvc: cvv,
|
||||
description: address,
|
||||
exp_month: expirationMonth,
|
||||
exp_year: expirationYear,
|
||||
paymenttype: 100,
|
||||
uid,
|
||||
};
|
||||
|
||||
// Send request to server to process payment
|
||||
const res = await apiURL.getPaidNewCard(reqData);
|
||||
const _response = res.data;
|
||||
if (res.data.internal_return < 0) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
awaitConfirm: { loader: false, state: false },
|
||||
acceptConfirm: { loader: false, state: true },
|
||||
},
|
||||
data: _response,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
// Handle response from server
|
||||
if (res.data.internal_return < 0) {
|
||||
// Payment could not be completed
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
@@ -287,9 +315,21 @@ function ConfirmAddFund({
|
||||
},
|
||||
data: _response,
|
||||
}));
|
||||
dispatch(tableReload({ type: "WALLETTABLE" }));
|
||||
}, 1500);
|
||||
} else {
|
||||
// Payment was successful
|
||||
setTimeout(() => {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
awaitConfirm: { loader: false, state: false },
|
||||
acceptConfirm: { loader: false, state: true },
|
||||
},
|
||||
data: _response,
|
||||
}));
|
||||
}, 1500);
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle error during payment process
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
@@ -362,7 +402,7 @@ function ConfirmAddFund({
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Reference No
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
<span className="text-xl font-normal text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{__confirmData?.credit_reference}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import CompleteConfirmCredit from "./CompleteConfirmCredit";
|
||||
import ConfirmAddFund from "./ConfirmAddFund";
|
||||
|
||||
const CreditPopup = ({ details, onClose, situation, walletItem }) => {
|
||||
let [input, setInput] = useState("");
|
||||
const [input, setInput] = useState("");
|
||||
const [confirmCredit, setConfirmCredit] = useState({
|
||||
show: {
|
||||
awaitConfirm: { loader: false, state: false },
|
||||
@@ -15,6 +15,20 @@ const CreditPopup = ({ details, onClose, situation, walletItem }) => {
|
||||
data: {},
|
||||
});
|
||||
|
||||
const getTitle = () => {
|
||||
if (confirmCredit?.show?.acceptConfirm?.state) {
|
||||
if (confirmCredit?.data?.internal_return < 0) {
|
||||
return "Credit Unsuccessful";
|
||||
} else {
|
||||
return "Credit Add Completed";
|
||||
}
|
||||
} else if (confirmCredit?.show?.awaitConfirm?.state) {
|
||||
return "Confirm Credit Add";
|
||||
} else {
|
||||
return "Add Credit";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalCom
|
||||
action={onClose}
|
||||
@@ -24,23 +38,9 @@ const CreditPopup = ({ details, onClose, situation, walletItem }) => {
|
||||
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
{confirmCredit?.show?.acceptConfirm?.state &&
|
||||
(confirmCredit?.data?.internal_return < 0
|
||||
// ||
|
||||
// confirmCredit?.data?.status !== "successful"
|
||||
) ? (
|
||||
"Credit Unsuccessful"
|
||||
) : (
|
||||
<>
|
||||
{confirmCredit?.show?.acceptConfirm?.loader
|
||||
? "Confirming Credit..."
|
||||
: confirmCredit?.show?.awaitConfirm?.state
|
||||
? "Confirm Credit Add"
|
||||
: confirmCredit?.show?.acceptConfirm?.state
|
||||
? "Credit Add Completed"
|
||||
: "Add Credit"}
|
||||
</>
|
||||
)}
|
||||
{confirmCredit?.show?.acceptConfirm?.loader
|
||||
? "Confirming Credit..."
|
||||
: getTitle()}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -12,6 +12,7 @@ function NairaWithdraw({
|
||||
state,
|
||||
setShowConfirmNairaWithdraw,
|
||||
}) {
|
||||
let MaxNoOfBanks = process.env.REACT_APP_MAX_CREDIT_BANK_ACCOUNT; // HOLDS THE VALUE OF THE MAX NUMBER OF BANKS USER CAN ADD
|
||||
const apiCall = new usersService();
|
||||
const [tab, setTab] = useState("previous");
|
||||
let [requestStatus, setRequestStatus] = useState(false);
|
||||
@@ -23,7 +24,9 @@ function NairaWithdraw({
|
||||
recipientID: state?.previousAccount?.recipientID || "",
|
||||
},
|
||||
newAccount: {
|
||||
country: state?.newAccount?.amount || "",
|
||||
country: wallet.walletCountry
|
||||
? wallet.walletCountry[0][0]
|
||||
: wallet.country,
|
||||
bank: state?.newAccount?.amount || "",
|
||||
accountNumber: state?.newAccount?.amount || "",
|
||||
accountType: state?.newAccount?.amount || "",
|
||||
@@ -65,10 +68,14 @@ function NairaWithdraw({
|
||||
|
||||
// Handling card change
|
||||
const handleBankOptions = (event) => {
|
||||
const { value } = event.target;
|
||||
let bankCountry = wallet.walletCountry
|
||||
? wallet.walletCountry[0][0]
|
||||
: wallet.country
|
||||
setBankName((prev) => ({ loading: true, data: [] }));
|
||||
apiCall
|
||||
.getCountryBank({ country: value })
|
||||
.getCountryBank({
|
||||
country: bankCountry
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setBankName((prev) => ({ loading: false, data: [] }));
|
||||
@@ -138,6 +145,7 @@ function NairaWithdraw({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
handleBankOptions()
|
||||
getCountry(); // TO LOAD LIST COUNTRY
|
||||
getAccountTypes(); // TO LOAD LIST ACCOUNT TYPES
|
||||
}, []);
|
||||
@@ -224,7 +232,7 @@ function NairaWithdraw({
|
||||
setShowConfirmNairaWithdraw({ show: true, state: stateData });
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
|
||||
if (tab === "new") {
|
||||
const { accountNumber, accountType, bank, city, country, state } =
|
||||
values?.newAccount;
|
||||
@@ -279,6 +287,8 @@ function NairaWithdraw({
|
||||
getRecipients();
|
||||
}, []);
|
||||
|
||||
console.log("Testing Wallet Country", wallet?.walletCountry[0][0]);
|
||||
|
||||
return (
|
||||
<ModalCom action={action} situation={situation} className="edit-popup">
|
||||
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
@@ -422,7 +432,11 @@ function NairaWithdraw({
|
||||
<label
|
||||
onClick={() => setTab("new")}
|
||||
htmlFor="new"
|
||||
className="cursor-pointer flex items-center gap-1"
|
||||
className={`cursor-pointer flex items-center gap-1 ${
|
||||
recipients.data.length >= MaxNoOfBanks
|
||||
? "pointer-events-none"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
id="new"
|
||||
@@ -435,6 +449,11 @@ function NairaWithdraw({
|
||||
} tracking-wide transition duration-200`}
|
||||
/>
|
||||
New Account{" "}
|
||||
{recipients.data.length >= MaxNoOfBanks && (
|
||||
<span className="text-[14px] text-red-500">
|
||||
Max Reached
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -521,275 +540,257 @@ function NairaWithdraw({
|
||||
</>
|
||||
)}
|
||||
|
||||
{tab == "new" && (
|
||||
<div className="w-full mt-3 rounded-md bg-slate-100">
|
||||
<div className="relative fields w-full flex flex-col p-4">
|
||||
<div className="flex flex-[2] min-h-[52px]">
|
||||
{/* country */}
|
||||
<div className="add-recipient w-full flex items-center flex-1 xl:mb-0">
|
||||
<label
|
||||
htmlFor="newAccount.country"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.3]"
|
||||
>
|
||||
Country{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding tracking-[1.5px]"
|
||||
name="newAccount.country"
|
||||
value={props.values.newAccount?.country}
|
||||
onChange={(e) => {
|
||||
props.handleChange(e);
|
||||
handleBankOptions(e);
|
||||
}}
|
||||
>
|
||||
{allCountries.loading ? (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Loading...
|
||||
</option>
|
||||
) : allCountries.data?.length ? (
|
||||
<>
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
{errorMsgs.newAccount?.country
|
||||
? errorMsgs.newAccount.country
|
||||
: "Select..."}
|
||||
</option>
|
||||
{allCountries.data.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item[0]}
|
||||
>
|
||||
{item[1]}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
No Options Found!
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
{/* {props.errors.country &&
|
||||
props.touched.country && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.country}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
|
||||
{/* bank name */}
|
||||
<div className="add-recipient w-full flex items-center flex-1">
|
||||
<label
|
||||
htmlFor="newAccount.bank"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4] tracking-[1.5px]"
|
||||
>
|
||||
Bank Name{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding "
|
||||
name="newAccount.bank"
|
||||
value={props.values.newAccount?.bank}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
>
|
||||
{bankName.loading ? (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Loading...
|
||||
</option>
|
||||
) : bankName.data?.length ? (
|
||||
<>
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Select...
|
||||
</option>
|
||||
{bankName.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item.bank_uid}
|
||||
>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
{allCountries.data?.length
|
||||
? "Select..."
|
||||
: "No Options Found!"}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
{/* {props.errors.bank && props.touched.bank && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.bank}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-[2] gap-4">
|
||||
{/* ACCOUNT NUMBER */}
|
||||
<div className="field w-full flex-[1.4] flex items-center gap-2">
|
||||
<label
|
||||
htmlFor="newAccount.accountNumber"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex items-center flex-1"
|
||||
>
|
||||
Account Number{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<InputCom
|
||||
fieldClass="px-6 tracking-[1.5px]"
|
||||
inputClass="flex items-center max-w-[15rem]"
|
||||
type="text"
|
||||
name="newAccount.accountNumber"
|
||||
placeholder="Account No"
|
||||
maxLength={10}
|
||||
value={props.values.newAccount?.accountNumber}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{/* {props.errors.accountNumber &&
|
||||
props.touched.accountNumber && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.accountNumber}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
|
||||
{/* Account Type */}
|
||||
<div className="add-recipient w-full flex flex-1 items-center">
|
||||
<label
|
||||
htmlFor="newAccount.accountType"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.3]"
|
||||
>
|
||||
Type <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding flex-grow tracking-[1.5px]"
|
||||
name="newAccount.accountType"
|
||||
value={props.values.newAccount?.accountType}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
>
|
||||
{accType.loading ? (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Loading...
|
||||
</option>
|
||||
) : accType.data?.length ? (
|
||||
<>
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Select...
|
||||
</option>
|
||||
{accType.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item.value}
|
||||
>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
No Options Found!
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
{/* {props.errors.accountType &&
|
||||
props.touched.accountType && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.accountType}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-1">
|
||||
{/* state */}
|
||||
<div className="field w-full flex items-center gap-4 flex-[0.4]">
|
||||
<label
|
||||
htmlFor="newAccount.state"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4]"
|
||||
>
|
||||
State <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<InputCom
|
||||
fieldClass="px-6 tracking-[1.5px]"
|
||||
inputClass="max-w-[10rem]"
|
||||
type="text"
|
||||
name="newAccount.state"
|
||||
placeholder="State/Province"
|
||||
value={props.values.newAccount?.state}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{/* {props.errors.state && props.touched.state && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.state}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
|
||||
{/* city */}
|
||||
<div className="field w-full flex items-center flex-[0.4]">
|
||||
<label
|
||||
htmlFor="newAccount.city"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4]"
|
||||
>
|
||||
City <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<InputCom
|
||||
fieldClass="px-6 tracking-[1.5px]"
|
||||
type="text"
|
||||
inputClass="max-w-[10rem]"
|
||||
name="newAccount.city"
|
||||
placeholder="City"
|
||||
value={props.values.newAccount?.city}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{/* {props.errors.city && props.touched.city && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.city}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* end of inputs for new accounts */}
|
||||
{tab == "new" &&
|
||||
(recipients.loading ? (
|
||||
<div className="mt-3 flex flex-col w-full h-[188px] justify-center items-center">
|
||||
<LoadingSpinner size="10" color="sky-blue" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
) : recipients.data.length < MaxNoOfBanks ? (
|
||||
<div className="w-full mt-3 rounded-md bg-slate-100">
|
||||
<div className="relative fields w-full flex flex-col p-4">
|
||||
<div className="flex flex-[2] min-h-[52px]">
|
||||
{/* country */}
|
||||
<div className="add-recipient w-full flex items-center flex-1 xl:mb-0">
|
||||
<label
|
||||
htmlFor="newAccount.country"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.3]"
|
||||
>
|
||||
Country{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<div className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding tracking-[1.5px] flex items-center pointer-events-none">
|
||||
<span className="text-slate-500 text-lg italic">
|
||||
{wallet.walletCountry[0][1]}
|
||||
</span>
|
||||
</div>
|
||||
{/* <select
|
||||
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding tracking-[1.5px]"
|
||||
name="newAccount.country"
|
||||
value={props.values.newAccount?.country}
|
||||
onChange={(e) => {
|
||||
props.handleChange(e);
|
||||
handleBankOptions(e);
|
||||
}}
|
||||
>
|
||||
{allCountries.loading ? (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Loading...
|
||||
</option>
|
||||
) : allCountries.data?.length ? (
|
||||
<>
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
{errorMsgs.newAccount?.country
|
||||
? errorMsgs.newAccount.country
|
||||
: "Select..."}
|
||||
</option>
|
||||
{allCountries.data.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item[0]}
|
||||
>
|
||||
{item[1]}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
No Options Found!
|
||||
</option>
|
||||
)}
|
||||
</select> */}
|
||||
</div>
|
||||
|
||||
{/* bank name */}
|
||||
<div className="add-recipient w-full flex items-center flex-1">
|
||||
<label
|
||||
htmlFor="newAccount.bank"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4] tracking-[1.5px]"
|
||||
>
|
||||
Bank Name{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding "
|
||||
name="newAccount.bank"
|
||||
value={props.values.newAccount?.bank}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
>
|
||||
{bankName.loading ? (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Loading...
|
||||
</option>
|
||||
) : bankName.data?.length ? (
|
||||
<>
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Select...
|
||||
</option>
|
||||
{bankName.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item.bank_uid}
|
||||
>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
{allCountries.data?.length
|
||||
? "Select..."
|
||||
: "No Options Found!"}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-[2] gap-4">
|
||||
{/* ACCOUNT NUMBER */}
|
||||
<div className="field w-full flex-[1.4] flex items-center gap-2">
|
||||
<label
|
||||
htmlFor="newAccount.accountNumber"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex items-center flex-1"
|
||||
>
|
||||
Account Number{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<InputCom
|
||||
fieldClass="px-6 tracking-[1.5px]"
|
||||
inputClass="flex items-center max-w-[15rem]"
|
||||
type="text"
|
||||
name="newAccount.accountNumber"
|
||||
placeholder="Account No"
|
||||
maxLength={10}
|
||||
value={
|
||||
props.values.newAccount?.accountNumber
|
||||
}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Account Type */}
|
||||
<div className="add-recipient w-full flex flex-1 items-center">
|
||||
<label
|
||||
htmlFor="newAccount.accountType"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.3]"
|
||||
>
|
||||
Type <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding flex-grow tracking-[1.5px]"
|
||||
name="newAccount.accountType"
|
||||
value={props.values.newAccount?.accountType}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
>
|
||||
{accType.loading ? (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Loading...
|
||||
</option>
|
||||
) : accType.data?.length ? (
|
||||
<>
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Select...
|
||||
</option>
|
||||
{accType.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item.value}
|
||||
>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
No Options Found!
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-1">
|
||||
{/* state */}
|
||||
<div className="field w-full flex items-center gap-4 flex-[0.4]">
|
||||
<label
|
||||
htmlFor="newAccount.state"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4]"
|
||||
>
|
||||
State{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<InputCom
|
||||
fieldClass="px-6 tracking-[1.5px]"
|
||||
inputClass="max-w-[10rem]"
|
||||
type="text"
|
||||
name="newAccount.state"
|
||||
placeholder="State/Province"
|
||||
value={props.values.newAccount?.state}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* city */}
|
||||
<div className="field w-full flex items-center flex-[0.4]">
|
||||
<label
|
||||
htmlFor="newAccount.city"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4]"
|
||||
>
|
||||
City <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<InputCom
|
||||
fieldClass="px-6 tracking-[1.5px]"
|
||||
type="text"
|
||||
inputClass="max-w-[10rem]"
|
||||
name="newAccount.city"
|
||||
placeholder="City"
|
||||
value={props.values.newAccount?.city}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* end of inputs for new accounts */}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-3 flex w-full h-[188px] justify-center items-center"></div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="transfer-fund-btn flex justify-end items-center gap-2 py-4">
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import React, {
|
||||
Suspense,
|
||||
lazy,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import React, { Suspense, lazy, useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import usersService from "../../services/UsersService";
|
||||
import Layout from "../Partials/Layout";
|
||||
@@ -14,31 +7,19 @@ const WalletBox = lazy(() => import("./WalletBox"));
|
||||
|
||||
const WalletRoutes = () => {
|
||||
const apiCall = new usersService();
|
||||
const { walletDetails } = useSelector((state) => state?.walletDetails); // WALLET STORE
|
||||
const { walletTable } = useSelector((state) => state.tableReload);
|
||||
const [walletList, setWalletList] = useState({
|
||||
loading: true,
|
||||
data: [],
|
||||
reload: false,
|
||||
});
|
||||
|
||||
const [paymentHistory, setPaymentHistory] = useState({
|
||||
loading: true,
|
||||
data: [],
|
||||
});
|
||||
|
||||
const getWalletList = () => {
|
||||
apiCall
|
||||
.getUserWallets()
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setWalletList({ loading: false, data: [] });
|
||||
} else {
|
||||
setWalletList({ loading: false, data: res.data?.result_list });
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setWalletList({ loading: false, data: [] });
|
||||
});
|
||||
}
|
||||
const [allCountries, setAllCountries] = useState({
|
||||
// STATE TO HOLD LIST OF COUNTRIES
|
||||
loading: true,
|
||||
data: [],
|
||||
});
|
||||
|
||||
const getPaymentHistory = () => {
|
||||
apiCall
|
||||
@@ -53,24 +34,47 @@ const WalletRoutes = () => {
|
||||
.catch(() => {
|
||||
setPaymentHistory({ loading: false, data: [] });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// FUNCTION TO GET COUNTRIES
|
||||
const getCountry = () => {
|
||||
apiCall
|
||||
.getSignupCountryData()
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setAllCountries((prev) => ({ loading: false, data: [] }));
|
||||
return;
|
||||
}
|
||||
setAllCountries((prev) => ({
|
||||
loading: false,
|
||||
data: res.data.signup_country,
|
||||
}));
|
||||
})
|
||||
.catch((error) => {
|
||||
setAllCountries((prev) => ({ loading: false, data: [] }));
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// const fetchData = async () => {
|
||||
// await Promise.all([getWalletList(), getPaymentHistory()]);
|
||||
// };
|
||||
|
||||
// if (walletList.loading) {
|
||||
// fetchData();
|
||||
// }
|
||||
getWalletList()
|
||||
getPaymentHistory()
|
||||
getCountry();
|
||||
getPaymentHistory();
|
||||
}, [walletTable]);
|
||||
|
||||
console.log(
|
||||
"Testing all country: ",
|
||||
allCountries,
|
||||
"Testing wallet: ",
|
||||
walletDetails
|
||||
);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||
<WalletBox wallet={walletList} payment={paymentHistory} />
|
||||
<WalletBox
|
||||
wallet={walletDetails}
|
||||
payment={paymentHistory}
|
||||
countries={allCountries.data}
|
||||
/>
|
||||
</Suspense>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import usersService from "../../services/UsersService";
|
||||
import ConfirmNairaWithdraw from "./Popup/ConfirmNairaWithdraw";
|
||||
import NairaWithdraw from "./Popup/NairaWithdraw";
|
||||
@@ -8,7 +8,7 @@ function WalletAction({ walletItem, payment, openPopUp }) {
|
||||
show: false,
|
||||
state: {},
|
||||
}); // DETERMINES WHEN NAIRA WITHDRAWAL POPS UP
|
||||
|
||||
|
||||
const [showConfirmNairaWithdraw, setShowConfirmNairaWithdraw] = useState({
|
||||
show: false,
|
||||
state: {},
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import WalletItemCard from "./WalletItemCard";
|
||||
|
||||
export default function WalletBox({ wallet, payment }) {
|
||||
/**
|
||||
* Renders a list of wallet items or a loading spinner depending on the state of the `wallet` object.
|
||||
*/
|
||||
export default function WalletBox({ wallet, payment, countries }) {
|
||||
const { loading, data } = wallet;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="my-wallet-wrapper w-full mb-10">
|
||||
<div className="main-wrapper w-full">
|
||||
<div className="balance-inquery w-full lg:grid grid-cols-[repeat(auto-fill,_minmax(325px,_1fr))] gap-5 mb-11 h-[22rem]">
|
||||
{wallet.loading ? (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
<div className="my-wallet-wrapper w-full mb-10">
|
||||
<div className="main-wrapper w-full">
|
||||
<div className="balance-inquery w-auto grid sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-[repeat(auto-fill,_minmax(354px,_1fr))] min-[1440px]:grid-cols-[repeat(auto-fill,_minmax(415px,_1fr))] gap-5 mb-11 h-auto">
|
||||
{loading ? (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
</div>
|
||||
) : (
|
||||
data.length > 0 && data.map((item) => (
|
||||
<div key={item.wallet_uid} className="lg:w-full h-full mb-10 lg:mb-0">
|
||||
<WalletItemCard walletItem={item} payment={payment} countries={countries} />
|
||||
</div>
|
||||
) : wallet.data.length ? (
|
||||
wallet.data.map((item, index) => (
|
||||
<div className="lg:w-full h-full mb-10 lg:mb-0">
|
||||
<WalletItemCard walletItem={item} payment={payment} />
|
||||
</div>
|
||||
))
|
||||
) : null}
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,12 @@ export default function WalletHeader(props) {
|
||||
//props.myWalletList.result_list
|
||||
let { pathname } = useLocation();
|
||||
let navigate = useNavigate();
|
||||
|
||||
const onWalletClick = () => {
|
||||
if (pathname == "/my-wallet")
|
||||
props.setBalanceDropdown.toggle();
|
||||
else navigate("/my-wallet", { replace: true });
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className="lg:flex hidden user-balance cursor-pointer lg:w-[152px] w-[150px] h-[48px] items-center rounded-full relative bg-sky-blue pr-1.5 pl-4">
|
||||
@@ -41,14 +47,15 @@ export default function WalletHeader(props) {
|
||||
<div className="content px-7 pb-7">
|
||||
<ul>
|
||||
{props.myWalletList &&
|
||||
props.myWalletList?.result_list?.length > 0 &&
|
||||
props.myWalletList.result_list.map((value, index) =>
|
||||
props.myWalletList?.length > 0 &&
|
||||
props.myWalletList.map((value, index) =>
|
||||
{
|
||||
let image = value.code ? `${value.code.toLocaleLowerCase()}.svg` : 'default.png'
|
||||
return(
|
||||
<li
|
||||
key={index}
|
||||
className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple"
|
||||
onClick={onWalletClick}
|
||||
>
|
||||
<div className="sm:flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">
|
||||
@@ -56,7 +63,7 @@ export default function WalletHeader(props) {
|
||||
<img src={localImgLoad(`images/currency/${image}`)} className="w-14 h-14" alt="" />
|
||||
</div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium">
|
||||
<p className="text-2xl font-bold text-dark-gray dark:text-white">
|
||||
{value.description}
|
||||
</p>
|
||||
</div>
|
||||
@@ -178,11 +185,7 @@ export default function WalletHeader(props) {
|
||||
</button> */}
|
||||
<Link
|
||||
to="/my-wallet"
|
||||
onClick={() => {
|
||||
if (pathname == "/my-wallet")
|
||||
props.setBalanceDropdown.toggle();
|
||||
else navigate("/my-wallet", { replace: true });
|
||||
}}
|
||||
onClick={onWalletClick}
|
||||
className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Manage
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
import React, { useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import background from "../../assets/images/bg-sky-blue.jpg"; //shape/balance-bg.svg";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import CreditPopup from "./Popup/CreditPopup";
|
||||
import WalletAction from "./WalletAction";
|
||||
|
||||
export default function WalletItemCard({ walletItem, payment }) {
|
||||
// const [eth] = useState(90);
|
||||
// const [btc] = useState(85);
|
||||
// const [ltc] = useState(20);
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
let accountType = userDetails?.account_type == "FAMILY";
|
||||
|
||||
// Credit popup
|
||||
/**
|
||||
* Renders a card displaying information about a wallet item.
|
||||
*/
|
||||
export default function WalletItemCard({ walletItem, payment, countries }) {
|
||||
const { userDetails } = useSelector((state) => state.userDetails);
|
||||
const accountType = userDetails?.account_type === "FAMILY";
|
||||
const dispatch = useDispatch();
|
||||
const [creditPopup, setCreditPopup] = useState({ show: false, data: {} });
|
||||
|
||||
/**
|
||||
* Opens the credit popup.
|
||||
* @param {Object} value - The value object.
|
||||
*/
|
||||
const openPopUp = (value) => {
|
||||
setCreditPopup({
|
||||
show: true,
|
||||
@@ -23,37 +27,45 @@ export default function WalletItemCard({ walletItem, payment }) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the credit popup and dispatches a table reload action.
|
||||
*/
|
||||
const closePopUp = () => {
|
||||
setCreditPopup({ show: false, data: {} });
|
||||
dispatch(tableReload({ type: "WALLETTABLE" }));
|
||||
};
|
||||
|
||||
let image = walletItem.code
|
||||
? `${walletItem.code.toLocaleLowerCase()}.svg`
|
||||
: "default.png"; // HOLDS THE VALUE NAME PROPERTY FOR IMAGE ICON
|
||||
const currentWalletCurrency = countries
|
||||
.map((country) => country)
|
||||
.filter((country) => country[0] === walletItem.country);
|
||||
|
||||
const image = walletItem.code
|
||||
? `${walletItem.code.toLowerCase()}.svg`
|
||||
: "default.png";
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={`current-balance-widget w-full h-full rounded-2xl overflow-hidden flex flex-col items-center gap-2 px-8 pt-9 pb-20`}
|
||||
className="current-balance-widget w-full h-full rounded-2xl overflow-hidden flex flex-col items-center gap-2 p-8 justify-between"
|
||||
style={{
|
||||
background: `url(${background}) 0% 0% / cover no-repeat`,
|
||||
}}
|
||||
>
|
||||
{/* <div className="w-[350px]"> */}
|
||||
<div className="wallet w-full flex justify-between items-start gap-3">
|
||||
<div className="min-w-[100px] min-h-[100px] max-w-[100px] max-h-[100px] rounded-full bg-[#e3e3e3] flex justify-center items-center">
|
||||
<div className="min-w-[100px] min-h-[100px] max-w-min md:max-w-[150px] max-h-min md:max-h-[150px] rounded-full bg-[#e3e3e3] flex justify-center items-center">
|
||||
<img
|
||||
src={localImgLoad(`images/currency/${image}`)}
|
||||
className="w-full h-full"
|
||||
alt="curreny-icon"
|
||||
alt="currency-icon"
|
||||
/>
|
||||
</div>
|
||||
<div className="balance w-full mt-2 flex justify-center">
|
||||
<div className="">
|
||||
<p className="text-lg text-white opacity-[70%] tracking-wide mb-6">
|
||||
<p className="text-base sm:text-lg text-white opacity-[70%] tracking-wide mb-2 sm:mb-6">
|
||||
Current Balance
|
||||
</p>
|
||||
<p className="text-[44px] font-bold text-white tracking-wide leading-10 mb-2">
|
||||
<p className="text-[44px] lg:text-[62px] font-bold text-white tracking-wide leading-10 xxs:scale-100 lg:scale-100 xl:scale-125">
|
||||
{PriceFormatter(
|
||||
walletItem.amount * 0.01,
|
||||
walletItem.code,
|
||||
@@ -65,9 +77,9 @@ export default function WalletItemCard({ walletItem, payment }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="my-5 text-lg text-white tracking-wide flex justify-center items-center gap-2">
|
||||
<p className="text-lg text-white tracking-wide flex justify-center items-center gap-8">
|
||||
HOLDINGS :{" "}
|
||||
<span className="mt-1">
|
||||
<span className="xxs:scale-100 lg:scale-100 xl:scale-125">
|
||||
{PriceFormatter(
|
||||
walletItem.escrow * 0.01,
|
||||
walletItem.code,
|
||||
@@ -76,18 +88,18 @@ export default function WalletItemCard({ walletItem, payment }) {
|
||||
)}
|
||||
</span>
|
||||
</p>
|
||||
{/* for white underline */}
|
||||
|
||||
<div className="my-2 w-full h-[1px] bg-white"></div>
|
||||
|
||||
{!accountType ? (
|
||||
{!accountType && (
|
||||
<WalletAction
|
||||
walletItem={walletItem}
|
||||
walletItem={{ ...walletItem, walletCountry: currentWalletCurrency }}
|
||||
payment={payment}
|
||||
openPopUp={openPopUp}
|
||||
/>
|
||||
) : null}
|
||||
{/* </div> */}
|
||||
)}
|
||||
</div>
|
||||
|
||||
{creditPopup.show && (
|
||||
<CreditPopup
|
||||
details={creditPopup.data}
|
||||
|
||||
@@ -15,6 +15,7 @@ import WalletHeader from "../MyWallet/WalletHeader";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import Flag from "../../assets/images/united-states.svg";
|
||||
import siteLogo from "../../assets/images/wrenchboard-logo-text.png";
|
||||
// import { updateWalletDetails } from "../../store/walletDetails";
|
||||
import TimeDifference from "../Helpers/TimeDifference";
|
||||
|
||||
const DEFAULT_PROFILE_IMAGE = require("../../assets/images/profile.jpg");
|
||||
@@ -33,19 +34,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { notifications } = useSelector((state) => state?.notifications); // NOTIFICATION STORE
|
||||
|
||||
const getMyWalletList = async () => {
|
||||
try {
|
||||
const res = await api.getUserWallets(null);
|
||||
console.log("wallet - > ", res.data);
|
||||
setMyWalletList(res.data);
|
||||
} catch (error) {
|
||||
console.log("Error getting mode");
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
getMyWalletList();
|
||||
}, [walletTable]);
|
||||
const { walletDetails } = useSelector((state) => state?.walletDetails); // WALLET STORE
|
||||
|
||||
const handlerBalance = () => {
|
||||
setbalanceValue.toggle();
|
||||
@@ -104,7 +93,6 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
|
||||
let userEmail = email?.split("@")[0];
|
||||
const userProfileImage = profile_pic_url || DEFAULT_PROFILE_IMAGE;
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="header-wrapper backdrop-blur-sm bg-[#efedfe5e]/60 dark:bg-transparent w-full h-full flex items-center xl:px-0 md:px-10 px-5">
|
||||
@@ -241,7 +229,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
|
||||
|
||||
{/*<div className="lg:hidden block"></div>*/}
|
||||
<WalletHeader
|
||||
myWalletList={myWalletList}
|
||||
myWalletList={walletDetails.data}
|
||||
handlerBalance={handlerBalance}
|
||||
balanceDropdown={balanceDropdown}
|
||||
addMoneyHandler={addMoneyHandler}
|
||||
|
||||
@@ -55,59 +55,29 @@ export default function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<div className="nft-main-wrapper-layout">
|
||||
<div className="nft-wrapper-layout-container 2xl:pr-20 md:pr-10 pr-2 pl-2 md:pl-0 w-full min-h-screen flex">
|
||||
<div className={`nft-wrapper-layout-container 2xl:pr-20 md:pr-10 pr-2 pl-2 md:pl-0 w-full min-h-screen flex`}>
|
||||
{/* sidebar */}
|
||||
<div
|
||||
className={`nft-sidebar xl:block hidden section-shadow ${
|
||||
drawer
|
||||
? "2xl:w-[335px] w-[280px] 2xl:pl-20 pl-10 pr-6 "
|
||||
: "w-[70px]"
|
||||
} bg-white dark:bg-dark-white h-full overflow-y-scroll overflow-style-none fixed left-0 top-0 pt-[30px]`}
|
||||
>
|
||||
<Sidebar
|
||||
logoutModalHandler={logoutModalHandler}
|
||||
sidebar={drawer}
|
||||
action={() => dispatch(drawerToggle())}
|
||||
myJobList={userJobList}
|
||||
/>
|
||||
<div className={`nft-sidebar xl:block hidden section-shadow ${drawer ? "2xl:w-[335px] w-[280px] 2xl:pl-20 pl-10 pr-6 " : "w-[70px]"} bg-white dark:bg-dark-white h-full overflow-y-scroll overflow-style-none fixed left-0 top-0 pt-[30px]`}>
|
||||
<Sidebar logoutModalHandler={logoutModalHandler} sidebar={drawer} action={() => dispatch(drawerToggle())} myJobList={userJobList} />
|
||||
</div>
|
||||
{MobileSideBar && (
|
||||
<div
|
||||
onClick={() => setMobileSidebar.toggle()}
|
||||
className="bg-black bg-opacity-20 fixed left-0 top-0 w-full h-full z-[50] block xl:hidden"
|
||||
></div>
|
||||
<div onClick={() => setMobileSidebar.toggle()} className="bg-black bg-opacity-20 fixed left-0 top-0 w-full h-full z-[50] block xl:hidden"></div>
|
||||
)}
|
||||
<div
|
||||
className={`nft-sidebar block xl:hidden section-shadow w-[280px] pl-3 bg-white dark:bg-dark-white h-full overflow-y-scroll overflow-style-none fixed z-[60] top-0 pt-8 ${
|
||||
MobileSideBar ? "left-0" : "-left-[290px]"
|
||||
}`}
|
||||
>
|
||||
<MobileSidebar
|
||||
logoutModalHandler={logoutModalHandler}
|
||||
sidebar={MobileSideBar}
|
||||
action={() => setMobileSidebar.toggle()}
|
||||
myJobList={userJobList}
|
||||
/>
|
||||
<div className={`nft-sidebar block xl:hidden section-shadow w-[280px] pl-3 bg-white dark:bg-dark-white h-full overflow-y-scroll overflow-style-none fixed z-[60] top-0 pt-8 ${MobileSideBar ? "left-0" : "-left-[290px]"}`}>
|
||||
<MobileSidebar logoutModalHandler={logoutModalHandler} sidebar={MobileSideBar} action={() => setMobileSidebar.toggle()} myJobList={userJobList} />
|
||||
</div>
|
||||
{/* end sidebar */}
|
||||
<div
|
||||
className={`nft-header-container-wrapper flex-1 md:ml-10 ${
|
||||
drawer ? "2xl:ml-[375px] xl:ml-[310px]" : "xl:ml-[110px]"
|
||||
} h-full`}
|
||||
>
|
||||
<div className={`nft-header-container-wrapper flex-1 md:ml-10 ${drawer ? "2xl:ml-[375px] xl:ml-[310px]" : "xl:ml-[110px]"} h-full`}>
|
||||
{/* header */}
|
||||
<div className="nft-header w-full lg:h-[100px] h-[70px] default-border-bottom dark:border-[#292967] z-40 xl:sticky fixed top-0 left-0 ">
|
||||
<Header
|
||||
sidebarHandler={() => setMobileSidebar.toggle()}
|
||||
logoutModalHandler={logoutModalHandler}
|
||||
/>
|
||||
<div className="nft-header w-full lg:h-[100px] h-[70px] default-border-bottom dark:border-[#292967] z-40 xl:sticky fixed top-0 left-0 ">
|
||||
<Header sidebarHandler={() => setMobileSidebar.toggle()} logoutModalHandler={logoutModalHandler} />
|
||||
</div>
|
||||
{/* container */}
|
||||
<div className="nft-container 2xl:flex 2xl:space-x-8 h-full mb-12 lg:mt-[140px] mt-24 xl:mt-10">
|
||||
<div className="nft-main-container flex-1">
|
||||
<div className="nft-container 2xl:flex 2xl:space-x-8 h-full mb-12 lg:mt-[140px] mt-24 xl:mt-10 flex flex-col xl:flex-row items-start justify-center gap-4">
|
||||
<div className="nft-main-container flex-[80%] w-full">
|
||||
{children && children}
|
||||
</div>
|
||||
<div className="nft-right-side-content 2xl:w-[270px] w-full h-full 2xl:flex justify-center relative">
|
||||
<div className="nft-right-side-content 2xl:w-[270px] w-full h-full 2xl:flex justify-center relative flex-[20%]">
|
||||
<RightSideBar />
|
||||
</div>
|
||||
</div>
|
||||
@@ -121,50 +91,19 @@ export default function Layout({ children }) {
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Confirm
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={logoutModalHandler}
|
||||
>
|
||||
<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"
|
||||
/>
|
||||
<button type="button" className="text-[#374557] dark:text-red-500" onClick={logoutModalHandler}>
|
||||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" className="fill-current" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z" fill="" fillOpacity="0.6" />
|
||||
<path d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z" fill="#" fillOpacity="0.6" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="logout-modal-body w-full flex flex-col items-center px-10 py-8">
|
||||
<div className="what-icon mb-6 cursor-pointer">
|
||||
<svg
|
||||
width="136"
|
||||
height="136"
|
||||
viewBox="0 0 136 136"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="68" cy="68" r="68" fill="#5356FB" />
|
||||
<path
|
||||
d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M67.485 100.21C66.1617 99.9268 64.9041 99.5091 63.803 98.6787C61.3804 96.8484 60.2877 93.7699 61.0386 90.7888C61.7726 87.8747 64.2138 85.6703 67.2089 85.2157C71.273 84.6 75.2024 87.3681 75.8135 91.277C76.4937 95.6153 73.8202 99.3782 69.544 100.103C69.4429 100.12 69.3487 100.172 69.2527 100.209C68.6635 100.21 68.0742 100.21 67.485 100.21Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width="136" height="136" viewBox="0 0 136 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="68" cy="68" r="68" fill="#4687ba" />
|
||||
<path d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z" fill="white" />
|
||||
<path d="M67.485 100.21C66.1617 99.9268 64.9041 99.5091 63.803 98.6787C61.3804 96.8484 60.2877 93.7699 61.0386 90.7888C61.7726 87.8747 64.2138 85.6703 67.2089 85.2157C71.273 84.6 75.2024 87.3681 75.8135 91.277C76.4937 95.6153 73.8202 99.3782 69.544 100.103C69.4429 100.12 69.3487 100.172 69.2527 100.209C68.6635 100.21 68.0742 100.21 67.485 100.21Z" fill="white" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
@@ -173,18 +112,10 @@ export default function Layout({ children }) {
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex space-x-2.5">
|
||||
<button
|
||||
onClick={logOut}
|
||||
type="button"
|
||||
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
<button onClick={logOut} type="button" className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full">
|
||||
{`Yes ${process.env.REACT_APP_LOGOUT_TEXT}`}
|
||||
</button>
|
||||
<button
|
||||
onClick={logoutModalHandler}
|
||||
type="button"
|
||||
className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
<button onClick={logoutModalHandler} type="button" className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full">
|
||||
<span className="text-gradient">Not Now</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { NavLink } from "react-router-dom";
|
||||
//import SideStatistics from "./SideStatistics";
|
||||
|
||||
export default function RightSideBar() {
|
||||
@@ -35,8 +35,8 @@ export default function RightSideBar() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="right-sidebar-wrapper overflow-y-scroll overflow-style-none 2xl:fixed 2xl:grid-cols-none 2xl:block grid lg:grid-cols-2 grid-cols-1 xl:gap-7 gap-4 h-full 2xl:pb-96">
|
||||
<div className="top-platform bg-white dark:bg-dark-white rounded-2xl p-8 2xl:w-[268px] w-full 2xl:mb-10 2xl:border-none border ">
|
||||
<div className="right-sidebar-wrapper overflow-y-scroll overflow-style-none 2xl:fixed h-full 2xl:pb-96">
|
||||
<div className="top-platform bg-white dark:bg-dark-white rounded-2xl p-8 2xl:w-[268px] w-full 2xl:mb-10 2xl:border-none border ">
|
||||
{/* heading */}
|
||||
<div className="heading flex justify-between items-center mb-3.5">
|
||||
<h3 className="text-xl font-bold text-dark-gray dark:text-white">
|
||||
@@ -47,31 +47,62 @@ export default function RightSideBar() {
|
||||
|
||||
<div className="platform-list">
|
||||
{userDetails && userDetails?.account_type !== "FAMILY" && (
|
||||
<>
|
||||
<div className="item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="history">
|
||||
<g data-name="14"><circle cx="9" cy="14" r="7" fill="#ffd54f"></circle>
|
||||
<path fill="#ef6c00" d="M21 9H17a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2zM21 5H3A1 1 0 0 1 3 3H21a1 1 0 0 1 0 2zM21 13H19a1 1 0 0 1 0-2h2a1 1 0 0 1 0 2zM21 17H19a1 1 0 0 1 0-2h2a1 1 0 0 1 0 2zM21 21H17a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z"></path><path fill="#ff8f00" d="M10,10a1,1,0,0,0-2,0v3.59L6.29,15.29a1,1,0,1,0,1.41,1.41l2-2A1,1,0,0,0,10,14Z">
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
{/* name */}
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-base font-medium">
|
||||
<NavLink to="/history">History</NavLink>
|
||||
</p>
|
||||
</div>
|
||||
{/* action */}
|
||||
</div>
|
||||
<>
|
||||
<div className="item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 rounded-full">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
id="history"
|
||||
>
|
||||
<g data-name="14">
|
||||
<circle cx="9" cy="14" r="7" fill="#ffd54f"></circle>
|
||||
<path
|
||||
fill="#ef6c00"
|
||||
d="M21 9H17a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2zM21 5H3A1 1 0 0 1 3 3H21a1 1 0 0 1 0 2zM21 13H19a1 1 0 0 1 0-2h2a1 1 0 0 1 0 2zM21 17H19a1 1 0 0 1 0-2h2a1 1 0 0 1 0 2zM21 21H17a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z"
|
||||
></path>
|
||||
<path
|
||||
fill="#ff8f00"
|
||||
d="M10,10a1,1,0,0,0-2,0v3.59L6.29,15.29a1,1,0,1,0,1.41,1.41l2-2A1,1,0,0,0,10,14Z"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
{/* name */}
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-base font-medium">
|
||||
<NavLink to="/history">History</NavLink>
|
||||
</p>
|
||||
</div>
|
||||
{/* action */}
|
||||
</div>
|
||||
|
||||
<div className="item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="add-user">
|
||||
<path fill="#9bcb5b" d="M12 13.4c-2 0-3.7-1.6-3.7-3.6s1.6-3.7 3.6-3.7 3.7 1.6 3.7 3.6-1.6 3.6-3.6 3.7zm0-6.2c-1.4 0-2.6 1.1-2.6 2.6 0 1.4 1.1 2.6 2.6 2.6s2.6-1.1 2.6-2.6c-.1-1.5-1.2-2.6-2.6-2.6z"></path><path fill="#9bcb5b" d="M16.6 17.9c-.3 0-.5-.2-.6-.5 0-2.2-1.8-4-4-4s-4 1.8-4 4c0 .3-.3.5-.6.5-.2 0-.4-.2-.5-.5 0-2.8 2.3-5.1 5.1-5.1s5.1 2.3 5.1 5.1c0 .3-.2.5-.5.5z"></path><path fill="#0376bc" d="M12 23.7C5.5 23.7.3 18.4.3 12 .3 5.5 5.6.3 12 .3c2.6 0 5.1.9 7.2 2.5.2.2.2.6 0 .8-.2.2-.4.2-.7.1-1.9-1.4-4.1-2.2-6.5-2.2C6.2 1.4 1.4 6.2 1.4 12S6.2 22.6 12 22.6 22.6 17.8 22.6 12c0-2.4-.8-4.6-2.2-6.5-.2-.3-.1-.6.2-.8.2-.1.5-.1.7.1 1.6 2 2.5 4.6 2.4 7.2 0 6.4-5.3 11.7-11.7 11.7z"></path><circle cx="20.2" cy="20.3" r="2.4" fill="#fff"></circle><path fill="#9bcb5b" d="M18 18.1c.6-.6 1.4-.9 2.2-.9.8 0 1.6.3 2.2.9s1 1.4.9 2.2c0 .8-.3 1.6-.9 2.2s-1.4 1-2.2.9c-.8 0-1.6-.3-2.2-.9s-1-1.4-.9-2.2c-.1-.8.3-1.7.9-2.2zm3.8 2.5V20h-1.3v-1.3h-.6V20h-1.3v.6h1.3v1.3h.6v-1.3h1.3z"></path>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
id="add-user"
|
||||
>
|
||||
<path
|
||||
fill="#9bcb5b"
|
||||
d="M12 13.4c-2 0-3.7-1.6-3.7-3.6s1.6-3.7 3.6-3.7 3.7 1.6 3.7 3.6-1.6 3.6-3.6 3.7zm0-6.2c-1.4 0-2.6 1.1-2.6 2.6 0 1.4 1.1 2.6 2.6 2.6s2.6-1.1 2.6-2.6c-.1-1.5-1.2-2.6-2.6-2.6z"
|
||||
></path>
|
||||
<path
|
||||
fill="#9bcb5b"
|
||||
d="M16.6 17.9c-.3 0-.5-.2-.6-.5 0-2.2-1.8-4-4-4s-4 1.8-4 4c0 .3-.3.5-.6.5-.2 0-.4-.2-.5-.5 0-2.8 2.3-5.1 5.1-5.1s5.1 2.3 5.1 5.1c0 .3-.2.5-.5.5z"
|
||||
></path>
|
||||
<path
|
||||
fill="#0376bc"
|
||||
d="M12 23.7C5.5 23.7.3 18.4.3 12 .3 5.5 5.6.3 12 .3c2.6 0 5.1.9 7.2 2.5.2.2.2.6 0 .8-.2.2-.4.2-.7.1-1.9-1.4-4.1-2.2-6.5-2.2C6.2 1.4 1.4 6.2 1.4 12S6.2 22.6 12 22.6 22.6 17.8 22.6 12c0-2.4-.8-4.6-2.2-6.5-.2-.3-.1-.6.2-.8.2-.1.5-.1.7.1 1.6 2 2.5 4.6 2.4 7.2 0 6.4-5.3 11.7-11.7 11.7z"
|
||||
></path>
|
||||
<circle cx="20.2" cy="20.3" r="2.4" fill="#fff"></circle>
|
||||
<path
|
||||
fill="#9bcb5b"
|
||||
d="M18 18.1c.6-.6 1.4-.9 2.2-.9.8 0 1.6.3 2.2.9s1 1.4.9 2.2c0 .8-.3 1.6-.9 2.2s-1.4 1-2.2.9c-.8 0-1.6-.3-2.2-.9s-1-1.4-.9-2.2c-.1-.8.3-1.7.9-2.2zm3.8 2.5V20h-1.3v-1.3h-.6V20h-1.3v.6h1.3v1.3h.6v-1.3h1.3z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
{/* name */}
|
||||
@@ -81,16 +112,38 @@ export default function RightSideBar() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" id="InternationalUser">
|
||||
<path fill="#e6e7f9" d="M38.5 31.1c2.1-1.1 3.9-2.5 5.4-4.4h-3.2c-.6 1.6-1.3 3.1-2.2 4.4zm-5.8 1.4c2-.7 3.7-2.8 4.9-5.8h-4.9v5.8zm8.8-8.6h4.2c.9-1.8 1.5-3.7 1.7-5.8h-5.1c-.1 2-.4 4-.8 5.8zm2.4-17.3c-1.5-1.8-3.3-3.3-5.4-4.4.8 1.2 1.6 2.7 2.2 4.4h3.2zm-5.3 2.9h-5.9v5.8h6.7c-.1-2.1-.4-4.1-.8-5.8zm3.7 5.8h5.1c-.2-2.1-.8-4-1.7-5.8h-4.2c.4 1.8.7 3.7.8 5.8zM32.7.8v5.8h4.9c-1.2-2.9-2.9-5.1-4.9-5.8zm6.7 17.3h-6.7v5.8h5.9c.4-1.8.7-3.8.8-5.8zM25 6.6h4.9V.8c-2 .7-3.7 2.9-4.9 5.8zm-1.8 8.7h6.7V9.5H24c-.4 1.7-.7 3.7-.8 5.8zm6.7 17.2v-5.8H25c1.2 3 2.9 5.1 4.9 5.8zM24.1 2.3c-2.1 1.1-3.9 2.5-5.4 4.4H22c.5-1.7 1.3-3.2 2.1-4.4zM24 23.9h5.9v-5.8h-6.7c.1 2 .4 4 .8 5.8z" className="colorc1e5ff svgShape"></path><path fill="#ff6699" d="M3.7 44.7c0 1.6 1.2 2.8 2.8 2.8 1.3 0 2.4-.9 2.7-2.2.3 1.3 1.4 2.2 2.7 2.2 1.5 0 2.8-1.3 2.8-2.8V30.1h3.1V18.8c0-4.2-3.3-7.5-7.4-7.5H8c-4.1 0-7.4 3.4-7.4 7.5v11.3h3.1v14.6z" className="colorff99b0 svgShape"></path><path fill="#998da0" d="M9.2 10.3c2.4 0 4.4-2.2 4.4-4.9S11.6.5 9.2.5C6.8.5 4.8 2.7 4.8 5.4s2 4.9 4.4 4.9z" className="colorffd499 svgShape"></path><path fill="#e6e7f9" d="M16.9 9.5c-.3.6-.5 1.2-.8 1.8 1.3 1 2.3 2.4 2.9 4h1.3c.1-2 .3-4 .8-5.8h-4.2zm2.9 9.3v5.1h1.4c-.4-1.8-.7-3.8-.8-5.8h-.6c-.1.2 0 .4 0 .7zm2.2 7.9h-2.2v1.2c1.3 1.3 2.7 2.4 4.4 3.2-.9-1.3-1.7-2.8-2.2-4.4z" className="colorc1e5ff svgShape"></path>
|
||||
</svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 48 48"
|
||||
id="InternationalUser"
|
||||
>
|
||||
<path
|
||||
fill="#e6e7f9"
|
||||
d="M38.5 31.1c2.1-1.1 3.9-2.5 5.4-4.4h-3.2c-.6 1.6-1.3 3.1-2.2 4.4zm-5.8 1.4c2-.7 3.7-2.8 4.9-5.8h-4.9v5.8zm8.8-8.6h4.2c.9-1.8 1.5-3.7 1.7-5.8h-5.1c-.1 2-.4 4-.8 5.8zm2.4-17.3c-1.5-1.8-3.3-3.3-5.4-4.4.8 1.2 1.6 2.7 2.2 4.4h3.2zm-5.3 2.9h-5.9v5.8h6.7c-.1-2.1-.4-4.1-.8-5.8zm3.7 5.8h5.1c-.2-2.1-.8-4-1.7-5.8h-4.2c.4 1.8.7 3.7.8 5.8zM32.7.8v5.8h4.9c-1.2-2.9-2.9-5.1-4.9-5.8zm6.7 17.3h-6.7v5.8h5.9c.4-1.8.7-3.8.8-5.8zM25 6.6h4.9V.8c-2 .7-3.7 2.9-4.9 5.8zm-1.8 8.7h6.7V9.5H24c-.4 1.7-.7 3.7-.8 5.8zm6.7 17.2v-5.8H25c1.2 3 2.9 5.1 4.9 5.8zM24.1 2.3c-2.1 1.1-3.9 2.5-5.4 4.4H22c.5-1.7 1.3-3.2 2.1-4.4zM24 23.9h5.9v-5.8h-6.7c.1 2 .4 4 .8 5.8z"
|
||||
className="colorc1e5ff svgShape"
|
||||
></path>
|
||||
<path
|
||||
fill="#ff6699"
|
||||
d="M3.7 44.7c0 1.6 1.2 2.8 2.8 2.8 1.3 0 2.4-.9 2.7-2.2.3 1.3 1.4 2.2 2.7 2.2 1.5 0 2.8-1.3 2.8-2.8V30.1h3.1V18.8c0-4.2-3.3-7.5-7.4-7.5H8c-4.1 0-7.4 3.4-7.4 7.5v11.3h3.1v14.6z"
|
||||
className="colorff99b0 svgShape"
|
||||
></path>
|
||||
<path
|
||||
fill="#998da0"
|
||||
d="M9.2 10.3c2.4 0 4.4-2.2 4.4-4.9S11.6.5 9.2.5C6.8.5 4.8 2.7 4.8 5.4s2 4.9 4.4 4.9z"
|
||||
className="colorffd499 svgShape"
|
||||
></path>
|
||||
<path
|
||||
fill="#e6e7f9"
|
||||
d="M16.9 9.5c-.3.6-.5 1.2-.8 1.8 1.3 1 2.3 2.4 2.9 4h1.3c.1-2 .3-4 .8-5.8h-4.2zm2.9 9.3v5.1h1.4c-.4-1.8-.7-3.8-.8-5.8h-.6c-.1.2 0 .4 0 .7zm2.2 7.9h-2.2v1.2c1.3 1.3 2.7 2.4 4.4 3.2-.9-1.3-1.7-2.8-2.2-4.4z"
|
||||
className="colorc1e5ff svgShape"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
{/* name */}
|
||||
<div>
|
||||
@@ -99,7 +152,6 @@ export default function RightSideBar() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/*<SideStatistics />*/}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import React, { useEffect, useState } from "react";
|
||||
// import authProfilePic from "../../assets/images/auth-profile-picture.png";
|
||||
// import profileBanner from "../../assets/images/profile-cover.png";
|
||||
// import collections from "../../data/collectionplan_data.json"; Should this be cleaned off?
|
||||
// import marketPlace from "../../data/marketplace_data.json";
|
||||
import { useSelector } from "react-redux";
|
||||
import LoadingSpinner from "../../components/Spinners/LoadingSpinner";
|
||||
import products from "../../data/product_data.json";
|
||||
import usersService from "../../services/UsersService";
|
||||
import Layout from "../Partials/Layout";
|
||||
import {
|
||||
ActivitiesTab, BlogTab,
|
||||
QuestionsTab,
|
||||
ActivitiesTab,
|
||||
BlogTab,
|
||||
CollectionTab,
|
||||
CreatedTab,
|
||||
HiddenProductsTab,
|
||||
MyUploadedFiles,
|
||||
OnSaleTab,
|
||||
OwnTab,
|
||||
QuestionsTab,
|
||||
} from "./tabs";
|
||||
//import MyUploadedFiles from "./tabs/MyUploadedFiles";
|
||||
|
||||
@@ -24,16 +24,61 @@ export default function Resources(props) {
|
||||
const ownProducts = products.datas;
|
||||
// Resource Props
|
||||
const __resources = props.MyResourceData;
|
||||
//debugger;
|
||||
//debugger;
|
||||
// Collection Items
|
||||
const CreatedSell = __resources?.marketdata?.data;
|
||||
const tab_categories = __resources?.tab_categories?.data;
|
||||
const collectionProducts = __resources?.collectiondata?.data;
|
||||
const onSaleProducts = __resources?.marketdata?.data;
|
||||
const CreatedBits = __resources?.productdata?.datas;
|
||||
const blogItems = __resources?.blogdata?.payload;
|
||||
const blogItems = __resources?.blogdata?.payload;
|
||||
|
||||
const [tab, setTab] = useState(tab_categories ? tab_categories[0]?.name : "");
|
||||
// My Items Data
|
||||
const [uploadedFiles, setUploadedFiles] = useState({
|
||||
loading: false,
|
||||
msg: "",
|
||||
data: null,
|
||||
});
|
||||
const { uploadsTable } = useSelector((state) => state.tableReload);
|
||||
|
||||
const apiCall = new usersService();
|
||||
|
||||
const getUploadedFiles = async () => {
|
||||
setUploadedFiles((prev) => ({ ...prev, loading: true }));
|
||||
|
||||
let res;
|
||||
|
||||
try {
|
||||
res = await apiCall.getUploadedList();
|
||||
res = res.data;
|
||||
if (res?.internal_return < 0) {
|
||||
setUploadedFiles((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
msg: "something went wrong",
|
||||
}));
|
||||
}
|
||||
setUploadedFiles((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
msg: "success",
|
||||
data: res?.result_list,
|
||||
}));
|
||||
} catch (error) {
|
||||
setUploadedFiles((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
msg: "An error occurred",
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUploadedFiles();
|
||||
}, [uploadsTable]);
|
||||
|
||||
// const [tab, setTab] = useState(tab_categories ? tab_categories[0]?.name : "");
|
||||
const [tab, setTab] = useState(props.activeTab? props.activeTab : tab_categories ? tab_categories[0]?.name : "");
|
||||
|
||||
const tabHandler = (value) => {
|
||||
setTab(value);
|
||||
@@ -44,7 +89,7 @@ export default function Resources(props) {
|
||||
blog: <BlogTab blogdata={blogItems} />,
|
||||
onsale: <QuestionsTab products={onSaleProducts} />,
|
||||
owned: <OwnTab products={ownProducts} />,
|
||||
created: <MyUploadedFiles marketProducts={CreatedSell} mainProducts={CreatedBits} />,
|
||||
created: <MyUploadedFiles uploadedFiles={uploadedFiles} />,
|
||||
hidden: (
|
||||
<HiddenProductsTab
|
||||
marketProducts={CreatedSell}
|
||||
@@ -55,26 +100,30 @@ export default function Resources(props) {
|
||||
activity: <ActivitiesTab />,
|
||||
};
|
||||
|
||||
const defaultTabComponent = <BlogTab blogdata={blogItems} />;
|
||||
// const defaultTabComponent = <BlogTab blogdata={blogItems} />;
|
||||
|
||||
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
||||
// const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
||||
|
||||
const defaultTabComponent = props.activeTab ? tabComponents[props.activeTab] : <BlogTab blogdata={blogItems} />;
|
||||
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
||||
|
||||
// Tab Item Component
|
||||
const TabItem = ({ tabValue, isActive }) => {
|
||||
let countNumber = (name) => { // FUNCTION TO DETERMINE THE COUNT NUMBER
|
||||
if(name == 'blog'){
|
||||
return blogItems?.blogdata?.length
|
||||
}else if(name == 'onsale'){
|
||||
return onSaleProducts?.length
|
||||
let countNumber = (name) => {
|
||||
// FUNCTION TO DETERMINE THE COUNT NUMBER
|
||||
if (name == "blog") {
|
||||
return blogItems?.blogdata?.length;
|
||||
} else if (name == "onsale") {
|
||||
return onSaleProducts?.length;
|
||||
// return null
|
||||
}else if(name == 'owned'){
|
||||
return ownProducts?.length
|
||||
}else if(name == 'created'){
|
||||
return CreatedSell?.length + CreatedBits?.length
|
||||
}else{
|
||||
return 0
|
||||
} else if (name == "owned") {
|
||||
return ownProducts?.length;
|
||||
} else if (name == "created") {
|
||||
return uploadedFiles?.data?.length;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<li
|
||||
className={`relative group inline`}
|
||||
@@ -89,17 +138,17 @@ export default function Resources(props) {
|
||||
>
|
||||
{tabValue.content}
|
||||
</span>
|
||||
{tabValue.name != 'onsale' &&
|
||||
<span
|
||||
className={`w-5 h-5 group-hover:bg-pink group-hover:text-white text-[10px] rounded-full absolute -top-2 -right-5 flex justify-center items-center ${
|
||||
isActive
|
||||
? "text-white bg-pink"
|
||||
: "text-thin-light-gray bg-[#F2B8FD]"
|
||||
}`}
|
||||
>
|
||||
{countNumber(tabValue.name)}
|
||||
</span>
|
||||
}
|
||||
{tabValue.name != "onsale" && (
|
||||
<span
|
||||
className={`w-5 h-5 group-hover:bg-pink group-hover:text-white text-[10px] rounded-full absolute -top-2 -right-5 flex justify-center items-center ${
|
||||
isActive
|
||||
? "text-white bg-pink"
|
||||
: "text-thin-light-gray bg-[#F2B8FD]"
|
||||
}`}
|
||||
>
|
||||
{countNumber(tabValue.name)}
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
};
|
||||
@@ -109,13 +158,18 @@ export default function Resources(props) {
|
||||
return (
|
||||
<ul className="lg:flex lg:space-x-14 space-x-8">
|
||||
{tabCategories?.length > 0 &&
|
||||
tabCategories?.map((tabValue, idx) => (
|
||||
<TabItem
|
||||
key={tabValue.id}
|
||||
tabValue={tabValue}
|
||||
isActive={tab === tabValue.name || (idx === 0 && tab === "")}
|
||||
/>
|
||||
))}
|
||||
tabCategories?.map((tabValue, idx) => {
|
||||
if(tabValue.enabled){
|
||||
return (
|
||||
<TabItem
|
||||
key={tabValue.id}
|
||||
tabValue={tabValue}
|
||||
isActive={tab === tabValue.name || (idx === 0 && tab === "")}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
)}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
@@ -136,14 +190,6 @@ export default function Resources(props) {
|
||||
<div className="tab-items">
|
||||
<TabList tabCategories={tab_categories} />
|
||||
</div>
|
||||
{/* <div style={{ transform: "translateY(-22px)" }}>
|
||||
<Link
|
||||
to="/my-uploads"
|
||||
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
|
||||
>
|
||||
Add My Item
|
||||
</Link>
|
||||
</div> */}
|
||||
</div>
|
||||
<div className="hidden lg:block w-full h-[1px] bg-[#DCD5FE] dark:bg-[#5356fb29] absolute top-[42px] left-0"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,278 +1,162 @@
|
||||
import React, { useState } from "react";
|
||||
import dataImage1 from "../../../assets/images/data-table-user-1.png";
|
||||
import dataImage2 from "../../../assets/images/data-table-user-2.png";
|
||||
import { Link } from "react-router-dom";
|
||||
// import dataImage3 from "../../../assets/images/data-table-user-3.png";
|
||||
// import dataImage4 from "../../../assets/images/data-table-user-4.png";
|
||||
// import SelectBox from "../Helpers/SelectBox";
|
||||
import defaultImg from "../../../assets/images/myfiles/default.svg";
|
||||
import localImgLoad from "../../../lib/localImgLoad";
|
||||
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||
|
||||
export default function MyUploadedFiles({ className }) {
|
||||
const filterCategories = ["All Categories", "Explore", "Featured"];
|
||||
const [selectedCategory, setCategory] = useState(filterCategories[0]);
|
||||
return (
|
||||
<>
|
||||
<div className="mb-4 w-full flex justify-end item-center">
|
||||
<Link
|
||||
to="/my-uploads"
|
||||
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
|
||||
>
|
||||
Add My Item
|
||||
</Link>
|
||||
</div>
|
||||
<div
|
||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow relative min-h-[520px] ${
|
||||
className || ""
|
||||
}`}
|
||||
export default function MyUploadedFiles({ uploadedFiles }) {
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentFiles = uploadedFiles?.data?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className="mb-4 w-full flex justify-end item-center">
|
||||
<Link
|
||||
to="/my-uploads"
|
||||
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
|
||||
>
|
||||
<div className="header w-full sm:flex justify-between items-center mb-5">
|
||||
<div className="flex space-x-2 items-center mb-2 sm:mb-0">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
My Uploads
|
||||
</h1>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{/* table heading */}
|
||||
{/*<tr className="text-base text-thin-light-gray whitespace-nowrap px-2 border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
|
||||
{/* <td className="py-4 w-[300px] block whitespace-nowrap">*/}
|
||||
{/* All Product*/}
|
||||
{/* </td>*/}
|
||||
{/* <td className="py-4 whitespace-nowrap text-center">.</td>*/}
|
||||
{/* <td className="py-4 whitespace-nowrap text-center"></td>*/}
|
||||
|
||||
{/* <td className="py-4 whitespace-nowrap text-right"></td>*/}
|
||||
{/*</tr>*/}
|
||||
<tr className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage1}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
Mullican Computer Joy
|
||||
</h1>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Owned by <span className="text-purple">Xoeyam</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
|
||||
fill="#627EEA"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
|
||||
fill="white"
|
||||
fillOpacity="0.2"
|
||||
/>
|
||||
<path
|
||||
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
||||
7473 ETH
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
|
||||
fill="#FEFEFE"
|
||||
/>
|
||||
<path
|
||||
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium">
|
||||
6392.99$
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td className="text-right py-4">
|
||||
<button
|
||||
type="button"
|
||||
className="text-sm text-white bg-purple px-2.5 py-1.5 rounded-full"
|
||||
>
|
||||
Active
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage2}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
Mullican Computer Joy
|
||||
</h1>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Owned by <span className="text-purple">Xoeyam</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
|
||||
fill="#627EEA"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
<path
|
||||
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
|
||||
fill="white"
|
||||
fillOpacity="0.2"
|
||||
/>
|
||||
<path
|
||||
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
|
||||
fill="white"
|
||||
fillOpacity="0.602"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
||||
7473 ETH
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-center py-4 px-2">
|
||||
<div className="flex space-x-1 items-center justify-center">
|
||||
<span>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
|
||||
fill="#FEFEFE"
|
||||
/>
|
||||
<path
|
||||
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
<path
|
||||
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
|
||||
fill="#59BE59"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="text-base text-dark-gray dark:text-white font-medium">
|
||||
6392.99$
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td className="text-right py-4">
|
||||
<button
|
||||
type="button"
|
||||
className="text-sm text-white bg-light-green px-2.5 py-1.5 rounded-full"
|
||||
>
|
||||
Complated
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
Add My Item
|
||||
</Link>
|
||||
</div>
|
||||
<div
|
||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow relative min-h-[520px]`}
|
||||
>
|
||||
<div className="header w-full sm:flex justify-between items-center mb-5">
|
||||
<div className="flex space-x-2 items-center mb-2 sm:mb-0">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
My Uploads
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
<>
|
||||
{uploadedFiles?.data && uploadedFiles?.data.length ? (
|
||||
currentFiles.map((value, idx) => {
|
||||
let addedDate = value?.added?.split(" ")[0];
|
||||
let formattedSize = formatFileSize(value?.file_size);
|
||||
return (
|
||||
<tr
|
||||
key={value?.file_uid}
|
||||
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/myfiles/${value.banner}`
|
||||
) || defaultImg
|
||||
}
|
||||
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 || "Dummy Text"}
|
||||
</h1>
|
||||
<div>
|
||||
{value.description || "Dummy Description"}
|
||||
</div>
|
||||
<span className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||
Added:{" "}
|
||||
<span className="text-purple">{addedDate}</span>
|
||||
</span>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
File Name:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value.file_name}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
File Size:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{formattedSize}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
File Type:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value?.file_type}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-right py-4 px-2">
|
||||
<div className="flex justify-center items-center">
|
||||
<button
|
||||
type="button"
|
||||
// onClick={() => {
|
||||
// navigate("/manage-active-job", {
|
||||
// state: { ...value, pathname },
|
||||
// });
|
||||
// }}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
<td className="p-2" colSpan={3}>
|
||||
No Files Currently!
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</>
|
||||
</tbody>
|
||||
</table>
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
uploadedFiles?.data.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={uploadedFiles?.data}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const formatFileSize = (sizeInBytes) => {
|
||||
if (sizeInBytes < 1024) {
|
||||
return `${sizeInBytes} bytes`;
|
||||
} else if (sizeInBytes < 1024 * 1024) {
|
||||
const sizeInKB = (sizeInBytes / 1024).toFixed(2);
|
||||
return `${sizeInKB} KB`;
|
||||
} else {
|
||||
const sizeInMB = (sizeInBytes / (1024 * 1024)).toFixed(2);
|
||||
return `${sizeInMB} MB`;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -69,7 +69,7 @@ function DeleteCardPopout({action, situation, data, setReloadCardList}) {
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="68" cy="68" r="68" fill="#5356FB" />
|
||||
<circle cx="68" cy="68" r="68" fill="#4687ba" />
|
||||
<path
|
||||
d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z"
|
||||
fill="white"
|
||||
|
||||
@@ -51,6 +51,7 @@ export default function PersonalInfoTab({
|
||||
coverImgInput,
|
||||
browseCoverImg,
|
||||
coverImgChangHandler,
|
||||
uploadStatus
|
||||
}) {
|
||||
let { userDetails } = useSelector((state) => state.userDetails);
|
||||
|
||||
@@ -68,7 +69,7 @@ export default function PersonalInfoTab({
|
||||
pref_email: 0,
|
||||
pref_phone: 0,
|
||||
accept_promo: false,
|
||||
online_name: "",
|
||||
online_name: userDetails?.online_name,
|
||||
};
|
||||
|
||||
let [profile, setProfile] = useState({
|
||||
@@ -158,7 +159,7 @@ export default function PersonalInfoTab({
|
||||
fieldClass="px-6"
|
||||
label="User Name"
|
||||
type="text"
|
||||
name="online_name"
|
||||
name="username"
|
||||
placeholder="Username"
|
||||
value={userDetails?.username}
|
||||
disable={true}
|
||||
@@ -361,63 +362,67 @@ export default function PersonalInfoTab({
|
||||
{/* inputs ends here */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-[232px] mb-10">
|
||||
<div className="update-profile w-full mb-9">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white flex items-center mb-2">
|
||||
Update Profile
|
||||
<span className="ml-1">
|
||||
<Icons name="block-question" />
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray mb-5">
|
||||
Profile of at least Size
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
300x300
|
||||
</span>
|
||||
. Gifs work too.
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
Max 5mb
|
||||
</span>
|
||||
.
|
||||
</p>
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={profileImg}
|
||||
alt="profile"
|
||||
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-contain object-center"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
<div
|
||||
onClick={browseProfileImg}
|
||||
className="w-[32px] h-[32px] absolute bottom-7 sm:right-10 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"
|
||||
{/* {process.env.REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE != 0 && */}
|
||||
<div className="w-[232px] mb-10">
|
||||
<div className="update-profile w-full mb-9">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white flex items-center mb-2">
|
||||
Update Profile
|
||||
<span className="ml-1">
|
||||
<Icons name="block-question" />
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray mb-5">
|
||||
Profile of at least Size
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
300x300
|
||||
</span>
|
||||
. Gifs work too.
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
Max 5mb
|
||||
</span>
|
||||
.
|
||||
</p>
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={profileImg}
|
||||
alt="profile"
|
||||
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-contain object-center"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
<div
|
||||
onClick={browseProfileImg}
|
||||
className="w-[32px] h-[32px] absolute bottom-7 sm:right-10 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
|
||||
>
|
||||
<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>
|
||||
<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>
|
||||
{uploadStatus.message && !uploadStatus.loading && <p className={`text-center ${uploadStatus.status ? 'text-green-500':'text-red-500'}`}>{uploadStatus.message}</p>}
|
||||
{uploadStatus.loading && <p className="text-center">{uploadStatus.message}</p>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* } */}
|
||||
</div>
|
||||
|
||||
<div className="content-footer w-full">
|
||||
|
||||
@@ -8,13 +8,16 @@ export default function TermsConditionTab() {
|
||||
<h1 className="text-3xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Terms of use
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
<p className="text-base text-thin-light-gray leading-[28px]">
|
||||
(updated August 10, 2023)
|
||||
</p>
|
||||
<p className="text-base text-thin-light-gray leading-[28px]">
|
||||
These Website Terms & Conditions (“T&Cs”) apply to your access and
|
||||
use of www.wrenchboard.com,dashboard.wrenchboard.com (the “Site”),
|
||||
including all software, data, reports, text, images, sounds, video,
|
||||
and all contents made available through any portion of the Site
|
||||
(collectively, the “Content”). Content includes all such elements as
|
||||
a whole, as well as individual elements and portions thereof.
|
||||
use of www.wrenchboard.com,users.wrenchboard.com (the “Site”),
|
||||
native apps, including all software, data, reports, text, images,
|
||||
sounds, video, and all contents made available through any portion
|
||||
of the Site (collectively, the “Content”). The range includes all
|
||||
such elements as whole, individual, and parts.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
@@ -37,103 +40,138 @@ export default function TermsConditionTab() {
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
General Conditions of Use
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
<b> Authorization to Access and Use Site and Content.</b> Subject to
|
||||
your compliance with these T&Cs and the provisions hereof, you may
|
||||
access or use the Site and Content solely for the purpose of your
|
||||
evaluation of WRENCHBOARD and WRENCHBOARD’s products and services.
|
||||
You may only link to the Site or Content, or any portion thereof, as
|
||||
expressly permitted by WRENCHBOARD.
|
||||
<br />
|
||||
<b> Ownership and Restrictions.</b> All rights, title, and interest
|
||||
in and to the Site and Content will remain with and belong
|
||||
exclusively to WRENCHBOARD. You will not (a) sublicense, resell,
|
||||
rent, lease, transfer, assign, time share or otherwise commercially
|
||||
exploit or make the Site and any Content available to any third
|
||||
party, (b) use the Site and Content in any unlawful manner
|
||||
(including without limitation in violation of any data, privacy or
|
||||
export control laws) or in any manner that interferes with or
|
||||
disrupts the integrity or performance of the Site and Content or
|
||||
their related components, or (c) modify, adapt or hack the Site and
|
||||
Content to, or try to, gain unauthorized access to the restricted
|
||||
portions of the Site and Content or related systems or networks
|
||||
(i.e., circumvent any encryption or other security measures, gain
|
||||
access to any source code or any other underlying form of technology
|
||||
or information, and gain access to any part of the Site and Content,
|
||||
or any other products or services of WRENCHBOARD that are not
|
||||
readily made available to the general public). You are not permitted
|
||||
to copy, modify, frame, repost, publicly perform or display, sell,
|
||||
reproduce, distribute, or create derivative works of the Site and
|
||||
Content, except that you may download, display, and print one copy
|
||||
of the publicly available materials (i.e., the Content that does not
|
||||
require an Account name or password to access) on any single
|
||||
computer solely for your personal, non-commercial use, provided that
|
||||
you do not modify the material in any way and you keep intact all
|
||||
copyright, trademark, and other proprietary notices. You agree not
|
||||
to access the Site or Content by any means other than through the
|
||||
interface that is provided by WRENCHBOARD to access the same. You
|
||||
may not use any “page-scrape,” “deep-link,” “spider,” or “robot or
|
||||
other automatic program, device, algorithm or methodology, or any
|
||||
similar manual process, to access, copy, acquire, or monitor any
|
||||
portion of the Site or any Content, or in any way reproduce or
|
||||
circumvent the presentation or navigational structure of the Site or
|
||||
any Content, to obtain or attempt to obtain any Content or other
|
||||
information through any means not made generally available through
|
||||
the Site by WRENCHBOARD. WRENCHBOARD reserves the right to take any
|
||||
lawful measures to prevent any such activity. You may not forge
|
||||
headers or otherwise manipulate identifiers in order to disguise the
|
||||
origin of any message or transmittal you send to WRENCHBOARD on or
|
||||
through the Site or any service offered on or through the Site. You
|
||||
may not pretend that you are, or that you represent, someone else,
|
||||
or impersonate any other individual or entity.
|
||||
<b> Responsibility for Your Data.</b> You are solely responsible for
|
||||
all data, information, and other content, that you upload, post, or
|
||||
otherwise provide or store (hereafter “post(ing)”) in connection
|
||||
with or relating to the Site.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Use of Intellectual Property.
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
<b> Rights in User Content.</b> By posting your information and
|
||||
other content (“User Content”) on or through the Site and Content,
|
||||
you grant WRENCHBOARD a worldwide, non-exclusive, perpetual,
|
||||
irrevocable, royalty-free, fully paid, sublicensable and
|
||||
transferable license to use, modify, reproduce, distribute, display,
|
||||
publish and perform User Content in connection with the Site and
|
||||
Content. WRENCHBOARD has the right, but not the obligation, to
|
||||
monitor the Site and Content and User Content. WRENCHBOARD may
|
||||
remove or disable any User Content at any time for any reason, or
|
||||
for no reason at all. You, the user, acknowledge that you bear sole
|
||||
responsibility for adequate security, protection, and backup of User
|
||||
Content. WRENCHBOARD will have no liability to you for any
|
||||
unauthorized access or use of any of User Content, or any
|
||||
corruption, deletion, destruction, or loss of any of User Content.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Feedback
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
You may submit ideas, suggestions, or comments (“Feedback”)
|
||||
regarding the Site and Content or WRENCHBOARD’s business, products,
|
||||
or services. By submitting any Feedback, you acknowledge and agree
|
||||
that (a) your Feedback is provided by you voluntarily and
|
||||
WRENCHBOARD may, without any obligations or limitation, use and
|
||||
exploit such Feedback in any manner and for any purpose, (b) you
|
||||
will not seek and are not entitled to any money or other form of
|
||||
compensation, consideration, or attribution with respect to your
|
||||
Feedback regardless of whether WRENCHBOARD considered or used your
|
||||
Feedback in any manner, and (c) your Feedback is not the
|
||||
confidential or proprietary information of you or any third party.
|
||||
</p>
|
||||
<ul className="ml-8">
|
||||
<li className="text-base text-thin-light-gray leading-[28px]">
|
||||
<h1 className="text-lg tracking-wide font-bold text-dark-gray dark:text-white my-4">
|
||||
Authorization to Access and Use Site and Content.
|
||||
</h1>
|
||||
<p className="text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Subject to your compliance with these T&Cs and the provisions
|
||||
hereof, you may access or use the Site and Content solely to
|
||||
evaluate WRENCHBOARD and WRENCHBOARD’s products and services.
|
||||
You may only link to the Site or Content, or any portion
|
||||
thereof, as expressly permitted by WRENCHBOARD.
|
||||
</p>
|
||||
</li>
|
||||
<li className="text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
<h1 className="text-lg tracking-wide font-bold text-dark-gray dark:text-white my-4">
|
||||
Ownership and Restrictions
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px]">
|
||||
All rights, title, and interest in and to the Site and Content
|
||||
will remain exclusive to WRENCHBOARD. You will not:
|
||||
</p>
|
||||
<ol className="ml-8 list-decimal">
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Sublicense, resell, rent, lease, transfer, assign, timeshare,
|
||||
or commercially exploit or make the Site and any Content
|
||||
available to any third party.
|
||||
</li>
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Use the Site and Content in any unlawful manner (including
|
||||
without limitation in violation of any data, privacy, or
|
||||
export control laws) or in any way that interferes with or
|
||||
disrupts the integrity or performance of the Site and Content
|
||||
or their related components.
|
||||
</li>
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Modify, adapt, or hack the Site and Content to, or try to,
|
||||
gain unauthorized access to the restricted portions of the
|
||||
Site and Content or related systems or networks (i.e.,
|
||||
circumvent any encryption or other security measures, gain
|
||||
access to any source code or any other underlying form of
|
||||
technology or information, and gain access to any part of the
|
||||
Site and Content, or any other products or services of
|
||||
WRENCHBOARD that are not readily made available to the general
|
||||
public).
|
||||
</li>
|
||||
</ol>
|
||||
<p className="my-4 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
You are not permitted to copy, modify, frame, repost, publicly
|
||||
perform or display, sell, reproduce, distribute, or create
|
||||
derivative works of the Site and Content, except that you may
|
||||
download and print one copy of the publicly available materials
|
||||
(i.e., the Content that does not require an Account name or
|
||||
password to access) on any single computer solely for your
|
||||
personal, non-commercial use, provided that you do not modify
|
||||
the material in any way. You keep intact all copyright,
|
||||
trademark, and other proprietary notices.
|
||||
</p>
|
||||
<p className="my-4 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
You agree not to access the Site or Content by any means other
|
||||
than through the interface that WRENCHBOARD provides to access
|
||||
the same. You may not use any “page-scrape,” “deep-link,”
|
||||
“spider,” or “robot or other automatic program, device,
|
||||
algorithm or methodology, or any similar manual process, to
|
||||
access, copy, acquire, or monitor any portion of the Site or any
|
||||
Content, or in any way reproduce or circumvent the presentation
|
||||
or navigational structure of the Site or any Content, to obtain
|
||||
or attempt to obtain any Content or other information through
|
||||
any means not made generally available through the Site by
|
||||
WRENCHBOARD.
|
||||
</p>
|
||||
<p className="my-4 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
WRENCHBOARD reserves the right to take lawful measures to
|
||||
prevent such activity. You may not forge headers or otherwise
|
||||
manipulate identifiers to disguise the origin of any message or
|
||||
transmittal you send to WRENCHBOARD on or through the Site or
|
||||
any service offered on or through the Site. You may not pretend
|
||||
that you are, or that you represent, someone else or impersonate
|
||||
any other individual or entity.
|
||||
</p>
|
||||
</li>
|
||||
<li className="text-base text-thin-light-gray leading-[28px]">
|
||||
<h1 className="text-lg tracking-wide font-bold text-dark-gray dark:text-white my-4">
|
||||
Responsibility for Your Data
|
||||
</h1>
|
||||
<p className="text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
You are solely responsible for all data, information, and other
|
||||
Content, that you upload, post, or otherwise provide or store
|
||||
(hereafter “post(ing)”) in connection with or relating to the
|
||||
Site. By posting your information and other Content (“User
|
||||
Content”) on or through the Site and Content, you grant
|
||||
WRENCHBOARD a worldwide, non-exclusive, perpetual, irrevocable,
|
||||
royalty-free, sublicensable, and transferable license to use,
|
||||
modify, reproduce, distribute, display, publish and perform User
|
||||
Content in connection with the Site and Content. WRENCHBOARD has
|
||||
the right, but not the obligation, to monitor the Site and
|
||||
Content and User Content. <br />
|
||||
WRENCHBOARD may remove or turn off any User Content at any time
|
||||
for any reason or no reason. WRENCHBOARD will have no liability
|
||||
to you for any unauthorized access or use of any of User Content
|
||||
or any corruption, deletion, destruction, or loss of any of User
|
||||
Content.
|
||||
</p>
|
||||
</li>
|
||||
<li className="text-base text-thin-light-gray leading-[28px]">
|
||||
<h1 className="text-lg tracking-wide font-bold text-dark-gray dark:text-white my-4">
|
||||
Feedback
|
||||
</h1>
|
||||
<p className="text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
You may submit ideas, suggestions, or comments (“Feedback”)
|
||||
regarding the Site and Content or WRENCHBOARD’s business,
|
||||
products, or services. By submitting any Feedback, you
|
||||
acknowledge and agree that:{" "}
|
||||
</p>
|
||||
<ol className="ml-8 list-decimal">
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Your Feedback is provided by you voluntarily, and WRENCHBOARD
|
||||
may, without any obligations or limitations, use and exploit
|
||||
such Feedback in any manner and for any purpose.
|
||||
</li>
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
You will not seek and are not entitled to any money or other
|
||||
form of compensation, consideration, or attribution concerning
|
||||
your Feedback, regardless of whether WRENCHBOARD considered or
|
||||
used your Feedback in any manner.
|
||||
</li>
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Your Feedback is not confidential or proprietary information
|
||||
of you or any third party.
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
@@ -141,36 +179,32 @@ export default function TermsConditionTab() {
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Termination of Access Due to Violations
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
<p className="font-bold text-base text-thin-light-gray leading-[28px] ">
|
||||
WRENCHBOARD may, in its sole discretion and without prior notice,
|
||||
terminate your access to the Site and/or block your future access to
|
||||
terminate your access to the Site and block your future access to
|
||||
the Site if we determine that you have violated these T&Cs or other
|
||||
agreements or guidelines which may be associated with your use of
|
||||
the Site. You also agree that any violation by you of these T&Cs
|
||||
will cause irreparable harm to WRENCHBOARD, for which monetary
|
||||
damages would be inadequate, and you consent to WRENCHBOARD
|
||||
obtaining any injunctive or equitable relief that WRENCHBOARD deems
|
||||
necessary or appropriate in such circumstances, without limiting
|
||||
WRENCHBOARD’s other available remedies. Further, WRENCHBOARD may, in
|
||||
its sole discretion and without prior notice, terminate your access
|
||||
to the Site, for cause, which includes (but is not limited to) (1)
|
||||
requests by law enforcement or other government agencies, (2)
|
||||
discontinuance or material modification of the Site or any service
|
||||
offered on or through the Site, or (3) unexpected technical issues
|
||||
or problems.
|
||||
the Site. Further, WRENCHBOARD may, in its sole discretion and
|
||||
without prior notice, terminate your access to the Site for cause,
|
||||
which includes (but is not limited to):
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
T&Cs Updates
|
||||
</h1>
|
||||
<ol className="ml-8 list-decimal font-bold">
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Requests by law enforcement or other government agencies
|
||||
</li>
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Discontinuance or material modification of the Site or any service
|
||||
offered on or through the Site
|
||||
</li>
|
||||
<li className="my-2 text-base font-bold text-thin-light-gray leading-[28px]">
|
||||
Unexpected technical issues or problems.T&Cs Updates
|
||||
</li>
|
||||
</ol>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
WRENCHBOARD reserves the right, at its sole discretion, to change or
|
||||
modify portions of these T&Cs at any time. WRENCHBOARD will post the
|
||||
changes to these T&Cs on the Site and will indicate at the top of
|
||||
this page the date these terms were last revised. It is your
|
||||
changes to these T&Cs on the Site and indicate at the top of this
|
||||
page the date these terms were last revised. It is your
|
||||
responsibility to check the T&Cs periodically for changes. Your
|
||||
continued use of the Site and Content after the date any such
|
||||
changes become effective constitutes your acceptance of the new or
|
||||
@@ -193,42 +227,36 @@ export default function TermsConditionTab() {
|
||||
REPRESENTATIONS OR WARRANTIES ARISING FROM COURSE OF DEALING, COURSE
|
||||
OF PERFORMANCE OR USAGE OF TRADE. YOU ACKNOWLEDGE THAT WRENCHBOARD
|
||||
DOES NOT WARRANT THAT YOUR ACCESS OR USE OR BOTH OF THE SITE AND
|
||||
CONTENT WILL BE UNINTERRUPTED, TIMELY, SECURE, ERROR-FREE OR
|
||||
CONTENT WILL BE UNINTERRUPTED, TIMELY, SECURE, ERROR-FREE, OR
|
||||
VIRUS-FREE, AND WRENCHBOARD DOES NOT MAKE ANY WARRANTY AS TO THE
|
||||
RESULTS THAT MAY BE OBTAINED FROM USE OF THE SITE AND CONTENT. NO
|
||||
INFORMATION, ADVICE OR SERVICES OBTAINED BY YOU FROM WRENCHBOARD OR
|
||||
THROUGH THE SITE WILL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN
|
||||
THESE TERMS and CONDITIONS AND YOU SHOULD NOT RELY ON THE SITE AND
|
||||
RESULTS THAT MAY BE OBTAINED FROM THE USE OF THE SITE AND CONTENT.
|
||||
NO INFORMATION, ADVICE, OR SERVICES OBTAINED BY YOU FROM WRENCHBOARD
|
||||
OR THROUGH THE SITE WILL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN
|
||||
THESE TERMS and CONDITIONS, AND YOU SHOULD NOT RELY ON THE SITE AND
|
||||
THE GENERAL CONTENT ALONE AS THE BASIS FOR YOUR BUSINESS DECISIONS.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
<p className="font-bold text-base text-thin-light-gray leading-[28px] ">
|
||||
WRENCHBOARD reserves the right to do any of the following, at any
|
||||
time, without notice: (1) to modify, suspend or terminate operation
|
||||
time, without notice: ( 1 ); to modify, suspend or terminate operation
|
||||
of or access to the Site, or any portion of the Site, for any
|
||||
reason; (2) to modify or change the Site, or any portion of the
|
||||
Site, for any reason; and (3) to interrupt the operation of the
|
||||
reason; ( 2 ) to modify or change the Site, or any portion of the
|
||||
Site, for any reason; and ( 3 ) to interrupt the operation of the
|
||||
Site, or any portion of the Site, as necessary to perform routine or
|
||||
non-routine maintenance, error correction, or other changes..
|
||||
non-routine maintenance, error correction, or other changes. Changes
|
||||
to the Policy
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="mt-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Changes To the Policy
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
We reserve the rights to update and make changes to this Privacy
|
||||
policy at anytime. Changes will become effective once posted.
|
||||
However, we will notify you by email or when you log on to the
|
||||
service or website about any changes that fundamentally affect how
|
||||
we manage your personal information. Contacting Us: You may contact
|
||||
us about this policy through our email address anytime :
|
||||
support@wrenchboard.com
|
||||
<p className="my-4 text-base text-thin-light-gray leading-[28px] ">
|
||||
We reserve the right to update and change this Privacy policy at any
|
||||
time. Changes will become effective once posted. However, we will
|
||||
notify you by email or when you log on to the service or website
|
||||
about any changes that fundamentally affect how we manage your
|
||||
personal information. Contacting Us: You may contact us about this
|
||||
policy through our email address anytime: support@wrenchboard.com
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,10 +24,12 @@ import {
|
||||
import RecipientAccountTab from "./Tabs/RecipientAccountTab";
|
||||
|
||||
export default function Settings({ faq }) {
|
||||
const apiCall = new usersService();
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
const [profileImg, setProfileImg] = useState(
|
||||
userDetails?.profile_pic_url ? userDetails.profile_pic_url : profile
|
||||
);
|
||||
let [uploadStatus, setUploadStatus] = useState({loading: false, status: false, message:''}) // HOLDS STATE FOR UPLOAD PROFILE PICTURE STATUS
|
||||
const [coverImg, setCoverImg] = useState(cover);
|
||||
const [reloadCardList, setReloadCardList] = useState(false); // STATE TO DETERMINE WHEN CARD LIST RELOADS. EG: WHEN USER DELETES A CARD
|
||||
|
||||
@@ -36,12 +38,68 @@ export default function Settings({ faq }) {
|
||||
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]);
|
||||
// }
|
||||
setUploadStatus({loading: false, status: false, message:''})
|
||||
let acceptedFormat = ["jpeg", "jpg", "png", "bmp", "gif"] // ARRAY OF SUPPORTED FORMATS
|
||||
let uploadedFile = e.target.files[0] //UPLOADED FILE
|
||||
|
||||
if(!acceptedFormat.includes(uploadedFile?.type?.split("/")[1]?.toLowerCase())){ //CHECKING FOR CORRECT UPLOAD FORMAT
|
||||
let msg = 'Please select '
|
||||
for(let i=0; i<=acceptedFormat.length-1; i++){
|
||||
if(i == acceptedFormat.length-1){
|
||||
msg+=`or ${acceptedFormat[i]}`
|
||||
}else{
|
||||
msg+=`${acceptedFormat[i]}, `
|
||||
}
|
||||
}
|
||||
setUploadStatus({loading: false, status: false, message:msg})
|
||||
return setTimeout(()=>{
|
||||
profileImgInput.current.value = '' // clear the input
|
||||
setUploadStatus({loading: false, status: false, message:''})
|
||||
},5000)
|
||||
}
|
||||
|
||||
if(uploadedFile.size > 5*1048576){ // CHECKING FOR CORRECT FILE SIZE
|
||||
setUploadStatus({loading: false, status: false, message:'File must not exceed 5MB'})
|
||||
return setTimeout(()=>{
|
||||
profileImgInput.current.value = '' // clear the input
|
||||
setUploadStatus({loading: false, status: false, message:''})
|
||||
},5000)
|
||||
}
|
||||
|
||||
if (e.target.value !== "") {
|
||||
const imgReader = new FileReader();
|
||||
imgReader.onload = (event) => {
|
||||
setProfileImg(event.target.result);
|
||||
let reqData = { // PAYLOAD FOR API CALL
|
||||
file_name: uploadedFile?.name,
|
||||
file_size: uploadedFile?.size,
|
||||
file_type: uploadedFile?.type?.split("/")[0]?.toLowerCase(),
|
||||
file_data: event?.target?.result,
|
||||
msg_type: 'FILE',
|
||||
action: 'WRENCHBOARD_PICTURE_PROFILE',
|
||||
// action: 11307
|
||||
}
|
||||
setUploadStatus({loading: true, status: false, message:'Loading...'})
|
||||
apiCall.sendFiles(reqData).then(res=>{
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
return setUploadStatus({loading: false, status: false, message: 'Something went wrong, try again'})
|
||||
}
|
||||
setUploadStatus({loading: false, status: true, message: 'Uploaded successfully'})
|
||||
setProfileImg(event.target.result);
|
||||
}).catch(error=>{
|
||||
setUploadStatus({loading: false, status: false, message: 'Network error, try again'})
|
||||
}).finally(()=>{
|
||||
setTimeout(()=>{
|
||||
setUploadStatus({loading: false, status: false, message: ''})
|
||||
},5000)
|
||||
})
|
||||
};
|
||||
imgReader.readAsDataURL(e.target.files[0]);
|
||||
}
|
||||
@@ -61,7 +119,6 @@ export default function Settings({ faq }) {
|
||||
}
|
||||
};
|
||||
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
// Tabs Handling
|
||||
const tabs = [
|
||||
{
|
||||
@@ -113,7 +170,7 @@ export default function Settings({ faq }) {
|
||||
iconName: "page-right",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
id: 9,
|
||||
name: "terms",
|
||||
title: "Terms and Conditions",
|
||||
iconName: "page-right",
|
||||
@@ -217,6 +274,7 @@ export default function Settings({ faq }) {
|
||||
coverImgChangHandler={coverImgChangHandler}
|
||||
browseCoverImg={browseCoverImg}
|
||||
coverImgInput={coverImgInput}
|
||||
uploadStatus={uploadStatus}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -7,10 +7,12 @@ import Layout from "../Partials/Layout";
|
||||
import ProductUploadField from "./ProductUploadField";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function UploadProduct() {
|
||||
export default function UploadProduct({uploadTypes}) {
|
||||
const apiCall = new usersService()
|
||||
const [requestStatus, setRequestStatus] = useState({loading: false, status: null, message: ''}) // DETERMINES THE STATUS OF UPLOAD
|
||||
const navigate = useNavigate()
|
||||
|
||||
// preview modal
|
||||
const [previewProductModal, setPreviewProductModal] = useState(false);
|
||||
@@ -79,22 +81,28 @@ export default function UploadProduct() {
|
||||
const [imgDetails, setImgDetails] = useState('')
|
||||
const changeFile = (e, file) => {
|
||||
if (e) {
|
||||
let uploadedFileType = e.target.files[0].type.split("/")[0].toLowerCase();
|
||||
|
||||
|
||||
setSelectedFile(e.target.files[0].name);
|
||||
setImgDetails(e?.target?.files[0])
|
||||
const imgRead = new FileReader();
|
||||
imgRead.onload = (event) => {
|
||||
setImg(event.target.result);
|
||||
// setImg(event.target.result);
|
||||
setImg({ type: uploadedFileType, file: event.target.result });
|
||||
};
|
||||
// most importend
|
||||
imgRead.readAsDataURL(e.target.files[0]);
|
||||
}
|
||||
if (file.length) {
|
||||
if (file?.length) {
|
||||
let uploadedFileType = file[0].type.split("/")[0].toLowerCase();
|
||||
if (file[0].name) {
|
||||
setSelectedFile(file?.[0].name);
|
||||
setImgDetails(file?.[0])
|
||||
const imgRead = new FileReader();
|
||||
imgRead.onload = (event) => {
|
||||
setImg(event.target.result);
|
||||
// setImg(event.target.result);
|
||||
setImg({ type: uploadedFileType, file: event.target.result });
|
||||
};
|
||||
// most importend
|
||||
imgRead.readAsDataURL(file[0]);
|
||||
@@ -134,28 +142,35 @@ export default function UploadProduct() {
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
},5000)
|
||||
}
|
||||
|
||||
let reqData = { // PAYLOAD FOR API CALL
|
||||
file_name: selectedFile.substring(0,21).replace(/ /gi, ""),//selectedFile.replace(/[ -]/gi, ""),
|
||||
file_size: imgDetails.size,
|
||||
file_type: imgDetails.type,
|
||||
file_data: img.file,
|
||||
title: itemName,
|
||||
description: description,
|
||||
msg_type: 'FILE',
|
||||
// action: 'WRENCHBOARD_RESOURCE_MYFILES',
|
||||
action: 11307
|
||||
}
|
||||
|
||||
if(imgDetails.size > 2097152){ // CHECKS IF IMAGE SIZE IS MORE THAN "MB"
|
||||
setRequestStatus({loading: false, status: null, message: 'Image must be less than 2MB'})
|
||||
if(!isValidFile(imgDetails, uploadTypes?.data)){ // FUNCTION TO CHECK IF FILE TYPE IS VALID
|
||||
setRequestStatus({loading: false, status: null, message: 'File type not supported'})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
},5000)
|
||||
}
|
||||
|
||||
let validSize = isValidFileSize(imgDetails, uploadTypes?.data) // FUNCTION TO CHECK IF FILE SIZE IS VALID
|
||||
if(!validSize.status){
|
||||
setRequestStatus({loading: false, status: null, message: validSize.message})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
},5000)
|
||||
}
|
||||
|
||||
let reqData = { // PAYLOAD FOR API CALL
|
||||
file_name: selectedFile,
|
||||
file_size: imgDetails.size,
|
||||
file_type: imgDetails.type,
|
||||
file_data: img,
|
||||
item_name: itemName,
|
||||
item_description: description,
|
||||
msg_type: 'FILE',
|
||||
// action: 'WRENCHBOARD_RESOURCE_MYFILES',
|
||||
action: 11307
|
||||
}
|
||||
// console.log('TESTING', reqData)
|
||||
|
||||
//API CALL TO UPLOAD COMES HERE
|
||||
// API CALL TO UPLOAD COMES HERE
|
||||
setRequestStatus({loading: true, status: null, message: ''}) // SETS REQUEST LOADING TRUE
|
||||
apiCall.sendFiles(reqData).then(res=>{
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
@@ -263,8 +278,15 @@ export default function UploadProduct() {
|
||||
Image,Video,Audio or Documents
|
||||
</h1>
|
||||
<p className="text-thin-light-gray text-base tracking-wide font-medium">
|
||||
File types supported: JPG, PNG, GIP, SVG, MP4, MP3, WEBM,
|
||||
OGG, GLB, GLTF
|
||||
File types supported: {uploadTypes.loading && <span className="italic">loading...</span>}
|
||||
{/* JPG, PNG, GIP, SVG, MP4, MP3, WEBM, OGG, GLB, GLTF */}
|
||||
{uploadTypes?.data?.length ?
|
||||
uploadTypes?.data?.map((item, index) => {
|
||||
return index != uploadTypes.data.length-1 ? `${item.name}, ` : `${item.name}`
|
||||
})
|
||||
:
|
||||
null
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div className="main-content w-full lg:flex justify-between lg:px-9 px-4">
|
||||
@@ -275,17 +297,29 @@ export default function UploadProduct() {
|
||||
>
|
||||
{img ? (
|
||||
<div className="w-full h-full">
|
||||
<img
|
||||
src={img}
|
||||
alt=""
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
{img.type === "image" ? (
|
||||
<img
|
||||
src={img.file}
|
||||
alt=""
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : img.type === "video" ? (
|
||||
<video
|
||||
type=""
|
||||
src={img.file}
|
||||
className="w-full h-full object-cover"
|
||||
controls
|
||||
></video>
|
||||
) : img.type != null ? (
|
||||
<p>{selectedFile}</p>
|
||||
) : null}
|
||||
|
||||
<input
|
||||
type="file"
|
||||
id="fileElem"
|
||||
name="file"
|
||||
className="hidden"
|
||||
accept="image/*"
|
||||
// accept="image/*"
|
||||
ref={fileRef}
|
||||
value={selectedFile.name}
|
||||
onChange={(e) => changeFile(e)}
|
||||
@@ -342,7 +376,7 @@ export default function UploadProduct() {
|
||||
id="fileElem"
|
||||
name="file"
|
||||
className="hidden"
|
||||
accept="image/*"
|
||||
// accept="image/*"
|
||||
ref={fileRef}
|
||||
value={selectedFile.name}
|
||||
onChange={(e) => changeFile(e)}
|
||||
@@ -376,7 +410,8 @@ export default function UploadProduct() {
|
||||
<div className="flex sm:space-x-4 space-x-2 sm:mr-9 mr-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={cancelUploadModalHandler}
|
||||
// onClick={cancelUploadModalHandler}
|
||||
onClick={()=>navigate('/resources', {state:{tab:'created'}})}
|
||||
className="sm:text-18 text-sm text-light-red tracking-wide "
|
||||
>
|
||||
<span className="border-b dark:border-[#5356fb29] border-light-red">
|
||||
@@ -415,7 +450,7 @@ export default function UploadProduct() {
|
||||
<div className="preview-upload-product lg:w-[580px] lg:h-[622px] w-full h-full bg-white dark:bg-[#11131F] lg:rounded-2xl">
|
||||
<div className="w-full h-full flex flex-col justify-between">
|
||||
{/* heading */}
|
||||
<div className="lg:px-[40px] lg:py-[33px] px-[30px] py-[23px] flex justify-between border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] mb-4 lg:mb-0">
|
||||
<div className="lg:px-[40px] lg:py-[33px] px-[30px] py-[23px] flex justify-between border-b border-light-purple dark:border-[#5356fb29] mb-4 lg:mb-0">
|
||||
<h1 className="text-dark-gray dark:text-white tracking-wide text-26 font-bold">
|
||||
Item Privew
|
||||
</h1>
|
||||
@@ -561,3 +596,37 @@ export default function UploadProduct() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//FUNCTIONS to check if file upload type is valid
|
||||
const isValidFile = (file, supportedFile=[]) => {
|
||||
let fileType = file.type.split("/")[1];
|
||||
let valid = supportedFile.filter(item => (
|
||||
item.name.toLowerCase() == fileType.toLowerCase()
|
||||
))
|
||||
if(valid.length){
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
//FUNCTIONS TO CHECK IF FILE SIZE IS VALID
|
||||
const isValidFileSize = (file, supportedFile=[]) => {
|
||||
let fileType = file.type.split("/")[1];
|
||||
let fileSize = file.size;
|
||||
let valid = supportedFile.filter(item => (
|
||||
item.name.toLowerCase() == fileType.toLowerCase()
|
||||
))
|
||||
if(valid.length){
|
||||
if((Number(valid[0].max_size_mb) * 1048576) >= fileSize){
|
||||
return {status: true}
|
||||
}else{
|
||||
return {status: false, message: `File must not exceed ${valid[0].max_size_mb}MB`}
|
||||
}
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ function DeleteJobPopout({ details, onClose, situation }) {
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="68" cy="68" r="68" fill="#5356FB" />
|
||||
<circle cx="68" cy="68" r="68" fill="#4687ba" />
|
||||
<path
|
||||
d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z"
|
||||
fill="white"
|
||||
|
||||
@@ -351,7 +351,7 @@ const EditJobPopOut = ({
|
||||
className="w-[120px] h-[40px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
// className='w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white'
|
||||
>
|
||||
Edit Job
|
||||
Save
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import Detail from "./popoutcomponent/Detail";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import InputCom from "../Helpers/Inputs/InputCom/index";
|
||||
import SiteService from "../../services/SiteService";
|
||||
import { Form, Formik, Field } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import SiteService from "../../services/SiteService";
|
||||
import InputCom from "../Helpers/Inputs/InputCom/index";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import Detail from "./popoutcomponent/Detail";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
family: Yup.string().required("This is required "),
|
||||
@@ -168,7 +168,6 @@ function JobListPopout({ details, onClose, situation }) {
|
||||
};
|
||||
|
||||
// console.log("Job List P >> ", details)
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation} className="job-popup">
|
||||
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
@@ -202,7 +201,7 @@ function JobListPopout({ details, onClose, situation }) {
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="md:flex bg-white rounded-lg shadow-lg">
|
||||
<div className="md:flex bg-white dark:bg-dark-white rounded-lg shadow-lg">
|
||||
<div className="p-4 w-full md:w-2/4 md:border-r-2">
|
||||
{/* <p className='text-lg font-semibold text-slate-900 tracking-wide'>{details.title}</p> */}
|
||||
|
||||
@@ -225,17 +224,17 @@ function JobListPopout({ details, onClose, situation }) {
|
||||
<div className="my-3 md:flex">
|
||||
<Detail
|
||||
label="Created"
|
||||
value={`Dummy, no value found for created!`}
|
||||
/>
|
||||
value={new Date(details?.created).toDateString()}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="my-3">
|
||||
<label className="w-full text-slate-900 tracking-wide font-semibold">
|
||||
<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"
|
||||
className={`p-2 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
|
||||
rows="7"
|
||||
style={{ resize: "none" }}
|
||||
value={textArea}
|
||||
onChange={handleInputChange}
|
||||
@@ -322,7 +321,7 @@ function JobListPopout({ details, onClose, situation }) {
|
||||
input={true}
|
||||
inputName="individual"
|
||||
value={props?.values.individual}
|
||||
placeholder="enter email of individual"
|
||||
placeholder="Enter email of individual"
|
||||
inputHandler={props?.handleChange}
|
||||
btnText="Send Offer to Individual"
|
||||
loader={loader?.jobFields.individual}
|
||||
@@ -338,7 +337,8 @@ function JobListPopout({ details, onClose, situation }) {
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
|
||||
|
||||
{ process.env.REACT_APP_SHOW_OFFER_GROUP_JOB != 0 &&
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema.fields.group}
|
||||
@@ -368,6 +368,7 @@ function JobListPopout({ details, onClose, situation }) {
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
}
|
||||
</div>
|
||||
{/* END OF ACTION SECTION */}
|
||||
</div>
|
||||
@@ -396,7 +397,7 @@ const JobFieldInput = ({
|
||||
data,
|
||||
}) => {
|
||||
return (
|
||||
<div className="field w-full p-3 mb-2 bg-red-50 rounded-md">
|
||||
<div className="field w-full p-3 mb-2 bg-red-50 dark:bg-[#D85A5A] rounded-md">
|
||||
{select && (
|
||||
<>
|
||||
<div className={`input-com ${parentClass}`}>
|
||||
@@ -468,7 +469,14 @@ const JobFieldInput = ({
|
||||
type="submit"
|
||||
name={inputName}
|
||||
onClick={errorHandler}
|
||||
className="px-2 py-1 text-sm text-white btn-gradient tracking-wide rounded-md"
|
||||
// className={`px-2 py-1 text-sm text-white btn-gradient tracking-wide rounded-md ${
|
||||
// !value && "disabled:grayscale-[65%] transition duration-300"
|
||||
// }`}
|
||||
className={`px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white ${
|
||||
!value && ""
|
||||
}
|
||||
`}
|
||||
// disabled={!value}
|
||||
>
|
||||
{loader ? <LoadingSpinner size={5} /> : btnText}
|
||||
</button>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React, { useMemo, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import usersService from "../../services/UsersService";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import Detail from "./popoutcomponent/Detail";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { useDispatch } from "react-redux";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
@@ -18,85 +18,95 @@ const showSuccessToast = (message) => {
|
||||
};
|
||||
|
||||
function PendingJobsPopout({ details, onClose, situation }) {
|
||||
|
||||
const dispatch = useDispatch()
|
||||
const navigate = useNavigate()
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [pendingJobLoader, setPendingJobLoader] = useState({
|
||||
extend: false,
|
||||
offer: false,
|
||||
});
|
||||
|
||||
let [requestMessage, setRequestMessage] = useState({status: false, message: ''})
|
||||
let [requestMessage, setRequestMessage] = useState({
|
||||
status: false,
|
||||
message: "",
|
||||
});
|
||||
|
||||
const apiCall = new usersService();
|
||||
|
||||
const handlePendingJobsBtn = ({ target: { name } }) => {
|
||||
let { job_uid, offer_code } = details;
|
||||
let { job_uid, offer_code } = details;
|
||||
|
||||
let reqData;
|
||||
let reqData;
|
||||
|
||||
let pendingData = { job_uid, offer_code };
|
||||
if(name=='extend'){ // RUNS THIS TO EXTEND JOB EXPIRY BY ONE WEEK
|
||||
reqData = { ...pendingData };
|
||||
setPendingJobLoader({ extend: true });
|
||||
apiCall.pendingJobExtend(reqData).then(res => {
|
||||
setRequestMessage({status: true, message: res.data.status})
|
||||
let pendingData = { job_uid, offer_code };
|
||||
if (name == "extend") {
|
||||
// RUNS THIS TO EXTEND JOB EXPIRY BY ONE WEEK
|
||||
reqData = { ...pendingData };
|
||||
setPendingJobLoader({ extend: true });
|
||||
apiCall
|
||||
.pendingJobExtend(reqData)
|
||||
.then((res) => {
|
||||
setRequestMessage({ status: true, message: res.data.status });
|
||||
setTimeout(() => {
|
||||
setPendingJobLoader({ extend: false, offer: false });
|
||||
setRequestMessage({status: false, message: ''})
|
||||
setRequestMessage({ status: false, message: "" });
|
||||
onClose();
|
||||
dispatch(tableReload({ type: "PENDINGTABLE" }));
|
||||
}, 4000);
|
||||
}).catch(error => {
|
||||
setRequestMessage({status: false, message:'Try Again'})
|
||||
setTimeout(() => {
|
||||
setPendingJobLoader({ extend: false, offer: false });
|
||||
setRequestMessage({status: false, message: ''})
|
||||
}, 3000);
|
||||
})
|
||||
}else if(name=='offer'){ // RUNS THIS IF JOB IS SENT TO USER
|
||||
reqData = { ...pendingData };
|
||||
setPendingJobLoader({ offer: true });
|
||||
apiCall.pendingJobSendTome(reqData).then(res => {
|
||||
setRequestMessage({status: true, message: res.data.status})
|
||||
.catch((error) => {
|
||||
setRequestMessage({ status: false, message: "Try Again" });
|
||||
setTimeout(() => {
|
||||
setPendingJobLoader({ extend: false, offer: false });
|
||||
setRequestMessage({status: false, message: ''})
|
||||
setRequestMessage({ status: false, message: "" });
|
||||
}, 3000);
|
||||
});
|
||||
} else if (name == "offer") {
|
||||
// RUNS THIS IF JOB IS SENT TO USER
|
||||
reqData = { ...pendingData };
|
||||
setPendingJobLoader({ offer: true });
|
||||
apiCall
|
||||
.pendingJobSendTome(reqData)
|
||||
.then((res) => {
|
||||
setRequestMessage({ status: true, message: res.data.status });
|
||||
setTimeout(() => {
|
||||
setPendingJobLoader({ extend: false, offer: false });
|
||||
setRequestMessage({ status: false, message: "" });
|
||||
}, 4000);
|
||||
}).catch(error => {
|
||||
setRequestMessage('Try Again')
|
||||
})
|
||||
.catch((error) => {
|
||||
setRequestMessage("Try Again");
|
||||
setTimeout(() => {
|
||||
setPendingJobLoader({ extend: false, offer: false });
|
||||
setRequestMessage({status: false, message: ''})
|
||||
setRequestMessage({ status: false, message: "" });
|
||||
}, 3000);
|
||||
})
|
||||
} else return
|
||||
// try {
|
||||
// if (name === "extend") {
|
||||
// setPendingJobLoader({ extend: true });
|
||||
// reqData = { ...pendingData };
|
||||
// // let { data } =
|
||||
// await apiCall.pendingJobExtend(reqData);
|
||||
// showSuccessToast("Job has been extended by a week!");
|
||||
// dispatch(tableReload({ type: "PENDINGTABLE" }));
|
||||
// } else if (name === "offer") {
|
||||
// setPendingJobLoader({ offer: true });
|
||||
// reqData = { ...pendingData };
|
||||
// // let { data } =
|
||||
// await apiCall.pendingJobSendTome(reqData);
|
||||
// showSuccessToast("Offer sent, check your email");
|
||||
// } else return;
|
||||
});
|
||||
} else return;
|
||||
// try {
|
||||
// if (name === "extend") {
|
||||
// setPendingJobLoader({ extend: true });
|
||||
// reqData = { ...pendingData };
|
||||
// // let { data } =
|
||||
// await apiCall.pendingJobExtend(reqData);
|
||||
// showSuccessToast("Job has been extended by a week!");
|
||||
// dispatch(tableReload({ type: "PENDINGTABLE" }));
|
||||
// } else if (name === "offer") {
|
||||
// setPendingJobLoader({ offer: true });
|
||||
// reqData = { ...pendingData };
|
||||
// // let { data } =
|
||||
// await apiCall.pendingJobSendTome(reqData);
|
||||
// showSuccessToast("Offer sent, check your email");
|
||||
// } else return;
|
||||
|
||||
// setTimeout(() => {
|
||||
// setPendingJobLoader({ extend: false, offer: false });
|
||||
// onClose();
|
||||
// }, 2700);
|
||||
// } catch (error) {
|
||||
// setPendingJobLoader({ extend: false, offer: false });
|
||||
// throw new Error(error);
|
||||
// }
|
||||
}
|
||||
// setTimeout(() => {
|
||||
// setPendingJobLoader({ extend: false, offer: false });
|
||||
// onClose();
|
||||
// }, 2700);
|
||||
// } catch (error) {
|
||||
// setPendingJobLoader({ extend: false, offer: false });
|
||||
// throw new Error(error);
|
||||
// }
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation} className="edit-popup">
|
||||
@@ -131,9 +141,9 @@ function PendingJobsPopout({ details, onClose, situation }) {
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="md:flex bg-white rounded-lg shadow-lg">
|
||||
<div className="md:flex bg-white dark:bg-dark-white rounded-lg shadow-lg">
|
||||
<div className="p-4 w-full md:w-3/4 md:border-r-2">
|
||||
<p className="text-base font-semibold text-slate-900 tracking-wide">
|
||||
<p className="text-base font-semibold text-slate-900 dark:text-white tracking-wide">
|
||||
{details.title}
|
||||
</p>
|
||||
<div className="my-2 p-2 flex justify-start items-center space-x-2 bg-red-100 border-2 border-red-300">
|
||||
@@ -177,7 +187,11 @@ function PendingJobsPopout({ details, onClose, situation }) {
|
||||
<Detail
|
||||
label="Price"
|
||||
// value={`${details.price * 0.01} ${details.currency}`}
|
||||
value={PriceFormatter(details.price * 0.01, details?.currency_code, details.currency)}
|
||||
value={PriceFormatter(
|
||||
details.price * 0.01,
|
||||
details?.currency_code,
|
||||
details.currency
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -194,19 +208,11 @@ function PendingJobsPopout({ details, onClose, situation }) {
|
||||
value={details.job_description || details.description}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* <div className="my-2 md:flex">
|
||||
<Detail
|
||||
label="Public Link"
|
||||
value="https://work.wrenchboard.com/plb/viewjob/218B4BWB83"
|
||||
bg="bg-slate-200"
|
||||
/>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
{/* ACTION SECTION */}
|
||||
<div className="p-4 w-full md:w-1/4 h-full">
|
||||
<p className="mb-6 text-sm">Actions</p>
|
||||
<p className="mb-6 text-sm dark:text-white">Actions</p>
|
||||
|
||||
<div className="mb-3">
|
||||
<p className="px-2 py-1 text-sm bg-slate-100">
|
||||
@@ -229,11 +235,15 @@ function PendingJobsPopout({ details, onClose, situation }) {
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{pendingJobLoader.extend && requestMessage.message &&
|
||||
<div className={`p-1 ${requestMessage.status ? 'bg-green-500':'bg-red-500'} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
|
||||
{pendingJobLoader.extend && requestMessage.message && (
|
||||
<div
|
||||
className={`p-1 ${
|
||||
requestMessage.status ? "bg-green-500" : "bg-red-500"
|
||||
} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
<p>{requestMessage.message}</p>
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
|
||||
<div className="my-3">
|
||||
<button
|
||||
@@ -251,11 +261,15 @@ function PendingJobsPopout({ details, onClose, situation }) {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{pendingJobLoader.offer && requestMessage.message &&
|
||||
<div className={`p-1 ${requestMessage.status ? 'bg-green-500':'bg-red-500'} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
|
||||
{pendingJobLoader.offer && requestMessage.message && (
|
||||
<div
|
||||
className={`p-1 ${
|
||||
requestMessage.status ? "bg-green-500" : "bg-red-500"
|
||||
} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
<p>{requestMessage.message}</p>
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
|
||||
<div className="mt-10 md:mt-32 md:flex md:justify-center">
|
||||
<button
|
||||
@@ -284,4 +298,4 @@ function PendingJobsPopout({ details, onClose, situation }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default PendingJobsPopout;
|
||||
export default PendingJobsPopout;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
font-family: "Product Sans";
|
||||
src: url("./assets/fonts/Product Sans Regular.ttf");
|
||||
}
|
||||
.nft-main-container{
|
||||
.nft-main-container {
|
||||
max-width: 1200px;
|
||||
}
|
||||
/* Bold Weight */
|
||||
@@ -11,57 +11,59 @@
|
||||
font-family: "Product Sans";
|
||||
src: url("./assets/fonts/Product Sans Bold.ttf");
|
||||
}
|
||||
.SENDER{
|
||||
.SENDER {
|
||||
margin-left: 60px !important;
|
||||
background-color: azure;
|
||||
}
|
||||
.RECIPIENT{
|
||||
.RECIPIENT {
|
||||
margin-right: 60px !important;
|
||||
background-color: #add8e6 !important;
|
||||
}
|
||||
.wallet-box{
|
||||
.wallet-box {
|
||||
background-color: aliceblue;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.bal-col1{
|
||||
.bal-col1 {
|
||||
width: 110px;
|
||||
}
|
||||
.bg-green{
|
||||
.bg-green {
|
||||
background-color: darkgreen;
|
||||
}
|
||||
.referral{
|
||||
margin-bottom: 20px
|
||||
.referral {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.task_action_panel{
|
||||
font-family: sans; color: white;
|
||||
.task_action_panel {
|
||||
font-family: sans;
|
||||
color: white;
|
||||
font-weight: bolder;
|
||||
font-size: 14px;
|
||||
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
||||
padding: 0px 10px 5px 10px
|
||||
padding: 0px 10px 5px 10px;
|
||||
}
|
||||
.heroSilderTitle{
|
||||
.heroSilderTitle {
|
||||
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
||||
font-family: sans; color: white;
|
||||
font-family: sans;
|
||||
color: white;
|
||||
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
||||
}
|
||||
.back-dark1{
|
||||
background-color: #193F5F;
|
||||
.back-dark1 {
|
||||
background-color: #193f5f;
|
||||
min-width: 280px !important;
|
||||
}
|
||||
.job-action{
|
||||
.job-action {
|
||||
background-color: #4687ba;
|
||||
height: 100px;
|
||||
border-radius: 15px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.msg_box{
|
||||
.msg_box {
|
||||
background-color: aliceblue;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
.msg_header{
|
||||
.msg_header {
|
||||
background-color: white;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
@@ -69,7 +71,7 @@
|
||||
font-size: 14px;
|
||||
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
||||
}
|
||||
.siderCardDescription{
|
||||
.siderCardDescription {
|
||||
background-color: aliceblue;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
@@ -78,7 +80,7 @@
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.56;
|
||||
}
|
||||
.siderCardButton{
|
||||
.siderCardButton {
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
@@ -91,33 +93,39 @@
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.short_style{
|
||||
.short_style {
|
||||
background-color: transparent;
|
||||
border-color: #a2d7f1;
|
||||
border-width: 3px;
|
||||
}
|
||||
.lr{
|
||||
.lr {
|
||||
background-color: #e1cace;
|
||||
}
|
||||
.lg{
|
||||
.lg {
|
||||
background-color: #a7dca7;
|
||||
}
|
||||
.lb{
|
||||
.lb {
|
||||
background-color: #b3ccd7;
|
||||
}
|
||||
.ly{
|
||||
.ly {
|
||||
background-color: #eeee67;
|
||||
}
|
||||
.offer-slide-item{
|
||||
background: rgb(2,0,36);
|
||||
background: radial-gradient(circle, rgba(2,0,36,1) 0%, rgba(3,51,2,0.782125350140056) 0%, rgba(0,212,255,0.07904411764705888) 0%, rgba(153,182,201,1) 99%);
|
||||
.offer-slide-item {
|
||||
background: rgb(2, 0, 36);
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
rgba(2, 0, 36, 1) 0%,
|
||||
rgba(3, 51, 2, 0.782125350140056) 0%,
|
||||
rgba(0, 212, 255, 0.07904411764705888) 0%,
|
||||
rgba(153, 182, 201, 1) 99%
|
||||
);
|
||||
margin: 5px;
|
||||
border-radius: 15px;
|
||||
padding: 15px;
|
||||
height: 250px;
|
||||
border-color: beige;
|
||||
}
|
||||
.banner-630-340{
|
||||
.banner-630-340 {
|
||||
width: 630px;
|
||||
height: 340px;
|
||||
background-color: aliceblue;
|
||||
@@ -133,6 +141,7 @@
|
||||
font-family: "Product Sans";
|
||||
src: url("./assets/fonts/Product Sans Regular.ttf");
|
||||
}
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -144,9 +153,8 @@
|
||||
--toastify-color-success: #f539f8;
|
||||
}
|
||||
|
||||
|
||||
/* ===================== EXTRA ===================== */
|
||||
.bottomMargin{
|
||||
.bottomMargin {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
/* TODO: =================================default================================ */
|
||||
@@ -159,8 +167,13 @@ html {
|
||||
font-family: "Product Sans";
|
||||
}
|
||||
.primary-gradient {
|
||||
background: linear-gradient(134.38deg, #f539f8 0%, #284f64 43.55%, #1a3544 104.51%);
|
||||
/* background-image: url("./assets/images/left-myft.jpg");
|
||||
background: linear-gradient(
|
||||
134.38deg,
|
||||
#f539f8 0%,
|
||||
#284f64 43.55%,
|
||||
#1a3544 104.51%
|
||||
);
|
||||
/* background-image: url("./assets/images/left-myft.jpg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; */
|
||||
}
|
||||
@@ -199,7 +212,12 @@ html {
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(134.38deg, #5356fb 0%, #c342f9 43.55%, #f539f8 104.51%);
|
||||
background: linear-gradient(
|
||||
134.38deg,
|
||||
#5356fb 0%,
|
||||
#c342f9 43.55%,
|
||||
#f539f8 104.51%
|
||||
);
|
||||
opacity: 30%;
|
||||
}
|
||||
/* Chrome, Safari, Edge, Opera */
|
||||
@@ -229,10 +247,20 @@ input[type="text"][dir="rtl"] {
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
.btn-gradient {
|
||||
background: linear-gradient(134.38deg, #f539f8 0%, #c342f9 43.55%, #5356fb 104.51%);
|
||||
background: linear-gradient(
|
||||
134.38deg,
|
||||
#f539f8 0%,
|
||||
#c342f9 43.55%,
|
||||
#5356fb 104.51%
|
||||
);
|
||||
}
|
||||
.btn-gradient:hover {
|
||||
background: linear-gradient(134.38deg, #5356fb 0%, #c342f9 43.55%, #f539f8 104.51%);
|
||||
background: linear-gradient(
|
||||
134.38deg,
|
||||
#5356fb 0%,
|
||||
#c342f9 43.55%,
|
||||
#f539f8 104.51%
|
||||
);
|
||||
}
|
||||
.text-26 {
|
||||
font-size: 26px;
|
||||
@@ -246,7 +274,12 @@ input[type="text"][dir="rtl"] {
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
background: linear-gradient(134.38deg, #f539f8 0%, #c342f9 43.55%, #5356fb 104.51%);
|
||||
background: linear-gradient(
|
||||
134.38deg,
|
||||
#f539f8 0%,
|
||||
#c342f9 43.55%,
|
||||
#5356fb 104.51%
|
||||
);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
@@ -305,6 +338,16 @@ input[type="text"][dir="rtl"] {
|
||||
transform: scale(1);
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 25rem) {
|
||||
.sidebar-logo.enter {
|
||||
width: 65%;
|
||||
}
|
||||
.sidebar-logo.enter + span{
|
||||
position: revert;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-logo {
|
||||
transform: scale(0);
|
||||
width: 0;
|
||||
@@ -437,7 +480,12 @@ input[type="text"][dir="rtl"] {
|
||||
.home-page-wrapper .hero-slider .slick-slider .slick-dots li {
|
||||
margin: 0;
|
||||
}
|
||||
.home-page-wrapper .hero-slider .slick-slider .slick-dots li.slick-active button {
|
||||
.home-page-wrapper
|
||||
.hero-slider
|
||||
.slick-slider
|
||||
.slick-dots
|
||||
li.slick-active
|
||||
button {
|
||||
background: white;
|
||||
}
|
||||
.home-page-wrapper .hero-slider .slick-slider .slick-dots li button {
|
||||
@@ -460,7 +508,12 @@ input[type="text"][dir="rtl"] {
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(134.38deg, #5356fb 0%, #c342f9 43.55%, #f539f8 104.51%);
|
||||
background: linear-gradient(
|
||||
134.38deg,
|
||||
#5356fb 0%,
|
||||
#c342f9 43.55%,
|
||||
#f539f8 104.51%
|
||||
);
|
||||
z-index: -1;
|
||||
opacity: 30%;
|
||||
}
|
||||
@@ -476,8 +529,10 @@ input[type="text"][dir="rtl"] {
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.transfer-field, .transfer-field:focus, .transfer-field:focus-within{
|
||||
background: #FFF !important;
|
||||
.transfer-field,
|
||||
.transfer-field:focus,
|
||||
.transfer-field:focus-within {
|
||||
background: #fff !important;
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
@@ -583,12 +638,12 @@ input[type="text"][dir="rtl"] {
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.content{
|
||||
.content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.job-items{
|
||||
.job-sub-menu{
|
||||
.job-items {
|
||||
.job-sub-menu {
|
||||
background-color: yellow;
|
||||
}
|
||||
}
|
||||
@@ -597,7 +652,7 @@ input[type="text"][dir="rtl"] {
|
||||
top: 0;
|
||||
right: -100%;
|
||||
opacity: 0;
|
||||
transition: all .5s;
|
||||
transition: all 0.5s;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
@@ -612,7 +667,12 @@ input[type="text"][dir="rtl"] {
|
||||
.notification-page .content-item .notifications {
|
||||
@apply flex space-x-4 items-center;
|
||||
}
|
||||
.notification-page .content-item .notifications .notification-page .content-item .notifications {
|
||||
.notification-page
|
||||
.content-item
|
||||
.notifications
|
||||
.notification-page
|
||||
.content-item
|
||||
.notifications {
|
||||
@apply mb-0;
|
||||
}
|
||||
.notification-setting-tab .notification-settings-items li:last-child {
|
||||
@@ -621,7 +681,11 @@ input[type="text"][dir="rtl"] {
|
||||
.faq-tab .accordion-items .accordion-item:first-child .accordion-title-bar {
|
||||
padding-top: 0;
|
||||
}
|
||||
.faq-tab .accordion-items .accordion-item:last-child .accordion-body .accordion-body-content {
|
||||
.faq-tab
|
||||
.accordion-items
|
||||
.accordion-item:last-child
|
||||
.accordion-body
|
||||
.accordion-body-content {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.faq-tab .accordion-title-bar {
|
||||
@@ -665,14 +729,15 @@ input[type="text"][dir="rtl"] {
|
||||
}
|
||||
|
||||
@media print {
|
||||
body .modal-com{
|
||||
body .modal-com {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.job-action-modal-body button, .message-modal-header button {
|
||||
.job-action-modal-body button,
|
||||
.message-modal-header button {
|
||||
display: none;
|
||||
}
|
||||
.message-modal-wrapper .message-table{
|
||||
.message-modal-wrapper .message-table {
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
@@ -839,30 +904,40 @@ TODO: Responsive ===========================
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* LoginPage */
|
||||
.main-wrapper.login-wrapper{
|
||||
background-image: url('./assets/images/login-dots.jpg');
|
||||
.main-wrapper.login-wrapper {
|
||||
background-image: url("./assets/images/login-dots.jpg");
|
||||
background-attachment: fixed;
|
||||
background-size: contain;
|
||||
background-position-y: bottom;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.layout-wrapper.login{
|
||||
background: rgb(236,237,241);
|
||||
background: linear-gradient(90deg, rgba(236,237,241,1) 0%, rgba(252,252,252,1) 31%, rgba(255,255,255,0.9416141456582633) 41%, rgba(255,255,255,0.9752275910364145) 61%, rgba(252,252,252,1) 71%, rgba(236,237,241,1) 100%);
|
||||
.layout-wrapper.login {
|
||||
background: rgb(236, 237, 241);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(236, 237, 241, 1) 0%,
|
||||
rgba(252, 252, 252, 1) 31%,
|
||||
rgba(255, 255, 255, 0.9416141456582633) 41%,
|
||||
rgba(255, 255, 255, 0.9752275910364145) 61%,
|
||||
rgba(252, 252, 252, 1) 71%,
|
||||
rgba(236, 237, 241, 1) 100%
|
||||
);
|
||||
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.56;
|
||||
}
|
||||
|
||||
.content-wrapper.login{
|
||||
--bg-color: 255,255,255;
|
||||
background: linear-gradient(90deg, rgba(236,237,240,1) 0%, rgba(255,255,255,1) 50%, rgba(236,237,240,1) 100%);
|
||||
|
||||
.content-wrapper.login {
|
||||
--bg-color: 255, 255, 255;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(236, 237, 240, 1) 0%,
|
||||
rgba(255, 255, 255, 1) 50%,
|
||||
rgba(236, 237, 240, 1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.content-wrapper select {
|
||||
@@ -880,51 +955,68 @@ TODO: Responsive ===========================
|
||||
}
|
||||
|
||||
/* Update table scrollbar */
|
||||
.update-table::-webkit-scrollbar-track, .update-table > *::-webkit-scrollbar-track,
|
||||
.update-table::-webkit-scrollbar-track,
|
||||
.update-table > *::-webkit-scrollbar-track,
|
||||
.market-pop::-webkit-scrollbar-track,
|
||||
.wallet.coupon::-webkit-scrollbar-track{
|
||||
.wallet.coupon::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
|
||||
background-color: transparent;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.update-table::-webkit-scrollbar, .update-table > *::-webkit-scrollbar,
|
||||
.update-table::-webkit-scrollbar,
|
||||
.update-table > *::-webkit-scrollbar,
|
||||
.market-pop::-webkit-scrollbar,
|
||||
.wallet.coupon::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.update-table::-webkit-scrollbar-thumb, .update-table > *::-webkit-scrollbar-thumb, .wallet.coupon::-webkit-scrollbar-thumb {
|
||||
.update-table::-webkit-scrollbar-thumb,
|
||||
.update-table > *::-webkit-scrollbar-thumb,
|
||||
.wallet.coupon::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
border-top-right-radius: 50px;
|
||||
border-bottom-right-radius: 50px;
|
||||
background-color: #fff;
|
||||
background: linear-gradient(134.38deg, #f539f8 0%, #c342f9 43.55%, #5356fb 104.51%);
|
||||
background: linear-gradient(
|
||||
134.38deg,
|
||||
#f539f8 0%,
|
||||
#c342f9 43.55%,
|
||||
#5356fb 104.51%
|
||||
);
|
||||
}
|
||||
|
||||
.market-pop::-webkit-scrollbar-thumb {
|
||||
border-radius: 100px;
|
||||
|
||||
|
||||
/* background-color: #fafafa; */
|
||||
/* background: linear-gradient(134.38deg, #f539f8 0%, #c342f9 43.55%, #5356fb 104.51%); */
|
||||
background: rgb(236,237,241);
|
||||
background: linear-gradient(90deg, rgba(236,237,241,1) 0%, rgba(252,252,252,1) 31%, rgba(255,255,255,0.9416141456582633) 41%, rgba(255,255,255,0.9752275910364145) 61%, rgba(252,252,252,1) 71%, rgba(236,237,241,1) 100%);
|
||||
background: rgb(236, 237, 241);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(236, 237, 241, 1) 0%,
|
||||
rgba(252, 252, 252, 1) 31%,
|
||||
rgba(255, 255, 255, 0.9416141456582633) 41%,
|
||||
rgba(255, 255, 255, 0.9752275910364145) 61%,
|
||||
rgba(252, 252, 252, 1) 71%,
|
||||
rgba(236, 237, 241, 1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.input-curve.lg{
|
||||
.input-curve.lg {
|
||||
border-radius: 35px !important;
|
||||
}
|
||||
|
||||
.edit-popup{
|
||||
.edit-popup {
|
||||
top: 75px;
|
||||
}
|
||||
|
||||
.job-popup{
|
||||
.job-popup {
|
||||
top: 55px;
|
||||
}
|
||||
|
||||
.addJob-popup{
|
||||
.addJob-popup {
|
||||
top: 30px;
|
||||
height: 55rem !important;
|
||||
}
|
||||
@@ -952,10 +1044,10 @@ TODO: Responsive ===========================
|
||||
}
|
||||
|
||||
/* TO REMOVE SLIDER COMPONENT FROM CENTRALIZED */
|
||||
.slider-left .slick-slider .slick-track{
|
||||
.slider-left .slick-slider .slick-track {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.assign-task-popup{
|
||||
.assign-task-popup {
|
||||
top: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function formattedDate(dateString) {
|
||||
export function formattedDate(dateString) {
|
||||
const parts = dateString.split(" ");
|
||||
const datePart = parts[0];
|
||||
const timePart = parts[1];
|
||||
@@ -15,3 +15,26 @@ export default function formattedDate(dateString) {
|
||||
|
||||
return new Date(year, month - 1, day, hour, minute);
|
||||
}
|
||||
|
||||
export function formatDateString(inputDateString) {
|
||||
// Parse the input date string
|
||||
const parsedDate = new Date(inputDateString);
|
||||
|
||||
// Get day, month, year, and time components
|
||||
const day = parsedDate.toLocaleDateString(undefined, { weekday: "long" });
|
||||
const month = parsedDate.toLocaleDateString(undefined, { month: "short" });
|
||||
const date = parsedDate.toLocaleDateString(undefined, { day: "numeric" });
|
||||
const year = parsedDate.toLocaleDateString(undefined, { year: "numeric" });
|
||||
|
||||
// Get the time in 12-hour format with 'AM' or 'PM'
|
||||
const hours = parsedDate.getHours();
|
||||
const minutes = parsedDate.getMinutes();
|
||||
const time = `${hours % 12 || 12}:${minutes.toString().padStart(2, "0")} ${
|
||||
hours < 12 ? "AM" : "PM"
|
||||
}`;
|
||||
|
||||
// Combine the components into the desired format
|
||||
const formattedDate = `${day}, ${month} ${date} ${year} - ${time}`;
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import ClearCookies from "./ClearCookies";
|
||||
import checkAndSetError from "./checkAndSetError";
|
||||
import formattedDate from "./fomattedDate";
|
||||
import { formatDateString, formattedDate } from "./fomattedDate";
|
||||
import getTimeAgo from "./getTimeAgo";
|
||||
import localImgLoad from "./localImgLoad";
|
||||
|
||||
export {
|
||||
ClearCookies,
|
||||
checkAndSetError,
|
||||
formatDateString,
|
||||
formattedDate,
|
||||
getTimeAgo,
|
||||
localImgLoad,
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Navigate, Outlet, useNavigate } from "react-router-dom";
|
||||
import LoadingSpinner from "../components/Spinners/LoadingSpinner";
|
||||
import formattedDate from "../lib/fomattedDate";
|
||||
import usersService from "../services/UsersService";
|
||||
import { commonHeadBanner } from "../store/CommonHeadBanner";
|
||||
import { recentActivitiesData } from "../store/RecentActivitiesData";
|
||||
@@ -10,6 +9,8 @@ import { updateUserDetails } from "../store/UserDetails";
|
||||
import { updateJobs } from "../store/jobLists";
|
||||
import { updateNotifications } from "../store/notifications";
|
||||
import { updateUserJobList } from "../store/userJobList";
|
||||
import { updateWalletDetails } from "../store/walletDetails";
|
||||
import { formattedDate } from "../lib";
|
||||
|
||||
const AuthRoute = ({ redirectPath = "/login", children }) => {
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
@@ -19,13 +20,13 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
||||
const [loadProfileDetails, setLoadProfileDetails] = useState([]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { jobListTable } = useSelector((state) => state.tableReload);
|
||||
const { jobListTable, walletTable } = useSelector((state) => state.tableReload);
|
||||
|
||||
const {
|
||||
userDetails: { username, uid },
|
||||
userDetails: { username, uid, session },
|
||||
} = useSelector((state) => state?.userDetails); // CHECKS IF USER Details are avaliable, to determine if user is active
|
||||
|
||||
let loggedIn = username && uid ? true : false; // variable to determine if user is logged in
|
||||
let loggedIn = username && session && uid ? true : false; // variable to determine if user is logged in
|
||||
|
||||
useEffect(() => {
|
||||
//Removing Data stored at localStorage after session expires
|
||||
@@ -149,7 +150,7 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
||||
// sort: _sorted,
|
||||
// header: _header,
|
||||
// },
|
||||
data: _sorted
|
||||
data: _sorted,
|
||||
})
|
||||
);
|
||||
})
|
||||
@@ -177,6 +178,21 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
||||
getMyJobList();
|
||||
}, [jobListTable]);
|
||||
|
||||
useEffect(() => {
|
||||
const getMyWalletList = async () => {
|
||||
dispatch(updateWalletDetails({ loading: true, data:[] }));
|
||||
try {
|
||||
const res = await apiCall.getUserWallets();
|
||||
console.log("wallet - >", res.data);
|
||||
dispatch(updateWalletDetails({ loading: false, data:res.data?.result_list }));
|
||||
} catch (error) {
|
||||
dispatch(updateWalletDetails({ loading: false, data:[] }));
|
||||
console.log("Error getting mode");
|
||||
}
|
||||
};
|
||||
getMyWalletList();
|
||||
}, [walletTable]);
|
||||
|
||||
useEffect(() => {
|
||||
// Getting market data
|
||||
const getMarketActiveJobList = async () => {
|
||||
@@ -211,7 +227,7 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
||||
.getRecentActivitiedData()
|
||||
.then((res) => {
|
||||
// debugger;
|
||||
if (res.data?.internal_return < 0) {
|
||||
if (res?.data?.internal_return < 0) {
|
||||
return;
|
||||
}
|
||||
dispatch(recentActivitiesData(res.data));
|
||||
|
||||
@@ -1,107 +1,113 @@
|
||||
import React from "react";
|
||||
import Axios from "axios";
|
||||
|
||||
class SiteService {
|
||||
constructor() {
|
||||
console.log("Er are here anyway");
|
||||
}
|
||||
// Blog Data {Get}
|
||||
blogData() {
|
||||
return this.getAuxEnd("/blogdata", null);
|
||||
}
|
||||
constructor() {
|
||||
console.log("Er are here anyway");
|
||||
}
|
||||
// Blog Data {Get}
|
||||
blogData() {
|
||||
return this.getAuxEnd("/blogdata", null);
|
||||
}
|
||||
|
||||
// Country Data {GET}
|
||||
countryData() {
|
||||
return this.getAuxEnd("/country", null);
|
||||
}
|
||||
// Country Data {GET}
|
||||
countryData() {
|
||||
return this.getAuxEnd("/country", null);
|
||||
}
|
||||
|
||||
// Contact Data{POST}
|
||||
contactData() {
|
||||
return this.postAuxEnd("/contact", null)
|
||||
}
|
||||
// Contact Data{POST}
|
||||
contactData() {
|
||||
return this.postAuxEnd("/contact", null);
|
||||
}
|
||||
|
||||
faqData() {
|
||||
return this.getAuxEnd("/faq", null);
|
||||
}
|
||||
faqData() {
|
||||
return this.getAuxEnd("/faq", null);
|
||||
}
|
||||
|
||||
priceData() {
|
||||
return this.getAuxEnd("/pricing", null);
|
||||
}
|
||||
priceData() {
|
||||
return this.getAuxEnd("/pricing", null);
|
||||
}
|
||||
|
||||
addFamily(reqData) {
|
||||
return this.postAuxEnd('/familyadd', reqData)
|
||||
}
|
||||
addFamily(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 22015,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/familyadd", postData);
|
||||
}
|
||||
|
||||
familyListings(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
...reqData
|
||||
};
|
||||
return this.postAuxEnd('/familylist', postData)
|
||||
}
|
||||
familyListings(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/familylist", postData);
|
||||
}
|
||||
|
||||
assignJobTask(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
...reqData
|
||||
};
|
||||
return this.postAuxEnd('/assigntask', postData)
|
||||
}
|
||||
assignJobTask(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/assigntask", postData);
|
||||
}
|
||||
|
||||
//---------------------------------------- -----
|
||||
//---------------------------------------- -----
|
||||
// Unified call below
|
||||
//---------------------------------------- -----
|
||||
//---------------------------------------- -----
|
||||
getAuxEnd(uri, reqData) {
|
||||
const endPoint = process.env.REACT_APP_AUX_ENDPOINT + uri;
|
||||
return Axios.get(endPoint)
|
||||
.then((response) => {
|
||||
// console.log(response);
|
||||
// res = response;
|
||||
// console.log("~~~~~~~ Toks2 GET ~~~~~~~~");
|
||||
return response;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response) {
|
||||
//response status is an error code
|
||||
console.log(error.response.status);
|
||||
} else if (error.request) {
|
||||
//response not received though the request was sent
|
||||
console.log(error.request);
|
||||
} else {
|
||||
//an error occurred when setting up the request
|
||||
console.log(error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
//---------------------------------------- -----
|
||||
//---------------------------------------- -----
|
||||
// Unified call below
|
||||
//---------------------------------------- -----
|
||||
//---------------------------------------- -----
|
||||
getAuxEnd(uri, reqData) {
|
||||
const endPoint = process.env.REACT_APP_AUX_ENDPOINT + uri;
|
||||
return Axios.get(endPoint)
|
||||
.then((response) => {
|
||||
// console.log(response);
|
||||
// res = response;
|
||||
// console.log("~~~~~~~ Toks2 GET ~~~~~~~~");
|
||||
return response;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response) {
|
||||
//response status is an error code
|
||||
console.log(error.response.status);
|
||||
} else if (error.request) {
|
||||
//response not received though the request was sent
|
||||
console.log(error.request);
|
||||
} else {
|
||||
//an error occurred when setting up the request
|
||||
console.log(error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
postAuxEnd(uri, reqData) {
|
||||
const endPoint = process.env.REACT_APP_AUX_ENDPOINT + uri;
|
||||
return Axios.post(endPoint, reqData)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
// res = response;
|
||||
console.log("~~~~~~~ Toks2 POST ~~~~~~~~");
|
||||
return response;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response) {
|
||||
//response status is an error code
|
||||
console.log(error.response.status);
|
||||
} else if (error.request) {
|
||||
//response not received though the request was sent
|
||||
console.log(error.request);
|
||||
} else {
|
||||
//an error occurred when setting up the request
|
||||
console.log(error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
postAuxEnd(uri, reqData) {
|
||||
const endPoint = process.env.REACT_APP_AUX_ENDPOINT + uri;
|
||||
return Axios.post(endPoint, reqData)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
// res = response;
|
||||
console.log("~~~~~~~ Toks2 POST ~~~~~~~~");
|
||||
return response;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response) {
|
||||
//response status is an error code
|
||||
console.log(error.response.status);
|
||||
} else if (error.request) {
|
||||
//response not received though the request was sent
|
||||
console.log(error.request);
|
||||
} else {
|
||||
//an error occurred when setting up the request
|
||||
console.log(error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default SiteService;
|
||||
|
||||
@@ -30,6 +30,16 @@ class usersService {
|
||||
return this.postAuxEnd("/dashdata", postData);
|
||||
}
|
||||
|
||||
getRecentActivities(){
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11202
|
||||
};
|
||||
return this.postAuxEnd("/recentactivities", postData);
|
||||
}
|
||||
|
||||
logInUser(reqData) {
|
||||
localStorage.setItem("session_token", ``);
|
||||
return this.postAuxEnd("/userlogin", reqData);
|
||||
@@ -86,6 +96,18 @@ class usersService {
|
||||
return this.postAuxEnd("/loadprofile", null);
|
||||
}
|
||||
|
||||
getUploadedList() {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
page: 1,
|
||||
limit: 20,
|
||||
action: 11309,
|
||||
};
|
||||
return this.postAuxEnd("/myfiles", postData);
|
||||
}
|
||||
|
||||
getOffersList() {
|
||||
var postData = {
|
||||
uuid: localStorage.getItem("uid"),
|
||||
@@ -226,7 +248,7 @@ class usersService {
|
||||
return this.postAuxEnd("/sendmoneyfee", postData);
|
||||
}
|
||||
|
||||
// Start Credit for Cards
|
||||
// Start Credit for Cards
|
||||
getStartCredit(value) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
@@ -346,6 +368,7 @@ class usersService {
|
||||
page: 0,
|
||||
offset: 0,
|
||||
limit: 100,
|
||||
allstatus: 0
|
||||
};
|
||||
return this.postAuxEnd("/activetaskslist", postData);
|
||||
}
|
||||
@@ -577,7 +600,7 @@ class usersService {
|
||||
return this.postAuxEnd("/familymanage", postData);
|
||||
}
|
||||
|
||||
// END POINT CALL FOR ACCOUNT TOP
|
||||
// END POINT CALL FOR ACCOUNT TOP
|
||||
startTopUp(post) {
|
||||
alert("WHY ARE WE CALLING THIS ?");
|
||||
// var postData = {
|
||||
@@ -591,7 +614,6 @@ class usersService {
|
||||
// return this.postAuxEnd("/starttopup", postData);
|
||||
}
|
||||
|
||||
|
||||
resultTopUp(post) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
@@ -600,7 +622,7 @@ class usersService {
|
||||
action: 11061,
|
||||
...post,
|
||||
};
|
||||
console.log("topupresult",postData);
|
||||
console.log("topupresult", postData);
|
||||
return this.postAuxEnd("/topupresult", postData);
|
||||
}
|
||||
|
||||
@@ -972,63 +994,87 @@ class usersService {
|
||||
return this.postAuxEnd("/familysuggestlist", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO CHANGE PROFILE PASSWORD
|
||||
profilePassChange(reqData) {
|
||||
// FUNCTION TO CHANGE PROFILE PASSWORD
|
||||
profilePassChange(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11005,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/profilepasschange", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO GET ACCOUNT SETTINGS
|
||||
getAccSettings() {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11059,
|
||||
};
|
||||
return this.postAuxEnd("/getaccsettings", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO SET ACCOUNT SETTINGS
|
||||
setAccSettings(reqdata) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11058,
|
||||
...reqdata,
|
||||
};
|
||||
return this.postAuxEnd("/setaccsettings", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO DELETE PAY CARD
|
||||
payRemCard(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11057,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/payremcard", postData);
|
||||
}
|
||||
|
||||
getHomeRecent() {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
limit: 30,
|
||||
offset: 0,
|
||||
action: 11202,
|
||||
};
|
||||
return this.postAuxEnd("/recentactivities", postData);
|
||||
}
|
||||
// FUNCTION TO GET SINGLE BLOG ITEM
|
||||
getSingleBlogData(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
limit: 4,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/blogdata", postData);
|
||||
}
|
||||
|
||||
|
||||
// FUNCTION TO CANCEL TASK OR SEND REMINDER BY FAMILY MEMBER
|
||||
suggestStatus(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11005,
|
||||
action: 22026,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/profilepasschange", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO GET ACCOUNT SETTINGS
|
||||
getAccSettings() {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11059,
|
||||
};
|
||||
return this.postAuxEnd("/getaccsettings", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO SET ACCOUNT SETTINGS
|
||||
setAccSettings(reqdata) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11058,
|
||||
...reqdata,
|
||||
};
|
||||
return this.postAuxEnd("/setaccsettings", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO DELETE PAY CARD
|
||||
payRemCard(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11057,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/payremcard", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO GET SINGLE BLOG ITEM
|
||||
getSingleBlogData(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
limit: 4,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/blogdata", postData);
|
||||
return this.postAuxEnd("/suggeststatus", postData);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -7,6 +7,7 @@ const initialState = {
|
||||
othersInterestedTable: false,
|
||||
couponTable: false,
|
||||
walletTable: false,
|
||||
uploadsTable: false,
|
||||
};
|
||||
|
||||
export const tableReloadSlice = createSlice({
|
||||
@@ -33,6 +34,9 @@ export const tableReloadSlice = createSlice({
|
||||
case "WALLETTABLE":
|
||||
state.walletTable = !state.walletTable;
|
||||
return;
|
||||
case "UPLOADSTABLE":
|
||||
state.uploadsTable = !state.uploadsTable;
|
||||
return;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
userDetails: {}
|
||||
userDetails: {},
|
||||
};
|
||||
|
||||
export const userSlice = createSlice({
|
||||
name: "userDetails",
|
||||
initialState,
|
||||
reducers: {
|
||||
updateUserDetails: (state,action) => {
|
||||
state.userDetails = {...action.payload}
|
||||
updateUserDetails: (state, action) => {
|
||||
state.userDetails = { ...action.payload };
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -17,4 +17,4 @@ export const userSlice = createSlice({
|
||||
// Action creators are generated for each case reducer function
|
||||
export const { updateUserDetails } = userSlice.actions;
|
||||
|
||||
export default userSlice.reducer;
|
||||
export default userSlice.reducer;
|
||||
|
||||
@@ -7,6 +7,7 @@ import userDetailReducer from "./UserDetails";
|
||||
import jobReducer from "./jobLists";
|
||||
import notificationsReducer from "./notifications";
|
||||
import userJobListReducer from "./userJobList";
|
||||
import walletDetails from "./walletDetails";
|
||||
|
||||
export default configureStore({
|
||||
reducer: {
|
||||
@@ -17,5 +18,6 @@ export default configureStore({
|
||||
userJobList: userJobListReducer,
|
||||
commonHeadBanner: commonHeadBannerReducer,
|
||||
notifications: notificationsReducer,
|
||||
walletDetails: walletDetails
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
walletDetails: {
|
||||
loading: true,
|
||||
data: []
|
||||
},
|
||||
};
|
||||
|
||||
export const walletSlice = createSlice({
|
||||
name: "walletDetails",
|
||||
initialState,
|
||||
reducers: {
|
||||
updateWalletDetails: (state, action) => {
|
||||
state.walletDetails = { ...action.payload };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { updateWalletDetails } = walletSlice.actions;
|
||||
export default walletSlice.reducer;
|
||||
@@ -5,27 +5,32 @@ import ModalCom from "../components/Helpers/ModalCom";
|
||||
function AddJobPage({ action, situation, categories }) {
|
||||
return (
|
||||
<ModalCom action={action} situation={situation} className="edit-popup">
|
||||
<div className="lg:w-[600px] w-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white ">
|
||||
<div className="heading flex justify-between items-center py-6 md:px-[30px] px-[23px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="lg:w-[600px] w-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white dark:text-white">
|
||||
<div className="heading flex justify-between items-center py-6 md:px-[30px] px-[23px] border-b border-light-purple dark:border-[#5356fb29] ">
|
||||
<p className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Create New Job
|
||||
</p>
|
||||
<button type="button" onClick={action}>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={action}
|
||||
>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M32 14.3645C32 15.5022 32 16.6399 32 17.7779C31.8143 17.8408 31.8787 18.0048 31.8565 18.1334C30.6952 24.8402 26.8853 29.2664 20.4091 31.362C19.4672 31.6668 18.4669 31.7917 17.4935 31.9997C16.3558 31.9997 15.2181 31.9997 14.0801 31.9997C13.8574 31.741 13.5279 31.7984 13.2475 31.7416C6.90872 30.4552 2.74424 26.7311 0.684152 20.6107C0.386668 19.7268 0.396442 18.7733 0 17.9199C0 16.6399 0 15.3598 0 14.0798C0.259 13.884 0.190585 13.5694 0.240675 13.3162C1.52285 6.84244 5.35655 2.66392 11.5936 0.623067C12.4549 0.34116 13.3785 0.343909 14.2221 0C15.3125 0 16.4029 0 17.4932 0C17.525 0.110258 17.6111 0.120948 17.7089 0.130417C24.2666 0.77242 29.8064 5.52819 31.449 11.9351C31.6552 12.739 31.8174 13.5542 32 14.3645ZM29.3431 16.0699C29.3718 8.68538 23.4154 2.66942 16.0684 2.66178C8.69759 2.65445 2.66972 8.58489 2.65353 15.8601C2.63704 23.2563 8.52319 29.2979 15.7868 29.3404C23.2862 29.3846 29.3144 23.4832 29.3431 16.0699Z"
|
||||
fill="#374557"
|
||||
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="M14.1604 16.0221C12.3843 14.2567 10.6724 12.5534 8.95837 10.8525C8.53353 10.431 8.23421 9.97162 8.46175 9.34031C8.83956 8.29209 9.95101 8.07371 10.794 8.906C12.3611 10.4536 13.9344 11.9963 15.4529 13.5909C15.9202 14.0817 16.1447 14.0005 16.5662 13.5643C18.0961 11.9804 19.6617 10.4307 21.2282 8.88248C22.0596 8.06058 23.208 8.30064 23.5522 9.35008C23.7584 9.97865 23.459 10.4383 23.0336 10.8619C21.489 12.3991 19.9531 13.9443 18.4088 15.4815C18.2421 15.6476 18.0408 15.779 17.8188 15.9558C19.629 17.7563 21.366 19.4676 23.0831 21.1987C23.934 22.0567 23.6875 23.2106 22.6072 23.556C21.9658 23.761 21.5223 23.4186 21.1067 23.0023C19.5502 21.444 17.9757 19.9031 16.448 18.3171C16.0616 17.9157 15.8854 17.9811 15.5375 18.3378C13.9835 19.9318 12.399 21.4956 10.8242 23.0692C10.4015 23.4916 9.94887 23.7768 9.30961 23.516C8.27819 23.0948 8.06073 22.0814 8.87591 21.2418C10.0307 20.0528 11.2118 18.8891 12.3895 17.7221C12.9588 17.1577 13.5462 16.6106 14.1604 16.0221Z"
|
||||
fill="#374557"
|
||||
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,31 +1,37 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import ActiveJobs from "../components/MyActiveJobs/ActiveJobs";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import ActiveJobs from "../components/MyActiveJobs/ActiveJobs";
|
||||
import usersService from "../services/UsersService";
|
||||
|
||||
/**
|
||||
* This code defines a React functional component called `ManageActiveJobs`.
|
||||
* It fetches a list of active job messages and renders the `ActiveJobs` component with the necessary props.
|
||||
*/
|
||||
function ManageActiveJobs() {
|
||||
const ApiCall = new usersService();
|
||||
|
||||
let navigate = useNavigate();
|
||||
let { state } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { state } = useLocation();
|
||||
|
||||
let [details, setDetails] = useState({}); // to hold state values
|
||||
const [details, setDetails] = useState({});
|
||||
|
||||
let [activeJobMesList, setActiveJobMesList] = useState({
|
||||
const [activeJobMesList, setActiveJobMesList] = useState({
|
||||
loading: true,
|
||||
error: false,
|
||||
data: [],
|
||||
});
|
||||
|
||||
let [activeJobMesListReload, setActiveJobMesListReload] = useState(false); // state to determine when ACTIVE JOB MESSAGE LIST RELOADS/RE-RENDERS
|
||||
const [activeJobMesListReload, setActiveJobMesListReload] = useState(false);
|
||||
|
||||
/**
|
||||
* Fetches the active job message list.
|
||||
*/
|
||||
const getActiveJobMesList = () => {
|
||||
// FUNCTION TO GET ACTIVE JOB MESSAGE LIST
|
||||
setActiveJobMesList({ loading: true, error: false, data: [] });
|
||||
let contract = { contract: state.contract };
|
||||
const contract = { contract: state.contract };
|
||||
ApiCall.activeJobMesList(contract)
|
||||
.then((res) => {
|
||||
if (res.status != 200 || res.data.internal_return < 0) {
|
||||
if (res.status !== 200 || res.data.internal_return < 0) {
|
||||
setActiveJobMesList({ loading: false, error: false, data: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import MarketPlace from "../components/MarketPlace";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
export default function MarketPlacePage() {
|
||||
|
||||
@@ -1,31 +1,36 @@
|
||||
import React, { useContext,useState, useEffect } from "react";
|
||||
import usersService from "../services/UsersService";
|
||||
import MyReviewDueJobs from "../components/MyActiveJobs/MyReviewDueJobs";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import MyReviewDueJobs from "../components/MyActiveJobs/MyReviewDueJobs";
|
||||
import usersService from "../services/UsersService";
|
||||
|
||||
/**
|
||||
* React component that fetches a list of review due jobs and renders the `MyReviewDueJobs` component with the fetched data.
|
||||
*/
|
||||
export default function MyReviewDueJobsPage() {
|
||||
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
|
||||
const [MyJobList, setMyJobList] = useState([]);
|
||||
const api = new usersService();
|
||||
const getMyJobList = async () => {
|
||||
try {
|
||||
const res = await api.getMyReviewDueJobList();
|
||||
setMyJobList(res.data);
|
||||
} catch (error) {
|
||||
console.log("Error getting mode");
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
getMyJobList();
|
||||
}, []);
|
||||
const { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
||||
const [myJobList, setMyJobList] = useState([]);
|
||||
|
||||
// debugger;
|
||||
return (
|
||||
<>
|
||||
<MyReviewDueJobs
|
||||
MyJobList={MyJobList}
|
||||
commonHeadData={commonHeadBanner.result_list}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
useEffect(() => {
|
||||
const api = new usersService();
|
||||
|
||||
const getMyJobList = async () => {
|
||||
try {
|
||||
const res = await api.getMyReviewDueJobList();
|
||||
setMyJobList(res.data);
|
||||
} catch (error) {
|
||||
console.log("Error getting mode");
|
||||
}
|
||||
};
|
||||
|
||||
getMyJobList();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MyReviewDueJobs
|
||||
myJobList={myJobList}
|
||||
commonHeadData={commonHeadBanner.result_list}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Resources from "../components/Resources";
|
||||
import usersService from "../services/UsersService";
|
||||
import { useLocation } from "react-router-dom";
|
||||
export default function ResourcePage() {
|
||||
const {state, pathname} = useLocation() // CHECKS IF THERE IS AN ACTIVE TAB WITH LINK BACK TO RESOURCES
|
||||
const [MyResourceData, setMyResourceData] = useState([]);
|
||||
const api = new usersService();
|
||||
|
||||
@@ -17,5 +19,5 @@ export default function ResourcePage() {
|
||||
getMyResourceData();
|
||||
}, []);
|
||||
|
||||
return <Resources MyResourceData={MyResourceData} />;
|
||||
return <Resources MyResourceData={MyResourceData} activeTab={state ? state.tab : ''} />;
|
||||
}
|
||||
@@ -1,6 +1,22 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import UploadProduct from "../components/UploadProduct";
|
||||
import usersService from "../services/UsersService";
|
||||
|
||||
export default function UploadProductPage() {
|
||||
return <UploadProduct />;
|
||||
const [uploadTypes, setUploadTypes] = useState({loading: true, data: []});
|
||||
const api = new usersService();
|
||||
|
||||
const getUploadTypes = async () => {
|
||||
try {
|
||||
const res = await api.getResourceList();
|
||||
setUploadTypes({loading: false, data: res?.data?.upload_types.data});
|
||||
} catch (error) {
|
||||
setUploadTypes({loading: false, data: []});
|
||||
throw new Error("Error getting mode");
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
getUploadTypes();
|
||||
}, []);
|
||||
return <UploadProduct uploadTypes={uploadTypes} />;
|
||||
}
|
||||
|
||||