Compare commits
128 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| de3bfa2541 | |||
| 71152f7a05 | |||
| 8cbdb1b8a6 | |||
| abbf60ad48 | |||
| c956befed9 | |||
| a5dbeaecbf | |||
| 0b0b563dda | |||
| f8a3e42fe6 | |||
| ced88fa497 | |||
| 89e2527ba6 | |||
| 9e6b59624f | |||
| 1b6b4f17b0 | |||
| 8a9ec35994 | |||
| fa2102eb61 | |||
| bf73461c64 | |||
| 5ffa6eb691 | |||
| 5a0d8aebdb | |||
| e8ed10ddbf | |||
| cca423a41c | |||
| 6a6900a62b | |||
| c6b4fcc43d | |||
| 29510c3b85 | |||
| 1d8e54c57d | |||
| 426599dd1f | |||
| c8d6d3d7d4 | |||
| 593ea74388 | |||
| d81b9970b3 | |||
| 777ff54220 | |||
| 382a266b9a | |||
| 2d80dd9450 | |||
| 0eaa72a5ec | |||
| a2e2df867d | |||
| 10d4e169d3 | |||
| 79ed578483 | |||
| 25440a3c06 | |||
| 5f4c40a318 | |||
| ff7e8ea1ab | |||
| cba14f4265 | |||
| 9c342f87f7 | |||
| 498966dd23 | |||
| b282295924 | |||
| 7222a4d750 | |||
| 271f5635a0 | |||
| 86c4283507 | |||
| 5e5d953769 | |||
| aa7065c5b4 | |||
| 29fee11ec3 | |||
| 264d7b8501 | |||
| 8f90bcdf10 | |||
| 4b897cb3a9 | |||
| 0977650bf4 | |||
| 1f76dd0db8 | |||
| f772cf0a68 | |||
| c4c5c7967e | |||
| 45ecec24ac | |||
| 16fd35df83 | |||
| 3f6a391d30 | |||
| 5eb64f49c0 | |||
| 1761150bd3 | |||
| a4b15dd06e | |||
| 1a15410e4c | |||
| da1133ed43 | |||
| 23605bc358 | |||
| 2092682be6 | |||
| 0e270d8efa | |||
| 3bb4fe6a02 | |||
| fa728d3879 | |||
| a9ce76123b | |||
| 3ac1be9b89 | |||
| e4be117c90 | |||
| 58834cd7ca | |||
| 59945c28e4 | |||
| 0feaf42f49 | |||
| 5a623dd147 | |||
| 9265fde343 | |||
| 452bb73bef | |||
| cfec230ce3 | |||
| 87430f530d | |||
| 52cb0cb2da | |||
| a19df45997 | |||
| 7868e7d689 | |||
| 08f1ae1a9f | |||
| c4cc27490b | |||
| 90b609d457 | |||
| a6c6c36fbc | |||
| 03b79f0e0c | |||
| 0af52df1d2 | |||
| 9e1a68f81a | |||
| 12e4b7824a | |||
| 5769332e74 | |||
| bab0296f4f | |||
| d457550d58 | |||
| f106e17ce6 | |||
| 8f1d2b6584 | |||
| 3a3503447a | |||
| e46d2bea8d | |||
| b05c519571 | |||
| 48ab2d80ad | |||
| 47876875cf | |||
| d78ad0b648 | |||
| d63690a43c | |||
| 3ce97a4b76 | |||
| 6e9af99d46 | |||
| 4ce8f813c4 | |||
| 9163c42d77 | |||
| 3b4ce9c99e | |||
| cfa6117a07 | |||
| 6f26e2e88f | |||
| b7927a9d6a | |||
| 2d366cd103 | |||
| 6eed7bf1f3 | |||
| 3c87a67581 | |||
| e31ee86299 | |||
| 4d3fe6a799 | |||
| 3e8c8e88ea | |||
| feca65eb80 | |||
| 9ea846bc56 | |||
| 8c31eb3145 | |||
| d049d1b2b0 | |||
| d34895c64c | |||
| 9a3fa2a4a4 | |||
| a9d982386c | |||
| 2341d2a17d | |||
| 076df9438d | |||
| bbf03b2b10 | |||
| afead464b0 | |||
| dcdf03e9c5 | |||
| 44e2402cb3 |
@@ -9,15 +9,15 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
||||
|
||||
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
|
||||
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
|
||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES=300000
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES=600000
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
|
||||
REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
||||
|
||||
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
# REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
# REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||
|
||||
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
|
||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES=300000
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES=600000
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
|
||||
REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
||||
|
||||
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
||||
#REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
||||
#REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
||||
|
||||
#REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
#REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
|
||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES=300000
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES=600000
|
||||
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
|
||||
REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import BlogPage from "./views/BlogPage";
|
||||
import MyReviewDueJobsPage from "./views/MyReviewDueJobsPage";
|
||||
import OffersInterestPage from "./views/OffersInterestPage";
|
||||
import ManageInterestOfferPage from './views/ManageInterestOfferPage'
|
||||
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
||||
|
||||
export default function Routers() {
|
||||
return (
|
||||
@@ -89,10 +90,11 @@ export default function Routers() {
|
||||
<Route exact path="/notification" element={<Notification />} />
|
||||
<Route exact path="/mytask" element={<MyTaskPage />} />
|
||||
<Route exact path="/myjobs" element={<MyJobsPage />} />
|
||||
<Route exact path="/add-job" element={<AddJobPage />} />
|
||||
{/* <Route exact path="/add-job" element={<AddJobPage />} /> */}
|
||||
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
|
||||
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
|
||||
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
|
||||
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
|
||||
<Route exact path="/my-review-jobs" element={<MyReviewDueJobsPage />} />
|
||||
<Route exact path="/acc-family" element={<FamilyAccPage />} />
|
||||
<Route exact path="/manage-family" element={<FamilyManagePage />} />
|
||||
|
||||
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 68 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg width="905" height="575" viewBox="0 0 905 575" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<rect width="905" height="575" fill="url(#pattern0)"/>
|
||||
<defs>
|
||||
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
|
||||
<use xlink:href="#image0_201_3" transform="matrix(0.00849979 0 0 0.0131639 -0.0662984 -0.354783)"/>
|
||||
</pattern>
|
||||
<image id="image0_201_3" width="130" height="130" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAACCCAMAAAC93eDPAAAApVBMVEX///82OzgAAAAuMi81OjdVXVfqpQCzs7NCSUSwsbAaIBslKyjk5OQuNDAhJiLZ2tpJT0opNTkvNzloVy31rAC1hRtPV1HNzc34+PgaLztBQUHLkg9UVFTw8PDGxsaioqKampp/f39sbGyIiIgaGho9Qj5MTExeXl5fUi+9vb03Nzd2dnYjIyORkZFjZWMNFQ9CQTWYcyLAjBSsfx12XytSSjEQEBBeBsYmAAAEiklEQVR4nO3a7XaqOBQG4BjoQXRraKc1GUoSPgQaETszZ473f2kTqm0VsKLLYs80b3+UhQgPOwlBESETExMTExMTExMTExMTk/9HQDk9xHUdcgiwmk7HPWQ0Gj0HrQiaWvagh9iWztSiTQH3rD4AW4I19nmDUI77EWwJ1ihpENJeWuGdYE0afXHSN2EMdUI/fXGHMK0Piv6rcJhg39VyadpRwt3g6Y+9PNl3/RLsvx7va3kcXLYOxwh/Ptz/qOX+79t+CY91wY8fD4ZgCIbwvQn/NAT3P/sl3P3bENz/uuwkcXSaun162M/PX5ctQofJ+u62lgtPlL/HLYshGIIhfDGC3chZ65ur7c6EYSN2+/r0wPYvn4/ttH19B4Lt3TRSGexZc316YP3LgZrrZ9sqTK5PsK7fEMcJn90d7eOEz84XIEyuT7CuTrCvT5hcn2BdnWBfnbAj+CaEtyvizrXROpfQOu0fAwyGnucN9X89XeiltPrebnIuwU5nO+n2dbmdbqfH1B6+Le02w4mEvYnX60J4PW61/fukb51PGO4SulWheRehMecTTu8LbTc+NzMvPZ9wctrupW505+yR0NYOelR41yVUgq5VaLnjOvmy0GyIStC5L6RH0okwbBN4g06ExpubFe00JPbKMNsIOl4XWofT6YTB4HU/3mDWLjjpc8RevE4APSF4VSFmQ31VTl8AqdWZcInuuEFUHWczLdgDuw7o637BnjSP/AHh8o9KPwR8fhXslsrXCfUHxpd8bH7k9LdpPDZHyajL+y6XUdQggD/uUzAeNNoBIWpN+xNMJy0/JNF1mD2Pespz0FKDDcJxe4k6BDAxMTExMTH5kunjZ8cfB+Gr53sTluE7YQ0gBSGrBEgEROIcCA0oVnEEkFfbCp44ZUYDAhLjiGAKCiugmASlXAGMa/teEBCLHCCSYZmEofBlqUIcACQ44r4PoJbVZnOk3ghzFPlMujyEbIViH8es4C6LSAKuAP16gaqlAlwomY9DVrCElSjhCVfSAYe6NYLPSq6oCFmohFIhl64kLqYkZEuFogzlqMSZEPo2nr4TijVLQk1YBihYa0IGigMNeZRF+vUcFTiGkiqxTpa45BIWUjIfQs4dh8KiXmGfBZQSqc9EACExsBcCuDHyKXd8hLmu9GY8wvKVADHnKJZIBIis8AoByTnoc4k2Z6hPeYlUKIRUfkXgcxxpQskBqTlhywYh3xB8DkRvByysCE6McghptiGwjYG+EgLMSigkwQHS5xTzAGdQIk2QVUP4q5BlnOVC5PqVqgq+cF+qkCCV64odICCMqEBLvadwW4UYCcj3quC/E1BElS5wjlaLqiFwwHUPAf2ho1jhGCUso2jh8IgFVV9ACSpRxBO2Ig4oShuEgju6ZJrgKraEgEmilrovaHKk/wKUbPsCmb+OCJphEReioDTRG+JAl9tXa7mKiZLSxWtJEpyo+ZwKx8eFwEoPG71XLLKo9Cmtd4aFomrp616gB1Xhrp0sSiQlmSBx4uLqKHK+GRHibUR8mCQ4tsW5mUrcjfD5+QKE/wC0yMO17JCUyAAAAABJRU5ErkJggg=="/>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 61 KiB |
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 52 52" data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"><path d="M14,16H2a2,2,0,0,1-2-2V2A2,2,0,0,1,2,0H14a2,2,0,0,1,2,2V14A2,2,0,0,1,14,16ZM4,12h8V4H4Z"/><path d="M14,34H2a2,2,0,0,1-2-2V20a2,2,0,0,1,2-2H14a2,2,0,0,1,2,2V32A2,2,0,0,1,14,34ZM4,30h8V22H4Z"/><path d="M14,52H2a2,2,0,0,1-2-2V38a2,2,0,0,1,2-2H14a2,2,0,0,1,2,2V50A2,2,0,0,1,14,52ZM4,48h8V40H4Z"/><path d="M32,16H20a2,2,0,0,1-2-2V2a2,2,0,0,1,2-2H32a2,2,0,0,1,2,2V14A2,2,0,0,1,32,16ZM22,12h8V4H22Z"/><path d="M32,34H20a2,2,0,0,1-2-2V20a2,2,0,0,1,2-2H32a2,2,0,0,1,2,2V32A2,2,0,0,1,32,34ZM22,30h8V22H22Z"/><path d="M32,52H20a2,2,0,0,1-2-2V38a2,2,0,0,1,2-2H32a2,2,0,0,1,2,2V50A2,2,0,0,1,32,52ZM22,48h8V40H22Z"/><path d="M50,16H38a2,2,0,0,1-2-2V2a2,2,0,0,1,2-2H50a2,2,0,0,1,2,2V14A2,2,0,0,1,50,16ZM40,12h8V4H40Z"/><path d="M50,34H38a2,2,0,0,1-2-2V20a2,2,0,0,1,2-2H50a2,2,0,0,1,2,2V32A2,2,0,0,1,50,34ZM40,30h8V22H40Z"/><path d="M50,52H38a2,2,0,0,1-2-2V38a2,2,0,0,1,2-2H50a2,2,0,0,1,2,2V50A2,2,0,0,1,50,52ZM40,48h8V40H40Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" id="delete"><g color="#000"><path fill="#ee4c45" style="line-height:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;block-progression:tb;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" d="M12 1028.362c-6.626 0-12 5.374-12 12s5.374 12 12 12 12-5.374 12-12-5.374-12-12-12z" font-family="sans-serif" font-weight="400" overflow="visible" transform="translate(0 -1028.362)"></path><path fill="#fff" style="isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" d="M10.5 1034.362v1h-3v1h9v-1h-3v-1h-3zm-2 3v9h7v-9h-7zm1 1h1v7h-1v-7zm2 0h1v7h-1v-7zm2 0h1v7h-1v-7z" overflow="visible" transform="translate(0 -1028.362)"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 841 B |
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 60 60" viewBox="0 0 60 60" id="edit"><path fill="#3B4652" d="M52.9687347,19.3099976l-2.7999878-2.7999878c-0.9099731-0.9100342-2.3899536-0.9100342-3.2999878,0
|
||||
l-1.4129639,1.4129639c0.0185547,0.017395,0.0423584,0.0234985,0.0601196,0.0422974l5.7765503,6.1199341
|
||||
c0.0361328,0.038269,0.0506592,0.0881348,0.0813599,0.1296997l1.5949097-1.5949097
|
||||
C53.8787689,21.7099609,53.8787689,20.2199707,52.9687347,19.3099976z"></path><path fill="#2B79C2" d="M10.8887787,25.5499878H34.998764l7.5900269-7.5900269l1.7599487-1.75V9c0-1.6500244-1.3499756-3-3-3h-32
|
||||
c-1.6599731,0-3,1.3499756-3,3v42c0,1.6499634,1.3400269,3,3,3h32c1.6500244,0,3-1.3500366,3-3V34.0700073l-5.8899536,5.8800049
|
||||
c-0.3099976,0.3199463-0.7000122,0.5599976-1.1199951,0.7099609l-7.2200317,2.5200195
|
||||
c-0.3099976,0.1099854-0.6500244,0.1699829-0.9899902,0.1699829c-0.7800293,0-1.5200195-0.2999878-2.0900269-0.8399658
|
||||
c-0.3399658-0.3400269-0.5799561-0.7400513-0.7299805-1.1600342H10.8887787c-0.5599976,0-1-0.4500122-1-1s0.4400024-1,1-1
|
||||
h15.4199829v-0.0100098l1.7000122-4.8899536H10.8887787c-0.5599976,0-1-0.4500122-1-1c0-0.5500488,0.4400024-1,1-1H28.708786
|
||||
l0.0999756-0.3000488c0.1699829-0.4699707,0.4400024-0.8800049,0.789978-1.1900024l3.4000244-3.4099731H10.8887787
|
||||
c-0.5599976,0-1-0.4500122-1-1S10.3287811,25.5499878,10.8887787,25.5499878z M10.8887787,46.25h24.9099731
|
||||
c0.5599976,0,1,0.4500122,1,1s-0.4400024,1-1,1H10.8887787c-0.5599976,0-1-0.4500122-1-1S10.3287811,46.25,10.8887787,46.25z
|
||||
M10.8887787,11.75h24.9099731c0.5599976,0,1,0.4500122,1,1s-0.4400024,1-1,1H10.8887787c-0.5599976,0-1-0.4500122-1-1
|
||||
S10.3287811,11.75,10.8887787,11.75z M10.8887787,18.6499634h24.9099731c0.5599976,0,1,0.4500122,1,1c0,0.5500488-0.4400024,1-1,1
|
||||
H10.8887787c-0.5599976,0-1-0.4499512-1-1C9.8887787,19.0999756,10.3287811,18.6499634,10.8887787,18.6499634z"></path><path fill="#3B4652" d="M30.9387665,32.4400024c-0.1099854,0.0999756-0.1900024,0.2299805-0.2399902,0.3699951
|
||||
l-2.5100098,7.2099609c-0.1300049,0.3600464-0.039978,0.7700195,0.2299805,1.0400391
|
||||
c0.2000122,0.1900024,0.4500122,0.289978,0.710022,0.289978c0.1099854,0,0.2199707-0.0200195,0.3300171-0.0599976
|
||||
l7.2099609-2.5100098c0.1400146-0.0499878,0.2700195-0.1300049,0.3800049-0.2399902l12.5599976-12.5599976l-5.9299927-6.2799683
|
||||
L30.9387665,32.4400024z"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
@@ -1,24 +1,26 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import * as Yup from "yup";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import usersService from "../../services/UsersService";
|
||||
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
country: Yup.string()
|
||||
.min(1, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Country is required"),
|
||||
price: Yup.number()
|
||||
.typeError("you must specify a number")
|
||||
price: Yup.string()
|
||||
.typeError("Invalid number")
|
||||
.min(1, "Price must be greater than 0")
|
||||
.test("no-e", "Invalid number", (value) => {
|
||||
if (value && /\d+e/.test(value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.required("Price is required"),
|
||||
title: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
@@ -36,28 +38,29 @@ const validationSchema = Yup.object().shape({
|
||||
.typeError("you must specify a number")
|
||||
.min(1, "Price must be greater than 0")
|
||||
.required("Timeline is required"),
|
||||
category: Yup.array().min(1, "Select at least one checkbox"),
|
||||
});
|
||||
|
||||
function AddJob({ popUpHandler }) {
|
||||
function AddJob({ popUpHandler, categories }) {
|
||||
const ApiCall = new usersService();
|
||||
|
||||
let dispatch = useDispatch();
|
||||
|
||||
let { userDetails } = useSelector((state) => state.userDetails);
|
||||
|
||||
let [country, setCountry] = useState({
|
||||
let [currency, setCurrency] = useState({
|
||||
loading: true,
|
||||
status: false,
|
||||
data: [],
|
||||
}); // To Hold the array of country getUserCountry returns
|
||||
data: null,
|
||||
}); // To Hold the array of currency getUserCurrency returns
|
||||
|
||||
let initialValues = {
|
||||
// initial values for formik
|
||||
country: userDetails.country,
|
||||
country: "",
|
||||
price: "",
|
||||
title: "",
|
||||
description: "",
|
||||
job_detail: "",
|
||||
timeline_days: "",
|
||||
category: [],
|
||||
};
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
@@ -66,30 +69,42 @@ function AddJob({ popUpHandler }) {
|
||||
message: "",
|
||||
}); // Holds state when submit button is pressed
|
||||
|
||||
// FUNCTION TO GET COUNTRY
|
||||
const getUserCountry = () => {
|
||||
setCountry((prev) => ({ ...prev, loading: true }));
|
||||
ApiCall.getSignupCountryData()
|
||||
// FUNCTION TO GET Currency
|
||||
const getUserCurrency = () => {
|
||||
setCurrency((prev) => ({ ...prev, loading: true }));
|
||||
ApiCall.getUserWallets()
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 1) {
|
||||
setCountry({ loading: false, status: true, data: [] });
|
||||
if (res.data.internal_return < 0) {
|
||||
setCurrency({ loading: false, status: true, data: [] });
|
||||
return;
|
||||
}
|
||||
setCountry({
|
||||
console.log("Res for currency >> ", res);
|
||||
|
||||
setCurrency({
|
||||
loading: false,
|
||||
status: true,
|
||||
data: res.data.signup_country,
|
||||
data: res.data.result_list,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setCountry({ loading: false, status: false, data: [] });
|
||||
setCurrency({ loading: false, status: false, data: [] });
|
||||
});
|
||||
};
|
||||
|
||||
// FUNCTION TO HANDLE ADD JOB FORM
|
||||
const handleAddJob = (values, helpers) => {
|
||||
let reqData = {
|
||||
country: values?.country,
|
||||
price: Number(values.price) * 100,
|
||||
title: values?.title,
|
||||
description: values?.description,
|
||||
job_detail: values?.job_detail,
|
||||
timeline_days: values?.timeline_days,
|
||||
category: values.category?.join("@"),
|
||||
};
|
||||
|
||||
setRequestStatus({ loading: true, status: false, message: "" });
|
||||
ApiCall.jobManagerCreateJob(values)
|
||||
ApiCall.jobManagerCreateJob(reqData)
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 1) {
|
||||
setRequestStatus({
|
||||
@@ -97,6 +112,9 @@ function AddJob({ popUpHandler }) {
|
||||
status: false,
|
||||
message: "Could not complete your request at the moment",
|
||||
});
|
||||
setTimeout(() => {
|
||||
popUpHandler();
|
||||
}, 1500);
|
||||
return;
|
||||
}
|
||||
setRequestStatus({
|
||||
@@ -106,14 +124,14 @@ function AddJob({ popUpHandler }) {
|
||||
});
|
||||
setTimeout(() => {
|
||||
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||
popUpHandler()
|
||||
popUpHandler();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Opps! soemthing went wrong. Try Again",
|
||||
message: "Opps! something went wrong. Try Again",
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -124,7 +142,7 @@ function AddJob({ popUpHandler }) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUserCountry();
|
||||
getUserCurrency();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -140,46 +158,44 @@ function AddJob({ popUpHandler }) {
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="fields w-full">
|
||||
{/* inputs starts here */}
|
||||
{/* country */}
|
||||
<div className="xl:flex xl:space-x-7 mb-6">
|
||||
<div className="xl:flex xl:space-x-7 mb-[5px]">
|
||||
<div className="field w-full mb-6 xl:mb-0">
|
||||
<label
|
||||
htmlFor="country"
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||
>
|
||||
Country
|
||||
Currency
|
||||
</label>
|
||||
<select
|
||||
id="country"
|
||||
name="country"
|
||||
disabled
|
||||
value={props.values.country}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none ${
|
||||
props.errors.country && props.touched.country
|
||||
? "border-[#ff0a0a63] shadow-red-500 border-[0.5px] animate-shake"
|
||||
: "border border-[#f5f8fa] dark:border-[#5e6278]"
|
||||
}`}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
>
|
||||
{country.loading ? (
|
||||
{currency.loading ? (
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
Loading...
|
||||
</option>
|
||||
) : country.data.length ? (
|
||||
) : currency.data.length ? (
|
||||
<>
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
Select...
|
||||
Select a currency
|
||||
</option>
|
||||
{country.data.map((item, index) => {
|
||||
if (item[0] == userDetails.country) {
|
||||
return (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item[0]}
|
||||
>
|
||||
{item[1]}
|
||||
</option>
|
||||
);
|
||||
}
|
||||
})}
|
||||
{currency.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item?.country}
|
||||
>
|
||||
{item?.description}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
@@ -187,11 +203,6 @@ function AddJob({ popUpHandler }) {
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
{props.errors.country && props.touched.country && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.country}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Price */}
|
||||
@@ -207,18 +218,14 @@ function AddJob({ popUpHandler }) {
|
||||
value={props.values.price}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
errorBorder={props.errors.price && props.touched.price}
|
||||
/>
|
||||
{props.errors.price && props.touched.price && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.price}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
|
||||
<div className="field w-full mb-6">
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Title"
|
||||
@@ -226,20 +233,15 @@ function AddJob({ popUpHandler }) {
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="title"
|
||||
// placeholder="Enter Job Title"
|
||||
value={props.values.title}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
errorBorder={props.errors.title && props.touched.title}
|
||||
/>
|
||||
{props.errors.title && props.touched.title && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.title}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div className="field w-full mb-6">
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Description"
|
||||
@@ -247,44 +249,76 @@ function AddJob({ popUpHandler }) {
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="description"
|
||||
// placeholder="Enter a description"
|
||||
value={props.values.description}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
errorBorder={
|
||||
props.errors.description && props.touched.description
|
||||
}
|
||||
/>
|
||||
{props.errors.description && props.touched.description && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
<div className="field w-full mb-6">
|
||||
<label
|
||||
htmlFor="Job Delivery Details"
|
||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||
>
|
||||
Job Delivery Details
|
||||
</label>
|
||||
<textarea
|
||||
id="Job Delivery Details"
|
||||
rows="7"
|
||||
className={`input-field p-6 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={props.values.job_detail}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
/>
|
||||
{props.errors.job_detail && props.touched.job_detail && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.job_detail}
|
||||
</p>
|
||||
)}
|
||||
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
|
||||
<div className="sm:w-[60%] w-full">
|
||||
<label
|
||||
htmlFor="Job Delivery Details"
|
||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||
>
|
||||
Job Delivery Details
|
||||
</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] ${
|
||||
props.errors.job_detail && props.touched.job_detail
|
||||
? "border-[#ff0a0a63] shadow-red-500 border-[0.5px] animate-shake"
|
||||
: "border border-[#f5f8fa] dark:border-[#5e6278]"
|
||||
} rounded-[10px]`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={props.values.job_detail}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="sm:w-[35%] w-full">
|
||||
<div
|
||||
htmlFor="Job Categories"
|
||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||
id="checked-group"
|
||||
>
|
||||
Categories
|
||||
</div>
|
||||
<div
|
||||
className="sm:flex-col flex flex-wrap px-3 mt-3"
|
||||
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>
|
||||
</label>
|
||||
))}
|
||||
<span className="h-5 text-sm italic text-[#cf3917]">
|
||||
{props.errors.category &&
|
||||
props.touched.category &&
|
||||
"please select a category"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field w-full mb-6">
|
||||
<div className="field w-full mb-[5px]">
|
||||
<div className={`flex items-center justify-between mb-2.5`}>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||
@@ -300,7 +334,12 @@ function AddJob({ popUpHandler }) {
|
||||
<Field
|
||||
component="select"
|
||||
name="timeline_days"
|
||||
className="input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none"
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none ${
|
||||
props.errors.timeline_days &&
|
||||
props.touched.timeline_days
|
||||
? "border-[#ff0a0a63] shadow-red-500 border-[0.5px] animate-shake"
|
||||
: "border border-[#f5f8fa] dark:border-[#5e6278]"
|
||||
}`}
|
||||
value={props.values.timeline_days}
|
||||
>
|
||||
<option value="">Select Duration</option>
|
||||
@@ -313,12 +352,6 @@ function AddJob({ popUpHandler }) {
|
||||
</option>
|
||||
))}
|
||||
</Field>
|
||||
{props.errors.timeline_days &&
|
||||
props.touched.timeline_days && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.timeline_days}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{/* inputs ends here */}
|
||||
</div>
|
||||
@@ -345,17 +378,20 @@ function AddJob({ popUpHandler }) {
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
|
||||
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||
<div className="w-full h-[70px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||
<div className="flex items-center space-x-4 mr-9">
|
||||
<Link
|
||||
to="/myjobs"
|
||||
<button
|
||||
type="button"
|
||||
className="text-18 text-light-red tracking-wide "
|
||||
>
|
||||
<span className="border-b dark:border-[#5356fb29] border-light-red">
|
||||
<span
|
||||
className="border-b dark:border-[#5356fb29] border-light-red"
|
||||
onClick={popUpHandler}
|
||||
>
|
||||
{" "}
|
||||
Cancel
|
||||
</span>
|
||||
</Link>
|
||||
</button>
|
||||
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
@@ -393,3 +429,10 @@ const publicArray = [
|
||||
{ duration: 21, name: "3 weeks" },
|
||||
{ duration: 28, name: "4 weeks" },
|
||||
];
|
||||
|
||||
// .test("no-e", "Invalid number", (value) => {
|
||||
// if (value && /\d+e/.test(value)) {
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// })
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function CollectionTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<CollectionCard key={datas.uniqKey} collectionData={datas} />
|
||||
|
||||
@@ -42,7 +42,9 @@ export default function CreateSaleSlider({
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Sell</h1>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Create for Sell
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button onClick={nextHandler} type="button">
|
||||
@@ -89,7 +91,7 @@ export default function CreateSaleSlider({
|
||||
<div className="trending-products relative w-full">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{products &&
|
||||
products.length > 0 &&
|
||||
products?.length > 0 &&
|
||||
products.map((item) => (
|
||||
<ProductCardStyleTwo
|
||||
key={item.id}
|
||||
|
||||
@@ -49,7 +49,9 @@ export default function CreatedBidsSlider({
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Bits</h1>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Create for Bits
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button onClick={nextHandler} type="button">
|
||||
@@ -96,7 +98,7 @@ export default function CreatedBidsSlider({
|
||||
<div className="trending-products relative w-full">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{products &&
|
||||
products.length > 0 &&
|
||||
products?.length > 0 &&
|
||||
products.map((item) => (
|
||||
<ProductCardStyleOne
|
||||
key={item.id}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function OnSaleTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<ProductCardStyleTwo key={datas.id} datas={datas} />
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function OwnTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<ProductCardStyleOne key={datas.id} datas={datas} />
|
||||
|
||||
@@ -18,6 +18,9 @@ export default function Login() {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
let [loginType, setLoginType] = useState({ full: true, family: false });
|
||||
const [selectedLoginType, setSelectedLoginType] = useState(
|
||||
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
|
||||
);
|
||||
|
||||
const [checked, setValue] = useState(false);
|
||||
const [loginLoading, setLoginLoading] = useState(false);
|
||||
@@ -77,6 +80,10 @@ export default function Login() {
|
||||
login_mode: 1100,
|
||||
action: 11025,
|
||||
};
|
||||
|
||||
// Clear the loginType cookie if the user switches to loginfull
|
||||
document.cookie =
|
||||
"loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
} else if (name == "loginfamily") {
|
||||
// Post Data Info for family Login
|
||||
postData = {
|
||||
@@ -86,6 +93,8 @@ export default function Login() {
|
||||
login_mode: 1105,
|
||||
action: 11025,
|
||||
};
|
||||
// Set the loginType cookie to remember the user's selection
|
||||
document.cookie = "loginType=family; expires=Session; path=/;";
|
||||
} else {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Login Type. Consider refreshing the page");
|
||||
@@ -127,15 +136,22 @@ export default function Login() {
|
||||
};
|
||||
|
||||
const googleLogin = useGoogleLogin({
|
||||
flow: 'auth-code',
|
||||
ux_mode:'redirect',
|
||||
flow: "auth-code",
|
||||
ux_mode: "redirect",
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
onSuccess: async (codeResponse) => {
|
||||
console.log("GOOGLE LOGIN GOOD --- ",codeResponse);
|
||||
console.log("GOOGLE LOGIN GOOD --- ", codeResponse);
|
||||
},
|
||||
onError: (errorResponse) => console.log(errorResponse),
|
||||
});
|
||||
|
||||
// In order to update the selected login type whenever the component renders
|
||||
useEffect(() => {
|
||||
setSelectedLoginType(
|
||||
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setMail("");
|
||||
setPassword("");
|
||||
|
||||
@@ -80,7 +80,7 @@ export default function SignUp() {
|
||||
|
||||
if (res.status === 200) {
|
||||
const { data } = res;
|
||||
if (data.status === -1 && data.acc === "DULPICATE") {
|
||||
if (data && data.acc === "DULPICATE") {
|
||||
setMsgError("This account has been already created");
|
||||
setSignUpLoading(false);
|
||||
}
|
||||
@@ -108,12 +108,12 @@ export default function SignUp() {
|
||||
|
||||
useEffect(() => {
|
||||
getCountryList();
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="layout-wrapper login">
|
||||
<div className="main-wrapper w-full xl:h-screen h-full xl:py-10 py-12 overflow-y-auto">
|
||||
<div className="main-wrapper login-wrapper w-full xl:h-screen h-full xl:py-10 py-12 overflow-y-auto">
|
||||
<div className=" h-full">
|
||||
<div className="flex-1 flex justify-center items-center">
|
||||
<div className="w-full">
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function CollectionTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<CollectionCard key={datas.uniqKey} collectionData={datas} />
|
||||
|
||||
@@ -42,7 +42,9 @@ export default function CreateSaleSlider({
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Sell</h1>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Create for Sell
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button onClick={nextHandler} type="button">
|
||||
@@ -89,7 +91,7 @@ export default function CreateSaleSlider({
|
||||
<div className="trending-products relative w-full">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{products &&
|
||||
products.length > 0 &&
|
||||
products?.length > 0 &&
|
||||
products.map((item) => (
|
||||
<ProductCardStyleTwo
|
||||
key={item.id}
|
||||
|
||||
@@ -49,7 +49,9 @@ export default function CreatedBidsSlider({
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Bits</h1>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Create for Bits
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button onClick={nextHandler} type="button">
|
||||
@@ -96,7 +98,7 @@ export default function CreatedBidsSlider({
|
||||
<div className="trending-products relative w-full">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{products &&
|
||||
products.length > 0 &&
|
||||
products?.length > 0 &&
|
||||
products.map((item) => (
|
||||
<ProductCardStyleOne
|
||||
key={item.id}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function OnSaleTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<ProductCardStyleTwo key={datas.id} datas={datas} />
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function OwnTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<ProductCardStyleOne key={datas.id} datas={datas} />
|
||||
|
||||
@@ -1,57 +1,33 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Link, useNavigate, } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import Icons from "../Helpers/Icons";
|
||||
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 dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||
|
||||
export default function AvailableJobsCard({
|
||||
className,
|
||||
datas,
|
||||
hidden = false,
|
||||
contentDisplay
|
||||
}) {
|
||||
//debugger;
|
||||
const [addFavorite, setValue] = useState(datas.whishlisted);
|
||||
const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} });
|
||||
const [manageInt, setManageInt] = useState(null)
|
||||
const [imageUrl, setImageUrl] = useState("");
|
||||
|
||||
const navigate = useNavigate();
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
|
||||
const favoriteHandler = () => {
|
||||
if (!addFavorite) {
|
||||
setValue(true);
|
||||
toast.success("Added to Favorite List");
|
||||
} else {
|
||||
setValue(false);
|
||||
toast.warn("Remove to Favorite List");
|
||||
}
|
||||
};
|
||||
|
||||
const marketInterestData = useCallback(async() => {
|
||||
let { offer_code } = datas;
|
||||
let reqData = { offer_code };
|
||||
|
||||
try {
|
||||
const manageInt = await apiCall.MarketInterest(reqData);
|
||||
const manageIntRes = await manageInt?.data;
|
||||
setManageInt(manageIntRes)
|
||||
} catch (error) {
|
||||
throw new Error(error)
|
||||
}
|
||||
|
||||
}, [])
|
||||
let thePrice = PriceFormatter(
|
||||
datas?.price * 0.01,
|
||||
datas?.currency_code,
|
||||
datas?.currency
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!datas) {
|
||||
navigate("/market", { replace: true });
|
||||
}
|
||||
marketInterestData()
|
||||
}, [marketInterestData, datas])
|
||||
const imagePath = require(`../../assets/images/${datas.thumbnil}`); // Replace with your directory path for local images
|
||||
setImageUrl(imagePath);
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
{contentDisplay == 'grid' ?
|
||||
<div
|
||||
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
@@ -87,11 +63,9 @@ export default function AvailableJobsCard({
|
||||
</div>
|
||||
<div className="thumbnail-area w-full">
|
||||
<div
|
||||
className="w-full h-[236px] p-6 rounded-xl overflow-hidden"
|
||||
className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-center bg-cover bg-no-repeat"
|
||||
style={{
|
||||
background: `url(${localImgLoad(
|
||||
`images/${datas.thumbnil}`
|
||||
)}) 0% 0% / cover no-repeat`,
|
||||
backgroundImage: `url('${imageUrl}')`,
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-center">{datas.description}</div>
|
||||
@@ -124,11 +98,14 @@ export default function AvailableJobsCard({
|
||||
<div className="flex items-center space-x-2">
|
||||
<div>
|
||||
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
|
||||
{datas.price * 0.01}
|
||||
{datas.currency} | {datas.timeline_days} day(s)
|
||||
{/* {thePrice} | {datas.timeline_days} day(s) */}
|
||||
{thePrice}
|
||||
</p>
|
||||
<p className="text-sm text-lighter-gray">
|
||||
( {datas.offer_code})
|
||||
( {datas.offer_code}) |
|
||||
<span className="italic ml-1">
|
||||
{datas.timeline_days} day(s)
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,7 +114,7 @@ export default function AvailableJobsCard({
|
||||
type="button"
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
onClick={() => {
|
||||
setMarketPopUp({show: true, data: datas})
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
>
|
||||
View
|
||||
@@ -147,6 +124,78 @@ export default function AvailableJobsCard({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
|
||||
<div className="flex gap-5 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||
<img src={dataImage2} alt="data" className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<Link to="/shop-details" className="">
|
||||
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||
{datas?.title}
|
||||
</h1>
|
||||
</Link>
|
||||
|
||||
<div className="my-2">
|
||||
<p className="text-dark-gray dark:text-white">{datas?.description}</p>
|
||||
</div>
|
||||
|
||||
{/* <div className="card-two-info flex gap-2 items-center">
|
||||
<div className="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>
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple italic">
|
||||
{" "}
|
||||
{datas?.timeline_days} day(s)
|
||||
</span>
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray">
|
||||
Code:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{datas?.offer_code}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="">
|
||||
<button
|
||||
type="button"
|
||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||
onClick={() => {
|
||||
setMarketPopUp({ show: true, data: datas });
|
||||
}}
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
{marketPopUp.show && (
|
||||
<MarketPopUp
|
||||
details={datas}
|
||||
@@ -154,7 +203,6 @@ export default function AvailableJobsCard({
|
||||
setMarketPopUp({ show: false, data: {} });
|
||||
}}
|
||||
situation={marketPopUp.show}
|
||||
marketInt={manageInt}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -9,7 +9,6 @@ export default function HomeBannerOffersCard(props) {
|
||||
let { banner, banner_location } = props?.itemData;
|
||||
if (banner_location === "LOCAL") {
|
||||
const imagePath = require(`../../assets/images/${banner}`); // Replace with your directory path for local images
|
||||
console.log("This is local");
|
||||
setImageUrl(imagePath);
|
||||
} else if (banner_location === "URL") setImageUrl(banner);
|
||||
else return null;
|
||||
@@ -24,21 +23,20 @@ export default function HomeBannerOffersCard(props) {
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col justify-between h-full">
|
||||
<div className="content flex justify-between items-center mb-5">
|
||||
<div className="content flex justify-between items-center">
|
||||
<div className="siderCardHeader">
|
||||
<h1 className="text-2xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
<span className="heroSilderTitle">{props.itemData.title}</span>
|
||||
</h1>
|
||||
</div>
|
||||
{/*<SelectBox datas={filterDatas} action={dataSetHandler} />*/}
|
||||
</div>
|
||||
<div className="h-[233px]">
|
||||
<div className="flex flex-col justify-around items-center flex-1">
|
||||
<div className="siderCardDescription">
|
||||
{props.itemData.description}
|
||||
</div>
|
||||
<div className="siderCardButton">
|
||||
[ {props.itemData.button_text} ]
|
||||
</div>
|
||||
<button className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
{props.itemData.button_text}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
@@ -6,6 +6,7 @@ import CountDown from "../Helpers/CountDown";
|
||||
import Icons from "../Helpers/Icons";
|
||||
|
||||
export default function ProductCardStyleOne({ datas, hidden = false }) {
|
||||
const [imageUrl, setImageUrl] = useState("");
|
||||
const [addFavorite, setValue] = useState(false);
|
||||
const [options, setOption] = useState(false);
|
||||
const favoriteHandler = () => {
|
||||
@@ -17,6 +18,8 @@ export default function ProductCardStyleOne({ datas, hidden = false }) {
|
||||
toast.warn("Remove to Favorite List");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
|
||||
<div className="content">
|
||||
|
||||
@@ -11,6 +11,7 @@ export default function FamilyManage() {
|
||||
let location = useLocation();
|
||||
let navigate = useNavigate();
|
||||
let accountDetails = location?.state;
|
||||
|
||||
// tab handler
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
import React, {useState, useEffect} from 'react'
|
||||
import ModalCom from '../../Helpers/ModalCom'
|
||||
import Detail from '../../jobPopout/popoutcomponent/Detail'
|
||||
import usersService from '../../../services/UsersService'
|
||||
import LoadingSpinner from '../../Spinners/LoadingSpinner'
|
||||
import { PriceFormatter } from '../../Helpers/PriceFormatter'
|
||||
|
||||
function AssignTaskPopout({action, situation, familyDetails}) {
|
||||
const apiCall = new usersService()
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: ''}) // HOLDS RESPONSE FOR SENDING API REQUEST
|
||||
|
||||
let [familyTask, setFamilyTask] = useState({loading: true, data: []})
|
||||
|
||||
let [taskType, setTaskType] = useState('select') // SWITCHES BTW SELECT TASK AND NEW TASK
|
||||
|
||||
let [activeTask, setActiveTask] = useState({id: 0, data: {}}) // HOLDS SELECTED TASK
|
||||
|
||||
const switchTaskType = ({target:{value}}) => { // FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setTaskType(value)
|
||||
}
|
||||
|
||||
const handleActiveTask = (id=0, data={}) => { // FUNCTION TO CHANGE SELECTED ACTIVE TASK
|
||||
setActiveTask({id, data})
|
||||
}
|
||||
|
||||
const assignFamilyTask = () => {
|
||||
setRequestStatus({loading: true, status: false, message: ''})
|
||||
let reqData = {}
|
||||
if(taskType == 'select'){ // RUNS HERE IF TASK TYPE IS SELECT
|
||||
if(!Object.keys(activeTask.data).length){
|
||||
setRequestStatus({loading: false, status: false, message: 'No Task is seleted'})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
}, 3000)
|
||||
}
|
||||
reqData = { // API PAYLOADS
|
||||
job_id: activeTask.data?.job_id,
|
||||
job_uid: activeTask.data?.job_uid,
|
||||
family_uid: familyDetails.uid,
|
||||
job_description: activeTask.data?.description,
|
||||
assign_mode: 110011,
|
||||
}
|
||||
|
||||
apiCall.assignFamilyTask(reqData).then(res => {
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
setRequestStatus({loading: false, status: false, message: 'failed to assign task'})
|
||||
return setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
}, 5000)
|
||||
}
|
||||
setRequestStatus({loading: false, status: true, message: 'action successful'})
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
action() // FUNCTION THAT CLOSES THE MODAL BOX
|
||||
}, 5000)
|
||||
}).catch(err => {
|
||||
setRequestStatus({loading: false, status: false, message: 'An Error occured, try again'})
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({loading: false, status: false, message: ''})
|
||||
}, 5000)
|
||||
})
|
||||
}
|
||||
|
||||
if(taskType == 'new'){ // RUNS HERE IF TASK TYPE IS NEW TASK
|
||||
console.log('TESTING')
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
const reqData = {
|
||||
limit: 30,
|
||||
offset: 0,
|
||||
job_type: 'FAMILY',
|
||||
action: 13005
|
||||
}
|
||||
apiCall.getMyJobList(reqData).then(res => {
|
||||
setFamilyTask({loading: false, data: res?.data?.result_list})
|
||||
if(res?.data?.result_list?.length){
|
||||
setActiveTask(prev => ({...prev, data:res?.data?.result_list[0]}))
|
||||
}
|
||||
}).catch(err => {
|
||||
setFamilyTask({loading: false, data: []})
|
||||
console.log('Error', err)
|
||||
})
|
||||
},[])
|
||||
return (
|
||||
<>
|
||||
<ModalCom
|
||||
action={action}
|
||||
situation={situation}
|
||||
>
|
||||
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Assign task to {familyDetails?.firstname}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={action}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{familyTask.loading ?
|
||||
<div className='h-[100px] w-full flex justify-center items-center'>
|
||||
<LoadingSpinner color='sky-blue' size='16' />
|
||||
</div>
|
||||
:
|
||||
<>
|
||||
<div className="job-action-modal-body w-full md:grid md:grid-cols-2">
|
||||
<div className="p-4">
|
||||
<div className="mb-2 w-full flex items-center gap-4">
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input type="radio" name='task-type' value='select' className="w-[20px] h-[20px] cursor-pointer" checked={taskType=='select'} onChange={switchTaskType}/>
|
||||
<span>Select Task</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input type="radio" name='task-type' value='new' className="w-[20px] h-[20px] cursor-pointer" checked={taskType=='new'} onChange={switchTaskType}/>
|
||||
<span>New Task</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='p-4 w-full h-[400px] overflow-y-auto bg-slate-100'>
|
||||
{
|
||||
taskType == 'select' ?
|
||||
familyTask?.data?.length ?
|
||||
familyTask?.data?.map((item, index)=>(
|
||||
<div key={item.job_uid} className="mb-2 flex justify-start items-center gap-2 text-sky-blue text-base cursor-pointer" onClick={()=>handleActiveTask(item.job_uid, item)}>
|
||||
<input
|
||||
type="radio"
|
||||
name='task-list'
|
||||
checked={(activeTask.id == item.job_uid) || (activeTask.id==index)&& true}
|
||||
onChange={()=>handleActiveTask(item.job_uid, item)}
|
||||
className="w-[15px] h-[15px] cursor-pointer"
|
||||
/>
|
||||
<p className="text-dark-gray tracking-wide">{item?.title}</p>
|
||||
</div>
|
||||
))
|
||||
:
|
||||
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center">No Task found!</p>
|
||||
:
|
||||
<p className="p-8 text-lg text-dark-gray dark:text-white tracking-wide text-center">SPACE FOR NEW TASK</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{familyTask?.data?.length > 0 ?
|
||||
<div className="p-4">
|
||||
<div className="w-full">
|
||||
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">{activeTask?.data?.title}</p>
|
||||
<div className="my-3">
|
||||
<Detail label="Description" value={activeTask?.data?.description} />
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className='text-slate-900 dark:text-white tracking-wide font-semibold'>Price</label>
|
||||
<p className='p-1 text-sm text-slate-900 dark:text-white'>{PriceFormatter(activeTask?.data?.price*0.01, activeTask?.data?.currency, activeTask?.data?.curreny_code)}</p>
|
||||
</div>
|
||||
|
||||
<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}
|
||||
/>
|
||||
{/* <p>{}</p> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<></>
|
||||
}
|
||||
</div>
|
||||
|
||||
{/* BTN */}
|
||||
<div className='p-2 border-t-2 flex justify-end items-center gap-3'>
|
||||
{/* error or success display */}
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-2 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
<div
|
||||
className={`relative p-2 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
<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' />
|
||||
:
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
>
|
||||
Assign
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</ModalCom>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssignTaskPopout
|
||||
@@ -14,6 +14,9 @@ import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import profile from "../../../assets/images/profile-info-profile.png";
|
||||
import FamilyTasks from "./FamilyTasks";
|
||||
|
||||
import AssignTaskPopout from '../FamilyPopout/AssignTaskPopout'
|
||||
|
||||
|
||||
export default function FamilyManageTabs({
|
||||
className,
|
||||
accountDetails,
|
||||
@@ -50,6 +53,13 @@ export default function FamilyManageTabs({
|
||||
const tabHandler = (value) => {
|
||||
setTab(value);
|
||||
};
|
||||
|
||||
let [familyTaskPopout, setFamilyTaskPopout] = useState(false) // DETERMINES WHEN FAMILY ADD TASK POPOUT DISPLAYS
|
||||
|
||||
const familyPopUpHandler = () => { // FUNCTION TO CHANGE THE FAMILY ADD TASK POPOIUT STATE
|
||||
setFamilyTaskPopout(prev => !prev)
|
||||
}
|
||||
|
||||
// For profile uploads
|
||||
const [profileImg, setProfileImg] = useState(profile);
|
||||
// profile img
|
||||
@@ -120,7 +130,7 @@ export default function FamilyManageTabs({
|
||||
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
>
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<Suspense
|
||||
fallback={
|
||||
@@ -141,21 +151,31 @@ export default function FamilyManageTabs({
|
||||
</div>
|
||||
<div className="col-span-3 justify-self-end h-full w-full">
|
||||
<div className="flex flex-col w-full">
|
||||
<ul className="flex-[0.1] flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
|
||||
{tabs.map(({ name, id }) => (
|
||||
<li
|
||||
onClick={() => tabHandler(name)}
|
||||
className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl ${
|
||||
tab === name
|
||||
? "text-purple border-r"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
key={id}
|
||||
>
|
||||
<h1>{name}</h1>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="w-full pr-8 flex items-center gap-1">
|
||||
<ul className="flex gap-2 items-center border-b border-b-[#FAFAF] w-full">
|
||||
{tabs.map(({ name, id }) => (
|
||||
<li
|
||||
onClick={() => tabHandler(name)}
|
||||
className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl ${
|
||||
tab === name
|
||||
? "text-purple border-r"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
key={id}
|
||||
>
|
||||
<h1>{name}</h1>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<button
|
||||
type="button"
|
||||
onClick={familyPopUpHandler}
|
||||
className="p-1 my-1 w-[100px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Add task
|
||||
{/* {accountDetails?.firstname} */}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-[0.9] lg:min-h-[450px] h-full">
|
||||
{/* Your content here */}
|
||||
{tabs.map(({ name, id }) => {
|
||||
@@ -171,6 +191,7 @@ export default function FamilyManageTabs({
|
||||
className={className}
|
||||
loader={details.familyTasks.loading}
|
||||
familyData={details.familyTasks.data}
|
||||
accountDetails={accountDetails}
|
||||
/>
|
||||
)}
|
||||
{name === "Account" && (
|
||||
@@ -191,6 +212,15 @@ export default function FamilyManageTabs({
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
{/* FAMILY ADD TASK POPOUT */}
|
||||
{familyTaskPopout &&
|
||||
<AssignTaskPopout
|
||||
action={familyPopUpHandler}
|
||||
situation={familyTaskPopout}
|
||||
familyDetails={details.familyDetails.data}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import PaginatedList from "../../Pagination/PaginatedList";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import Icons from "../../Helpers/Icons";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import Detail from "../../jobPopout/popoutcomponent/Detail";
|
||||
|
||||
export default function FamilyTasks({ familyData, className, loader }) {
|
||||
|
||||
export default function FamilyTasks({ familyData, className, loader, accountDetails }) {
|
||||
let navigate = useNavigate();
|
||||
let { pathname } = useLocation();
|
||||
|
||||
@@ -34,7 +37,6 @@ export default function FamilyTasks({ familyData, className, loader }) {
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{" "}
|
||||
{familyData && familyData?.result_list && (
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
@@ -72,7 +74,7 @@ export default function FamilyTasks({ familyData, className, loader }) {
|
||||
{value.title}
|
||||
</h1>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
<span className="text-sm text-thin-light-gray flex flex-start gap-1">
|
||||
Price:{" "}
|
||||
<span className="text-purple">
|
||||
{thePrice}
|
||||
@@ -105,9 +107,8 @@ export default function FamilyTasks({ familyData, className, loader }) {
|
||||
state: {
|
||||
...value,
|
||||
pathname,
|
||||
dueDate,
|
||||
thePrice,
|
||||
},
|
||||
accountDetails
|
||||
}
|
||||
});
|
||||
}}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
|
||||
@@ -1,59 +1,64 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function CountDown({ lastDate = "" }) {
|
||||
// const [showDate, setDate] = useState(0);
|
||||
const [showHour, setHour] = useState(0);
|
||||
const [showMinute, setMinute] = useState(0);
|
||||
const [showSecound, setDateSecound] = useState(0);
|
||||
// count Down
|
||||
const provideDate = new Date(lastDate);
|
||||
// format date
|
||||
const year = provideDate.getFullYear();
|
||||
const month = provideDate.getMonth();
|
||||
// console.log(month);
|
||||
const date = provideDate.getDate();
|
||||
// console.log(date);
|
||||
const hours = provideDate.getHours();
|
||||
// console.log(hours);
|
||||
const minutes = provideDate.getMinutes();
|
||||
// console.log(minutes);
|
||||
const seconds = provideDate.getSeconds();
|
||||
// console.log(seconds);
|
||||
|
||||
// date calculation logic
|
||||
const _seconds = 1000;
|
||||
const _minutes = _seconds * 60;
|
||||
const _hours = _minutes * 60;
|
||||
const _date = _hours * 24;
|
||||
|
||||
// interval function
|
||||
const startInterval = () => {
|
||||
const timer = setInterval(() => {
|
||||
const now = new Date();
|
||||
const distance =
|
||||
new Date(year, month, date, hours, minutes, seconds).getTime() -
|
||||
now.getTime();
|
||||
if (distance < 0) {
|
||||
clearInterval(timer);
|
||||
return;
|
||||
}
|
||||
// setDate(Math.floor(distance / _date));
|
||||
setMinute(Math.floor((distance % _hours) / _minutes));
|
||||
setHour(Math.floor((distance % _date) / _hours));
|
||||
setDateSecound(Math.floor((distance % _minutes) / _seconds));
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// effect
|
||||
useEffect(() => {
|
||||
if (lastDate !== "") {
|
||||
startInterval();
|
||||
}
|
||||
// State to store the countdown values
|
||||
const [countdownValues, setCountdownValues] = useState({
|
||||
showHour: 0,
|
||||
showMinute: 0,
|
||||
showSecond: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (lastDate) {
|
||||
// Interval function to update countdown values
|
||||
const intervalId = setInterval(() => {
|
||||
const now = new Date().getTime();
|
||||
const targetDate = new Date(lastDate).getTime();
|
||||
const distance = targetDate - now;
|
||||
|
||||
if (distance < 0) {
|
||||
// If the countdown has reached zero or gone past the target date, clear the interval
|
||||
clearInterval(intervalId);
|
||||
setCountdownValues({
|
||||
showHour: 0,
|
||||
showMinute: 0,
|
||||
showSecond: 0,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the countdown values (days, hours, minutes, seconds)
|
||||
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
||||
const hours = Math.floor(
|
||||
(distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
|
||||
);
|
||||
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
||||
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
||||
|
||||
// since we don't have a slot for days...
|
||||
const totalHours = days * 24 + hours;
|
||||
|
||||
// Update the countdown values in the state
|
||||
setCountdownValues({
|
||||
showHour: totalHours,
|
||||
showMinute: minutes,
|
||||
showSecond: seconds,
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
// Clean up the interval on component unmount or when the lastDate prop changes
|
||||
return () => clearInterval(intervalId);
|
||||
}
|
||||
}, [lastDate]);
|
||||
|
||||
// Destructure the countdown values from the state
|
||||
const { showHour, showMinute, showSecond } = countdownValues;
|
||||
|
||||
return (
|
||||
<span>
|
||||
{showHour} : {showMinute} : {showSecound}
|
||||
{showHour < 10 ? "0" + showHour : showHour} :{" "}
|
||||
{showMinute < 10 ? "0" + showMinute : showMinute} :{" "}
|
||||
{showSecond < 10 ? "0" + showSecond : showSecond}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import React from "react";
|
||||
|
||||
import ATMCard from '../../assets/images/card.svg'
|
||||
import VisaCard from '../../assets/images/visa.svg'
|
||||
import MasterCard from '../../assets/images/master.svg'
|
||||
|
||||
export default function Icons({ name }) {
|
||||
return (
|
||||
<>
|
||||
@@ -483,6 +487,12 @@ export default function Icons({ name }) {
|
||||
c0.3,0,0.5-0.1,0.7-0.3l5.7-5.7c0,0,0,0,0,0C15.9,12.3,15.9,11.7,15.5,11.3z"
|
||||
></path>
|
||||
</svg>
|
||||
) : name === "atm-card" ? (
|
||||
<img className="w-[20px]" src={ATMCard} alt="card" />
|
||||
) : name === "visa-card" ? (
|
||||
<img className="w-[20px]" src={VisaCard} alt="card" />
|
||||
) : name === "master-card" ? (
|
||||
<img className="w-[20px]" src={MasterCard} alt="card" />
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useRef } from "react";
|
||||
import Icons from "../../Icons";
|
||||
import { Link } from "react-router-dom";
|
||||
import Icons from "../../Icons";
|
||||
|
||||
export default function InputCom({
|
||||
label,
|
||||
@@ -21,7 +21,8 @@ export default function InputCom({
|
||||
blurHandler,
|
||||
spanTag,
|
||||
inputBg,
|
||||
direction
|
||||
direction,
|
||||
errorBorder,
|
||||
}) {
|
||||
const inputRef = useRef(null);
|
||||
// Entry Validation
|
||||
@@ -40,8 +41,8 @@ export default function InputCom({
|
||||
// for Patterns
|
||||
const inputPatterns = () => {
|
||||
const inputConfig = inputConfigs[inputRef?.current?.name]?.pattern;
|
||||
return inputConfig || ""
|
||||
}
|
||||
return inputConfig || "";
|
||||
};
|
||||
return (
|
||||
<div className={`input-com ${parentClass}`}>
|
||||
<div className={`flex items-center justify-between mb-2.5 ${labelClass}`}>
|
||||
@@ -51,7 +52,12 @@ export default function InputCom({
|
||||
htmlFor={name}
|
||||
>
|
||||
{label}
|
||||
{spanTag && (
|
||||
{spanTag && spanTag == "*" ? (
|
||||
<span className="text-red-700 text-sm tracking-wide">
|
||||
{" "}
|
||||
{spanTag}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-green-700 text-sm tracking-wide">
|
||||
{spanTag}
|
||||
</span>
|
||||
@@ -68,7 +74,11 @@ export default function InputCom({
|
||||
)}
|
||||
</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 ${inputClass}`}
|
||||
className={`input-wrapper border ${
|
||||
errorBorder
|
||||
? "border-[#ff0a0a63] border-[0.5px] shadow-red-500 animate-shake"
|
||||
: "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 ${inputClass}`}
|
||||
>
|
||||
<input
|
||||
placeholder={placeholder}
|
||||
@@ -89,8 +99,10 @@ export default function InputCom({
|
||||
dir={direction}
|
||||
/>
|
||||
{iconName && (
|
||||
<div className="absolute right-6 bottom-[10px] z-10">
|
||||
<Icons name={iconName} />
|
||||
<div className="absolute right-6 bottom-[10px] z-10 flex gap-2">
|
||||
{iconName.split(" ").map((item, index) => (
|
||||
<Icons key={index} name={item} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{passIcon && (
|
||||
@@ -116,6 +128,7 @@ const inputConfigs = {
|
||||
province: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
||||
city: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
|
||||
amount: { minLength: 1, maxLength: 9, pattern: "[0-9]+" },
|
||||
description: { minLength: 5, maxLength: 250 },
|
||||
};
|
||||
|
||||
/* Numbers Only: <input type="text" pattern="[0-9]*" /> strictly numbers
|
||||
|
||||
@@ -1,16 +1,51 @@
|
||||
export const PriceFormatter = (price, currency, currencyName) => {
|
||||
const supportedCurrencies = ["USD", "EUR", "GBP"];
|
||||
const symbolFormatter = supportedCurrencies.includes(currency)
|
||||
? currency
|
||||
: undefined;
|
||||
import React from "react";
|
||||
|
||||
const formatter = new Intl.NumberFormat("en", {
|
||||
style: symbolFormatter,
|
||||
currencyDisplay: "symbol",
|
||||
minimumFractionDigits: 2,
|
||||
});
|
||||
// export const PriceFormatter = (price, currency, currencyName) => {
|
||||
// const supportedCurrencies = ["USD", "EUR", "GBP"];
|
||||
// const symbolFormatter = supportedCurrencies.includes(currency)
|
||||
// ? currency
|
||||
// : undefined;
|
||||
|
||||
const displayCurrencyName = symbolFormatter ? "" : currencyName;
|
||||
// const formatter = new Intl.NumberFormat("en", {
|
||||
// style: symbolFormatter,
|
||||
// currencyDisplay: "symbol",
|
||||
// minimumFractionDigits: 2,
|
||||
// });
|
||||
|
||||
return `${formatter.format(price)} ${displayCurrencyName}`;
|
||||
// const displayCurrencyName = symbolFormatter ? "" : currencyName;
|
||||
|
||||
// return `${formatter.format(price)} ${displayCurrencyName}`;
|
||||
// };
|
||||
|
||||
export const PriceFormatter = (
|
||||
price = "00",
|
||||
currency = "",
|
||||
currencyName = ""
|
||||
) => {
|
||||
// Convert the number to a string
|
||||
let numStr = String(price);
|
||||
|
||||
// Split the string into integer and decimal parts
|
||||
let parts = numStr.split(".");
|
||||
let integerPart = parts[0] || "";
|
||||
let decimalPart = parts[1] || "";
|
||||
|
||||
// Add thousands separators to the integer part
|
||||
// let formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
let formattedInteger = integerPart;
|
||||
|
||||
// Truncate or pad the decimal part to two decimal points
|
||||
let formattedDecimal = decimalPart.slice(0, 2).padEnd(2, "0");
|
||||
|
||||
// Combine the formatted integer and decimal parts
|
||||
// let formattedNumber = formattedInteger + '.' + formattedDecimal;
|
||||
|
||||
// return formattedNumber;
|
||||
return (
|
||||
<span className="text-sm flex items-center">
|
||||
<sup>{currency || currencyName || ""}</sup>
|
||||
<span className="px-1 font-bold text-lg">{formattedInteger || ""}</span>
|
||||
<sup>{formattedDecimal || ""}</sup>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import useToggle from "../../../hooks/useToggle";
|
||||
|
||||
function SelectBox({ datas = [], className, action, contentBodyClasses }) {
|
||||
function SelectBox({ datas = [], className, action, contentBodyClasses, position }) {
|
||||
const [item, setItem] = useState(datas[0]);
|
||||
// custom hook
|
||||
const [toggle, setToggle] = useToggle(false);
|
||||
@@ -49,7 +49,7 @@ function SelectBox({ datas = [], className, action, contentBodyClasses }) {
|
||||
|
||||
<div
|
||||
style={{ boxShadow: "0px 4px 87px 0px #0000002B" }}
|
||||
className={`drop-down-content w-[120px] bg-white dark:bg-dark-white rounded-[4px] p-3 absolute right-0 top-[100%] z-20 ${
|
||||
className={`drop-down-content w-[120px] bg-white dark:bg-dark-white rounded-[4px] p-3 absolute ${position =='left' ? 'left-0' : 'right-0'} top-[100%] z-20 ${
|
||||
toggle ? "active" : ""
|
||||
} ${contentBodyClasses || ""}`}
|
||||
>
|
||||
|
||||
@@ -13,7 +13,9 @@ import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
export default function History() {
|
||||
|
||||
const apiCall = new usersService()
|
||||
const apiCall = new usersService()
|
||||
|
||||
let [tab, setTab] = useState("purchases"); //STATE FOR SWITCHING BETWEEN TABS
|
||||
|
||||
let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY
|
||||
loading: true,
|
||||
@@ -63,7 +65,7 @@ export default function History() {
|
||||
<>
|
||||
<Layout>
|
||||
<div className="history-wrapper w-full mb-10">
|
||||
<div className="main-wrapper w-full">
|
||||
<div className="w-full">
|
||||
<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">
|
||||
@@ -213,33 +215,57 @@ export default function History() {
|
||||
{/*</div>*/}
|
||||
{/*<MarketHistorySection />*/}
|
||||
{/* <TopHxBox className="mb-11" /> */}
|
||||
<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>
|
||||
{/* PURCHASE SECTION */}
|
||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full max-h-[700px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1>
|
||||
{purchaseHistory.loading ?
|
||||
<LoadingSpinner size='16' color='sky-blue' />
|
||||
:
|
||||
<PurchasesTable purchase={purchaseHistory} />
|
||||
}
|
||||
</div>
|
||||
<div className='w-full p-4 md:p-8 bg-white dark:bg-dark-white rounded-2xl shadow bottomMargin'>
|
||||
{/* switch button */}
|
||||
<div className="my-1 flex items-center border-b border-slate-300">
|
||||
<button
|
||||
name="purchases"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "purchases" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
Purchases
|
||||
</button>
|
||||
<button
|
||||
name="recent"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "recent" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
Recent Activity
|
||||
</button>
|
||||
</div>
|
||||
{/* END OF PURCHASE SECTION */}
|
||||
|
||||
{/* RECENT ACTIVITY SECTION */}
|
||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full max-h-[700px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">Recent Activity</h1>
|
||||
{/* <p className='text-base text-slate-500 dark:text-white'>Activity Report</p> */}
|
||||
{paymentHistory.loading ?
|
||||
<LoadingSpinner size='16' color='sky-blue' />
|
||||
:
|
||||
<RecentActivityTable payment={paymentHistory} />
|
||||
{/* END OF switch button */}
|
||||
<div className="history-tables w-full">
|
||||
{/* PURCHASE SECTION */}
|
||||
{tab == 'purchases' &&
|
||||
<div className="wallet w-full border-t">
|
||||
<h1 className="p-2 text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1>
|
||||
{purchaseHistory.loading ?
|
||||
<LoadingSpinner size='16' color='sky-blue' />
|
||||
:
|
||||
<PurchasesTable purchase={purchaseHistory} />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{/* END OF PURCHASE SECTION */}
|
||||
|
||||
{/* RECENT ACTIVITY SECTION */}
|
||||
{tab == 'recent' &&
|
||||
<div className="wallet w-full border-t">
|
||||
<h1 className="p-2 text-xl font-bold text-dark-gray dark:text-white tracking-wide">Recent Activity</h1>
|
||||
{/* <p className='text-base text-slate-500 dark:text-white'>Activity Report</p> */}
|
||||
{paymentHistory.loading ?
|
||||
<LoadingSpinner size='16' color='sky-blue' />
|
||||
:
|
||||
<RecentActivityTable payment={paymentHistory} />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{/* END OF RECENT ACTIVITY SECTION */}
|
||||
</div>
|
||||
{/* END OF RECENT ACTIVITY SECTION */}
|
||||
</div>
|
||||
{/*<HistoryTable />*/}
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,8 @@ import datas from "../../data/product_data.json";
|
||||
import TopSellerTopBuyerSliderSection from "./TopSellerTopBuyerSliderSection";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import FamilyActiveLSlde from "./FamilyActiveLSlde";
|
||||
|
||||
import OverviewSection from "../ActiveBids/OverviewSection";
|
||||
import ParentWaiting from "../MyPendingJobs/ParentWaiting";
|
||||
|
||||
|
||||
export default function FamilyDash(props) {
|
||||
@@ -18,7 +19,8 @@ export default function FamilyDash(props) {
|
||||
commonHeadData={props.commonHeadData}
|
||||
/>
|
||||
<FamilyActiveLSlde trending={trending} className="mb-10" />
|
||||
<TopSellerTopBuyerSliderSection className="mb-10" />
|
||||
{/*<TopSellerTopBuyerSliderSection className="mb-10" />*/}
|
||||
<ParentWaiting className="mb-10" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,11 +3,10 @@ import slider2 from "../../assets/images/slider-2.jpg";
|
||||
import HomeBannerOffersCard from "../Cards/HomeBannerOffersCard";
|
||||
|
||||
export default function HomeSliders(props) {
|
||||
// console.log("BANNER LIST IN HomeSliders->", props.bannerList);
|
||||
// debugger;
|
||||
return (
|
||||
<>
|
||||
<div className="hero-slider relative 2xl:w-[600px] xl:w-[500px] lg:w-[420px] w-full mb-2 lg:mb-0 ">
|
||||
<div className="hero-slider relative 2xl:w-[600px] xl:w-[400px] lg:w-[420px] w-full mb-2 lg:mb-0 ">
|
||||
<div className="w-full">
|
||||
<SliderCom settings={props.settings}>
|
||||
{props.bannerList?.length <= 0 && (
|
||||
|
||||
@@ -1,106 +1,105 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
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 SelectBox from "../Helpers/SelectBox";
|
||||
|
||||
export default function MainSection({ className, marketPlaceProduct }) {
|
||||
const [tab, setTab] = useState("all");
|
||||
const [products, setProducts] = useState(marketPlaceProduct);
|
||||
export default function MainSection({
|
||||
className,
|
||||
marketPlaceProduct,
|
||||
categories,
|
||||
}) {
|
||||
// Creating All cart..
|
||||
let marketCategories = useMemo(
|
||||
() => ({ All: "All Categories", ...categories }),
|
||||
[categories]
|
||||
);
|
||||
const [tab, setTab] = useState(Object.keys(marketCategories)[0]);
|
||||
|
||||
let [contentDisplay, setContentDisplay] = useState('grid') // STATE TO HOLD LIST VIEW STYLE
|
||||
|
||||
// Convert to array in order to map
|
||||
const mappedArray = Object.entries(marketCategories).map(([key, value]) => {
|
||||
return { key, value };
|
||||
});
|
||||
|
||||
const [products, setProducts] = useState([]);
|
||||
const tabHandler = (value) => {
|
||||
setTab(value);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (tab === "artist") {
|
||||
setProducts(marketPlaceProduct?.slice(0, 3));
|
||||
} else if (tab === "market") {
|
||||
setProducts(marketPlaceProduct?.slice(0, 6));
|
||||
} else if (tab === "shop") {
|
||||
setProducts(marketPlaceProduct?.slice(6, 9));
|
||||
} else if (tab === "assets") {
|
||||
setProducts(marketPlaceProduct?.slice(3, 6));
|
||||
} else {
|
||||
setProducts(marketPlaceProduct);
|
||||
|
||||
// Handles the category selection on mobile view
|
||||
const handleSetCategory = (value) => {
|
||||
for (let i in marketCategories) {
|
||||
if (marketCategories[i] == value) {
|
||||
setTab(i);
|
||||
}
|
||||
}
|
||||
}, [tab, marketPlaceProduct]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (tab === "All") {
|
||||
setProducts(marketPlaceProduct);
|
||||
} else {
|
||||
const filteredProducts = marketPlaceProduct.filter((product) =>
|
||||
product.category.includes(tab)
|
||||
);
|
||||
setProducts(filteredProducts);
|
||||
}
|
||||
}, [tab, marketPlaceProduct, categories, marketCategories]);
|
||||
|
||||
return (
|
||||
<div className={`market-place-section w-full ${className || ""}`}>
|
||||
<div className="market-place-wrapper w-full">
|
||||
<div className="filter-navigate-area lg:flex justify-between mb-8 items-center">
|
||||
<div className="tab-item lg:mb-0 mb-5">
|
||||
<div className="md:flex md:space-x-8 space-x-2">
|
||||
<span
|
||||
onClick={() => tabHandler("all")}
|
||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||
tab === "all"
|
||||
? "text-pink border-pink"
|
||||
: " border-transparent"
|
||||
}`}
|
||||
>
|
||||
All
|
||||
</span>
|
||||
|
||||
|
||||
<span
|
||||
onClick={() => tabHandler("artist")}
|
||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||
tab === "artist"
|
||||
? "text-pink border-pink"
|
||||
: " border-transparent"
|
||||
}`}
|
||||
>
|
||||
Featured Artist
|
||||
</span>
|
||||
<span
|
||||
onClick={() => tabHandler("market")}
|
||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||
tab === "market"
|
||||
? "text-pink border-pink"
|
||||
: " border-transparent"
|
||||
}`}
|
||||
>
|
||||
Open Market
|
||||
</span>
|
||||
<span
|
||||
onClick={() => tabHandler("shop")}
|
||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||
tab === "shop"
|
||||
? "text-pink border-pink"
|
||||
: " border-transparent"
|
||||
}`}
|
||||
>
|
||||
Partner Shops
|
||||
</span>
|
||||
<span
|
||||
onClick={() => tabHandler("assets")}
|
||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||
tab === "assets"
|
||||
? "text-pink border-pink"
|
||||
: " border-transparent"
|
||||
}`}
|
||||
>
|
||||
Game Assets
|
||||
</span>
|
||||
|
||||
|
||||
<div className="filter-navigate-area flex justify-between items-center mb-8">
|
||||
<div className="tab-item w-full flex items-center">
|
||||
<div className="hidden lg:flex md:space-x-8 space-x-2">
|
||||
{mappedArray.map(({ key, value }) => (
|
||||
<span
|
||||
key={key}
|
||||
onClick={() => tabHandler(key)}
|
||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||
tab === key
|
||||
? "text-pink border-pink"
|
||||
: " border-transparent"
|
||||
}`}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
{/* market categories on screen smaller than large screen */}
|
||||
<div className="w-[80%] lg:hidden">
|
||||
<SelectBox
|
||||
action={handleSetCategory}
|
||||
datas={Object.values(marketCategories)}
|
||||
className="Update-table-dropdown"
|
||||
contentBodyClasses="w-auto min-w-max"
|
||||
position='left'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/*<div className="search-item flex lg:flex-none justify-end">*/}
|
||||
{/* <SearchCom*/}
|
||||
{/* className="lg:bg-transparent"*/}
|
||||
{/* inputClasses="lg:bg-transparent"*/}
|
||||
{/* />*/}
|
||||
{/*</div>*/}
|
||||
{/* contentDisplay toggler */}
|
||||
<div className="p-2 w-[35px] h-[35px] bg-white dark:bg-slate-200 rounded-lg">
|
||||
<img
|
||||
title={contentDisplay=='grid'? 'list view' : 'grid view'}
|
||||
onClick={()=>setContentDisplay((prev)=>prev=='grid'? 'list' : 'grid')}
|
||||
src={contentDisplay=='grid'? ListView : GridView}
|
||||
className="w-full h-full cursor-pointer" alt="view"
|
||||
/>
|
||||
</div>
|
||||
{/* end of contentDisplay toggler */}
|
||||
</div>
|
||||
<div className="filter-navigate-content w-full min-h-screen">
|
||||
<div className="grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]">
|
||||
<div className={contentDisplay == 'grid' ? 'grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]' : 'w-full'}>
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<AvailableJobsCard key={datas.id} datas={datas} />
|
||||
<AvailableJobsCard contentDisplay={contentDisplay} key={datas.id} datas={datas} />
|
||||
)}
|
||||
</DataIteration>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react'
|
||||
|
||||
function Detail({label, value, bg,}) {
|
||||
return (
|
||||
<>
|
||||
<label className='w-full md:w-1/4 text-slate-900 tracking-wide font-semibold'>{label}</label>
|
||||
<p className={`p-1 w-full md:w-3/4 text-sm text-slate-900 ${bg ? bg : null}`}>{value}</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Detail
|
||||
@@ -1,22 +1,98 @@
|
||||
import React, { useCallback, useMemo, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import { toast } from "react-toastify";
|
||||
import { Form, Formik } from "formik";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
|
||||
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
const [marketMsg, setMarketMsg] = useState({
|
||||
loading: false,
|
||||
data: {},
|
||||
state: undefined,
|
||||
});
|
||||
const [manageInt, setManageInt] = useState({
|
||||
loading: false,
|
||||
data: {},
|
||||
state: undefined,
|
||||
msg: "",
|
||||
});
|
||||
const MarketCalls = (details) => {
|
||||
const [marketMsg, setMarketMsg] = useState({
|
||||
loading: false,
|
||||
data: {},
|
||||
state: undefined,
|
||||
});
|
||||
const [manageInt, setManageInt] = useState({
|
||||
loading: false,
|
||||
data: {},
|
||||
state: undefined,
|
||||
msg: "",
|
||||
});
|
||||
|
||||
const { offer_code } = details;
|
||||
const reqData = { offer_code };
|
||||
|
||||
const MarketDetail = async () => {
|
||||
try {
|
||||
setMarketMsg({ loading: true });
|
||||
if (!textValue) return;
|
||||
|
||||
reqData.yourmessage = textValue;
|
||||
|
||||
const marketMessage = await apiCall.MarketMessage(reqData);
|
||||
const marketMessageRes = marketMessage?.data;
|
||||
|
||||
if (marketMessageRes?.internal_return < 0) {
|
||||
toast.warn("Something wrong happened", {
|
||||
autoClose: 2000,
|
||||
hideProgressBar: true,
|
||||
});
|
||||
onClose();
|
||||
return;
|
||||
}
|
||||
|
||||
toast.success("Message sent", {
|
||||
autoClose: 2500,
|
||||
hideProgressBar: true,
|
||||
});
|
||||
|
||||
setMarketMsg({ data: marketMessageRes, state: true });
|
||||
setTimeout(() => onClose(), 2000);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
setTextValue("");
|
||||
setMarketMsg({ loading: false });
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
const ManageInterest = async () => {
|
||||
try {
|
||||
setManageInt({ loading: true });
|
||||
|
||||
const manageInt = await apiCall.MarketInterest(reqData);
|
||||
const manageIntRes = manageInt?.data;
|
||||
|
||||
if (manageIntRes?.internal_return < 0) {
|
||||
setManageInt({
|
||||
loading: false,
|
||||
msg: manageIntRes?.status,
|
||||
data: manageIntRes,
|
||||
state: false,
|
||||
});
|
||||
} else {
|
||||
setManageInt({
|
||||
loading: false,
|
||||
msg: manageIntRes?.status,
|
||||
data: manageIntRes,
|
||||
state: true,
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => setManageInt({ msg: "" }), 3000);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// ManageInterest();
|
||||
// }, []);
|
||||
|
||||
return { MarketDetail, ManageInterest, manageInt, marketMsg };
|
||||
};
|
||||
|
||||
const [textValue, setTextValue] = useState("");
|
||||
|
||||
@@ -26,84 +102,33 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
const marketCalls = useCallback(
|
||||
async (e) => {
|
||||
try {
|
||||
const nameOfCall = e?.target?.name;
|
||||
const { offer_code } = details;
|
||||
const reqData = { offer_code };
|
||||
let { manageInt, ManageInterest, MarketDetail, marketMsg } = MarketCalls(details);
|
||||
|
||||
if (nameOfCall === "market-message") {
|
||||
setMarketMsg({ loading: true });
|
||||
if (!textValue) return;
|
||||
|
||||
reqData.yourmessage = textValue;
|
||||
|
||||
const marketMessage = await apiCall.MarketMessage(reqData);
|
||||
const marketMessageRes = marketMessage?.data;
|
||||
|
||||
if (marketMessageRes?.internal_return < 0) {
|
||||
toast.warn("Something wrong happened", {
|
||||
autoClose: 2000,
|
||||
hideProgressBar: true,
|
||||
});
|
||||
onClose();
|
||||
return;
|
||||
}
|
||||
|
||||
toast.success("Message sent", {
|
||||
autoClose: 2500,
|
||||
hideProgressBar: true,
|
||||
});
|
||||
|
||||
setMarketMsg({ data: marketMessageRes, state: true });
|
||||
setTimeout(() => onClose(), 2000);
|
||||
} else {
|
||||
setManageInt({ loading: true });
|
||||
|
||||
const manageInt = await apiCall.MarketInterest(reqData);
|
||||
const manageIntRes = manageInt?.data;
|
||||
|
||||
if (manageIntRes?.internal_return < 0) {
|
||||
setManageInt({
|
||||
loading: false,
|
||||
msg: `Error - ${manageIntRes?.status}`,
|
||||
data: manageIntRes,
|
||||
state: false,
|
||||
});
|
||||
} else {
|
||||
setManageInt({
|
||||
loading: false,
|
||||
msg: manageIntRes?.status,
|
||||
data: manageIntRes,
|
||||
state: true,
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => setManageInt({ msg: "" }), 3000);
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
setTextValue("");
|
||||
setMarketMsg({ loading: false });
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
[apiCall, details, onClose, textValue]
|
||||
let thePrice = PriceFormatter(
|
||||
details?.price * 0.01,
|
||||
details?.currency_code,
|
||||
details?.currency
|
||||
);
|
||||
|
||||
console.log('Checking my mangeInt',manageInt)
|
||||
|
||||
// let addedIntDate = marketInt?.added?.split(" ")[0];
|
||||
let expireIntDate = marketInt?.expire?.split(" ")[0];
|
||||
// let expireIntDate = marketInt?.expire?.split(" ")[0];
|
||||
|
||||
let cleanedText = details?.job_description
|
||||
?.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, '"')
|
||||
.replace(/&/g, "&");
|
||||
|
||||
console.log("first wait", {
|
||||
manageInt,
|
||||
ManageInterest,
|
||||
MarketDetail,
|
||||
marketMsg,
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation} className="edit-popup">
|
||||
<div className="logout-modal-wrapper md:w-[750px] md:h-[700px] h-full bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="logout-modal-wrapper md:w-[750px] md:h-[660px] h-full 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]">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
{details.offer_code}
|
||||
@@ -112,8 +137,8 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</div>
|
||||
|
||||
<div className="md:flex bg-white rounded-lg">
|
||||
<div className="p-4 w-full md:w-3/4 md:border-r-1">
|
||||
<div className="min-h-[290px]">
|
||||
<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">
|
||||
{details?.title}
|
||||
</h2>
|
||||
@@ -128,17 +153,17 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
name: "",
|
||||
content: {
|
||||
text: `Timeline: ${details.timeline_days} day(s) -- `,
|
||||
bold: `Budget: ${details.price} naira`,
|
||||
bold: `Budget: ${thePrice}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Delivery Detail",
|
||||
content: details.job_description,
|
||||
content: cleanedText,
|
||||
danger: true,
|
||||
},
|
||||
].map(({ name, content, danger }, idx) => (
|
||||
<div className={`my-3 md:flex items-center`} key={idx}>
|
||||
<label className="w-full md:w-1/4 text-slate-900 tracking-wide font-semibold">
|
||||
<label className="w-full md:w-[19%] text-slate-900 tracking-wide font-semibold whitespace-pre-wrap">
|
||||
{name}
|
||||
</label>
|
||||
<div
|
||||
@@ -152,19 +177,23 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
<p
|
||||
className={``}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: danger && content?.replace(/"/g, ""),
|
||||
__html: danger && content,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<p className={`w-full md:w-3/4 text-slate-900`}>
|
||||
<p className={`w-full text-slate-900`}>
|
||||
{name !== "Delivery Detail" ? (
|
||||
<>
|
||||
{typeof content !== "object" ? content : null}
|
||||
{typeof content === "object" && (
|
||||
<span className="flex items-center gap-2">
|
||||
{content?.text}
|
||||
<strong>{content?.bold}</strong>
|
||||
</span>
|
||||
<>
|
||||
<hr className="mb-1" />
|
||||
<span className="flex items-center gap-2">
|
||||
{content?.text}
|
||||
<strong>{thePrice}</strong>
|
||||
</span>
|
||||
<hr className="mt-1" />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
@@ -194,7 +223,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
<button
|
||||
className="self-end w-[150px] h-[52px] rounded-md text-base bg-yellow-500 text-white"
|
||||
name="market-message"
|
||||
onClick={marketCalls}
|
||||
onClick={MarketDetail}
|
||||
>
|
||||
{marketMsg.loading ? (
|
||||
<LoadingSpinner size={5} color="white" />
|
||||
@@ -207,17 +236,17 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full md:w-1/4 h-full ">
|
||||
<div className="w-[90%] mx-auto bg-[#f1f8ff] p-4 rounded-md md:min-h-[550px] flex flex-col justify-between">
|
||||
<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="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?
|
||||
</p>
|
||||
<hr />
|
||||
<button
|
||||
className="bg-[#57cd89] text-center text-lg font-semibold text-white py-2 px-4 rounded-md inline-flex flex-col items-center justify-center"
|
||||
className="bg-[#57cd89] text-center text-lg font-semibold text-white py-2 px-4 rounded-md inline-flex sm:flex-col flex-row sm:gap-0 gap-1 items-center justify-center"
|
||||
name="market-interest"
|
||||
onClick={marketCalls}
|
||||
onClick={ManageInterest}
|
||||
>
|
||||
{" "}
|
||||
<span>Send</span>
|
||||
@@ -248,9 +277,18 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
Interest: <b className="ml-1">{details.interest_count}</b>
|
||||
</p>
|
||||
<hr />
|
||||
<p className="my-1">Expire: {expireIntDate}</p>
|
||||
<p className="my-1">
|
||||
Expire: {details.expire}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="self-end w-[150px] mt-2 h-[52px] rounded-md text-base bg-transparent border border-red-500 text-red-500 mx-auto"
|
||||
name="cancel"
|
||||
onClick={onClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
{/* END OF ACTION SECTION */}
|
||||
</div>
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import React from "react";
|
||||
// import products from "../../data/marketplace_data.json";
|
||||
//import CreateNft from "../Home/CreateNft";
|
||||
import Layout from "../Partials/Layout";
|
||||
import MainSection from "./MainSection";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
export default function MarketPlace({commonHeadData}) {
|
||||
export default function MarketPlace({ commonHeadData }) {
|
||||
let { jobLists } = useSelector((state) => state.jobLists);
|
||||
const marketData = jobLists?.result_list;
|
||||
const categories = jobLists?.categories;
|
||||
|
||||
// const marketProduct = products.data;
|
||||
return (
|
||||
<>
|
||||
<Layout>
|
||||
<CommonHead commonHeadData={commonHeadData} />
|
||||
<MainSection marketPlaceProduct={marketData} className="mb-10" />
|
||||
<CommonHead commonHeadData={commonHeadData} />
|
||||
<MainSection
|
||||
marketPlaceProduct={marketData}
|
||||
categories={categories}
|
||||
className="mb-10"
|
||||
/>
|
||||
</Layout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -248,6 +248,8 @@ function ActiveJobs(props) {
|
||||
}
|
||||
}, [passDue]);
|
||||
|
||||
console.log("AC JOBS >>", props);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="py-[20px] bg-white dark:bg-black dark:text-white px-4 rounded-2xl shadow-md md:flex justify-between items-start gap-16">
|
||||
@@ -257,8 +259,13 @@ function ActiveJobs(props) {
|
||||
<button
|
||||
type="button"
|
||||
className="min-w-[45px] h-auto text-[#374557] border border-sky-blue p-1 rounded-full"
|
||||
onClick={() =>
|
||||
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
|
||||
@@ -278,12 +285,14 @@ function ActiveJobs(props) {
|
||||
|
||||
<div className="w-full my-2">
|
||||
<p className="w-full text-base text-right text-sky-blue">
|
||||
{props.details.job_to && props.details.job_to}
|
||||
{props?.details && props.details.job_to}
|
||||
</p>
|
||||
<div className="text-base text-slate-700 dark:text-white tracking-wide">
|
||||
<p className="font-semibold text-black dark:text-white">Description: </p>
|
||||
<p className="font-semibold text-black dark:text-white">
|
||||
Description:{" "}
|
||||
</p>
|
||||
<p className="p-2 border border-sky-blue">
|
||||
{props.details?.description && props.details.description}
|
||||
{props?.details && props.details.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -297,11 +306,10 @@ function ActiveJobs(props) {
|
||||
<div className="my-1">
|
||||
<p className="text-base text-slate-700">
|
||||
<span className="font-semibold">Due: </span>
|
||||
{props.details?.delivery_date &&
|
||||
props.details.delivery_date.split(" ")[0]}
|
||||
{props?.details && props.details.delivery_date.split(" ")[0]}
|
||||
</p>
|
||||
<p className="py-2 text-base text-slate-700">
|
||||
{props.details?.delivery_date &&
|
||||
{props?.delivery_date &&
|
||||
props.details.delivery_date.split(" ")[1]}
|
||||
</p>
|
||||
</div>
|
||||
@@ -310,7 +318,9 @@ function ActiveJobs(props) {
|
||||
<p className="font-semibold">Due: </p>
|
||||
<div className="flex flex-col justify-between">
|
||||
<p className="text-base text-slate-700 tracking-wide">
|
||||
<CountDown lastDate={props.details.delivery_date} />
|
||||
<CountDown
|
||||
lastDate={props?.details && props.details.delivery_date}
|
||||
/>
|
||||
</p>
|
||||
<div className="text-base text-slate-700 tracking-wide flex gap-[5px]">
|
||||
<span>Hrs</span>
|
||||
@@ -322,14 +332,18 @@ function ActiveJobs(props) {
|
||||
)}
|
||||
|
||||
<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: </span>
|
||||
<span className="font-semibold text-black dark:text-white">
|
||||
Duration:{" "}
|
||||
</span>
|
||||
<span className="">
|
||||
{props.details?.timeline_days && props.details.timeline_days}{" "}
|
||||
day(s)
|
||||
</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">No: </span>
|
||||
<span className="font-semibold text-black dark:text-white">
|
||||
No:{" "}
|
||||
</span>
|
||||
<span className="">
|
||||
{props.details?.contract && props.details.contract}
|
||||
</span>
|
||||
|
||||
@@ -79,7 +79,7 @@ function CurrentTaskAction({jobDetails}) {
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex justify-center items-center">
|
||||
<button onClick={popUpHandler} type="button" className="w-120 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
<button onClick={popUpHandler} type="button" className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
Send of Review
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -10,8 +10,8 @@ import ReviewJobAction from './ReviewJobAction'
|
||||
import ReviewTaskAction from './ReviewTaskAction'
|
||||
|
||||
function IndexJobActions({details}) { // FUNCTION TO RENDER SPECIFIC JOB ACTION DEPENDING ON OWNER STATUS & STATUS DESCRIPTION
|
||||
let owner = details.owner_status
|
||||
let description = details.status_description
|
||||
let owner = details?.owner_status
|
||||
let description = details?.status_description
|
||||
switch(owner) {
|
||||
case 'OWNER':
|
||||
return (()=>{
|
||||
|
||||
@@ -119,7 +119,7 @@ function PastDueJobAction({jobDetails}) {
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex justify-center items-center">
|
||||
<button type="button" onClick={popUpHandler} className="w-120 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
<button type="button" onClick={popUpHandler} className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
Cancel or Extend Timeline
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@ function PastDueTaskAction() {
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex justify-center items-center">
|
||||
<button type="button" className="w-120 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
<button type="button" className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
Request Extension
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -108,7 +108,7 @@ function ReviewJobAction({jobDetails}) {
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex justify-center items-center">
|
||||
<button type="button" onClick={popUpHandler} className="w-120 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
<button type="button" onClick={popUpHandler} className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
Reject or Accept
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,7 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
||||
{value.title}
|
||||
</h1>
|
||||
<div>{value.description}</div>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
<span className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||
Price:{" "}
|
||||
<span className="text-purple">
|
||||
{thePrice}
|
||||
|
||||
@@ -10,6 +10,7 @@ export default function MyActiveJobs(props) {
|
||||
setValue(value);
|
||||
};
|
||||
console.log("AMEYE LOC1", props.MyJobList);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<CommonHead commonHeadData={props.commonHeadData} />
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||
import SelectBox from "../Helpers/SelectBox";
|
||||
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
|
||||
import JobListPopout from "../jobPopout/JobListPopout";
|
||||
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
@@ -13,7 +11,27 @@ import PaginatedList from "../Pagination/PaginatedList";
|
||||
import EditJobPopOut from "../jobPopout/EditJobPopout";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
import EditIcon from '../../assets/images/icon-edit.svg'
|
||||
import DeleteIcon from '../../assets/images/icon-delete.svg'
|
||||
|
||||
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
// Getting the categories
|
||||
const currentJobCart = MyJobList?.data?.categories;
|
||||
// DropDown Box
|
||||
const filterCategories = { All: "All Categories", ...currentJobCart };
|
||||
|
||||
const [selectedCategory, setCategory] = useState(
|
||||
Object.keys(filterCategories)[0]
|
||||
);
|
||||
|
||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||
|
||||
let [deleteJobPopout, setDeleteJobPopout] = useState({
|
||||
show: false,
|
||||
data: {},
|
||||
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
|
||||
const [editJob, setEditJob] = useState({ show: false, data: {} });
|
||||
|
||||
const [myCountry, setCountries] = useState("");
|
||||
const {
|
||||
userDetails: { country },
|
||||
@@ -45,22 +63,25 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
getCountryList();
|
||||
}, [getCountryList]);
|
||||
|
||||
const filterCategories = ["All Categories", "Explore", "Featured"];
|
||||
const [selectedCategory, setCategory] = useState(filterCategories[0]);
|
||||
|
||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||
|
||||
let [deleteJobPopout, setDeleteJobPopout] = useState({
|
||||
show: false,
|
||||
data: {},
|
||||
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
|
||||
const [editJob, setEditJob] = useState({ show: false, data: {} });
|
||||
|
||||
// Handle Pagination
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentJobList = MyJobList?.data?.result_list?.slice(
|
||||
|
||||
// Handle Filter Job List
|
||||
const filterJobList = () => {
|
||||
if (selectedCategory === "All") return MyJobList?.data?.result_list;
|
||||
else
|
||||
return MyJobList?.data?.result_list?.filter((item) =>
|
||||
item.category.includes(selectedCategory)
|
||||
);
|
||||
};
|
||||
|
||||
const currentJobList = filterJobList();
|
||||
|
||||
// Handling Filter Pagination
|
||||
const filteredCurrentJobList = currentJobList?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
@@ -69,6 +90,97 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
// Handles the category selection
|
||||
const handleSetCategory = (value) => {
|
||||
setCurrentPage(0);
|
||||
for (let i in filterCategories) {
|
||||
if (filterCategories[i] == value) {
|
||||
setCategory(i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const JobListItem = ({ value, index }) => {
|
||||
let thePrice = PriceFormatter(
|
||||
value?.price * 0.01,
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
return (
|
||||
<tr
|
||||
key={index}
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
>
|
||||
<td className="py-9">
|
||||
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
|
||||
<div className="flex space-x-2 items-center job-items w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||
<img src={dataImage2} alt="data" className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
{value.title}
|
||||
</h1>
|
||||
<div>{value.description}</div>
|
||||
<span className="text-sm text-thin-light-gray flex items-start gap-1">
|
||||
Price: <span className="text-purple">{thePrice}</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value.timeline_days} day(s)
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="h-[33px] w-[150px] flex flex-nowrap items-center self-end">
|
||||
<button
|
||||
type="button"
|
||||
className="p-1 border-2 border-red-400 rounded-md"
|
||||
onClick={() => {
|
||||
setDeleteJobPopout({
|
||||
show: true,
|
||||
data: { thePrice, ...value },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<img className="w-[21px] h-[21px]" src={DeleteIcon} alt='delete-icon' />
|
||||
</button>
|
||||
<div className="mx-[4px] h-full w-[1px] bg-black dark:bg-dark-gray"></div>
|
||||
<button
|
||||
type="button"
|
||||
className="p-1 border-2 border-sky-blue rounded-md flex items-center"
|
||||
onClick={() => {
|
||||
setEditJob({
|
||||
show: true,
|
||||
data: { thePrice, ...value },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<img className="w-[21px] h-[21px]" src={EditIcon} alt='edit-icon' />
|
||||
<span className="text-sm text-sky-blue">Edit</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td className="text-right py-9 px-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setJobPopout({ show: true, data: { thePrice, ...value } });
|
||||
}}
|
||||
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 p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
||||
@@ -78,12 +190,12 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
<div className="header w-full flex justify-between items-center mb-5">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
All Jobs
|
||||
{filterCategories[selectedCategory]} Jobs
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<SelectBox
|
||||
action={setCategory}
|
||||
datas={filterCategories}
|
||||
action={handleSetCategory}
|
||||
datas={Object.values(filterCategories)}
|
||||
className="Update-table-dropdown"
|
||||
contentBodyClasses="w-auto min-w-max"
|
||||
/>
|
||||
@@ -94,112 +206,27 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
<tr className="text-base text-thin-light-gray border-b default-border-b dark:border-[#5356fb29] ottom ">
|
||||
<td className="py-1">.</td>
|
||||
<td className="py-1 text-right">.</td>
|
||||
</tr>
|
||||
|
||||
{selectedCategory === "All Categories" ? (
|
||||
<>
|
||||
{MyJobList &&
|
||||
MyJobList?.data?.result_list &&
|
||||
MyJobList.data?.result_list.length > 0 ? (
|
||||
currentJobList.map((value, index) => {
|
||||
let thePrice = PriceFormatter(
|
||||
value?.price * 0.01,
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
return(
|
||||
<tr
|
||||
key={index}
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
>
|
||||
<td className="py-9">
|
||||
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
|
||||
<div className="flex space-x-2 items-center job-items w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||
<img
|
||||
src={dataImage2}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-[0.9]">
|
||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||
{value.title}
|
||||
</h1>
|
||||
<div>{value.description}</div>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Price:{" "}
|
||||
<span className="text-purple">
|
||||
{thePrice}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value.timeline_days} day(s)
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="min-w-[110px] max-w-[110px] bg-yellow-300 mx-2 rounded-md flex flex-nowrap space-x-2 justify-center items-center self-end">
|
||||
<button
|
||||
type="button"
|
||||
className="p-2 w-[60px] h-11"
|
||||
onClick={() => {
|
||||
setDeleteJobPopout({
|
||||
show: true,
|
||||
data: value,
|
||||
});
|
||||
}}
|
||||
>
|
||||
[Delete]
|
||||
</button>
|
||||
<span>|</span>
|
||||
<button
|
||||
type="button"
|
||||
className="p-2 w-[40px] h-11"
|
||||
onClick={() => {
|
||||
setEditJob({
|
||||
show: true,
|
||||
data: value,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td className="text-right py-9 px-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setJobPopout({ show: true, data: value });
|
||||
}}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
)})
|
||||
<>
|
||||
{MyJobList &&
|
||||
MyJobList?.data?.result_list &&
|
||||
MyJobList.data?.result_list.length > 0 ? (
|
||||
filteredCurrentJobList?.length ? (
|
||||
filteredCurrentJobList.map((value, index) => (
|
||||
<JobListItem index={index} key={index} value={value} />
|
||||
))
|
||||
) : (
|
||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
<td className="p-2">No Jobs Avaliable!</td>
|
||||
<td className="p-2">
|
||||
No Jobs Available In This Category!
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</>
|
||||
) : selectedCategory === "Explore" ? (
|
||||
<></>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
)
|
||||
) : (
|
||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
<td className="p-2">No Jobs Avaliable!</td>
|
||||
</tr>
|
||||
)}
|
||||
</>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -209,11 +236,11 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
MyJobList?.data?.result_list?.length
|
||||
currentJobList?.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={MyJobList?.data?.result_list}
|
||||
data={currentJobList}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
@@ -257,6 +284,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
}}
|
||||
situation={editJob.show}
|
||||
country={myCountry}
|
||||
categories={currentJobCart}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,31 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import MyJobTable from "./MyJobTable";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import AddJobPage from "../../views/AddJobPage";
|
||||
|
||||
export default function MyJobs(props) {
|
||||
let { state } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [popUp, setPopUp] = useState(false);
|
||||
const popUpHandler = () => {
|
||||
setPopUp((prev) => !prev);
|
||||
|
||||
if (state?.popup) navigate("/", { replace: true })
|
||||
else return
|
||||
};
|
||||
|
||||
const categoryOptions = props.MyJobList?.data?.categories;
|
||||
|
||||
useEffect(() => {
|
||||
if (!state?.popup) {
|
||||
setPopUp(false);
|
||||
} else {
|
||||
setPopUp(true);
|
||||
}
|
||||
}, [state?.popup]);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<CommonHead commonHeadData={props.commonHeadData} />
|
||||
@@ -36,8 +51,14 @@ export default function MyJobs(props) {
|
||||
</div>
|
||||
|
||||
{/* Add Job List Popout */}
|
||||
{popUp && <AddJobPage action={popUpHandler} situation={popUp} />}
|
||||
{popUp && (
|
||||
<AddJobPage
|
||||
action={popUpHandler}
|
||||
situation={popUp}
|
||||
categories={categoryOptions}
|
||||
/>
|
||||
)}
|
||||
{/* End of Add Job List Popout */}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
||||
{value.title}
|
||||
</h1>
|
||||
<div>{value.description}</div>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
<span className="text-sm text-thin-light-gray flex items-start gap-1">
|
||||
Price:{" "}
|
||||
<span className="text-purple">
|
||||
{thePrice}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import activeAidsBanner from "../../assets/images/kids-waiting.jpg";
|
||||
import HeroUser from "../../assets/images/hero-user.png";
|
||||
import CountDown from "../Helpers/CountDown";
|
||||
import ParentWaitingTable from "./ParentWaitingTable";
|
||||
|
||||
export default function ParentWaiting({ className }) {
|
||||
const [addFavorite, setValue] = useState(false);
|
||||
const favoriteHandler = () => {
|
||||
if (!addFavorite) {
|
||||
setValue(true);
|
||||
toast.success("Added to Favorite List");
|
||||
} else {
|
||||
setValue(false);
|
||||
toast.warn("Remove to Favorite List");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className={`overview-section w-full ${className || ""}`}>
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Waiting for Parent to Get Started...</h1>
|
||||
</div>
|
||||
<div className="overview-section-wrapper lg:flex lg:h-[494px] lg:pace-x-2">
|
||||
<div className="lg:w-[540px] w-full h-full bg-white dark:bg-dark-white rounded-2xl overflow-hidden mb-10">
|
||||
<img
|
||||
src={activeAidsBanner}
|
||||
alt="banner"
|
||||
className="w-full lg:h-full h-[400px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="overview-countdown lg:w-2/5 w-full h-full flex flex-col justify-between lg:pl-11 rounded-2xl bg-white dark:bg-dark-white ">
|
||||
{<ParentWaitingTable />}
|
||||
|
||||
{/* <div className="lg:mb-0 mb-3">*/}
|
||||
{/* <h1 className="text-2xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* Lock and Lob x Fiesta Spurs*/}
|
||||
{/* </h1>*/}
|
||||
{/* <span className="text-[18px] font-thin tracking-wide text-dark-gray dark:text-white">*/}
|
||||
{/* ID : 2320382*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* /!* user *!/*/}
|
||||
{/* <div className="flex items-center space-x-3 lg:mb-0 mb-3">*/}
|
||||
{/* <div className="w-14 h-14 flex justify-center items-center rounded-full overflow-hidden">*/}
|
||||
{/* <img src={HeroUser} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl tracking-wide font-bold antise text-dark-gray dark:text-white">*/}
|
||||
{/* Brokln Simons*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm tracking-wide text-dark-gray dark:text-white">*/}
|
||||
{/* @broklinslam_75*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
import React, { useState } from "react";
|
||||
import transaction1 from "../../assets/images/recent-transation-1.png";
|
||||
import transaction2 from "../../assets/images/recent-transation-2.png";
|
||||
import transaction3 from "../../assets/images/recent-transation-3.png";
|
||||
|
||||
export default function ParentWaitingTable() {
|
||||
const transationFilterData = [
|
||||
{
|
||||
id: 1,
|
||||
name: "all",
|
||||
uniqueId: Math.random(),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "send",
|
||||
uniqueId: Math.random(),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "recent",
|
||||
uniqueId: Math.random(),
|
||||
},
|
||||
];
|
||||
const [filterActive, setValue] = useState(transationFilterData[0].id);
|
||||
const filterHander = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
return (
|
||||
<div className="rounded-2xl bg-white dark:bg-dark-white ">
|
||||
{/* heading */}
|
||||
<div className="heading sm:flex justify-between items-center">
|
||||
|
||||
<div>
|
||||
<ul className="flex space-x-5 items-center">
|
||||
{transationFilterData.map((value) => (
|
||||
<li
|
||||
onClick={() => filterHander(value.id)}
|
||||
key={value.uniqueId}
|
||||
className={`text-base text-thin-light-gray hover:text-purple border-b dark:border-[#5356fb29] border-transparent hover:border-purple uppercase ${
|
||||
filterActive === value.id ? "border-purple text-purple" : ""
|
||||
}`}
|
||||
>
|
||||
{value.name}
|
||||
</li>
|
||||
))}
|
||||
{/* <li className="text-base text-thin-light-gray hover:text-purple border-b dark:border-[#5356fb29] border-transparent hover:border-purple uppercase">
|
||||
All
|
||||
</li>
|
||||
<li className="text-base text-thin-light-gray hover:text-purple border-b dark:border-[#5356fb29] border-transparent hover:border-purple uppercase">
|
||||
SEND
|
||||
</li>
|
||||
<li className="text-base text-thin-light-gray hover:text-purple border-b dark:border-[#5356fb29] border-transparent hover:border-purple uppercase">
|
||||
recent
|
||||
</li> */}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/* content */}
|
||||
|
||||
{filterActive === 2 ? (
|
||||
<div className="content">
|
||||
<ul>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction2} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add BTC from Coinbase Wallet
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-824.78
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction3} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Buy Nft art from LTC
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-924.54
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
) : filterActive === 3 ? (
|
||||
<div className="content">
|
||||
<ul>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction2} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add BTC from Coinbase Wallet
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-824.78
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
) : (
|
||||
<div className="content">
|
||||
<ul>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction2} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add BTC from Coinbase Wallet
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-824.78
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction3} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Buy Nft art from LTC
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-red text-right">
|
||||
-924.54
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="content-item py-3 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] hover:border-purple">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img src={transaction1} alt="" className="" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium mb-1">
|
||||
Add ETH from MetaMask
|
||||
</p>
|
||||
</div>
|
||||
<div className="time">
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
22 hours ago
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-dark-gray dark:text-white">
|
||||
$512.44
|
||||
</p>
|
||||
<p className="usd text-base text-light-green text-right">
|
||||
+324.75
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
const noTasksBg = require("../../assets/images/no-task-background.jpg");
|
||||
|
||||
export default function MyJobTable({ className, ActiveJobList }) {
|
||||
export default function MyJobTable({ className, ActiveJobList, Account }) {
|
||||
let navigate = useNavigate();
|
||||
let { pathname } = useLocation();
|
||||
|
||||
@@ -30,7 +30,7 @@ export default function MyJobTable({ className, ActiveJobList }) {
|
||||
const navigateMarket = () => {
|
||||
setBtnLoader(true);
|
||||
setTimeout(() => {
|
||||
navigate("/market", { replace: true });
|
||||
navigate(Account == "FULL" ? "/market" : "/", { replace: true });
|
||||
setBtnLoader(false);
|
||||
}, 2500);
|
||||
};
|
||||
@@ -60,6 +60,8 @@ export default function MyJobTable({ className, ActiveJobList }) {
|
||||
<div className="h-auto w-full">
|
||||
{ActiveJobList?.data?.length > 0 &&
|
||||
currentTask?.map((task, idx) => {
|
||||
// find due date
|
||||
const dueDate = task?.delivery_date.split(" ")[0];
|
||||
let thePrice = PriceFormatter(
|
||||
task?.price * 0.01,
|
||||
task?.currency_code,
|
||||
@@ -86,7 +88,7 @@ export default function MyJobTable({ className, ActiveJobList }) {
|
||||
<span className="text-base text-gray-600">
|
||||
{task?.description}
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
<span className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||
Price:
|
||||
<span className="text-purple ml-1">{thePrice}</span>
|
||||
</span>
|
||||
@@ -101,9 +103,7 @@ export default function MyJobTable({ className, ActiveJobList }) {
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Due Date:
|
||||
<span className="text-purple ml-1">
|
||||
{task?.delivery_date}
|
||||
</span>
|
||||
<span className="text-purple ml-1">{dueDate}</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Confirmation:
|
||||
|
||||
@@ -143,7 +143,10 @@ export default function MyOffersTable({ className, MyActiveOffersList }) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setOfferPopout({ show: true, data: value });
|
||||
setOfferPopout({
|
||||
show: true,
|
||||
data: {...value, thePrice },
|
||||
});
|
||||
}}
|
||||
className="w-20 h-11 self-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import MyJobTable from "./MyJobTable";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import TopSellerTopBuyerSliderSection from "../Home/TopSellerTopBuyerSliderSection";
|
||||
// import TopSellerTopBuyerSliderSection from "../Home/TopSellerTopBuyerSliderSection";
|
||||
import MyOffersTable from "./MyOffersTable";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
export default function MyTasks({
|
||||
MyActiveOffersList,
|
||||
ActiveJobList,
|
||||
commonHeadData,
|
||||
}) {
|
||||
const { userDetails: account_type } = useSelector(
|
||||
(state) => state?.userDetails
|
||||
);
|
||||
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
@@ -45,7 +49,7 @@ export default function MyTasks({
|
||||
className="mb-10"
|
||||
/>
|
||||
)}
|
||||
<MyJobTable ActiveJobList={ActiveJobList} />
|
||||
<MyJobTable ActiveJobList={ActiveJobList} Account={account_type} />
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
import { useState } from "react";
|
||||
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
|
||||
|
||||
export default function MyWaitingJobTable({ MyJobList, className }) {
|
||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentActiveJobList = MyJobList?.result_list?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
{MyJobList && MyJobList?.result_list && (
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{
|
||||
<>
|
||||
{MyJobList &&
|
||||
MyJobList?.result_list &&
|
||||
MyJobList.result_list.length > 0 ? (
|
||||
currentActiveJobList.map((value, index) => {
|
||||
// let deliveryDate = value?.expire?.split(" ")[0];
|
||||
let thePrice = PriceFormatter(
|
||||
value?.price * 0.01,
|
||||
value?.currency_code,
|
||||
value?.currency
|
||||
);
|
||||
return (
|
||||
<tr
|
||||
key={index}
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
>
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px]">
|
||||
<img
|
||||
src={dataImage2}
|
||||
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">
|
||||
{value.title}
|
||||
</h1>
|
||||
<div>{value.description}</div>
|
||||
<span className="text-sm text-thin-light-gray flex items-start gap-1">
|
||||
Price:{" "}
|
||||
<span className="text-purple">
|
||||
{thePrice}
|
||||
</span>
|
||||
</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Duration:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value?.timeline_days} day(s)
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Expire:{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value?.expire}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-sm text-thin-light-gray">
|
||||
Sent :{" "}
|
||||
<span className="text-purple">
|
||||
{" "}
|
||||
{value?.sent}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td className="text-right py-4 px-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setJobPopout({ show: true, data: value });
|
||||
}}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||
<td className="p-2">No Pending Task!</td>
|
||||
</tr>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
MyJobList?.result_list.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={MyJobList?.result_list}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Active Job Popout */}
|
||||
{jobPopout.show && (
|
||||
<MarketPopUp
|
||||
details={jobPopout.data}
|
||||
onClose={() => {
|
||||
setJobPopout({ show: false, data: {} });
|
||||
}}
|
||||
situation={jobPopout.show}
|
||||
/>
|
||||
)}
|
||||
{/* End of Active Job Popout */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import MyWaitingJobTable from "./MyWaitingJobTable";
|
||||
|
||||
export default function MyWaitingJobs(props) {
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
console.log("AMEYE LOC1", props.MyJobList);
|
||||
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"}`}
|
||||
>
|
||||
Waiting Job(s)
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<div
|
||||
onClick={() => filterHandler("today")}
|
||||
className="relative"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<MyWaitingJobTable MyJobList={props.MyJobList} />
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,18 @@
|
||||
import React, {useState} from 'react'
|
||||
import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import InputCom from '../Helpers/Inputs/InputCom'
|
||||
|
||||
import AddFundDollars from './AddFundDollars'
|
||||
|
||||
function AddFund({payment}) {
|
||||
|
||||
const navigate = useNavigate()
|
||||
const {currency} = useLocation()?.state //GETS THE USER CURRENCY FOR ADD FUND
|
||||
|
||||
//STATE FOR CONTROLLED INPUT
|
||||
let [input, setInput] = useState('0')
|
||||
let [input, setInput] = useState('')
|
||||
|
||||
let [inputError, setInputError] = useState('')
|
||||
|
||||
@@ -23,15 +26,15 @@ function AddFund({payment}) {
|
||||
setInputError('')
|
||||
if(!input || input == '0'){
|
||||
setInputError('Please Enter Amount')
|
||||
return
|
||||
return setTimeout(()=>{setInputError('')}, 5000)
|
||||
}
|
||||
|
||||
if(isNaN(input)){
|
||||
setInputError('Amount must be a Number')
|
||||
return
|
||||
return setTimeout(()=>{setInputError('')}, 5000)
|
||||
}
|
||||
|
||||
const stateData = {amount: Number(input)}
|
||||
const stateData = {amount: Number(input), currency: 'naira'}
|
||||
navigate('confirm-add-fund', {state: stateData})
|
||||
|
||||
setInput('')
|
||||
@@ -79,18 +82,27 @@ function AddFund({payment}) {
|
||||
<div className="field w-full mb-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Amount(Naira)"
|
||||
label={currency == 'US Dollars' ? "Amount (USD)" : "Amount (Naira)"}
|
||||
type="text"
|
||||
name="amount"
|
||||
placeholder="Amount"
|
||||
placeholder="0"
|
||||
value={input}
|
||||
inputHandler={handleChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
/>
|
||||
{inputError && <p className='text-base text-red-500'>{inputError}</p>}
|
||||
</div>
|
||||
</form>
|
||||
<hr />
|
||||
|
||||
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
||||
{currency == 'US Dollars' &&
|
||||
<div className='w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow'>
|
||||
<AddFundDollars setInputError={setInputError} input={input} setInput={setInput} />
|
||||
</div>
|
||||
}
|
||||
|
||||
{/* HIDES THIS BUTTON IF CURENCY IS NAIRA */}
|
||||
{currency != 'US Dollars' &&
|
||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
@@ -100,10 +112,13 @@ function AddFund({payment}) {
|
||||
<span className="text-white">Continue</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
|
||||
{currency != 'US Dollars' &&
|
||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
@@ -117,6 +132,7 @@ function AddFund({payment}) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
import React,{useEffect, useState} from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import InputCom from '../Helpers/Inputs/InputCom';
|
||||
import PaginatedList from '../Pagination/PaginatedList';
|
||||
import { handlePagingFunc } from '../Pagination/HandlePagination';
|
||||
import LoadingSpinner from '../Spinners/LoadingSpinner';
|
||||
import usersService from '../../services/UsersService';
|
||||
|
||||
import { Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(50, "Maximum 50 characters")
|
||||
.required("Name is required"),
|
||||
cardNum: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Card Number is required"),
|
||||
code: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Postal Code is required"),
|
||||
state: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("State is required"),
|
||||
address: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(50, "Maximum 50 characters")
|
||||
.required("Address is required"),
|
||||
expirationYear: Yup.string()
|
||||
.min(4, "Minimum 4 characters")
|
||||
.max(4, "Maximum 4 characters")
|
||||
.required("Expiration Year is required"),
|
||||
expirationMonth: Yup.string()
|
||||
.min(1, "Minimum 1 characters")
|
||||
.max(2, "Maximum 2 characters")
|
||||
.required("Expiration Month is required"),
|
||||
cvv: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(4, "Maximum 4 characters")
|
||||
.required("CVV Year is required"),
|
||||
});
|
||||
|
||||
const initialValues = {
|
||||
name: '',
|
||||
cardNum: '',
|
||||
code: '',
|
||||
state: '',
|
||||
address: '',
|
||||
expirationYear: '',
|
||||
expirationMonth: '',
|
||||
cvv: ''
|
||||
};
|
||||
|
||||
|
||||
function AddFundDollars(props) {
|
||||
const navigate = useNavigate()
|
||||
let apiCall = new usersService()
|
||||
|
||||
let [tab, setTab] = useState("previous"); //STATE FOR SWITCHING BETWEEN TABS
|
||||
|
||||
let [prevCardDetails, setPrevCardDetails] = useState(null) // STATE TO HOLD PREVIOUS CARD SELECTED
|
||||
|
||||
let [payListCard, setPayListCard] = useState({loading: true, data:[]}) //USER PREVIOUS CARDS
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentPreviousCards = payListCard?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e,setCurrentPage)
|
||||
}
|
||||
|
||||
// FUNCTION TO SUBMIT
|
||||
const handleSubmit = (values, helpers) => {
|
||||
props.setInputError('')
|
||||
if(!props.input || props.input == '0'){
|
||||
props.setInputError('Please Enter Amount')
|
||||
return setTimeout(()=>{props.setInputError('')}, 5000)
|
||||
}
|
||||
|
||||
if(isNaN(props.input)){
|
||||
props.setInputError('Amount must be a Number')
|
||||
return setTimeout(()=>{props.setInputError('')}, 5000)
|
||||
}
|
||||
if(tab == 'previous'){
|
||||
const stateData = {amount: Number(props.input), currency: 'dollars'}
|
||||
navigate('confirm-add-fund', {state: stateData}) // State will change later dummy for now
|
||||
}
|
||||
if(tab == 'new'){
|
||||
const stateData = {amount: Number(props.input), currency: 'dollars', ...values}
|
||||
navigate('confirm-add-fund', {state: stateData}) // State will change later dummy for now
|
||||
}
|
||||
props.setInput('')
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
apiCall.payListCard().then(res => {
|
||||
setPayListCard({loading: false, data: res.data.result_list})
|
||||
}).catch(err => {
|
||||
console.log('PAYCARDLIST ERROR', err)
|
||||
setPayListCard({loading: false, data: []})
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className='mb-2 text-xl font-bold text-dark-gray dark:text-white'>Payment Method</h1>
|
||||
<div className="w-full">
|
||||
{/* switch button */}
|
||||
<div className="my-1 flex items-center border-b border-slate-300">
|
||||
<button
|
||||
name="previous"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "previous" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
Previous Cards
|
||||
</button>
|
||||
<button
|
||||
name="new"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "new" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
Add New Card
|
||||
</button>
|
||||
</div>
|
||||
{/* END OF switch button */}
|
||||
|
||||
{/* previous tab */}
|
||||
{tab == 'previous' ?
|
||||
<div className="p-4 previous-details w-full border min-h-[300px] flex flex-col justify-between items-center">
|
||||
{ payListCard.loading ?
|
||||
<LoadingSpinner size='10' color='sky-blue' />
|
||||
:
|
||||
payListCard?.data?.length ?
|
||||
<table className="my-3 w-full">
|
||||
<tbody>
|
||||
{currentPreviousCards.map((item, index)=>(
|
||||
<tr key={index} className={index != 0 && 'border-t-2'}>
|
||||
<td>
|
||||
<div className='my-2 flex items-center gap-5'>
|
||||
<input type="radio" className='w-8 h-8' name='card' value='value' />
|
||||
<div className='card-details'>
|
||||
<h1 className='text-lg font-bold text-dark-gray dark:text-white tracking-wide'>{item.description} Card</h1>
|
||||
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>Bank **************{item.digits}</p>
|
||||
<div className='w-full sm:flex items-center gap-5'>
|
||||
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>{item.added}</p>
|
||||
<p className='text-sm font-bold text-green-700 dark:text-white tracking-wide'>Verified</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
// onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Manage</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
:
|
||||
<div className='w-full flex flex-col items-center'>
|
||||
<p className='my-5 text-base font-bold text-dark-gray dark:text-white tracking-wide'>No Previous Card Found!</p>
|
||||
<button
|
||||
onClick={()=> setTab('new')}
|
||||
type="button"
|
||||
className="my-5 px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Add Card</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
{/* PAGINATION BUTTON */}
|
||||
<div className='w-full'>
|
||||
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= payListCard?.data?.length ? true : false} data={payListCard?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
|
||||
</div>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
:
|
||||
<div className="new-details w-full min-h-[300px] border-t">
|
||||
<div className="w-full flex flex-col justify-between">
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form>
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="flex-1 sm:mr-10">
|
||||
<div className="fields w-full">
|
||||
{/* inputs starts here */}
|
||||
{/* Name */}
|
||||
<div className="field w-full my-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="Name on Card"
|
||||
type="text"
|
||||
name="name"
|
||||
placeholder="DUMMY NAME"
|
||||
value={props.values.name}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.name && props.touched.name && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.name}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* CARD NUMBER */}
|
||||
<div className="field w-full mb-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
iconName='master-card visa-card atm-card'
|
||||
label="Card Number"
|
||||
type="text"
|
||||
name="cardNum"
|
||||
placeholder="Enter Card Number"
|
||||
value={props.values.cardNum}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.cardNum && props.touched.cardNum && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.cardNum}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{/* EXPIRE YEAR, YEAR AND CVV */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 mb-6">
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div className={`flex items-center justify-between mb-2.5`}>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||
htmlFor='expiration'
|
||||
>Expiration Month <span className="text-red-700 text-sm tracking-wide">*</span></label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationMonth}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name='expirationMonth'
|
||||
>
|
||||
<option value=''>Select...</option>
|
||||
{expireMonth?.length &&
|
||||
expireMonth.map((item, index) => (
|
||||
<option key={index} value={item.value}>{item.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{props.errors.expirationMonth && props.touched.expirationMonth && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.expirationMonth}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div className={`flex items-center justify-between mb-2.5`}>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||
htmlFor='expiration'
|
||||
>Expiration Year <span className="text-red-700 text-sm tracking-wide">*</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationYear}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name='expirationYear'
|
||||
>
|
||||
<option value=''>Select...</option>
|
||||
{expireYear?.length &&
|
||||
expireYear.map((item, index) => (
|
||||
<option key={index} value={item}>{item}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{props.errors.expirationYear && props.touched.expirationYear && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.expirationYear}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="field w-full col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
iconName='atm-card'
|
||||
label="CVV"
|
||||
type="text"
|
||||
name="cvv"
|
||||
placeholder="CVV"
|
||||
value={props.values.cvv}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.cvv && props.touched.cvv && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.cvv}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* Address */}
|
||||
<div className="field w-full my-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="Billing Address"
|
||||
type="text"
|
||||
name="address"
|
||||
placeholder="Billing Address"
|
||||
value={props.values.Address}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.address && props.touched.address && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.address}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{/* postal code and state */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 mb-6">
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="Postal Code"
|
||||
type="text"
|
||||
name="code"
|
||||
placeholder="Postal Code"
|
||||
value={props.values.code}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.code && props.touched.code && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.code}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="field w-full col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="State"
|
||||
type="text"
|
||||
name="state"
|
||||
placeholder="State"
|
||||
value={props.values.state}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.state && props.touched.state && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.state}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <div className="w-full">
|
||||
{requestStatus.message != "" && (
|
||||
<p
|
||||
className={`text-center text-base ${
|
||||
requestStatus.status ? "text-green-800" : "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</p>
|
||||
)}
|
||||
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||
<div className="flex items-center space-x-4 mr-9">
|
||||
<Link
|
||||
to="/"
|
||||
className="text-18 text-light-red tracking-wide "
|
||||
>
|
||||
<span className="border-b dark:border-[#5356fb29] border-light-red">
|
||||
{" "}
|
||||
Cancel
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<button
|
||||
type="submit"
|
||||
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Update Profile
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Continue</span>
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{ tab == 'previous' &&
|
||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Continue</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddFundDollars
|
||||
|
||||
|
||||
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
|
||||
const expireYear = []
|
||||
let currentYear = new Date().getFullYear()
|
||||
for(let i=0; i<=6; i++){
|
||||
expireYear.push(currentYear + i)
|
||||
}
|
||||
|
||||
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
|
||||
let month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
const expireMonth = []
|
||||
for(let i=0; i<month.length; i++){
|
||||
expireMonth.push({name:month[i], value:i+1})
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
||||
import PurchasesTable from './WalletComponent/PurchasesTable'
|
||||
import CouponTable from './WalletComponent/CouponTable'
|
||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
||||
import { PriceFormatter } from '../Helpers/PriceFormatter'
|
||||
|
||||
function Balance({wallet, coupon}) {
|
||||
return (
|
||||
@@ -42,11 +43,11 @@ function Balance({wallet, coupon}) {
|
||||
</div>
|
||||
<div className='balance-info'>
|
||||
<p className='py-2'>Balance</p>
|
||||
<span className='py-1 px-2 bg-green-100 text-green-500 rounded-lg'>{item.symbol}{(item.amount*0.01).toFixed(2)}</span>
|
||||
<span className='py-1 px-2 bg-green-100 text-green-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.amount * 0.01, item.code)}</span>
|
||||
</div>
|
||||
<div className='balance-info'>
|
||||
<p className='py-2'>Escrow</p>
|
||||
<span className='py-1 px-2 bg-red-100 text-red-500 rounded-lg'>{item.symbol}{(item.escrow*0.01).toFixed(2)}</span>
|
||||
<span className='py-1 px-2 bg-red-100 text-red-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.escrow * 0.01, item.code)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -55,7 +56,7 @@ function Balance({wallet, coupon}) {
|
||||
item.action_type != 'AC_AD_FD_ONLY' ?
|
||||
<Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:''
|
||||
}
|
||||
<Link to='add-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'>
|
||||
<Link to='add-fund' state={{currency:item.description}} className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'>
|
||||
<span className="">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="38"
|
||||
height="38" viewBox="0 0 42 42" fill="none"><path
|
||||
|
||||
@@ -50,7 +50,6 @@ function ConfirmAddFund({ payment }) {
|
||||
toast.success("Account Topup was sucessful");
|
||||
setTimeout(() => {
|
||||
navigate("/my-wallet", { replace: true });
|
||||
window.location.reload(true);
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -102,11 +101,11 @@ function ConfirmAddFund({ payment }) {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||
<div className="content-wrapper w-full">
|
||||
{pageLoading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
||||
<div className="w-full mb-10">
|
||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
<h2 className="md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||
Confirm Add Fund To Account
|
||||
@@ -116,7 +115,7 @@ function ConfirmAddFund({ payment }) {
|
||||
<div className="field w-full mb-3">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Amount (Naira):"
|
||||
label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
|
||||
type="text"
|
||||
name="amount"
|
||||
value={state.amount || ""}
|
||||
@@ -127,16 +126,26 @@ function ConfirmAddFund({ payment }) {
|
||||
|
||||
<hr />
|
||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
|
||||
<FlutterWaveButton
|
||||
{...fwConfig}
|
||||
{
|
||||
state.currency == 'naira' ?
|
||||
<FlutterWaveButton
|
||||
{...fwConfig}
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
/>
|
||||
:
|
||||
<button
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
/>
|
||||
onClick={()=>console.log('WORKING')}
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
||||
<div className="w-full mb-10">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||
Recent Activity
|
||||
|
||||
@@ -15,11 +15,11 @@ function PurchasesTable({purchase}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='flex flex-col justify-between h-full'>
|
||||
<div className='flex flex-col justify-between min-h-[500px]'>
|
||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||
<thead className='border-b-2'>
|
||||
<tr className='text-slate-600'>
|
||||
<th className="p-4">Trx.</th>
|
||||
<th className="p-2">Trx.</th>
|
||||
<th className="p-2">Amount</th>
|
||||
<th className="p-2">Fee</th>
|
||||
</tr>
|
||||
@@ -29,7 +29,7 @@ function PurchasesTable({purchase}) {
|
||||
<tbody>
|
||||
{currentPurchase.map((item, index) => (
|
||||
<tr key={index} className='text-slate-500'>
|
||||
<td className="p-4">{item.added_date}<br />
|
||||
<td className="p-2">{item.added_date}<br />
|
||||
<b>{item.confirmation} </b>
|
||||
</td>
|
||||
<td className="p-2">{item.amount}</td>
|
||||
|
||||
@@ -15,7 +15,7 @@ function RecentActivityTable({payment}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='flex flex-col justify-between h-full'>
|
||||
<div className='flex flex-col justify-between min-h-[500px]'>
|
||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||
<thead className='border-b-2'>
|
||||
<tr className='text-slate-600'>
|
||||
|
||||
@@ -1,60 +1,73 @@
|
||||
import React, {useState} from 'react'
|
||||
import { useState } from "react";
|
||||
import PaginatedList from "../../Pagination/PaginatedList";
|
||||
import { handlePagingFunc } from "../../Pagination/HandlePagination";
|
||||
|
||||
import PaginatedList from '../../Pagination/PaginatedList';
|
||||
import {handlePagingFunc} from '../../Pagination/HandlePagination';
|
||||
function ReferralTable({ history }) {
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentReferral = history?.data?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
function ReferralTable({history}) {
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentReferral = history?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e,setCurrentPage)
|
||||
}
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='flex flex-col justify-between min-h-[420px] overflow-x-auto'>
|
||||
<table className="referral-list w-full table-auto border-collapse text-left">
|
||||
<thead className='border-b-2'>
|
||||
<tr className='text-slate-600'>
|
||||
<th className="p-3">Added/Name</th>
|
||||
<th className="p-3">Email</th>
|
||||
<th className="p-3">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{history.data.length ?
|
||||
currentReferral.map((item, index) => (
|
||||
<tr key={index} className='text-slate-500'>
|
||||
<td className="p-3">{item.added_date} / {item.firstname} {item.lastname}</td>
|
||||
<td className="p-3">{item.email}</td>
|
||||
<td className="p-3">{item.status}</td>
|
||||
</tr>
|
||||
))
|
||||
:
|
||||
(
|
||||
history.error ?
|
||||
<tr className='text-slate-500'>
|
||||
<td colSpan={3}>Opps! couldn't get referral history. Try reloading the page</td>
|
||||
</tr>
|
||||
:
|
||||
(
|
||||
<tr className='text-slate-500'>
|
||||
<td colSpan={3}>No Item Found on referral List</td>
|
||||
</tr>
|
||||
)
|
||||
)
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="flex flex-col justify-between min-h-[420px] overflow-x-auto">
|
||||
<table className="referral-list w-full table-auto border-collapse text-left">
|
||||
<thead className="border-b-2">
|
||||
<tr className="text-slate-600">
|
||||
<th className="p-3">Added/Name</th>
|
||||
<th className="p-3">Email</th>
|
||||
<th className="p-3">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{history.data.length ? (
|
||||
currentReferral.map((item, index) => (
|
||||
<tr key={index} className="text-slate-500">
|
||||
<td className="p-3">
|
||||
{item.added_date} / {item.firstname} {item.lastname}
|
||||
</td>
|
||||
<td className="p-3">{item.email}</td>
|
||||
<td className="p-3">{item.status}</td>
|
||||
</tr>
|
||||
))
|
||||
) : history.error ? (
|
||||
<tr className="text-slate-500">
|
||||
<td colSpan={3}>
|
||||
Opps! couldn't get referral history. Try reloading the page
|
||||
</td>
|
||||
</tr>
|
||||
) : (
|
||||
<tr className="text-slate-500">
|
||||
<td colSpan={3}>No Item Found on referral List</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= history?.data?.length ? true : false} data={history?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
history?.data?.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={history?.data}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default ReferralTable
|
||||
export default ReferralTable;
|
||||
|
||||
@@ -5,6 +5,7 @@ import bank2 from "../../assets/images/bank-2.png";
|
||||
import bank3 from "../../assets/images/bank-3.png";
|
||||
import bank4 from "../../assets/images/bank-4.png";
|
||||
import Accordion from "../Helpers/Accordion";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
|
||||
export default function WalletHeader(props) {
|
||||
// debugger;
|
||||
@@ -58,10 +59,7 @@ export default function WalletHeader(props) {
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-purple">
|
||||
{(value.amount * 0.01).toFixed(2)} {value.code}
|
||||
</p>
|
||||
<p className="usd text-base text-thin-light-gray text-right">
|
||||
{/*(773.69 USD)*/}
|
||||
{PriceFormatter(value.amount * 0.01, value.code)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,6 @@ import Layout from "../Partials/Layout";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
|
||||
import usersService from "../../services/UsersService";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import OthersInterestedTable from "./OthersInterestedTable";
|
||||
|
||||
@@ -15,25 +13,64 @@ export default function ManageInterestOffer(props) {
|
||||
|
||||
let [redirectTime, setRedirectTime] = useState(5)
|
||||
|
||||
let [messageToSend, setMessageToSend] = useState('')
|
||||
|
||||
let [tab, setTab] = useState("info"); //message STATE FOR SWITCHING BETWEEN TABS
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: '', processType: ''})
|
||||
|
||||
const messageList = {data: [1,2,3,4,5,6]} // TO BE REMOVED AND REPLACE WITH REAL MESSAGE FROM API CALL
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem = Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentMessageList = messageList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
let [messageListReload, setMessageListReload] = useState(false) // STATE TO DETERMINE WHEN MESSAGE LIST WILL RELOAD
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
const [messageList, setMessageList] = useState({loading: true, data: []}) // TO BE REMOVED AND REPLACE WITH REAL MESSAGE FROM API CALL
|
||||
|
||||
const [selectTab, setValue] = useState("today");
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
|
||||
//FUNCTION TO HANDLE ON CHANGE MESSAGE IN TEXTAREA
|
||||
const onMessageChange = ({target:{value}}) => {
|
||||
if(messageToSend.length > 149){
|
||||
setRequestStatus({loading: false, status: false, message: 'max of 150 characters', processType: 'sendmessage'})
|
||||
}else{
|
||||
setRequestStatus({loading: false, status: false, message: '', processType: 'sendmessage'})
|
||||
}
|
||||
setMessageToSend(value)
|
||||
}
|
||||
|
||||
//FUNCTION TO SEND MESSAGE TO CLIENT
|
||||
const sendMessage = () => {
|
||||
let reqData = { // API PAYLOADS
|
||||
msg_type: 'MRKTINT',
|
||||
yourmessage: messageToSend,
|
||||
offer_uid: props.offerDetails.offer_uid,
|
||||
interest_uid: props.offerDetails.interest_uid
|
||||
}
|
||||
setRequestStatus(prev => ({...prev, loading: true, processType: 'sendmessage'}))
|
||||
if(!messageToSend){
|
||||
setRequestStatus({loading: false, status: false, message: 'Please enter message to send', processType: 'sendmessage'})
|
||||
return
|
||||
}
|
||||
if(messageToSend.length > 149){
|
||||
return
|
||||
}
|
||||
apiCall.offerInterestMsg(reqData).then(res=>{
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
setRequestStatus({loading: false, status: false, message: 'message not sent, try again', processType: 'sendmessage'})
|
||||
return
|
||||
}
|
||||
setRequestStatus({loading: false, status: true, message: 'message sent', processType: 'sendmessage'})
|
||||
setMessageToSend('') // sets message to empty strings
|
||||
setMessageListReload(prev => !prev) //A FUNCTION TO MAKE MESSAGE LIST RELOAD
|
||||
}).catch(error => {
|
||||
setRequestStatus({loading: false, status: false, message: 'Opps, an error occured', processType: 'sendmessage'})
|
||||
}).finally(()=>{
|
||||
setTimeout(() => {
|
||||
setRequestStatus({loading: false, status: false, message: '', processType: ''})
|
||||
}, 5000);
|
||||
})
|
||||
}
|
||||
|
||||
//FUNCTION TO ACCEPT/REJECT OFFER INTEREST
|
||||
const interestOfferProcess = ({target:{name}}) => {
|
||||
setRequestStatus(prev => ({...prev, loading: true, processType: name}))
|
||||
@@ -48,12 +85,13 @@ export default function ManageInterestOffer(props) {
|
||||
setRequestStatus({loading: false, status: false, message: 'Unable to complete request', processType: ''})
|
||||
return
|
||||
}
|
||||
setInterval(() => { // SETS REDIRECT COUNT DOWN
|
||||
let intervalTime = setInterval(() => { // SETS REDIRECT COUNT DOWN
|
||||
setRedirectTime(prev => prev - 1)
|
||||
}, 1000);
|
||||
setRequestStatus({loading: false, status: true, message: `Offer ${name}ed`, processType: ''})
|
||||
setTimeout(()=>{
|
||||
navigate('/offer-interest', {replace: true})
|
||||
clearInterval(intervalTime)
|
||||
},5000)
|
||||
}).catch(err => {
|
||||
setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong. Try again', processType: ''})
|
||||
@@ -64,9 +102,20 @@ export default function ManageInterestOffer(props) {
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
// run API to get message to replace message array above, add reload variable as dependence array
|
||||
},[])
|
||||
useEffect(()=>{ //API to get Offer Interest message list
|
||||
let reqData = { // API PAYLOADS
|
||||
msg_type: 'MRKTINT',
|
||||
offer_uid: props.offerDetails?.offer_uid,
|
||||
interest_uid: props.offerDetails?.interest_uid
|
||||
}
|
||||
setMessageList(prev => ({...prev, loading: true}))
|
||||
apiCall.offerInterestListMsg(reqData).then(res=>{
|
||||
setMessageList({loading: false, data:res?.data?.result_list})
|
||||
}).catch(err => {
|
||||
setMessageList(prev => ({...prev, loading: false}))
|
||||
console.log('Failed', err)
|
||||
})
|
||||
},[messageListReload])
|
||||
return (
|
||||
<Layout>
|
||||
<CommonHead
|
||||
@@ -142,13 +191,15 @@ export default function ManageInterestOffer(props) {
|
||||
{/* info tab */}
|
||||
{tab == 'info' ?
|
||||
<div className="info-details w-full border-t">
|
||||
<div className="my-3 flex items-center gap-1">
|
||||
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Name</span>
|
||||
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_name}</span>
|
||||
</div>
|
||||
<div className="my-3 flex items-center gap-1">
|
||||
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Member Since</span>
|
||||
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_added}</span>
|
||||
<div className="my-0 md:my-3 block md:flex items-center gap-10">
|
||||
<div className="my-3 md:my-0 flex items-center gap-1">
|
||||
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Name</span>
|
||||
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_name}</span>
|
||||
</div>
|
||||
<div className="my-3 md:my-0 flex items-center gap-1">
|
||||
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Member Since</span>
|
||||
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_added}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="my-3 flex items-center gap-1">
|
||||
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Jobs completed</span>
|
||||
@@ -177,45 +228,67 @@ export default function ManageInterestOffer(props) {
|
||||
</div>
|
||||
:
|
||||
<div className="message-details w-full border-t">
|
||||
<div className="my-0 w-full flex items-center gap-5">
|
||||
<div className="w-3/4">
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">Message to dummy name</p>
|
||||
<textarea rows={2} autoFocus={true} className="p-2 text-base font-bold text-dark-gray dark:text-white dark:bg-dark-gray border tracking-wide w-full resize-none rounded-md outline-none" />
|
||||
<p className="my-1 text-base text-dark-gray dark:text-white tracking-wide">To: <span className="font-bold">{props.offerDetails?.client_name}</span></p>
|
||||
<div className="w-full flex items-center gap-5">
|
||||
<div className="w-full">
|
||||
<textarea
|
||||
value={messageToSend}
|
||||
onChange={onMessageChange}
|
||||
rows={2} autoFocus={true}
|
||||
className="p-2 text-base font-bold text-dark-gray dark:text-white dark:bg-dark-gray border tracking-wide w-full resize-none rounded-md outline-none"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/4 flex flex-col justify-center items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Send</span>
|
||||
</button>
|
||||
<div className="flex justify-end items-center">
|
||||
{requestStatus.loading && requestStatus.processType == 'sendmessage' ?
|
||||
<LoadingSpinner color='sky-blue' size='10' />
|
||||
:
|
||||
<button
|
||||
type="button"
|
||||
onClick={sendMessage}
|
||||
disabled={requestStatus.loading}
|
||||
// className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
className="w-[100px] h-[50px] bg-sky-blue text-center text-lg font-semibold text-white rounded-md shadow-md flex justify-center items-center"
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{/* message list */}
|
||||
<div className="min-h-[100px] max-h-[200px] overflow-y-auto">
|
||||
{currentMessageList.map((item, index)=>(
|
||||
<div key={index} className="my-2 w-full flex items-center gap-1">
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">2023-04-06-from { }<span className="font-normal">Dummy name</span></p>
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">I am testing message</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
messageList?.data?.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={messageList?.data}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
{/* ERROR DISPLAY FOR MESSAGE SENDING */}
|
||||
<div className="w-full">
|
||||
{/* error or success display */}
|
||||
{requestStatus.message != "" && requestStatus.processType == 'sendmessage' &&
|
||||
(!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>
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
{/* END OF ERROR DISPLAY FOR MESSAGE SENDING */}
|
||||
|
||||
{/* message list */}
|
||||
<div className="my-1 min-h-[100px] max-h-[200px] border-t overflow-y-scroll">
|
||||
{ messageList.loading ?
|
||||
<LoadingSpinner color='sky-blue' size='16' />
|
||||
: messageList?.data?.map((item, index)=>(
|
||||
<div key={index} className="my-2 w-full flex items-center gap-1">
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">{item.added.split(' ')[0]}-from { }<span className="font-normal">{item.sender || 'Dummy name'}</span></p>
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">{item.msg}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -225,7 +298,7 @@ export default function ManageInterestOffer(props) {
|
||||
{/* BUTTON section */}
|
||||
<div className="p-4 w-full min-h-full bg-sky-100 dark:bg-dark-gray col-span-1">
|
||||
<div className="w-full h-full">
|
||||
<div className="mt-0 sm:mt-10 flex sm:flex-col justify-center items-center gap-10">
|
||||
<div className="h-full flex sm:flex-col justify-center items-center gap-10">
|
||||
{requestStatus.loading && requestStatus.processType == 'accept' ?
|
||||
<LoadingSpinner color='sky-blue' size='10' />
|
||||
:
|
||||
@@ -234,9 +307,10 @@ export default function ManageInterestOffer(props) {
|
||||
name='accept'
|
||||
disabled={requestStatus.loading}
|
||||
onClick={interestOfferProcess}
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
// className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
className='max-w-[150px] h-[100px] bg-[#57cd89] text-center text-lg font-semibold text-white py-2 px-4 rounded-md shadow-md'
|
||||
>
|
||||
Accept
|
||||
Accept this Interest
|
||||
</button>
|
||||
}
|
||||
|
||||
@@ -248,9 +322,10 @@ export default function ManageInterestOffer(props) {
|
||||
name='reject'
|
||||
disabled={requestStatus.loading}
|
||||
onClick={interestOfferProcess}
|
||||
className="px-2 py-1 h-11 flex justify-center items-center border-gradient text-base rounded-full text-black"
|
||||
// className="px-2 py-1 h-11 flex justify-center items-center border-gradient text-base rounded-full text-black"
|
||||
className='max-w-[150px] h-[100px] bg-red-300 text-center text-lg font-semibold text-white py-2 px-4 rounded-md shadow-md'
|
||||
>
|
||||
Reject
|
||||
Reject this Interest
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
@@ -258,7 +333,7 @@ export default function ManageInterestOffer(props) {
|
||||
{/* ERROR DISPLAY */}
|
||||
<div className="w-full">
|
||||
{/* error or success display */}
|
||||
{requestStatus.message != "" && requestStatus.processType != 'sendmeassge' &&
|
||||
{requestStatus.message != "" && requestStatus.processType != 'sendmessage' &&
|
||||
(!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]`}
|
||||
@@ -284,6 +359,7 @@ export default function ManageInterestOffer(props) {
|
||||
{/* END OF manage offer section */}
|
||||
</div>
|
||||
|
||||
{props.othersInterestedList?.data?.length ?
|
||||
<div className="w-full overflow-x-auto">
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-3">
|
||||
@@ -295,6 +371,9 @@ export default function ManageInterestOffer(props) {
|
||||
</div>
|
||||
<OthersInterestedTable othersInterestedList={props.othersInterestedList} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -107,19 +107,7 @@ export default function OffersInterestTable({offerInterestList, className}) {
|
||||
:
|
||||
(
|
||||
<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">No Offer list avaliable.</p>
|
||||
<button
|
||||
onClick={()=>{navigate('/market', {replace: true})}}
|
||||
type="button"
|
||||
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
|
||||
>
|
||||
Goto Market
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-2 w-full md:w-1/2">
|
||||
<img className='w-full' src={familyImage && familyImage} alt="Add Family" />
|
||||
</div>
|
||||
<p className="mb-4 p-3">No list avaliable.</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, {useEffect, useState} from "react";
|
||||
import React, { useState} from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import useToggle from "../../hooks/useToggle";
|
||||
import { drawerToggle } from "../../store/drawer";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
|
||||
@@ -225,9 +225,10 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
|
||||
<ul className="flex flex-col space-y-6">
|
||||
<ListItem
|
||||
title="Add Job"
|
||||
route="/add-job"
|
||||
route="/myjobs"
|
||||
iconName="people-two"
|
||||
sidebar={sidebar}
|
||||
state={true}
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -301,11 +302,12 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
|
||||
);
|
||||
}
|
||||
|
||||
const ListItem = ({ sidebar, route, title, bubble }) => {
|
||||
const ListItem = ({ sidebar, route, title, bubble, popup }) => {
|
||||
return (
|
||||
<li className="item group">
|
||||
<NavLink
|
||||
to={route}
|
||||
state={popup ? { popup: true } : { popup: false }}
|
||||
className={`nav-item flex items-center ${
|
||||
((navData) => (navData.isActive ? "active" : ""),
|
||||
sidebar ? "justify-start space-x-3.5" : "justify-center")
|
||||
|
||||
@@ -8,7 +8,12 @@ import {
|
||||
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||
import Icons from "../Helpers/Icons";
|
||||
|
||||
export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList }) {
|
||||
export default function Sidebar({
|
||||
sidebar,
|
||||
action,
|
||||
logoutModalHandler,
|
||||
myJobList,
|
||||
}) {
|
||||
const darkMode = useContext(DarkModeContext);
|
||||
|
||||
let { userDetails } = useSelector((state) => state.userDetails);
|
||||
@@ -131,27 +136,25 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
|
||||
|
||||
{/* menu and settings item */}
|
||||
{userDetails?.account_type !== "FAMILY" && (
|
||||
<div
|
||||
className={`menu-item transition-all duration-300 ease-in-out ${
|
||||
sidebar ? "my-5" : ""
|
||||
}`}
|
||||
>
|
||||
<div className="heading mb-5">
|
||||
<h1 className="title text-xl font-bold text-purple">
|
||||
Family
|
||||
</h1>
|
||||
</div>
|
||||
<div className="items">
|
||||
<ul className="flex flex-col space-y-6">
|
||||
<ListItem
|
||||
title="Family Corner"
|
||||
route="/acc-family"
|
||||
iconName="people-two"
|
||||
sidebar={sidebar}
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className={`menu-item transition-all duration-300 ease-in-out ${
|
||||
sidebar ? "my-5" : ""
|
||||
}`}
|
||||
>
|
||||
<div className="heading mb-5">
|
||||
<h1 className="title text-xl font-bold text-purple">Family</h1>
|
||||
</div>
|
||||
<div className="items">
|
||||
<ul className="flex flex-col space-y-6">
|
||||
<ListItem
|
||||
title="Family Corner"
|
||||
route="/acc-family"
|
||||
iconName="people-two"
|
||||
sidebar={sidebar}
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{userDetails?.account_type !== "FAMILY" && (
|
||||
<>
|
||||
@@ -249,9 +252,10 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
|
||||
<ul className="flex flex-col space-y-6">
|
||||
<ListItem
|
||||
title="Add Job"
|
||||
route="/add-job"
|
||||
route="/myjobs"
|
||||
iconName="people-two"
|
||||
sidebar={sidebar}
|
||||
popup={true}
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -325,11 +329,12 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
|
||||
);
|
||||
}
|
||||
|
||||
const ListItem = ({ sidebar, route, title, bubble, iconName }) => {
|
||||
const ListItem = ({ sidebar, route, title, bubble, iconName, popup }) => {
|
||||
return (
|
||||
<li className={`item group`}>
|
||||
<NavLink
|
||||
to={route}
|
||||
state={popup ? { popup: true } : { popup: false }}
|
||||
className={`nav-item flex items-center ${
|
||||
((navData) => (navData.isActive ? "active" : ""),
|
||||
sidebar ? "justify-start space-x-3.5" : "justify-center")
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from 'react'
|
||||
import Layout from '../Partials/Layout'
|
||||
import ReferralDisplay from './ReferralDisplay'
|
||||
import React from "react";
|
||||
import Layout from "../Partials/Layout";
|
||||
import ReferralDisplay from "./ReferralDisplay";
|
||||
|
||||
function Referral() {
|
||||
return (
|
||||
<Layout>
|
||||
<ReferralDisplay />
|
||||
<ReferralDisplay />
|
||||
</Layout>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default Referral
|
||||
export default Referral;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import usersService from "../../services/UsersService";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
@@ -10,30 +9,29 @@ import * as Yup from "yup";
|
||||
import ReferralTable from "../MyWallet/WalletComponent/ReferralTable";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
email: Yup.string()
|
||||
ref_email: Yup.string()
|
||||
.email("Wrong email format")
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(50, "Maximum 50 characters")
|
||||
.required("Email is required"),
|
||||
firstname: Yup.string()
|
||||
ref_firstname: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Firstname is required"),
|
||||
lastname: Yup.string()
|
||||
ref_lastname: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Lastname is required"),
|
||||
});
|
||||
|
||||
const initialValues = {
|
||||
firstname: "",
|
||||
lastname: "",
|
||||
email: "",
|
||||
ref_firstname: "",
|
||||
ref_lastname: "",
|
||||
ref_email: "",
|
||||
};
|
||||
|
||||
function ReferralDisplay() {
|
||||
const apiCall = new usersService(); // GET API CALL
|
||||
const navigate = useNavigate();
|
||||
|
||||
let [refHistoryReload, setRefHistoryReload] = useState(false); // Determines when referral history reloads
|
||||
|
||||
@@ -76,13 +74,13 @@ function ReferralDisplay() {
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setError({
|
||||
message: "Email already referred",
|
||||
message: res.data.status,
|
||||
loading: false,
|
||||
status: false,
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
toast.success("Message Sent");
|
||||
toast.success(res.data.status | "Message Sent!");
|
||||
setError({ message: "", loading: false, status: true });
|
||||
setRefHistoryReload((prev) => !prev);
|
||||
}
|
||||
@@ -99,16 +97,7 @@ function ReferralDisplay() {
|
||||
//FUNCTION TO HANDLE SUBMIT
|
||||
const handleSubmit = (values, helpers) => {
|
||||
setError({ message: "", loading: true, status: false });
|
||||
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11032,
|
||||
...values,
|
||||
};
|
||||
|
||||
sendReferralMsg(postData); // FUNCTION TO SEND REFERRAL MESSAGE
|
||||
sendReferralMsg({...values}); // FUNCTION TO SEND REFERRAL MESSAGE
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -121,12 +110,9 @@ function ReferralDisplay() {
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="mb-5 sm:mb-0">
|
||||
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||
<span>
|
||||
Refer a Friend
|
||||
</span>
|
||||
<span>Refer a Friend</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="referral w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
@@ -147,17 +133,18 @@ function ReferralDisplay() {
|
||||
fieldClass="px-6"
|
||||
label="Firstname"
|
||||
type="text"
|
||||
name="firstname"
|
||||
name="ref_firstname"
|
||||
placeholder="Firstname"
|
||||
value={props.values.firstname}
|
||||
value={props.values.ref_firstname}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.firstname && props.touched.firstname && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.firstname}
|
||||
</p>
|
||||
)}
|
||||
{props.errors.ref_firstname &&
|
||||
props.touched.ref_firstname && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.ref_firstname}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Lastname */}
|
||||
@@ -166,17 +153,18 @@ function ReferralDisplay() {
|
||||
fieldClass="px-6"
|
||||
label="Lastname"
|
||||
type="text"
|
||||
name="lastname"
|
||||
name="ref_lastname"
|
||||
placeholder="Lastname"
|
||||
value={props.values.lastname}
|
||||
value={props.values.ref_lastname}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.lastname && props.touched.lastname && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.lastname}
|
||||
</p>
|
||||
)}
|
||||
{props.errors.ref_lastname &&
|
||||
props.touched.ref_lastname && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.ref_lastname}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -185,14 +173,16 @@ function ReferralDisplay() {
|
||||
fieldClass="px-6"
|
||||
label="Email"
|
||||
type="text"
|
||||
name="email"
|
||||
name="ref_email"
|
||||
placeholder="Email"
|
||||
value={props.values.email}
|
||||
value={props.values.ref_email}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.email && props.touched.email && (
|
||||
<p className="text-sm text-red-500">{props.errors.email}</p>
|
||||
{props.errors.ref_email && props.touched.ref_email && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.ref_email}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -206,7 +196,8 @@ function ReferralDisplay() {
|
||||
) : (
|
||||
<button
|
||||
type="submit"
|
||||
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" >
|
||||
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Send Message
|
||||
</button>
|
||||
)}
|
||||
@@ -221,14 +212,12 @@ function ReferralDisplay() {
|
||||
Referral List
|
||||
</h2>
|
||||
{referralList.loading ? (
|
||||
<LoadingSpinner size="32" color="sky-blue" />
|
||||
<LoadingSpinner size="32" color="sky-blue" />
|
||||
) : (
|
||||
<ReferralTable history={referralList} />
|
||||
<ReferralTable history={referralList} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,140 +1,142 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import authProfilePic from "../../assets/images/auth-profile-picture.png";
|
||||
import profileBanner from "../../assets/images/profile-cover.png";
|
||||
import collections from "../../data/collectionplan_data.json";
|
||||
import marketPlace from "../../data/marketplace_data.json";
|
||||
// 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 LoadingSpinner from "../../components/Spinners/LoadingSpinner";
|
||||
import products from "../../data/product_data.json";
|
||||
import Layout from "../Partials/Layout";
|
||||
import ActivitiesTab from "./ActivitiesTab";
|
||||
import CollectionTab from "./CollectionTab";
|
||||
import CreatedTab from "./CreatedTab";
|
||||
import HiddenProductsTab from "./HiddenProductsTab";
|
||||
import OnSaleTab from "./OnSaleTab";
|
||||
import OwnTab from "./OwnTab";
|
||||
import {
|
||||
ActivitiesTab,
|
||||
CollectionTab,
|
||||
CreatedTab,
|
||||
HiddenProductsTab,
|
||||
OnSaleTab,
|
||||
OwnTab,
|
||||
} from "./tabs";
|
||||
|
||||
export default function Resources() {
|
||||
const onSaleProducts = marketPlace.data;
|
||||
const CreatedSell = marketPlace.data;
|
||||
const CreatedBits = products.datas;
|
||||
// const mainProducts = products.datas;
|
||||
export default function Resources(props) {
|
||||
// console.log("RESOURCES=>", props);
|
||||
const ownProducts = products.datas;
|
||||
const collectionProducts = collections.data;
|
||||
// Resource Props
|
||||
const __resources = props.MyResourceData;
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
id: 1,
|
||||
name: "onsale",
|
||||
content: "On Sale",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "owned",
|
||||
content: "Owned",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "created",
|
||||
content: "Created",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "hidden",
|
||||
content: "Hidden",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "collection",
|
||||
content: "Collection",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "activity",
|
||||
content: "Activity",
|
||||
},
|
||||
];
|
||||
// Collection Items
|
||||
const collectionProducts = __resources?.collectiondata?.data;
|
||||
const tab_categories = __resources?.tab_categories?.data;
|
||||
const onSaleProducts = __resources?.marketdata?.data;
|
||||
const CreatedSell = __resources?.marketdata?.data;
|
||||
const CreatedBits = __resources?.productdata?.data;
|
||||
|
||||
const [tab, setTab] = useState(tab_categories ? tab_categories[0]?.name : "");
|
||||
|
||||
const [tab, setTab] = useState(tabs[0].name);
|
||||
const tabHandler = (value) => {
|
||||
setTab(value);
|
||||
};
|
||||
|
||||
console.log("first")
|
||||
|
||||
// Category Components
|
||||
const tabComponents = {
|
||||
onsale: <OnSaleTab products={onSaleProducts} />,
|
||||
owned: <OwnTab products={ownProducts} />,
|
||||
created: (
|
||||
<CreatedTab marketProducts={CreatedSell} mainProducts={CreatedBits} />
|
||||
),
|
||||
hidden: (
|
||||
<HiddenProductsTab
|
||||
marketProducts={CreatedSell}
|
||||
mainProducts={CreatedBits}
|
||||
/>
|
||||
),
|
||||
collection: <CollectionTab products={collectionProducts} />,
|
||||
activity: <ActivitiesTab />,
|
||||
};
|
||||
|
||||
const defaultTabComponent = <OnSaleTab products={onSaleProducts} />;
|
||||
|
||||
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
||||
|
||||
// Tab Item Component
|
||||
const TabItem = ({ tabValue, isActive }) => {
|
||||
return (
|
||||
<li
|
||||
className={`relative group inline`}
|
||||
onClick={() => tabHandler(tabValue.name)}
|
||||
>
|
||||
<span
|
||||
className={`py-4 sm:border-b-none border-b group-hover:border-purple border-transparent lg:text-xl text-sm tracking-wide font-bold group-hover:text-purple text-dark-gray dark:text-white relative z-10 cursor-pointer ${
|
||||
isActive
|
||||
? "text-purple border-purple"
|
||||
: "text-dark-gray dark:text-white border-transparent"
|
||||
}`}
|
||||
>
|
||||
{tabValue.content}
|
||||
</span>
|
||||
<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]"
|
||||
}`}
|
||||
>
|
||||
16
|
||||
</span>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
// Tab List Component
|
||||
const TabList = ({ tabCategories }) => {
|
||||
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 === "")}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout>
|
||||
<div className="nft-authprofile-wrapper w-full">
|
||||
<div className="main-wrapper w-full">
|
||||
<div className="content-wrapper-profile-only w-full mb-6">
|
||||
<div className="auth-tab-content relative mb-10">
|
||||
<div className="lg:flex justify-between">
|
||||
<div className="tab-items">
|
||||
<ul className="lg:flex lg:space-x-14 space-x-8">
|
||||
{tabs &&
|
||||
tabs.length > 0 &&
|
||||
tabs.map((tabValue) => (
|
||||
<li
|
||||
key={tabValue.id}
|
||||
className="relative group inline"
|
||||
onClick={() => tabHandler(tabValue.name)}
|
||||
>
|
||||
<span
|
||||
className={`py-4 sm:border-b-none border-b group-hover:border-purple border-transparent lg:text-xl text-sm tracking-wide font-bold group-hover:text-purple text-dark-gray dark:text-white relative z-10 cursor-pointer ${
|
||||
tab === tabValue.name
|
||||
? "text-purple border-purple "
|
||||
: "text-dark-gray dark:text-white border-transparent "
|
||||
}`}
|
||||
>
|
||||
{tabValue.content}
|
||||
</span>
|
||||
<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 ${
|
||||
tab === tabValue.name
|
||||
? "text-white bg-pink"
|
||||
: "text-thin-light-gray bg-[#F2B8FD]"
|
||||
}`}
|
||||
>
|
||||
16
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ transform: "translateY(-22px)" }}>
|
||||
<Link
|
||||
to="/upload-product"
|
||||
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
|
||||
>
|
||||
Upload Product
|
||||
</Link>
|
||||
{__resources.length == 0 || Object.keys(__resources).length == 0 ? (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<LoadingSpinner size={16} color="sky-blue" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="main-wrapper w-full">
|
||||
<div className="content-wrapper-profile-only w-full mb-6">
|
||||
<div className="auth-tab-content relative mb-10">
|
||||
<div className="lg:flex justify-between">
|
||||
<div className="tab-items">
|
||||
<TabList tabCategories={tab_categories} />
|
||||
</div>
|
||||
<div style={{ transform: "translateY(-22px)" }}>
|
||||
<Link
|
||||
to="/upload-product"
|
||||
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
|
||||
>
|
||||
Upload Product
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden lg:block w-full h-[1px] bg-[#DCD5FE] dark:bg-[#5356fb29] absolute top-[42px] left-0"></div>
|
||||
</div>
|
||||
<div className="hidden lg:block w-full h-[1px] bg-[#DCD5FE] dark:bg-[#5356fb29] absolute top-[42px] left-0"></div>
|
||||
</div>
|
||||
|
||||
<div className="tab-cotainer w-full mb-10">
|
||||
{selectedTabComponent}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="tab-cotainer w-full mb-10">
|
||||
{tab === "onsale" ? (
|
||||
<OnSaleTab products={onSaleProducts} />
|
||||
) : tab === "owned" ? (
|
||||
<OwnTab products={ownProducts} />
|
||||
) : tab === "created" ? (
|
||||
<CreatedTab
|
||||
marketProducts={CreatedSell}
|
||||
mainProducts={CreatedBits}
|
||||
/>
|
||||
) : tab === "hidden" ? (
|
||||
<HiddenProductsTab
|
||||
marketProducts={CreatedSell}
|
||||
mainProducts={CreatedBits}
|
||||
/>
|
||||
) : tab === "collection" ? (
|
||||
<CollectionTab products={collectionProducts} />
|
||||
) : tab === "activity" ? (
|
||||
<ActivitiesTab />
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Layout>
|
||||
</>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React 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 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";
|
||||
|
||||
export default function ActivitiesTab({ className }) {
|
||||
return (
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from "react";
|
||||
import CollectionCard from "../Cards/CollectionCard";
|
||||
import DataIteration from "../Helpers/DataIteration";
|
||||
import SearchCom from "../Helpers/SearchCom";
|
||||
import CollectionCard from "../../Cards/CollectionCard";
|
||||
import DataIteration from "../../Helpers/DataIteration";
|
||||
import SearchCom from "../../Helpers/SearchCom";
|
||||
|
||||
export default function CollectionTab({ className, products }) {
|
||||
return (
|
||||
@@ -43,7 +42,7 @@ export default function CollectionTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<CollectionCard key={datas.uniqKey} collectionData={datas} />
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useRef } from "react";
|
||||
import ProductCardStyleTwo from "../Cards/ProductCardStyleTwo";
|
||||
import Icons from "../Helpers/Icons";
|
||||
import SliderCom from"../Helpers/SliderCom";
|
||||
import { useRef } from "react";
|
||||
import ProductCardStyleTwo from "../../Cards/ProductCardStyleTwo";
|
||||
import Icons from "../../Helpers/Icons";
|
||||
import SliderCom from "../../Helpers/SliderCom";
|
||||
|
||||
export default function CreateSaleSlider({
|
||||
className,
|
||||
@@ -42,7 +42,9 @@ export default function CreateSaleSlider({
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Sell</h1>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Create for Sell
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button onClick={nextHandler} type="button">
|
||||
@@ -89,7 +91,7 @@ export default function CreateSaleSlider({
|
||||
<div className="trending-products relative w-full">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{products &&
|
||||
products.length > 0 &&
|
||||
products?.length > 0 &&
|
||||
products.map((item) => (
|
||||
<ProductCardStyleTwo
|
||||
key={item.id}
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useRef } from "react";
|
||||
import ProductCardStyleOne from "../Cards/ProductCardStyleOne";
|
||||
import Icons from "../Helpers/Icons";
|
||||
import SliderCom from "../Helpers/SliderCom";
|
||||
import { useRef } from "react";
|
||||
import ProductCardStyleOne from "../../Cards/ProductCardStyleOne";
|
||||
import Icons from "../../Helpers/Icons";
|
||||
import SliderCom from "../../Helpers/SliderCom";
|
||||
|
||||
export default function CreatedBidsSlider({
|
||||
className,
|
||||
@@ -49,7 +49,9 @@ export default function CreatedBidsSlider({
|
||||
{/* heading */}
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">Create for Bits</h1>
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||
Create for Bits
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<button onClick={nextHandler} type="button">
|
||||
@@ -96,7 +98,7 @@ export default function CreatedBidsSlider({
|
||||
<div className="trending-products relative w-full">
|
||||
<SliderCom selector={trendingSlider} settings={settings}>
|
||||
{products &&
|
||||
products.length > 0 &&
|
||||
products?.length > 0 &&
|
||||
products.map((item) => (
|
||||
<ProductCardStyleOne
|
||||
key={item.id}
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from "react";
|
||||
import SearchCom from "../Helpers/SearchCom";
|
||||
import SearchCom from "../../Helpers/SearchCom";
|
||||
import CreatedBidsSlider from "./CreatedBidsSlider";
|
||||
import CreateSaleSlider from "./CreateSaleSlider";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from "react";
|
||||
import SearchCom from "../Helpers/SearchCom";
|
||||
import SearchCom from "../../Helpers/SearchCom";
|
||||
import CreatedBidsSlider from "./CreatedBidsSlider";
|
||||
import CreateSaleSlider from "./CreateSaleSlider";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from "react";
|
||||
import ProductCardStyleTwo from "../Cards/ProductCardStyleTwo";
|
||||
import DataIteration from "../Helpers/DataIteration";
|
||||
import SearchCom from "../Helpers/SearchCom";
|
||||
import ProductCardStyleTwo from "../../Cards/ProductCardStyleTwo";
|
||||
import DataIteration from "../../Helpers/DataIteration";
|
||||
import SearchCom from "../../Helpers/SearchCom";
|
||||
|
||||
export default function OnSaleTab({ className, products }) {
|
||||
return (
|
||||
@@ -43,7 +42,7 @@ export default function OnSaleTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<ProductCardStyleTwo key={datas.id} datas={datas} />
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from "react";
|
||||
import ProductCardStyleOne from "../Cards/ProductCardStyleOne";
|
||||
import DataIteration from "../Helpers/DataIteration";
|
||||
import SearchCom from "../Helpers/SearchCom";
|
||||
import ProductCardStyleOne from "../../Cards/ProductCardStyleOne";
|
||||
import DataIteration from "../../Helpers/DataIteration";
|
||||
import SearchCom from "../../Helpers/SearchCom";
|
||||
|
||||
export default function OwnTab({ className, products }) {
|
||||
return (
|
||||
@@ -43,7 +42,7 @@ export default function OwnTab({ className, products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<ProductCardStyleOne key={datas.id} datas={datas} />
|
||||
@@ -0,0 +1,15 @@
|
||||
import ActivitiesTab from "./ActivitiesTab";
|
||||
import CollectionTab from "./CollectionTab";
|
||||
import CreatedTab from "./CreatedTab";
|
||||
import HiddenProductsTab from "./HiddenProductsTab";
|
||||
import OnSaleTab from "./OnSaleTab";
|
||||
import OwnTab from "./OwnTab";
|
||||
|
||||
export {
|
||||
ActivitiesTab,
|
||||
CollectionTab,
|
||||
CreatedTab,
|
||||
HiddenProductsTab,
|
||||
OnSaleTab,
|
||||
OwnTab,
|
||||
};
|
||||
@@ -8,7 +8,7 @@ export default function MainSection({ products }) {
|
||||
<DataIteration
|
||||
datas={products}
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products.length}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<div key={datas.id + Math.random()} className="item">
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
import React from "react";
|
||||
|
||||
export default function PrivacyPolicyTab() {
|
||||
return (
|
||||
<div className="terms-conditon-tab w-full">
|
||||
<div className="terms-condition-wrappr w-full">
|
||||
<div className="mb-6">
|
||||
<h1 className="text-3xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Privacy Policy
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
Wrenchboard issues this policy to inform users about the information
|
||||
we collect, the use and disclosures in the course of interactions
|
||||
with the WrenchBoard services by customers. We value the privacy of
|
||||
our customers and such strive to employ best industry standards and
|
||||
practices to protect their privacy. By signing up for this services,
|
||||
using our products or technologies offered through the WrenchBoard
|
||||
website, you expressly agree to the terms of this Privacy Policy.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Collection of Information
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
When you sign up for WrenchBoard platform as a user, freelancer,
|
||||
worker or client, you inadvertently provide certain personal
|
||||
information such as name and email address. This information may be
|
||||
used to identify or contact you as part of the service we provide.
|
||||
Below is information we may collect from registered users of the
|
||||
service.
|
||||
</p>
|
||||
<ul className="flex flex-col rounded-[0.25rem]">
|
||||
{[
|
||||
"We collect financial information which include bank account numbers, debit/credit account.",
|
||||
"We collect financial information which include bank account numbers, debit/credit account.",
|
||||
"We collect personal information (names email addresses) from you and your friends when you use our referral program. We may also receive information about you from third party sites during promotions and campaigns.",
|
||||
].map((item, idx) => (
|
||||
<li
|
||||
className="border-opacity-10 block relative px-[1.25rem] py-[0.75rem] first:rounded-tl first:rounded-tr text-[#505056]"
|
||||
key={idx}
|
||||
>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Use of Personal Information
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
The information we collect about you is mainly utilized to provide a
|
||||
secure, efficient and smooth user experience as you interact with
|
||||
the site. We may also utilize the information to contact you to
|
||||
resolve issues with your account or resolve disputes between
|
||||
freelancers and clients. We also use your personal information in
|
||||
the following ways.
|
||||
</p>
|
||||
<ul className="flex flex-col rounded-[0.25rem]">
|
||||
{[
|
||||
"To comply with the regulatory requirement, whenever the need arises.",
|
||||
"To improve business relationship between Wrenchboard and users.",
|
||||
"To manage and protect our IT infrastructure.",
|
||||
"To contact you as the need arises as part of the services we offer to users.",
|
||||
"To provide some indication on the promotional offers and advertisement we direct to you.",
|
||||
"To protect you and your information. We regularly send you notification based on activities as you use the service.",
|
||||
].map((item, idx) => (
|
||||
<li
|
||||
className="border-opacity-10 block relative px-[1.25rem] py-[0.75rem] first:rounded-tl first:rounded-tr text-[#505056]"
|
||||
key={idx}
|
||||
>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
How We Share Your Personal Information:
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
When you sign up to the Service as a freelancer and create a
|
||||
profile, we will share your limited personal information with
|
||||
clients or project owners for whom you may perform a task or do work
|
||||
for based on expression of interest. Such information will include
|
||||
name, profile information with experience and your ranking based on
|
||||
previous performance. This information will be available to the
|
||||
public.
|
||||
<br />
|
||||
When you register as a client or project owner and post a job in the
|
||||
market place or offer jobs to preselected freelancers or workers on
|
||||
this service, information about you, your business will be shared.
|
||||
This information will be based on the information provided in your
|
||||
profile. <br />
|
||||
In order to deliver a quality service on WrenchBoard, we require the
|
||||
services of third parties and agents such as PayPal, Quickteller
|
||||
Service or banks to facilitate and process transactions. <br />
|
||||
We may also share your personal information when and if compelled or
|
||||
mandated by government agencies, or court injunctions or regulatory
|
||||
requirement. In order to settle disputes or claims, we may also be
|
||||
compelled to share your information in order to deliver services to
|
||||
you. <br />
|
||||
Finally, we may share your information with companies that we plan
|
||||
to to merge with or to be acquired by. We will take necessary
|
||||
measure to ensure that all such new affiliations and corporate
|
||||
entities comply with the Privacy Policies hereby stated failing
|
||||
which you will be notified duly.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
How We Use Cookies and Related Technologies:
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
When you access the service or website, www.wrenchboard.com , we
|
||||
store small files called Cookies in your browser. Cookies and
|
||||
related technologies like beacons and tags are used to identify
|
||||
customers uniquely. With Cookies, we can track and trend the pages
|
||||
of interest within the website. Hence, these technologies help us
|
||||
focus only relevant promotions or advertisement to each customer.
|
||||
Through this technologies, we are able to improve the service based
|
||||
on the feedback from the interaction with users. We also rely on
|
||||
these technologies to mitigate fraudulent attempts on your
|
||||
WrenchBoard account. You may elect to disable cookies to prevent
|
||||
installation of cookies from the website to your browser. However,
|
||||
your functional experience with the service or website may be
|
||||
impacted. Note that you automatically disconnect from cookies when
|
||||
you close your browser session or log out of the service.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Measures We Take to Secure Your Information
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
Your data and privacy are important to us as such we take extreme
|
||||
care on how we protect your information. We use a combination of
|
||||
industry standard encryption technologies to protect your
|
||||
information. Your password is not visible to our technical support
|
||||
team or any one in WrenchBoard. Our IT infrastructures are located
|
||||
in hosting facilities with strict access controls, and security
|
||||
protocols with only pre checked and authorized persons have access.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Updating Your Information or Opting Out
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
Users of this service may update the information posted in profiles
|
||||
or their accounts at any time. The accuracy of information posted on
|
||||
the profiles and accounts is entirely the responsibility of users.
|
||||
You may also decide to opt out the service or close your account at
|
||||
any time. We may also deactivate your account if you violate the
|
||||
terms of use of the website. Whilst we will endeavor to delete your
|
||||
core information in such instances, we will retain minimal records
|
||||
for reasons including disputes, claims or administrative purposes.
|
||||
Also, note that it may not be possible to delete any information you
|
||||
had shared with other users on the website previously.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Deactivate/Delete your account
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
If you no longer wish to use our Services, you can deactivate your
|
||||
Services account. If you want to deactivate your account, that
|
||||
setting is available to you in your account settings. Otherwise,
|
||||
please get in touch with our support. While we close any associated
|
||||
process, you will not be able to access your account. Note that this
|
||||
process cannot be reversed since we will remove your data. If you
|
||||
want to use our services in the future, it will be a new account
|
||||
altogether.
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -4,77 +4,231 @@ export default function TermsConditionTab() {
|
||||
return (
|
||||
<div className="terms-conditon-tab w-full">
|
||||
<div className="terms-condition-wrappr w-full">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
1. Definitions
|
||||
<div className="mb-6">
|
||||
<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] ">
|
||||
What you do own when you buy an NFT are the keys to a non-fungible –
|
||||
perhaps unique – token. That token is yours to trade or hold or
|
||||
display in Decentraland. But the digital file associated with an NFT
|
||||
is just as easy to copy and paste and download as any other – the
|
||||
Finally, players lose their NFTs sometimes according to the rules
|
||||
and regulations of the NFT game.
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-8">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
2. Acceptance
|
||||
<hr />
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
Acceptance of Terms
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
Amet minim mollit non deserunt ullamco est sit aliqua dolor do amet
|
||||
sint. Velit officia consequat duis enim velit mollit. Exercitation
|
||||
veniam consequat sunt nostrud amet.Capacity. You confirm that you
|
||||
have the legal capacity to receive and hold and make use of the NFT
|
||||
under French jurisdiction and any other relevant
|
||||
jurisdiction.Acceptance. By participating in the Sale, You accept
|
||||
and agree to these Terms and Conditions without any condition or
|
||||
restriction. If You do not agree to this Contract, You shall not
|
||||
participate in the Sale made by the Company Exercitation veniam
|
||||
consequat sunt nostrud amet.Capacity. You confirm that you have the
|
||||
legal capacity to receive and hold find to end.Contract, You shall
|
||||
not participate in the Sale made by the Company Exercitation venia
|
||||
WRENCHBOARD permits you (“User” or “you” or “your”) to access and
|
||||
use the Site and Content, subject to these T&Cs. By accessing or
|
||||
using any portion of the Site, you acknowledge that you have read,
|
||||
understood, and agree to be bound by these T&Cs. If you do not agree
|
||||
with these T&Cs, you must not accept these T&Cs or access or use the
|
||||
site or content.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-8 bg-purple p-[23px] text-white rounded-lg">
|
||||
<p className="text-[18px]">
|
||||
These Terms and Conditions are related to the sale of NFTs by the
|
||||
Company (the “Company”) on its Website. It solely governs the
|
||||
contractual relationship between You and the Company regarding the
|
||||
Sale and any related contract.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-8">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
3. The Sale
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<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] ">
|
||||
The Company offers NFTs featuring the Betonyou universe. The holders
|
||||
of one or more NFTs will be able to win cryptos while playing video
|
||||
games. In the future, the Company plans to develop its own games and
|
||||
Metaverse around the Betonyou universe (“Project”). <br />
|
||||
<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 />
|
||||
To release the NFTs and fund the project, the Company offers NFTs
|
||||
from a dedicated website("Sale"). The web address of this website
|
||||
will be given at the time of the mint. The NFT acquisition does not
|
||||
confer any rights on the Company or in the future development.
|
||||
<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>
|
||||
<div className="mb-8">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
4. Purchaser’s obligations
|
||||
<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] ">
|
||||
To the fullest extent permitted by applicable law, You undertake to
|
||||
indemnify, defend and hold harmless the Company from and against all
|
||||
claims, demands, actions, damages, losses, costs and expenses
|
||||
(including attorneys’ fees) that arise from or relate to (i) your
|
||||
Subscription or use of the NFTs; (ii) your responsibilities or
|
||||
obligations under this Contract; and (iii) your breach of this
|
||||
Contract. <br /> <br /> Company undertakes to act with the care
|
||||
normally expected from a professional in his field and to comply
|
||||
with the best practice in force. The best endeavor obligation only
|
||||
binds the Company.
|
||||
<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>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<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] ">
|
||||
WRENCHBOARD may, in its sole discretion and without prior notice,
|
||||
terminate your access to the Site and/or 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.
|
||||
</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>
|
||||
<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
|
||||
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
|
||||
revised T&Cs.
|
||||
</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div className="my-8">
|
||||
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||
NO WARRANTIES AND DISCLAIMER BY WRENCHBOARD
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||
THE SITE AND CONTENT, AND ALL SERVER AND NETWORK COMPONENTS, ARE
|
||||
PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS WITH ALL ERRORS AND
|
||||
DEFECTS AND WITHOUT ANY WARRANTIES OF ANY KIND, AND WRENCHBOARD
|
||||
EXPRESSLY DISCLAIMS ALL REPRESENTATIONS AND WARRANTIES, INCLUDING
|
||||
ANY IMPLIED WARRANTIES OF ACCURACY, COMPLETENESS, MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, AND ANY
|
||||
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
|
||||
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
|
||||
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] ">
|
||||
WRENCHBOARD reserves the right to do any of the following, at any
|
||||
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
|
||||
Site, or any portion of the Site, as necessary to perform routine or
|
||||
non-routine maintenance, error correction, or other changes..
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import ChangePasswordTab from "./ChangePasswordTab";
|
||||
import FaqTab from "./FaqTab";
|
||||
import LoginActivityTab from "./LoginActivityTab";
|
||||
import NotificationSettingTab from "./NotificationSettingTab";
|
||||
import PaymentMathodsTab from "./PaymentMathodsTab";
|
||||
import PersonalInfoTab from "./PersonalInfoTab";
|
||||
import PrivacyPolicyTab from "./PrivacyPolicyTab";
|
||||
import TermsConditionTab from "./TermsConditionTab";
|
||||
|
||||
export {
|
||||
ChangePasswordTab,
|
||||
FaqTab,
|
||||
LoginActivityTab,
|
||||
NotificationSettingTab,
|
||||
PaymentMathodsTab,
|
||||
PersonalInfoTab,
|
||||
PrivacyPolicyTab,
|
||||
TermsConditionTab,
|
||||
};
|
||||
@@ -1,56 +1,20 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import cover from "../../assets/images/profile-info-cover.png";
|
||||
import profile from "../../assets/images/profile-info-profile.png";
|
||||
|
||||
import Icons from "../Helpers/Icons";
|
||||
import Layout from "../Partials/Layout";
|
||||
import ChangePasswordTab from "./Tabs/ChangePasswordTab";
|
||||
import FaqTab from "./Tabs/FaqTab";
|
||||
import LoginActivityTab from "./Tabs/LoginActivityTab";
|
||||
import NotificationSettingTab from "./Tabs/NotificationSettingTab";
|
||||
import PaymentMathodsTab from "./Tabs/PaymentMathodsTab";
|
||||
import PersonalInfoTab from "./Tabs/PersonalInfoTab";
|
||||
import TermsConditionTab from "./Tabs/TermsConditionTab";
|
||||
import {
|
||||
ChangePasswordTab,
|
||||
FaqTab,
|
||||
LoginActivityTab,
|
||||
NotificationSettingTab,
|
||||
PaymentMathodsTab,
|
||||
PersonalInfoTab,
|
||||
PrivacyPolicyTab,
|
||||
TermsConditionTab,
|
||||
} from "./Tabs";
|
||||
|
||||
export default function Settings({faq}) {
|
||||
const tabs = [
|
||||
{
|
||||
id: 1,
|
||||
name: "personal",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "payment",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "notification",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "login_activity",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "password",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "faq",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "privacy",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "terms",
|
||||
},
|
||||
];
|
||||
const [tab, setTab] = useState(tabs[0].name);
|
||||
const tabHandler = (value) => {
|
||||
setTab(value);
|
||||
};
|
||||
export default function Settings({ faq }) {
|
||||
const [profileImg, setProfileImg] = useState(profile);
|
||||
const [coverImg, setCoverImg] = useState(cover);
|
||||
|
||||
@@ -83,6 +47,62 @@ export default function Settings({faq}) {
|
||||
}
|
||||
};
|
||||
|
||||
// Tabs Handling
|
||||
const tabs = [
|
||||
{
|
||||
id: 1,
|
||||
name: "personal",
|
||||
title: "Edit Profile",
|
||||
iconName: "people-hover",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "payment",
|
||||
title: "Payment Method",
|
||||
iconName: "bank-card",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "notification",
|
||||
title: "Notification Setting",
|
||||
iconName: "notification-setting",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "login_activity",
|
||||
title: "Login Activity",
|
||||
iconName: "login-activity",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "password",
|
||||
title: "Change Password",
|
||||
iconName: "password-hover",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "faq",
|
||||
title: "FAQ",
|
||||
iconName: "block-question",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "privacy",
|
||||
title: "Privacy Policy",
|
||||
iconName: "page-right",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "terms",
|
||||
title: "Terms and Conditions",
|
||||
iconName: "page-right",
|
||||
},
|
||||
];
|
||||
const [tab, setTab] = useState(tabs[0].name);
|
||||
const tabHandler = (value) => {
|
||||
setTab(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout>
|
||||
@@ -97,136 +117,28 @@ export default function Settings({faq}) {
|
||||
<div className="content-container w-full pt-10 rounded-2xl bg-white dark:bg-dark-white ">
|
||||
<div className="content-heading w-full mb-8 lg:px-10 px-4">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white antialiased">
|
||||
Parsonal Informaiton
|
||||
Personal Information
|
||||
</h1>
|
||||
</div>
|
||||
<div className="content-body w-full lg:flex lg:px-10 px-4">
|
||||
<div className="content-tab-items lg:w-[230px] w-full mr-2">
|
||||
<ul className="overflow-hidden mb-10 lg:mb-0">
|
||||
<li
|
||||
onClick={() => tabHandler("personal")}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "personal"
|
||||
? "text-purple"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="people-hover" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">Edit Profile</p>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => tabHandler("payment")}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "payment"
|
||||
? "text-purple"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="bank-card" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">Payment Method</p>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => tabHandler("notification")}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "notification"
|
||||
? "text-purple"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="notification-setting" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">
|
||||
Notifiction Setting
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => tabHandler("login_activity")}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "login_activity"
|
||||
? "text-purple"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="login-activity" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">Login Activity</p>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => tabHandler("password")}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "password"
|
||||
? "text-purple"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="password-hover" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">Change Password</p>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => tabHandler("faq")}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "faq" ? "text-purple" : " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="block-question" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">FAQ</p>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => tabHandler("terms")}
|
||||
{tabs.map(({ name, id, title, iconName }) => (
|
||||
<li
|
||||
onClick={() => tabHandler(name)}
|
||||
key={id}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "privacy"
|
||||
? "text-purple"
|
||||
: " text-thin-light-gray"
|
||||
tab === name ? "text-purple" : " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="page-right" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">
|
||||
Privacy Policy
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => tabHandler("terms")}
|
||||
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
|
||||
tab === "terms"
|
||||
? "text-purple"
|
||||
: " text-thin-light-gray"
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<Icons name="page-right" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">
|
||||
Terms and Conditions
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
>
|
||||
<div>
|
||||
<Icons name={iconName} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-18 tracking-wide">{title}</p>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="w-[1px] bg-[#E3E4FE] dark:bg-[#a7a9b533] mr-10"></div>
|
||||
@@ -258,6 +170,7 @@ export default function Settings({faq}) {
|
||||
{tab === "login_activity" && <LoginActivityTab />}
|
||||
{tab === "password" && <ChangePasswordTab />}
|
||||
{tab === "faq" && <FaqTab datas={faq} />}
|
||||
{tab === "privacy" && <PrivacyPolicyTab />}
|
||||
{tab === "terms" && <TermsConditionTab />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,34 +2,36 @@ import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import RecomendedSliders from "./RecomendedSliders";
|
||||
|
||||
export default function CommonHead({ className,commonHeadData }) {
|
||||
return (
|
||||
<div
|
||||
className={`create-nft w-full lg:h-[140px] shadow lg:flex rounded-lg justify-between items-center md:p-2 p-2 bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] -2 border-pink mb-10 ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
{commonHeadData?.length > 0 && <RecomendedSliders bannerData={commonHeadData} /> }
|
||||
{/*<div className="lg:w-8/12 w-full mb-8 lg:mb-0">*/}
|
||||
{/* /!*<h1 className="text-2xl text-dark-gray dark:text-white font-bold mb-2">*!/*/}
|
||||
{/* /!* This is common head which will appear as needed , will take many shape*!/*/}
|
||||
{/* /!*</h1>*!/*/}
|
||||
{/* /!*<p className="text-base text-thin-light-gray tracking-wide">*!/*/}
|
||||
{/* /!* some space for extra texts here*!/*/}
|
||||
{/* /!*</p>*!/*/}
|
||||
{/* */}
|
||||
{/*</div>*/}
|
||||
{/*<div className="flex-1 flex lg:justify-end">*/}
|
||||
{/* <div className="flex items-center space-x-5">*/}
|
||||
{/* <Link*/}
|
||||
{/* to="/mytask"*/}
|
||||
{/* className="w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"*/}
|
||||
{/* >*/}
|
||||
{/* View Task*/}
|
||||
{/* </Link>*/}
|
||||
export default function CommonHead({ className, commonHeadData }) {
|
||||
return (
|
||||
<div
|
||||
className={`create-nft w-full lg:h-[140px] shadow lg:flex rounded-lg justify-between items-center md:p-2 p-2 bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] -2 border-pink mb-10 ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
{commonHeadData?.length > 0 && (
|
||||
<RecomendedSliders bannerData={commonHeadData} />
|
||||
)}
|
||||
{/*<div className="lg:w-8/12 w-full mb-8 lg:mb-0">*/}
|
||||
{/* /!*<h1 className="text-2xl text-dark-gray dark:text-white font-bold mb-2">*!/*/}
|
||||
{/* /!* This is common head which will appear as needed , will take many shape*!/*/}
|
||||
{/* /!*</h1>*!/*/}
|
||||
{/* /!*<p className="text-base text-thin-light-gray tracking-wide">*!/*/}
|
||||
{/* /!* some space for extra texts here*!/*/}
|
||||
{/* /!*</p>*!/*/}
|
||||
{/* */}
|
||||
{/*</div>*/}
|
||||
{/*<div className="flex-1 flex lg:justify-end">*/}
|
||||
{/* <div className="flex items-center space-x-5">*/}
|
||||
{/* <Link*/}
|
||||
{/* to="/mytask"*/}
|
||||
{/* className="w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"*/}
|
||||
{/* >*/}
|
||||
{/* View Task*/}
|
||||
{/* </Link>*/}
|
||||
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
);
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,126 +7,128 @@ import Icons from "../Helpers/Icons";
|
||||
import SliderCom from "../Helpers/SliderCom";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export default function RecomendedSliders({ className,bannerData }) {
|
||||
const settings = {
|
||||
arrows: false,
|
||||
dots: false,
|
||||
infinite: bannerData.length > 4 ? true : false,
|
||||
autoplay: true,
|
||||
slidesToShow: bannerData.length > 4 ? 4 : bannerData.length,
|
||||
slidesToScroll: 1,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 426,
|
||||
settings: {
|
||||
infinite: bannerData.length > 2 ? true : false,
|
||||
slidesToShow: bannerData.length > 2 ? 2 : bannerData.length,
|
||||
slidesToScroll: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const sellSlider = useRef(null);
|
||||
const buySlider = useRef(null);
|
||||
const prevHandler = (value) => {
|
||||
if (value === "sell") {
|
||||
sellSlider.current.slickPrev();
|
||||
}
|
||||
if (value === "buy") {
|
||||
buySlider.current.slickPrev();
|
||||
}
|
||||
};
|
||||
const nextHandler = (value) => {
|
||||
if (value === "sell") {
|
||||
sellSlider.current.slickNext();
|
||||
}
|
||||
if (value === "buy") {
|
||||
buySlider.current.slickNext();
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{/*<div className="heading flex justify-between items-center mb-4">*/}
|
||||
{/* <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* Top Seller*/}
|
||||
{/* </h1>*/}
|
||||
{/* <div className="slider-btns flex space-x-4">*/}
|
||||
{/* <button*/}
|
||||
{/* onClick={() => nextHandler("sell")}*/}
|
||||
{/* type="button"*/}
|
||||
{/* className="transform rotate-180 text-dark-gray dark:text-white dark:opacity-25"*/}
|
||||
{/* >*/}
|
||||
{/* <Icons name="arrows" />*/}
|
||||
{/* </button>*/}
|
||||
{/* <button*/}
|
||||
{/* onClick={() => prevHandler("sell")}*/}
|
||||
{/* type="button"*/}
|
||||
{/* className="transform rotate-180"*/}
|
||||
{/* >*/}
|
||||
{/* <div className=" text-dark-gray dark:text-white">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="11"*/}
|
||||
{/* height="19"*/}
|
||||
{/* viewBox="0 0 11 19"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M9.09766 1.1499L1.13307 9.11449L9.09766 17.0791"*/}
|
||||
{/* stroke="url(#paint0_linear_220_23410)"*/}
|
||||
{/* strokeWidth="2"*/}
|
||||
{/* strokeLinecap="round"*/}
|
||||
{/* strokeLinejoin="round"*/}
|
||||
{/* />*/}
|
||||
{/* <defs>*/}
|
||||
{/* <linearGradient*/}
|
||||
{/* id="paint0_linear_220_23410"*/}
|
||||
{/* x1="9.09766"*/}
|
||||
{/* y1="1.1499"*/}
|
||||
{/* x2="-4.2474"*/}
|
||||
{/* y2="7.96749"*/}
|
||||
{/* gradientUnits="userSpaceOnUse"*/}
|
||||
{/* >*/}
|
||||
{/* <stop stopColor="#F539F8" />*/}
|
||||
{/* <stop offset="0.416763" stopColor="#C342F9" />*/}
|
||||
{/* <stop offset="1" stopColor="#5356FB" />*/}
|
||||
{/* </linearGradient>*/}
|
||||
{/* </defs>*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* </button>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
<div className="slider-content">
|
||||
<SliderCom settings={settings} selector={sellSlider}>
|
||||
{bannerData.map((item, index) => (
|
||||
<Link key={index} to={`/${item.link_path}`}>
|
||||
<div className="item">
|
||||
<div className={`commonHeaderSliderItem flex flex-col justify-between items-center ${item.short_style}`}>
|
||||
{/* title */}
|
||||
<div className="flex justify-center">
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white">
|
||||
{item.short_title}
|
||||
</p>
|
||||
</div>
|
||||
{/* username */}
|
||||
<div className="flex justify-center mb-1">
|
||||
<p className="text-xs text-thin-light-gray">
|
||||
{item.short_description}
|
||||
</p>
|
||||
</div>
|
||||
{/* items */}
|
||||
<div className="flex justify-center">
|
||||
<div className="flex space-x-1 items-center text-purple text-xs">
|
||||
<span>{item.short_button_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</SliderCom>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
export default function RecomendedSliders({ className, bannerData }) {
|
||||
const settings = {
|
||||
arrows: false,
|
||||
dots: false,
|
||||
infinite: bannerData.length > 4 ? true : false,
|
||||
autoplay: true,
|
||||
slidesToShow: bannerData.length > 4 ? 4 : bannerData.length,
|
||||
slidesToScroll: 1,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 426,
|
||||
settings: {
|
||||
infinite: bannerData.length > 2 ? true : false,
|
||||
slidesToShow: bannerData.length > 2 ? 2 : bannerData.length,
|
||||
slidesToScroll: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const sellSlider = useRef(null);
|
||||
const buySlider = useRef(null);
|
||||
const prevHandler = (value) => {
|
||||
if (value === "sell") {
|
||||
sellSlider.current.slickPrev();
|
||||
}
|
||||
if (value === "buy") {
|
||||
buySlider.current.slickPrev();
|
||||
}
|
||||
};
|
||||
const nextHandler = (value) => {
|
||||
if (value === "sell") {
|
||||
sellSlider.current.slickNext();
|
||||
}
|
||||
if (value === "buy") {
|
||||
buySlider.current.slickNext();
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{/*<div className="heading flex justify-between items-center mb-4">*/}
|
||||
{/* <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* Top Seller*/}
|
||||
{/* </h1>*/}
|
||||
{/* <div className="slider-btns flex space-x-4">*/}
|
||||
{/* <button*/}
|
||||
{/* onClick={() => nextHandler("sell")}*/}
|
||||
{/* type="button"*/}
|
||||
{/* className="transform rotate-180 text-dark-gray dark:text-white dark:opacity-25"*/}
|
||||
{/* >*/}
|
||||
{/* <Icons name="arrows" />*/}
|
||||
{/* </button>*/}
|
||||
{/* <button*/}
|
||||
{/* onClick={() => prevHandler("sell")}*/}
|
||||
{/* type="button"*/}
|
||||
{/* className="transform rotate-180"*/}
|
||||
{/* >*/}
|
||||
{/* <div className=" text-dark-gray dark:text-white">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="11"*/}
|
||||
{/* height="19"*/}
|
||||
{/* viewBox="0 0 11 19"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M9.09766 1.1499L1.13307 9.11449L9.09766 17.0791"*/}
|
||||
{/* stroke="url(#paint0_linear_220_23410)"*/}
|
||||
{/* strokeWidth="2"*/}
|
||||
{/* strokeLinecap="round"*/}
|
||||
{/* strokeLinejoin="round"*/}
|
||||
{/* />*/}
|
||||
{/* <defs>*/}
|
||||
{/* <linearGradient*/}
|
||||
{/* id="paint0_linear_220_23410"*/}
|
||||
{/* x1="9.09766"*/}
|
||||
{/* y1="1.1499"*/}
|
||||
{/* x2="-4.2474"*/}
|
||||
{/* y2="7.96749"*/}
|
||||
{/* gradientUnits="userSpaceOnUse"*/}
|
||||
{/* >*/}
|
||||
{/* <stop stopColor="#F539F8" />*/}
|
||||
{/* <stop offset="0.416763" stopColor="#C342F9" />*/}
|
||||
{/* <stop offset="1" stopColor="#5356FB" />*/}
|
||||
{/* </linearGradient>*/}
|
||||
{/* </defs>*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* </button>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
<div className="slider-content">
|
||||
<SliderCom settings={settings} selector={sellSlider}>
|
||||
{bannerData.map((item, index) => (
|
||||
<Link key={index} to={`/${item.link_path}`}>
|
||||
<div className="item">
|
||||
<div
|
||||
className={`commonHeaderSliderItem flex gap-1 flex-col justify-between items-center ${item.short_style}`}
|
||||
>
|
||||
{/* title */}
|
||||
<div className="flex justify-center items-center text-center">
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white">
|
||||
{item.short_title}
|
||||
</p>
|
||||
</div>
|
||||
{/* username */}
|
||||
<div className="flex justify-center mb-1">
|
||||
<p className="text-xs text-thin-light-gray text-justify">
|
||||
{item.short_description}
|
||||
</p>
|
||||
</div>
|
||||
{/* items */}
|
||||
<div className="flex justify-center">
|
||||
<div className="flex space-x-1 items-center text-purple text-xs">
|
||||
<span>{item.short_button_text}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</SliderCom>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,152 +1,173 @@
|
||||
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'
|
||||
import { tableReload } from '../../store/TableReloads'
|
||||
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";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
|
||||
function DeleteJobPopout({details, onClose, situation}) {
|
||||
let dispatch = useDispatch()
|
||||
const navigate = useNavigate()
|
||||
const ApiCall = new usersService()
|
||||
function DeleteJobPopout({ details, onClose, situation }) {
|
||||
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
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
laoding: false,
|
||||
status: false,
|
||||
message: "",
|
||||
}); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
|
||||
|
||||
// FUNCTION CALLED ONCE USER CONFIRM DELETE JOB
|
||||
const deleteJob = (details) => {
|
||||
setRequestStatus({laoding: true, status:false, message: ''})
|
||||
let reqData = {
|
||||
job_id: details.job_id,
|
||||
job_uid: details.job_uid
|
||||
} // DATA NEEDED BY THE API
|
||||
|
||||
// API CALL TO DELETE A JOB
|
||||
ApiCall.deleteJob(reqData).then(res => {
|
||||
if(res.data.internal_return < 0){
|
||||
setRequestStatus({laoding: false, status:false, message: 'Could not perform the request, try again!'})
|
||||
return
|
||||
}
|
||||
setRequestStatus({laoding: false, status:true, message: 'Job deleted successfully'})
|
||||
setTimeout(()=>{
|
||||
dispatch(tableReload({type:'JOBTABLE'}))
|
||||
navigate('/myjobs', {replace: true})
|
||||
onClose()
|
||||
}, 1000)
|
||||
}).catch(error => {
|
||||
setRequestStatus({laoding: false, status:false, message: 'Opps! something went wrong, try again'})
|
||||
}).finally(()=>{
|
||||
setTimeout(()=>{
|
||||
setRequestStatus({laoding: false, status:false, message: ''})
|
||||
}, 5000)
|
||||
})
|
||||
}
|
||||
// FUNCTION CALLED ONCE USER CONFIRM DELETE JOB
|
||||
const deleteJob = (details) => {
|
||||
setRequestStatus({ laoding: true, status: false, message: "" });
|
||||
let reqData = {
|
||||
job_id: details.job_id,
|
||||
job_uid: details.job_uid,
|
||||
}; // DATA NEEDED BY THE API
|
||||
|
||||
// API CALL TO DELETE A JOB
|
||||
ApiCall.deleteJob(reqData)
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setRequestStatus({
|
||||
laoding: false,
|
||||
status: false,
|
||||
message: "Could not perform the request, try again!",
|
||||
});
|
||||
return;
|
||||
}
|
||||
setRequestStatus({
|
||||
laoding: false,
|
||||
status: true,
|
||||
message: "Job deleted successfully",
|
||||
});
|
||||
setTimeout(() => {
|
||||
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||
navigate("/myjobs", { replace: true });
|
||||
onClose();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
setRequestStatus({
|
||||
laoding: false,
|
||||
status: false,
|
||||
message: "Opps! something went wrong, try again",
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ laoding: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation}>
|
||||
<div className="logout-modal-wrapper lg:w-[600px] 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 Job
|
||||
</h1>
|
||||
<div className="logout-modal-wrapper lg:w-[600px] 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 Job
|
||||
</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="#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>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white">
|
||||
{details.title}
|
||||
</p>
|
||||
<p className="text-lg tracking-wide text-dark-gray dark:text-white flex items-start gap-1">
|
||||
Price: {details.thePrice}
|
||||
</p>
|
||||
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Duration: {details.timeline_days} day(s)
|
||||
</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.laoding ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<button
|
||||
onClick={() => deleteJob(details)}
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={onClose}
|
||||
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
<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>
|
||||
Confirm Delete
|
||||
</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>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white">
|
||||
{details.title}
|
||||
</p>
|
||||
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Price: {details.price * 0.01}
|
||||
</p>
|
||||
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Duration: {details.timeline_days} day(s)
|
||||
</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.laoding ?
|
||||
<LoadingSpinner size='8' color='sky-blue' />
|
||||
:
|
||||
<button
|
||||
onClick={() => deleteJob(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>
|
||||
)
|
||||
{/* 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 DeleteJobPopout
|
||||
export default DeleteJobPopout;
|
||||
|
||||