Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b6ab3a6ee7 | |||
| f968cc5a50 | |||
| 1ddb2fd903 | |||
| 70f6ac4e24 | |||
| 3d30481852 | |||
| 63c0b07f61 | |||
| 60568c42e8 | |||
| 77ac52820d | |||
| 240e075305 | |||
| bea41d8181 | |||
| 6268d68b67 | |||
| f96b16b373 | |||
| 9fb6a4db86 | |||
| 1aa3c79666 | |||
| ecc2360dc4 | |||
| ca9bb1c211 | |||
| 2f756d189a | |||
| d7acea769c | |||
| 7ff5e2b6e0 | |||
| 2f90c4a6c2 | |||
| 29e0345e1c | |||
| 129cdc8cba | |||
| 9d42ebebab | |||
| 6193f0b492 | |||
| 1d86465812 | |||
| 7a6f43ad20 | |||
| 37b94a68ca | |||
| a1b63c5d0c | |||
| e5162a2aaf | |||
| 6ee9c7e7d8 | |||
| 5928ddb3c1 | |||
| 06c1e339b1 | |||
| 29cec58122 | |||
| d258158a13 | |||
| 1c47fa283a | |||
| d1b07e6e66 | |||
| 648f228e45 | |||
| 551a302ede | |||
| 108c82b2f8 | |||
| f46713ef00 | |||
| 992993b710 | |||
| 617df4200e | |||
| a47e398e87 | |||
| 281c4c7ab7 | |||
| 3c901e5d0d | |||
| 3bcbaae4c3 | |||
| 17e972d603 | |||
| dbc821a804 | |||
| 0e4b1af1ce | |||
| ec88f304ab | |||
| 8d795a29b4 | |||
| da12f5905c | |||
| 99d4301588 |
@@ -98,4 +98,8 @@ REACT_APP_FAMILY_MINIMUM_AGE=4
|
|||||||
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
||||||
|
|
||||||
#CHANGE LOGIN LAYOUT
|
#CHANGE LOGIN LAYOUT
|
||||||
REACT_APP_NEW_LOGIN_LAYOUT=1
|
REACT_APP_NEW_LOGIN_LAYOUT=1
|
||||||
|
|
||||||
|
#APP DOWNLOAD LINKS
|
||||||
|
REACT_APP_ANDROID_APP='https://play.google.com/store/apps/details?id=com.wrenchboard.users'
|
||||||
|
REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls=1&mt=8'
|
||||||
@@ -66,4 +66,8 @@ REACT_APP_FAMILY_MINIMUM_AGE=4
|
|||||||
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
||||||
|
|
||||||
#CHANGE LOGIN LAYOUT
|
#CHANGE LOGIN LAYOUT
|
||||||
REACT_APP_NEW_LOGIN_LAYOUT=1
|
REACT_APP_NEW_LOGIN_LAYOUT=1
|
||||||
|
|
||||||
|
#APP DOWNLOAD LINKS
|
||||||
|
REACT_APP_ANDROID_APP='https://play.google.com/store/apps/details?id=com.wrenchboard.users'
|
||||||
|
REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls=1&mt=8'
|
||||||
@@ -72,4 +72,8 @@ REACT_APP_FAMILY_MINIMUM_AGE=4
|
|||||||
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
||||||
|
|
||||||
#CHANGE LOGIN LAYOUT
|
#CHANGE LOGIN LAYOUT
|
||||||
REACT_APP_NEW_LOGIN_LAYOUT=0
|
REACT_APP_NEW_LOGIN_LAYOUT=1
|
||||||
|
|
||||||
|
#APP DOWNLOAD LINKS
|
||||||
|
REACT_APP_ANDROID_APP='https://play.google.com/store/apps/details?id=com.wrenchboard.users'
|
||||||
|
REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls=1&mt=8'
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<title>WrenchBoard</title>
|
<title>WrenchBoard</title>
|
||||||
|
|
||||||
|
<!-- FONT AWESOME -->
|
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v6.5.1/css/all.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import Toaster from "./components/Helpers/Toaster";
|
|
||||||
import Routers from "./Routers";
|
|
||||||
import Default from "./components/Partials/Default";
|
|
||||||
import { Navigate, useLocation } from "react-router-dom";
|
import { Navigate, useLocation } from "react-router-dom";
|
||||||
|
import Routers from "./Routers";
|
||||||
|
import Toaster from "./components/Helpers/Toaster";
|
||||||
|
import Default from "./components/Partials/Default";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const {pathname} = useLocation()
|
const { pathname } = useLocation();
|
||||||
return (
|
return (
|
||||||
<Default>
|
<Default>
|
||||||
<>
|
<>
|
||||||
{pathname.startsWith('/@') ?
|
{pathname.startsWith("/@") ? (
|
||||||
<Navigate to="/app" replace={true} />
|
<Navigate to="/app" replace={true} />
|
||||||
:
|
) : (
|
||||||
<Routers />
|
<Routers />
|
||||||
}
|
)}
|
||||||
<Toaster />
|
<Toaster />
|
||||||
</>
|
</>
|
||||||
</Default>
|
</Default>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
@@ -1,65 +1,61 @@
|
|||||||
import { Route, Routes } from "react-router-dom";
|
import { Route, Routes } from "react-router-dom";
|
||||||
import FourZeroFour from "./components/FourZeroFour";
|
import FourZeroFour from "./components/FourZeroFour";
|
||||||
import ScrollToTop from "./components/Helpers/ScrollToTop";
|
import ScrollToTop from "./components/Helpers/ScrollToTop";
|
||||||
import MyCollection from "./components/MyCollection";
|
import StartJob from "./components/MyJobs/StartJob";
|
||||||
import Notification from "./components/Notification";
|
import Notification from "./components/Notification";
|
||||||
import AuthRoute from "./middleware/AuthRoute";
|
import AuthRoute from "./middleware/AuthRoute";
|
||||||
import AcitveBidsPage from "./views/AcitveBidsPage";
|
import AppDownloadPage from "./views/AppDownloadPage";
|
||||||
|
import AppleRedirectPage from "./views/AppleRedirectPage";
|
||||||
import AuthProfilePage from "./views/AuthProfilePage";
|
import AuthProfilePage from "./views/AuthProfilePage";
|
||||||
|
import AuthRedirect from "./views/AuthRedirect";
|
||||||
|
import BlogPage from "./views/BlogPage";
|
||||||
|
import CalendarPage from "./views/CalendarPage";
|
||||||
import CollectionItemPage from "./views/CollectionItemPage";
|
import CollectionItemPage from "./views/CollectionItemPage";
|
||||||
|
import FacebookRedirect from "./views/FacebookRedirect";
|
||||||
|
import FamilyAccPage from "./views/FamilyAccPage";
|
||||||
|
import FamilyManagePage from "./views/FamilyManagePage";
|
||||||
|
import FamilyMarketPage from "./views/FamilyMarketPage";
|
||||||
|
import FamilySettingsPage from "./views/FamilySettingsPage";
|
||||||
import ForgotPasswordPages from "./views/ForgotPasswordPages";
|
import ForgotPasswordPages from "./views/ForgotPasswordPages";
|
||||||
import ForgotPasswordPagesTwo from "./views/ForgotPasswordPagesTwo";
|
import ForgotPasswordPagesTwo from "./views/ForgotPasswordPagesTwo";
|
||||||
import HistoryPage from "./views/HistoryPage";
|
import HistoryPage from "./views/HistoryPage";
|
||||||
import HomePages from "./views/HomePages";
|
import HomePages from "./views/HomePages";
|
||||||
|
import JobGroupsPage from "./views/JobGroupsPage";
|
||||||
|
import LndPage from "./views/LndPage";
|
||||||
import LoginPage from "./views/LoginPage";
|
import LoginPage from "./views/LoginPage";
|
||||||
import LoginPageTwo from "./views/LoginPageTwo";
|
import LoginPageTwo from "./views/LoginPageTwo";
|
||||||
|
import ManageActiveJobs from "./views/ManageActiveJobs";
|
||||||
|
import ManageInterestOfferPage from "./views/ManageInterestOfferPage";
|
||||||
import MarketPlacePage from "./views/MarketPlacePage";
|
import MarketPlacePage from "./views/MarketPlacePage";
|
||||||
|
import MyActiveJobsPage from "./views/MyActiveJobsPage";
|
||||||
|
import MyCouponPage from "./views/MyCouponPage";
|
||||||
|
import MyJobsPage from "./views/MyJobsPage";
|
||||||
|
import MyOffersPage from "./views/MyOffersPage";
|
||||||
|
import MyPastDueJobsPage from "./views/MyPastDueJobsPage";
|
||||||
|
import MyReviewDueJobsPage from "./views/MyReviewDueJobsPage";
|
||||||
|
import MyTaskPage from "./views/MyTaskPage";
|
||||||
|
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
||||||
import MyWalletPage from "./views/MyWalletPage";
|
import MyWalletPage from "./views/MyWalletPage";
|
||||||
|
import OffersInterestPage from "./views/OffersInterestPage";
|
||||||
|
import ReferralPage from "./views/ReferralPage";
|
||||||
|
import RemindersPage from "./views/RemindersPage";
|
||||||
|
import ResourcePage from "./views/ResourcePage";
|
||||||
import SavedPage from "./views/SavedPage";
|
import SavedPage from "./views/SavedPage";
|
||||||
import SellPage from "./views/SellPage";
|
import SellPage from "./views/SellPage";
|
||||||
import SettingsPage from "./views/SettingsPage";
|
import SettingsPage from "./views/SettingsPage";
|
||||||
import ShopDetailsPage from "./views/ShopDetailsPage";
|
|
||||||
import SignupPage from "./views/SignupPage";
|
import SignupPage from "./views/SignupPage";
|
||||||
import SignupPageTwo from "./views/SignupPageTwo";
|
import SignupPageTwo from "./views/SignupPageTwo";
|
||||||
|
import TrackingPage from "./views/TrackingPage";
|
||||||
import UpdatePasswordPages from "./views/UpdatePasswordPages";
|
import UpdatePasswordPages from "./views/UpdatePasswordPages";
|
||||||
import UpdatePasswordPagesTwo from "./views/UpdatePasswordPagesTwo";
|
import UpdatePasswordPagesTwo from "./views/UpdatePasswordPagesTwo";
|
||||||
import UploadProductPage from "./views/UploadProductPage";
|
import UploadProductPage from "./views/UploadProductPage";
|
||||||
import UserProfilePage from "./views/UserProfilePage";
|
import UserProfilePage from "./views/UserProfilePage";
|
||||||
import VerifyYouPages from "./views/VerifyYouPages";
|
|
||||||
import VerifyYouPagesTwo from "./views/VerifyYouPagesTwo";
|
|
||||||
import VerifyPasswordPages from "./views/VerifyPasswordPages";
|
|
||||||
import VerifyPasswordPagesTwo from "./views/VerifyPasswordPagesTwo";
|
|
||||||
import RemindersPage from './views/RemindersPage';
|
|
||||||
import TrackingPage from "./views/TrackingPage";
|
|
||||||
import CalendarPage from "./views/CalendarPage";
|
|
||||||
import ResourcePage from "./views/ResourcePage";
|
|
||||||
import MyTaskPage from "./views/MyTaskPage";
|
|
||||||
import MyJobsPage from "./views/MyJobsPage";
|
|
||||||
import ReferralPage from "./views/ReferralPage";
|
|
||||||
import VerifyLinkPages from "./views/VerifyLinkPages";
|
import VerifyLinkPages from "./views/VerifyLinkPages";
|
||||||
import VerifyLinkPagesTwo from "./views/VerifyLinkPagesTwo";
|
import VerifyLinkPagesTwo from "./views/VerifyLinkPagesTwo";
|
||||||
import MyActiveJobsPage from "./views/MyActiveJobsPage";
|
import VerifyPasswordPages from "./views/VerifyPasswordPages";
|
||||||
import FamilyAccPage from "./views/FamilyAccPage";
|
import VerifyPasswordPagesTwo from "./views/VerifyPasswordPagesTwo";
|
||||||
import StartJob from "./components/MyJobs/StartJob";
|
import VerifyYouPages from "./views/VerifyYouPages";
|
||||||
import AddJobPage from "./views/AddJobPage";
|
import VerifyYouPagesTwo from "./views/VerifyYouPagesTwo";
|
||||||
import MyPendingJobsPage from "./views/MyPendingJobsPage";
|
|
||||||
import ManageActiveJobs from "./views/ManageActiveJobs";
|
|
||||||
import FamilyManagePage from "./views/FamilyManagePage";
|
|
||||||
import MyCouponPage from "./views/MyCouponPage";
|
|
||||||
import AuthRedirect from "./views/AuthRedirect";
|
|
||||||
import MyPastDueJobsPage from "./views/MyPastDueJobsPage";
|
|
||||||
import BlogPage from "./views/BlogPage";
|
|
||||||
import MyReviewDueJobsPage from "./views/MyReviewDueJobsPage";
|
|
||||||
import OffersInterestPage from "./views/OffersInterestPage";
|
|
||||||
import ManageInterestOfferPage from './views/ManageInterestOfferPage'
|
|
||||||
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
|
||||||
import FamilyMarketPage from "./views/FamilyMarketPage";
|
|
||||||
import FacebookRedirect from "./views/FacebookRedirect";
|
|
||||||
import AppleRedirectPage from "./views/AppleRedirectPage";
|
|
||||||
import LndPage from "./views/LndPage";
|
|
||||||
import FamilySettingsPage from "./views/FamilySettingsPage";
|
|
||||||
import AppDownloadPage from "./views/AppDownloadPage";
|
|
||||||
import JobGroupsPage from "./views/JobGroupsPage";
|
|
||||||
import YourPages from "./views/YourPage_";
|
import YourPages from "./views/YourPage_";
|
||||||
|
|
||||||
export default function Routers() {
|
export default function Routers() {
|
||||||
@@ -67,31 +63,47 @@ export default function Routers() {
|
|||||||
<ScrollToTop>
|
<ScrollToTop>
|
||||||
<Routes>
|
<Routes>
|
||||||
{/* guest routes */}
|
{/* guest routes */}
|
||||||
{process.env.REACT_APP_NEW_LOGIN_LAYOUT == 1 ?
|
{process.env.REACT_APP_NEW_LOGIN_LAYOUT == 1 ? (
|
||||||
<>
|
<>
|
||||||
<Route exact path="/login" element={<LoginPageTwo />} />
|
<Route exact path="/login" element={<LoginPageTwo />} />
|
||||||
<Route exact path="/signup" element={<SignupPageTwo />} />
|
<Route exact path="/signup" element={<SignupPageTwo />} />
|
||||||
<Route exact path="/forgot-password" element={<ForgotPasswordPagesTwo />} />
|
<Route
|
||||||
<Route exact path="/update-password" element={<UpdatePasswordPagesTwo />} />
|
exact
|
||||||
<Route path="/vemail" element={<VerifyLinkPagesTwo />} />
|
path="/forgot-password"
|
||||||
<Route path="/complereset" element={<VerifyPasswordPagesTwo />} />
|
element={<ForgotPasswordPagesTwo />}
|
||||||
<Route exact path="/outmessage" element={<VerifyYouPagesTwo />} />
|
/>
|
||||||
<Route exact path="/eoffer" element={<LoginPageTwo />} />
|
<Route
|
||||||
<Route exact path="/invite" element={<LoginPageTwo />} />
|
exact
|
||||||
</>
|
path="/update-password"
|
||||||
:
|
element={<UpdatePasswordPagesTwo />}
|
||||||
<>
|
/>
|
||||||
<Route exact path="/login" element={<LoginPage />} />
|
<Route path="/vemail" element={<VerifyLinkPagesTwo />} />
|
||||||
<Route exact path="/signup" element={<SignupPage />} />
|
<Route path="/complereset" element={<VerifyPasswordPagesTwo />} />
|
||||||
<Route exact path="/forgot-password" element={<ForgotPasswordPages />} />
|
<Route exact path="/outmessage" element={<VerifyYouPagesTwo />} />
|
||||||
<Route exact path="/update-password" element={<UpdatePasswordPages />} />
|
<Route exact path="/eoffer" element={<LoginPageTwo />} />
|
||||||
<Route path="/vemail" element={<VerifyLinkPages />} />
|
<Route exact path="/invite" element={<LoginPageTwo />} />
|
||||||
<Route path="/complereset" element={<VerifyPasswordPages />} />
|
</>
|
||||||
<Route exact path="/outmessage" element={<VerifyYouPages />} />
|
) : (
|
||||||
<Route exact path="/eoffer" element={<LoginPage />} />
|
<>
|
||||||
<Route exact path="/invite" element={<LoginPage />} />
|
<Route exact path="/login" element={<LoginPage />} />
|
||||||
</>
|
<Route exact path="/signup" element={<SignupPage />} />
|
||||||
}
|
<Route
|
||||||
|
exact
|
||||||
|
path="/forgot-password"
|
||||||
|
element={<ForgotPasswordPages />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/update-password"
|
||||||
|
element={<UpdatePasswordPages />}
|
||||||
|
/>
|
||||||
|
<Route path="/vemail" element={<VerifyLinkPages />} />
|
||||||
|
<Route path="/complereset" element={<VerifyPasswordPages />} />
|
||||||
|
<Route exact path="/outmessage" element={<VerifyYouPages />} />
|
||||||
|
<Route exact path="/eoffer" element={<LoginPage />} />
|
||||||
|
<Route exact path="/invite" element={<LoginPage />} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
||||||
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
||||||
<Route exact path="/login/auth/apple" element={<AppleRedirectPage />} />
|
<Route exact path="/login/auth/apple" element={<AppleRedirectPage />} />
|
||||||
@@ -117,25 +129,48 @@ export default function Routers() {
|
|||||||
<Route exact path="/market-place" element={<MarketPlacePage />} />
|
<Route exact path="/market-place" element={<MarketPlacePage />} />
|
||||||
<Route exact path="/market" element={<MarketPlacePage />} />
|
<Route exact path="/market" element={<MarketPlacePage />} />
|
||||||
<Route exact path="/familymarket" element={<FamilyMarketPage />} />
|
<Route exact path="/familymarket" element={<FamilyMarketPage />} />
|
||||||
<Route exact path="/familysettings" element={<FamilySettingsPage />} />
|
<Route
|
||||||
|
exact
|
||||||
|
path="/familysettings"
|
||||||
|
element={<FamilySettingsPage />}
|
||||||
|
/>
|
||||||
<Route exact path="/notification" element={<Notification />} />
|
<Route exact path="/notification" element={<Notification />} />
|
||||||
<Route exact path="/mytask" element={<MyTaskPage />} />
|
<Route exact path="/mytask" element={<MyTaskPage />} />
|
||||||
<Route exact path="/myjobs" element={<MyJobsPage />} />
|
<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-active-jobs" element={<MyActiveJobsPage />} />
|
||||||
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
|
<Route
|
||||||
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
|
exact
|
||||||
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
|
path="/my-pastdue-jobs"
|
||||||
<Route exact path="/my-review-jobs" element={<MyReviewDueJobsPage />} />
|
element={<MyPastDueJobsPage />}
|
||||||
<Route exact path="/acc-family" element={<FamilyAccPage />} />
|
/>
|
||||||
<Route exact path="/manage-family" element={<FamilyManagePage />} />
|
<Route exact path="/my-offers" element={<MyOffersPage />} />
|
||||||
<Route exact path="/start-job" element={<StartJob />} />
|
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
|
||||||
<Route exact path="/yourpage" element={<YourPages />} />
|
<Route
|
||||||
<Route exact path="/manage-active-job" element={<ManageActiveJobs />} />
|
exact
|
||||||
<Route exact path="/blog-page" element={<BlogPage />} />
|
path="/my-review-jobs"
|
||||||
<Route exact path="/offer-interest" element={<OffersInterestPage />} />
|
element={<MyReviewDueJobsPage />}
|
||||||
<Route exact path="/manage-offer" element={<ManageInterestOfferPage />} />
|
/>
|
||||||
|
<Route exact path="/acc-family" element={<FamilyAccPage />} />
|
||||||
|
<Route exact path="/manage-family" element={<FamilyManagePage />} />
|
||||||
|
<Route exact path="/start-job" element={<StartJob />} />
|
||||||
|
<Route exact path="/yourpage" element={<YourPages />} />
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/manage-active-job"
|
||||||
|
element={<ManageActiveJobs />}
|
||||||
|
/>
|
||||||
|
<Route exact path="/blog-page" element={<BlogPage />} />
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/offer-interest"
|
||||||
|
element={<OffersInterestPage />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/manage-offer"
|
||||||
|
element={<ManageInterestOfferPage />}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 32 28" viewBox="0 0 32 28" id="List"><circle cx="2" cy="2" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M8 0h24v4H8z" class="color4e4e50 svgShape"></path><circle cx="10" cy="10" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M16 8h16v4H16z" class="color4e4e50 svgShape"></path><circle cx="10" cy="26" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M16 24h16v4H16z" class="color4e4e50 svgShape"></path><circle cx="18" cy="18" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M24 16h8v4h-8z" class="color4e4e50 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 743 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="Group" x="0" y="0" version="1.1" viewBox="0 0 52 52" xml:space="preserve"><path d="M26.003 13.05c2.44 0 4.43-1.99 4.43-4.43a4.44 4.44 0 0 0-4.43-4.44c-2.45 0-4.44 1.99-4.44 4.44a4.44 4.44 0 0 0 4.44 4.43zM11.293 38.77c2.44 0 4.43-1.99 4.43-4.43a4.44 4.44 0 0 0-4.43-4.44c-2.45 0-4.43 1.99-4.43 4.44 0 2.44 1.98 4.43 4.43 4.43z" fill="#4687ba" class="color000000 svgShape"></path><path d="M49.493 41.93a10.091 10.091 0 0 0-3.643-3.739 6.418 6.418 0 0 1-5.138 2.58 6.392 6.392 0 0 1-4.371-1.737.975.975 0 0 0-.158-.258l-9.184-9.903V22.1h4.344c1.41 0 2.68-.73 3.4-1.94.72-1.23.73-2.7.04-3.95a10.09 10.09 0 0 0-3.643-3.739 6.418 6.418 0 0 1-5.138 2.579 6.43 6.43 0 0 1-5.144-2.58 10.085 10.085 0 0 0-3.645 3.74c-.69 1.25-.67 2.72.05 3.95a3.9 3.9 0 0 0 3.39 1.94h4.346v6.624c-.01.022-.016.044-.025.066l-9.22 9.941a.978.978 0 0 0-.22.42 6.378 6.378 0 0 1-4.242 1.62 6.417 6.417 0 0 1-5.14-2.584 10.086 10.086 0 0 0-3.65 3.743c-.69 1.25-.67 2.72.05 3.95a3.9 3.9 0 0 0 3.39 1.94h10.69c1.41 0 2.68-.73 3.4-1.94.72-1.23.73-2.7.04-3.95a10.03 10.03 0 0 0-2.134-2.612l8.01-8.636 8.055 8.685c-.815.73-1.53 1.58-2.08 2.563-.69 1.25-.67 2.72.05 3.95a3.9 3.9 0 0 0 3.39 1.94h10.69c1.41 0 2.68-.73 3.4-1.94.72-1.23.73-2.7.04-3.95z" fill="#4687ba" class="color000000 svgShape"></path><path d="M40.713 38.77c2.44 0 4.43-1.99 4.43-4.43a4.44 4.44 0 0 0-4.43-4.44c-2.45 0-4.44 1.99-4.44 4.44a4.44 4.44 0 0 0 4.44 4.43z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" id="List"><switch><g fill="#767fad" class="color000000 svgShape"><g fill="#4687ba" class="color0ac5ab svgShape"><path d="M20 0H8a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V8a8 8 0 00-8-8zM56 0H44a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V8a8 8 0 00-8-8zM20 36H8a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V44a8 8 0 00-8-8zM56 36H44a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V44a8 8 0 00-8-8z" fill="#767fad" class="color000000 svgShape"></path></g></g></switch></svg>
|
||||||
|
After Width: | Height: | Size: 527 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8" id="List"><path d="M0 0v3h3V0H0zm4 0v1h4V0H4zm0 2v1h3V2H4zM0 4v3h3V4H0zm4 0v1h4V4H4zm0 2v1h3V6H4z" fill="#b22b7d" class="color000000 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 214 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" id="List"><path d="M9 3a6 6 0 1 0 6 6A6 6 0 0 0 9 3zM9 13a4 4 0 1 1 4-4A4 4 0 0 1 9 13zM17 9H28a1 1 0 0 0 0-2H17a1 1 0 0 0 0 2zM17 13h6a1 1 0 0 0 0-2H17a1 1 0 0 0 0 2zM9 17a6 6 0 1 0 6 6A6 6 0 0 0 9 17zM9 27a4 4 0 1 1 4-4A4 4 0 0 1 9 27zM28 21H17a1 1 0 0 0 0 2H28a1 1 0 0 0 0-2zM23 25H17a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 437 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 64 64" id="delete"><path d="M44.41 19.59a2 2 0 0 0-2.83 0L32 29.18l-9.59-9.59a2 2 0 0 0-2.83 2.83L29.17 32l-9.59 9.59a2 2 0 1 0 2.83 2.83L32 34.83l9.59 9.59a2 2 0 0 0 2.83-2.83L34.83 32l9.59-9.59a2 2 0 0 0-.01-2.82Z" fill="#b22b7d" class="color000000 svgShape"></path><path d="M32 3a29 29 0 1 0 29 29A29 29 0 0 0 32 3Zm0 54a25 25 0 1 1 25-25 25 25 0 0 1-25 25Z" fill="#b22b7d" class="color000000 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 492 B |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 245 KiB |
@@ -1,20 +1,28 @@
|
|||||||
import React, { lazy } from "react";
|
import React, { lazy, useContext } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { localImgLoad } from "../../lib";
|
import { localImgLoad } from "../../lib";
|
||||||
|
|
||||||
|
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||||
|
|
||||||
export default function LoginLayout({ slogan, children }) {
|
export default function LoginLayout({ slogan, children }) {
|
||||||
const bgImg = localImgLoad('images/left-wrenchboard.jpg')
|
const bgImg = localImgLoad('images/left-wrenchboard.jpg')
|
||||||
|
const bgImgNig = localImgLoad('images/wrench-home-back-nigeria.jpg')
|
||||||
|
const bgImgCom = localImgLoad('images/wrench-home-back-common.jpg')
|
||||||
|
|
||||||
|
const {countryMode} = useContext(DarkModeContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`layout-wrapper login`}>
|
<div className={`h-screen overflow-y-auto bg-cover bg-center`}
|
||||||
<div className={`w-full min-h-screen overflow-y-auto lg:grid grid-cols-2`}>
|
style={{backgroundImage: `url(${ countryMode == 'NG' ? bgImgNig : bgImgCom})`}}
|
||||||
<div
|
>
|
||||||
|
<div className={`w-full grid grid-cols-1 lg:grid-cols-2`}>
|
||||||
|
{/* <div
|
||||||
className={`auth-bg hidden lg:block bg-blue-50 relative bg-cover bg-no-repeat border-0 after:content-[''] after:absolute after:inset-0`}
|
className={`auth-bg hidden lg:block bg-blue-50 relative bg-cover bg-no-repeat border-0 after:content-[''] after:absolute after:inset-0`}
|
||||||
style={{backgroundImage: `url(${bgImg})`}}
|
style={{backgroundImage: `url(${bgImg})`}}
|
||||||
>
|
>
|
||||||
</div>
|
</div> */}
|
||||||
<div className="p-5 sm:p-7 flex place-content-center">
|
<div className="p-5 sm:p-7 flex place-content-center lg:col-start-2">
|
||||||
<div className="py-10 w-11/12 h-full flex flex-col justify-between items-center content-wrapper login shadow-md xl:bg-white dark:bg-dark-white rounded-[0.475rem]">
|
<div className="py-5 w-full sm:w-11/12 max-w-2xl shadow-md bg-slate-50 dark:bg-dark-white rounded-[0.475rem]">
|
||||||
<div className="w-full flex justify-center items-center">
|
<div className="w-full flex justify-center items-center">
|
||||||
{children && children}
|
{children && children}
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +56,7 @@ export default function LoginLayout({ slogan, children }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="py-1 text-black text-[15px] px-2 font-medium flex items-center gap-1">
|
<p className="py-1 text-black text-[15px] px-2 font-medium flex items-center gap-1">
|
||||||
<span className="">© {new Date().getFullYear()} -</span>
|
<span className="dark:text-white">© {new Date().getFullYear()} -</span>
|
||||||
<Link to="/" className="text-[#009ef7] ml-1">
|
<Link to="/" className="text-[#009ef7] ml-1">
|
||||||
WrenchBoard
|
WrenchBoard
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export default function ForgotPassword() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex place-content-center">
|
<div className="flex place-content-center">
|
||||||
<div className="w-11/12 sm:max-w-[400px]">
|
<div className="w-10/12">
|
||||||
{msgSuccess == null ?
|
{msgSuccess == null ?
|
||||||
<>
|
<>
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ export default function Login() {
|
|||||||
</div>
|
</div>
|
||||||
{/* <div className="content-wrapper login shadow-md w-10/12 mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5"> */}
|
{/* <div className="content-wrapper login shadow-md w-10/12 mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5"> */}
|
||||||
<div className="flex place-content-center">
|
<div className="flex place-content-center">
|
||||||
<div className="w-11/12 sm:max-w-[530px]">
|
<div className="w-10/12">
|
||||||
{/* HIDES THIS IF USER SESSION HAS EXPIRED */}
|
{/* HIDES THIS IF USER SESSION HAS EXPIRED */}
|
||||||
{sessionExpired != "true" && (
|
{sessionExpired != "true" && (
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
@@ -520,11 +520,36 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
{/* END of login component */}
|
{/* END of login component */}
|
||||||
|
|
||||||
|
{/* APP DOWNLOAD STORE */}
|
||||||
|
<div className="w-full mt-4">
|
||||||
|
<div className="w-full flex justify-center items-center gap-4">
|
||||||
|
<div className='w-28 lg:w-32'>
|
||||||
|
<a className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300" target='_blank' href={process.env.REACT_APP_APPLE_APP}>
|
||||||
|
<i className="fa-brands fa-apple text-3xl"></i>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="text-[11px]">Available on the</span>
|
||||||
|
<span className="text-[12px] lg:text-base">App Store</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className='w-28 lg:w-32'>
|
||||||
|
<a className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300" target='_blank' href={process.env.REACT_APP_ANDROID_APP}>
|
||||||
|
<i className="fa-brands fa-google-play text-2xl"></i>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="text-[11px]">Available on the</span>
|
||||||
|
<span className="text-[12px] lg:text-base">Google Play</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{loginType == "full" && (
|
{loginType == "full" && (
|
||||||
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
<>
|
||||||
This site is protected by a Captcha. Our Privacy Policy and
|
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
||||||
Terms of Service apply.
|
This site is protected by a Captcha. Our Privacy Policy and
|
||||||
</div>
|
Terms of Service apply.
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,19 +9,21 @@ export default function SignUp() {
|
|||||||
// eslint-disable-next-line no-restricted-globals
|
// eslint-disable-next-line no-restricted-globals
|
||||||
const queryParams = new URLSearchParams(location?.search);
|
const queryParams = new URLSearchParams(location?.search);
|
||||||
const country = queryParams.get("cnt")?.toUpperCase();
|
const country = queryParams.get("cnt")?.toUpperCase();
|
||||||
|
|
||||||
const {pathname} = useLocation()
|
const { pathname } = useLocation();
|
||||||
const currentPath = country ? `${pathname}?cnt=${country.toLowerCase()}`:pathname // Determines the new pathname is country query params exist
|
const currentPath = country
|
||||||
|
? `${pathname}?cnt=${country.toLowerCase()}`
|
||||||
|
: pathname; // Determines the new pathname is country query params exist
|
||||||
|
|
||||||
const [signUpLoading, setSignUpLoading] = useState(false);
|
const [signUpLoading, setSignUpLoading] = useState(false);
|
||||||
const [checked, setValue] = useState(false);
|
const [checked, setValue] = useState(false);
|
||||||
// for the catch error
|
// for the catch error
|
||||||
const [msgError, setMsgError] = useState("");
|
const [msgError, setMsgError] = useState("");
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const [countries, setCountries] = useState({loading:true, data:[]});
|
const [countries, setCountries] = useState({ loading: true, data: [] });
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
country: country? country : "",
|
country: country ? country : "",
|
||||||
first_name: "",
|
first_name: "",
|
||||||
last_name: "",
|
last_name: "",
|
||||||
email: "",
|
email: "",
|
||||||
@@ -47,22 +49,23 @@ export default function SignUp() {
|
|||||||
|
|
||||||
// Get Country Api
|
// Get Country Api
|
||||||
const getCountryList = useCallback(async () => {
|
const getCountryList = useCallback(async () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await userApi.getSignupCountryData();
|
const res = await userApi.getSignupCountryData();
|
||||||
if (res.status === 200 && res.data.internal_return >= 0) {
|
if (res.status === 200 && res.data.internal_return >= 0) {
|
||||||
const { result_list } = await res.data;
|
const { result_list } = await res.data;
|
||||||
if(country){ // IF LINK/PATHNAME HAS CNT QUERY VALUE
|
if (country) {
|
||||||
let cnt = result_list.filter(item => item.code == country) // test to see country passed in query param exist from list of countries supplied by API
|
// IF LINK/PATHNAME HAS CNT QUERY VALUE
|
||||||
if(!cnt.length){ // IF CNT EMPTY, SET FORMDATA COUNTRY BACK TO EMPTY STRING: RE: THIS IS BCOS WE INITAIL SET COUNTRY VALUE IN FORMDATA, IF COUNTRY PARAM IS PRESENT IN LINK
|
let cnt = result_list.filter((item) => item.code == country); // test to see country passed in query param exist from list of countries supplied by API
|
||||||
setFormData(prev => ({...prev, country: ''}))
|
if (!cnt.length) {
|
||||||
return setCountries({loading: false, data: result_list});
|
// IF CNT EMPTY, SET FORMDATA COUNTRY BACK TO EMPTY STRING: RE: THIS IS BCOS WE INITAIL SET COUNTRY VALUE IN FORMDATA, IF COUNTRY PARAM IS PRESENT IN LINK
|
||||||
|
setFormData((prev) => ({ ...prev, country: "" }));
|
||||||
|
return setCountries({ loading: false, data: result_list });
|
||||||
}
|
}
|
||||||
return setCountries({loading: false, data: cnt});
|
return setCountries({ loading: false, data: cnt });
|
||||||
}
|
}
|
||||||
setCountries({loading: false, data:result_list});
|
setCountries({ loading: false, data: result_list });
|
||||||
} else if (res.data.result !== 100) {
|
} else if (res.data.result !== 100) {
|
||||||
setCountries({loading: false, data:[]});
|
setCountries({ loading: false, data: [] });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
@@ -113,9 +116,7 @@ export default function SignUp() {
|
|||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
const { data } = res;
|
const { data } = res;
|
||||||
if (data && data.acc === "DULPICATE") {
|
if (data && data.acc === "DULPICATE") {
|
||||||
setMsgError(
|
setMsgError("Duplicate username. Please try another email.");
|
||||||
"Unable to use this username. Please try another username."
|
|
||||||
);
|
|
||||||
setSignUpLoading(false);
|
setSignUpLoading(false);
|
||||||
}
|
}
|
||||||
if (data && data.status === "1") {
|
if (data && data.status === "1") {
|
||||||
@@ -124,6 +125,11 @@ export default function SignUp() {
|
|||||||
setSignUpLoading(false);
|
setSignUpLoading(false);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data && data.status === "5") {
|
||||||
|
setMsgError("Something went wrong. Please try another email.");
|
||||||
|
setSignUpLoading(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setSignUpLoading(false);
|
setSignUpLoading(false);
|
||||||
setMsgError("An error occurred");
|
setMsgError("An error occurred");
|
||||||
@@ -158,7 +164,7 @@ export default function SignUp() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex place-content-center">
|
<div className="flex place-content-center">
|
||||||
<div className="w-11/12 sm:max-w-[530px]">
|
<div className="w-10/12">
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||||
Create Account
|
Create Account
|
||||||
@@ -187,7 +193,9 @@ export default function SignUp() {
|
|||||||
name="country"
|
name="country"
|
||||||
value={formData.country}
|
value={formData.country}
|
||||||
inputHandler={handleInputChange}
|
inputHandler={handleInputChange}
|
||||||
disable={country && countries?.data?.length <= 1 ? true : false}
|
disable={
|
||||||
|
country && countries?.data?.length <= 1 ? true : false
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<div className="input-fl-name mb-4 sm:flex w-full sm:space-x-6 ">
|
<div className="input-fl-name mb-4 sm:flex w-full sm:space-x-6 ">
|
||||||
<div className="input-item sm:w-1/2 w-full mb-4 sm:mb-0">
|
<div className="input-item sm:w-1/2 w-full mb-4 sm:mb-0">
|
||||||
@@ -325,7 +333,7 @@ export default function SignUp() {
|
|||||||
disabled={countries.loading}
|
disabled={countries.loading}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleSignUp}
|
onClick={handleSignUp}
|
||||||
className={`rounded-full mb-6 text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
|
className={`rounded-full text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
|
||||||
>
|
>
|
||||||
{signUpLoading ? (
|
{signUpLoading ? (
|
||||||
<div className="signup btn-loader"></div>
|
<div className="signup btn-loader"></div>
|
||||||
@@ -335,6 +343,44 @@ export default function SignUp() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* APP DOWNLOAD STORE */}
|
||||||
|
<div className="w-full mt-4">
|
||||||
|
<div className="w-full flex justify-center items-center gap-4">
|
||||||
|
<div className="w-28 lg:w-32">
|
||||||
|
<a
|
||||||
|
className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300"
|
||||||
|
target="_blank"
|
||||||
|
href={process.env.REACT_APP_APPLE_APP}
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<i className="fa-brands fa-apple text-3xl"></i>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="text-[11px]">Available on the</span>
|
||||||
|
<span className="text-[12px] lg:text-base">
|
||||||
|
App Store
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="w-28 lg:w-32">
|
||||||
|
<a
|
||||||
|
className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300"
|
||||||
|
target="_blank"
|
||||||
|
href={process.env.REACT_APP_ANDROID_APP}
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
<i className="fa-brands fa-google-play text-2xl"></i>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="text-[11px]">Available on the</span>
|
||||||
|
<span className="text-[12px] lg:text-base">
|
||||||
|
Google Play
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -350,7 +396,7 @@ const SelectOption = ({
|
|||||||
inputHandler,
|
inputHandler,
|
||||||
value,
|
value,
|
||||||
data, // passing the data from parent
|
data, // passing the data from parent
|
||||||
disable
|
disable,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="input-com mb-7">
|
<div className="input-com mb-7">
|
||||||
@@ -364,39 +410,33 @@ const SelectOption = ({
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
disabled={disable}
|
disabled={disable}
|
||||||
name={name}
|
name={name}
|
||||||
id={name}
|
id={name}
|
||||||
className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
|
className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
|
||||||
onChange={inputHandler}
|
onChange={inputHandler}
|
||||||
value={value}
|
value={value}
|
||||||
>
|
>
|
||||||
{data?.data?.length > 1 ?
|
{data?.data?.length > 1 ? (
|
||||||
<>
|
<>
|
||||||
<option value={""}>Select your Country</option>
|
<option value={""}>Select your Country</option>
|
||||||
{data?.data?.map((item) => (
|
{data?.data?.map((item) => (
|
||||||
<option value={item.code} key={item.uid}>
|
<option value={item.code} key={item.uid}>
|
||||||
{item.country}
|
{item.country}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
:
|
) : data?.data?.length == 1 ? (
|
||||||
data?.data?.length == 1 ?
|
|
||||||
data?.data?.map((item) => (
|
data?.data?.map((item) => (
|
||||||
<option value={item.code} key={item.uid}>
|
<option value={item.code} key={item.uid}>
|
||||||
{item.country}
|
{item.country}
|
||||||
</option>
|
</option>
|
||||||
))
|
))
|
||||||
:
|
) : data?.data?.length < 1 && data.loading ? (
|
||||||
data?.data?.length < 1 && data.loading ?
|
<option value="">Loading...</option>
|
||||||
<option value=''>
|
) : (
|
||||||
Loading...
|
<option value="">No Country Found!</option>
|
||||||
</option>
|
)}
|
||||||
:
|
|
||||||
<option value=''>
|
|
||||||
No Country Found!
|
|
||||||
</option>
|
|
||||||
}
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function UpdatePassword() {
|
|||||||
<AuthLayout slogan="Welcome to myFit">
|
<AuthLayout slogan="Welcome to myFit">
|
||||||
{updated === false ? (
|
{updated === false ? (
|
||||||
<div className="flex place-content-center">
|
<div className="flex place-content-center">
|
||||||
<div className="w-11/12 sm:max-w-[600px]">
|
<div className="w-10/12">
|
||||||
<div className="title-area relative flex flex-col justify-center items-center mb-7">
|
<div className="title-area relative flex flex-col justify-center items-center mb-7">
|
||||||
<h1 className="sm:text-5xl text-4xl font-bold leading-[74px] text-dark-gray dark:text-white">
|
<h1 className="sm:text-5xl text-4xl font-bold leading-[74px] text-dark-gray dark:text-white">
|
||||||
Update Password
|
Update Password
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ export default function VerifyLink() {
|
|||||||
localStorage.setItem("member_id", `${data?.member_id}`);
|
localStorage.setItem("member_id", `${data?.member_id}`);
|
||||||
localStorage.setItem("session_token", `${data?.session}`);
|
localStorage.setItem("session_token", `${data?.session}`);
|
||||||
localStorage.setItem("session", `${data?.session}`);
|
localStorage.setItem("session", `${data?.session}`);
|
||||||
localStorage.setItem("uid", data?.uid)
|
localStorage.setItem("uid", data?.uid);
|
||||||
|
|
||||||
|
|
||||||
navigate("/", { replace: true });
|
navigate("/", { replace: true });
|
||||||
setLinkLoader(false);
|
setLinkLoader(false);
|
||||||
@@ -80,19 +79,19 @@ export default function VerifyLink() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// for verifying the incoming verification link and render the correct component
|
// for verifying the incoming verification link and render the correct component
|
||||||
const verifyEmail = useCallback(async (code) => {
|
const verifyEmail = async (code) => {
|
||||||
try {
|
try {
|
||||||
const verifyRes = await userApi.verifyEmail(code);
|
const verifyRes = await userApi.verifyEmail(code);
|
||||||
if (verifyRes.status === 200) {
|
if (verifyRes.status === 200) {
|
||||||
let { data } = verifyRes;
|
let { data } = verifyRes;
|
||||||
console.log('TESTING VERIFY',data)
|
console.log("TESTING VERIFY", data);
|
||||||
if (
|
if (
|
||||||
data &&
|
data &&
|
||||||
data.internal_return >= 0 &&
|
data.internal_return >= 0 &&
|
||||||
data.status == 0 &&
|
data.status == 0 &&
|
||||||
data.pending_id != '' &&
|
data.pending_id != "" &&
|
||||||
data.pending_uid != '' &&
|
data.pending_uid != "" &&
|
||||||
data.username != '' &&
|
data.username != "" &&
|
||||||
data.status_text === "Link Verified"
|
data.status_text === "Link Verified"
|
||||||
) {
|
) {
|
||||||
setPageLoader(false);
|
setPageLoader(false);
|
||||||
@@ -106,12 +105,13 @@ export default function VerifyLink() {
|
|||||||
setLinkSuccess(false);
|
setLinkSuccess(false);
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}, []);
|
};
|
||||||
|
|
||||||
// delay verify requests by 10000ms
|
// delay verify requests by 10000ms
|
||||||
const debouncedEmail = debounce(verifyEmail, 1000);
|
const debouncedEmail = debounce(verifyEmail, 1000);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setEmail("")
|
||||||
debouncedEmail(token);
|
debouncedEmail(token);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -171,53 +171,57 @@ const SuccessfulComponent = ({
|
|||||||
handleEmail,
|
handleEmail,
|
||||||
msgErr,
|
msgErr,
|
||||||
loader,
|
loader,
|
||||||
}) => (
|
}) => {
|
||||||
<div className="input-area">
|
return (
|
||||||
{/* INPUT */}
|
<div className="input-area">
|
||||||
<div className="mb-5">
|
{/* INPUT */}
|
||||||
<InputCom
|
<div className="mb-5">
|
||||||
fieldClass="px-6"
|
<InputCom
|
||||||
value={email}
|
fieldClass="px-6"
|
||||||
inputHandler={handleEmail}
|
value={email}
|
||||||
placeholder="support@mermsemr.com"
|
inputHandler={handleEmail}
|
||||||
label="Email"
|
placeholder="support@mermsemr.com"
|
||||||
name="email"
|
label="Email"
|
||||||
type="email"
|
name="email"
|
||||||
iconName="message"
|
type="email"
|
||||||
/>
|
iconName="message"
|
||||||
</div>
|
autoComplete="off"
|
||||||
<div className="mb-5">
|
/>
|
||||||
<InputCom
|
</div>
|
||||||
fieldClass="px-6"
|
<div className="mb-5">
|
||||||
value={password}
|
<InputCom
|
||||||
inputHandler={handlePassword}
|
fieldClass="px-6"
|
||||||
placeholder="● ● ● ● ● ●"
|
value={password}
|
||||||
label="Password"
|
inputHandler={handlePassword}
|
||||||
name="password"
|
placeholder="● ● ● ● ● ●"
|
||||||
type="password"
|
label="Password"
|
||||||
iconName="password"
|
name="password"
|
||||||
/>
|
type="password"
|
||||||
</div>
|
iconName="password"
|
||||||
{msgErr && (
|
autoComplete="off"
|
||||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
/>
|
||||||
{msgErr}
|
</div>
|
||||||
|
{msgErr && (
|
||||||
|
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||||
|
{msgErr}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="signin-area mb-3.5">
|
||||||
|
<button
|
||||||
|
onClick={onSubmit}
|
||||||
|
type="button"
|
||||||
|
className={`btn-login rounded-[0.475rem] mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||||
|
>
|
||||||
|
{loader ? (
|
||||||
|
<div className="signup btn-loader"></div>
|
||||||
|
) : (
|
||||||
|
<span>Continue</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
<div className="signin-area mb-3.5">
|
|
||||||
<button
|
|
||||||
onClick={onSubmit}
|
|
||||||
type="button"
|
|
||||||
className={`btn-login rounded-[0.475rem] mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
|
||||||
>
|
|
||||||
{loader ? (
|
|
||||||
<div className="signup btn-loader"></div>
|
|
||||||
) : (
|
|
||||||
<span>Continue</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
};
|
||||||
|
|
||||||
const ErrorComponent = ({ onClick }) => (
|
const ErrorComponent = ({ onClick }) => (
|
||||||
<div className="input-area">
|
<div className="input-area">
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ export default function VerifyLink() {
|
|||||||
localStorage.setItem("member_id", `${data?.member_id}`);
|
localStorage.setItem("member_id", `${data?.member_id}`);
|
||||||
localStorage.setItem("session_token", `${data?.session}`);
|
localStorage.setItem("session_token", `${data?.session}`);
|
||||||
localStorage.setItem("session", `${data?.session}`);
|
localStorage.setItem("session", `${data?.session}`);
|
||||||
localStorage.setItem("uid", data?.uid)
|
localStorage.setItem("uid", data?.uid);
|
||||||
|
|
||||||
|
|
||||||
navigate("/", { replace: true });
|
navigate("/", { replace: true });
|
||||||
setLinkLoader(false);
|
setLinkLoader(false);
|
||||||
@@ -85,16 +84,17 @@ export default function VerifyLink() {
|
|||||||
const verifyRes = await userApi.verifyEmail(code);
|
const verifyRes = await userApi.verifyEmail(code);
|
||||||
if (verifyRes.status === 200) {
|
if (verifyRes.status === 200) {
|
||||||
let { data } = verifyRes;
|
let { data } = verifyRes;
|
||||||
console.log('TESTING VERIFY',data)
|
console.log("TESTING VERIFY", data);
|
||||||
if (
|
if (
|
||||||
data &&
|
data &&
|
||||||
data.internal_return >= 0 &&
|
data.internal_return >= 0 &&
|
||||||
data.status == 0 &&
|
data.status == 0 &&
|
||||||
data.pending_id != '' &&
|
data.pending_id != "" &&
|
||||||
data.pending_uid != '' &&
|
data.pending_uid != "" &&
|
||||||
data.username != '' &&
|
data.username != "" &&
|
||||||
data.status_text === "Link Verified"
|
data.status_text === "Link Verified"
|
||||||
) {
|
) {
|
||||||
|
setEmail(data.username);
|
||||||
setPageLoader(false);
|
setPageLoader(false);
|
||||||
} else {
|
} else {
|
||||||
setPageLoader(false);
|
setPageLoader(false);
|
||||||
@@ -132,7 +132,7 @@ export default function VerifyLink() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex place-content-center">
|
<div className="flex place-content-center">
|
||||||
<div className="w-11/12 sm:max-w-[500px]">
|
<div className="w-10/12">
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||||
{linkSuccess
|
{linkSuccess
|
||||||
@@ -184,6 +184,7 @@ const SuccessfulComponent = ({
|
|||||||
name="email"
|
name="email"
|
||||||
type="email"
|
type="email"
|
||||||
iconName="message"
|
iconName="message"
|
||||||
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-5">
|
<div className="mb-5">
|
||||||
@@ -196,6 +197,7 @@ const SuccessfulComponent = ({
|
|||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type="password"
|
||||||
iconName="password"
|
iconName="password"
|
||||||
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{msgErr && (
|
{msgErr && (
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ const VerifyPassword = () => {
|
|||||||
{requestStatus.loading ? (
|
{requestStatus.loading ? (
|
||||||
<LoadingSpinner color="sky-blue" size="16" height="h-300px" />
|
<LoadingSpinner color="sky-blue" size="16" height="h-300px" />
|
||||||
) : !requestStatus.loading && requestStatus.status ? (
|
) : !requestStatus.loading && requestStatus.status ? (
|
||||||
<div className="w-11/12 sm:max-w-[500px]">
|
<div className="w-10/12">
|
||||||
{linkSuccess == null ? (
|
{linkSuccess == null ? (
|
||||||
<>
|
<>
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function VerifyYou() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex place-content-center">
|
<div className="flex place-content-center">
|
||||||
<div className="w-11/12 sm:max-w-[500px]">
|
<div className="w-10/12">
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||||
Let's verify your email now
|
Let's verify your email now
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default function HomeBannerOffersCard(props) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let { banner, banner_location } = props?.itemData;
|
let { banner, banner_location } = props?.itemData;
|
||||||
if (banner_location === "LOCAL") {
|
if (banner_location === "LOCAL") {
|
||||||
const imagePath = require(`../../assets/images/${banner}`); // Replace with your directory path for local images
|
const imagePath = require(`../../assets/images/${banner}`);
|
||||||
setImageUrl(imagePath);
|
setImageUrl(imagePath);
|
||||||
} else if (banner_location === "URL") setImageUrl(banner);
|
} else if (banner_location === "URL") setImageUrl(banner);
|
||||||
else return null;
|
else return null;
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import heroBg from "../../assets/images/bg-sky-blue.jpg"; //hero-bg.svg";
|
||||||
|
import heroUser from "../../assets/images/hero-user.png";
|
||||||
|
import CountDown from "../Helpers/CountDown";
|
||||||
|
// import HomeSliders from "./HomeSliders";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import HomeSliders from "../Home/HomeSliders";
|
||||||
|
|
||||||
|
export default function FamilyParentDashboard({ className, bannerList, nextDueTask }) {
|
||||||
|
const settings = {
|
||||||
|
autoplay: true,
|
||||||
|
dots: true,
|
||||||
|
arrows: false,
|
||||||
|
infinite: true,
|
||||||
|
swipe: true,
|
||||||
|
};
|
||||||
|
const sildeData = null;
|
||||||
|
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||||
|
|
||||||
|
let loginDate = userDetails?.last_login.split(" ")[0];
|
||||||
|
let { firstname, lastname, email, profile_pic } = userDetails;
|
||||||
|
let userEmail = email.split("@")[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-full min-h-[400px] md:grid grid-cols-2 lg:p-8 p-4 justify-between items-center gap-2 rounded-2xl overflow-hidden bg-blue-500 ${
|
||||||
|
className || ""
|
||||||
|
}`}
|
||||||
|
style={{
|
||||||
|
// background: `url(${heroBg})`,
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="h-full flex flex-col justify-between mb-5 lg:mb-0">
|
||||||
|
{/* heading */}
|
||||||
|
<div>
|
||||||
|
<h1 className="lg:text-2xl text-xl font-medium text-white tracking-wide">
|
||||||
|
Welcome
|
||||||
|
</h1>
|
||||||
|
<span className="text-[18px] font-thin tracking-wide text-white">
|
||||||
|
Last Login : {loginDate}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/* user */}
|
||||||
|
<div className="flex items-center space-x-3">
|
||||||
|
<div className="w-14 h-14 flex justify-center items-center rounded-full overflow-hidden">
|
||||||
|
<img src={profile_pic != "" ? profile_pic : heroUser} alt="" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-xl tracking-wide font-bold antise text-white">
|
||||||
|
{`${firstname} ${lastname}`}
|
||||||
|
</p>
|
||||||
|
<p className="text-sm tracking-wide text-white">@{userEmail}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* countdown */}
|
||||||
|
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && (
|
||||||
|
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Current Task</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{(nextDueTask.next_due.item_code).substr(0,4)+'...'}
|
||||||
|
</p>
|
||||||
|
<p className="text-base text-white tracking-wide">
|
||||||
|
{nextDueTask.next_due.price * 0.01} Naira
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="w-[1px] h-full bg-white-opacity"></div>
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Next due in</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
|
||||||
|
<CountDown lastDate={nextDueTask.next_due.due_date} />
|
||||||
|
</p>
|
||||||
|
<div className="text-base text-white tracking-wide flex gap-[23px]">
|
||||||
|
<span>Hrs</span>
|
||||||
|
<span>Min</span>
|
||||||
|
<span>Sec</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* action */}
|
||||||
|
<div className="flex lg:space-x-3 space-x-1 items-center">
|
||||||
|
<Link to="/mytask" className="text-white text-base">
|
||||||
|
<span className=" border-b dark:border-[#5356fb29] border-white">
|
||||||
|
{" "}
|
||||||
|
View All Task(s)
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<HomeSliders
|
||||||
|
settings={settings}
|
||||||
|
sideData={sildeData}
|
||||||
|
bannerList={bannerList}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import heroBg from "../../assets/images/bg-sky-blue.jpg"; //hero-bg.svg";
|
||||||
|
import heroUser from "../../assets/images/hero-user.png";
|
||||||
|
import CountDown from "../Helpers/CountDown";
|
||||||
|
// import HomeSliders from "./HomeSliders";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import HomeSliders from "../Home/HomeSliders";
|
||||||
|
|
||||||
|
export default function HomeDashboard({ className, bannerList, nextDueTask }) {
|
||||||
|
const settings = {
|
||||||
|
autoplay: true,
|
||||||
|
dots: true,
|
||||||
|
arrows: false,
|
||||||
|
infinite: true,
|
||||||
|
swipe: true,
|
||||||
|
};
|
||||||
|
const sildeData = null;
|
||||||
|
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||||
|
|
||||||
|
let loginDate = userDetails?.last_login.split(" ")[0];
|
||||||
|
let { firstname, lastname, email, profile_pic } = userDetails;
|
||||||
|
let userEmail = email.split("@")[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-full min-h-[400px] md:grid grid-cols-2 lg:p-8 p-4 justify-between items-center gap-2 rounded-2xl overflow-hidden ${
|
||||||
|
className || ""
|
||||||
|
}`}
|
||||||
|
style={{
|
||||||
|
background: `url(${heroBg})`,
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="h-full flex flex-col justify-between mb-5 lg:mb-0">
|
||||||
|
{/* heading */}
|
||||||
|
<div>
|
||||||
|
<h1 className="lg:text-2xl text-xl font-medium text-white tracking-wide">
|
||||||
|
Welcome
|
||||||
|
</h1>
|
||||||
|
<span className="text-[18px] font-thin tracking-wide text-white">
|
||||||
|
Last Login : {loginDate}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/* user */}
|
||||||
|
<div className="flex items-center space-x-3">
|
||||||
|
<div className="w-14 h-14 flex justify-center items-center rounded-full overflow-hidden">
|
||||||
|
<img src={profile_pic != "" ? profile_pic : heroUser} alt="" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-xl tracking-wide font-bold antise text-white">
|
||||||
|
{`${firstname} ${lastname}`}
|
||||||
|
</p>
|
||||||
|
<p className="text-sm tracking-wide text-white">@{userEmail}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* countdown */}
|
||||||
|
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && (
|
||||||
|
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Current Task</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{(nextDueTask.next_due.item_code).substr(0,4)+'...'}
|
||||||
|
</p>
|
||||||
|
<p className="text-base text-white tracking-wide">
|
||||||
|
{nextDueTask.next_due.price * 0.01} Naira
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="w-[1px] h-full bg-white-opacity"></div>
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Next due in</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
|
||||||
|
<CountDown lastDate={nextDueTask.next_due.due_date} />
|
||||||
|
</p>
|
||||||
|
<div className="text-base text-white tracking-wide flex gap-[23px]">
|
||||||
|
<span>Hrs</span>
|
||||||
|
<span>Min</span>
|
||||||
|
<span>Sec</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* action */}
|
||||||
|
<div className="flex lg:space-x-3 space-x-1 items-center">
|
||||||
|
<Link to="/mytask" className="text-white text-base">
|
||||||
|
<span className=" border-b dark:border-[#5356fb29] border-white">
|
||||||
|
{" "}
|
||||||
|
View All Task(s)
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<HomeSliders
|
||||||
|
settings={settings}
|
||||||
|
sideData={sildeData}
|
||||||
|
bannerList={bannerList}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import heroBg from "../../assets/images/bg-sky-blue.jpg"; //hero-bg.svg";
|
||||||
|
import heroUser from "../../assets/images/hero-user.png";
|
||||||
|
import CountDown from "../Helpers/CountDown";
|
||||||
|
// import HomeSliders from "./HomeSliders";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import HomeSliders from "../Home/HomeSliders";
|
||||||
|
|
||||||
|
export default function JobOwnerDashboard({ className, bannerList, nextDueTask }) {
|
||||||
|
const settings = {
|
||||||
|
autoplay: true,
|
||||||
|
dots: true,
|
||||||
|
arrows: false,
|
||||||
|
infinite: true,
|
||||||
|
swipe: true,
|
||||||
|
};
|
||||||
|
const sildeData = null;
|
||||||
|
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||||
|
|
||||||
|
let loginDate = userDetails?.last_login.split(" ")[0];
|
||||||
|
let { firstname, lastname, email, profile_pic } = userDetails;
|
||||||
|
let userEmail = email.split("@")[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-full min-h-[400px] md:grid grid-cols-2 lg:p-8 p-4 justify-between items-center gap-2 rounded-2xl overflow-hidden bg-blue-800 ${
|
||||||
|
className || ""
|
||||||
|
}`}
|
||||||
|
style={{
|
||||||
|
// background: `url(${heroBg})`,
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="h-full flex flex-col justify-between mb-5 lg:mb-0">
|
||||||
|
{/* heading */}
|
||||||
|
<div>
|
||||||
|
<h1 className="lg:text-2xl text-xl font-medium text-white tracking-wide">
|
||||||
|
Welcome
|
||||||
|
</h1>
|
||||||
|
<span className="text-[18px] font-thin tracking-wide text-white">
|
||||||
|
Last Login : {loginDate}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/* user */}
|
||||||
|
<div className="flex items-center space-x-3">
|
||||||
|
<div className="w-14 h-14 flex justify-center items-center rounded-full overflow-hidden">
|
||||||
|
<img src={profile_pic != "" ? profile_pic : heroUser} alt="" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-xl tracking-wide font-bold antise text-white">
|
||||||
|
{`${firstname} ${lastname}`}
|
||||||
|
</p>
|
||||||
|
<p className="text-sm tracking-wide text-white">@{userEmail}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* countdown */}
|
||||||
|
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && (
|
||||||
|
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Current Task</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{(nextDueTask.next_due.item_code).substr(0,4)+'...'}
|
||||||
|
</p>
|
||||||
|
<p className="text-base text-white tracking-wide">
|
||||||
|
{nextDueTask.next_due.price * 0.01} Naira
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="w-[1px] h-full bg-white-opacity"></div>
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Next due in</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
|
||||||
|
<CountDown lastDate={nextDueTask.next_due.due_date} />
|
||||||
|
</p>
|
||||||
|
<div className="text-base text-white tracking-wide flex gap-[23px]">
|
||||||
|
<span>Hrs</span>
|
||||||
|
<span>Min</span>
|
||||||
|
<span>Sec</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* action */}
|
||||||
|
<div className="flex lg:space-x-3 space-x-1 items-center">
|
||||||
|
<Link to="/mytask" className="text-white text-base">
|
||||||
|
<span className=" border-b dark:border-[#5356fb29] border-white">
|
||||||
|
{" "}
|
||||||
|
View All Task(s)
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<HomeSliders
|
||||||
|
settings={settings}
|
||||||
|
sideData={sildeData}
|
||||||
|
bannerList={bannerList}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import heroBg from "../../assets/images/bg-sky-blue.jpg"; //hero-bg.svg";
|
||||||
|
import heroUser from "../../assets/images/hero-user.png";
|
||||||
|
import CountDown from "../Helpers/CountDown";
|
||||||
|
// import HomeSliders from "./HomeSliders";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import HomeSliders from "../Home/HomeSliders";
|
||||||
|
|
||||||
|
export default function WorkerDashboard({ className, bannerList, nextDueTask }) {
|
||||||
|
const settings = {
|
||||||
|
autoplay: true,
|
||||||
|
dots: true,
|
||||||
|
arrows: false,
|
||||||
|
infinite: true,
|
||||||
|
swipe: true,
|
||||||
|
};
|
||||||
|
const sildeData = null;
|
||||||
|
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||||
|
|
||||||
|
let loginDate = userDetails?.last_login.split(" ")[0];
|
||||||
|
let { firstname, lastname, email, profile_pic } = userDetails;
|
||||||
|
let userEmail = email.split("@")[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-full min-h-[400px] md:grid grid-cols-2 lg:p-8 p-4 justify-between items-center gap-2 rounded-2xl overflow-hidden bg-blue-900 ${
|
||||||
|
className || ""
|
||||||
|
}`}
|
||||||
|
style={{
|
||||||
|
// background: `url(${heroBg})`,
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
backgroundSize: "cover",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="h-full flex flex-col justify-between mb-5 lg:mb-0">
|
||||||
|
{/* heading */}
|
||||||
|
<div>
|
||||||
|
<h1 className="lg:text-2xl text-xl font-medium text-white tracking-wide">
|
||||||
|
Welcome
|
||||||
|
</h1>
|
||||||
|
<span className="text-[18px] font-thin tracking-wide text-white">
|
||||||
|
Last Login : {loginDate}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/* user */}
|
||||||
|
<div className="flex items-center space-x-3">
|
||||||
|
<div className="w-14 h-14 flex justify-center items-center rounded-full overflow-hidden">
|
||||||
|
<img src={profile_pic != "" ? profile_pic : heroUser} alt="" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-xl tracking-wide font-bold antise text-white">
|
||||||
|
{`${firstname} ${lastname}`}
|
||||||
|
</p>
|
||||||
|
<p className="text-sm tracking-wide text-white">@{userEmail}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* countdown */}
|
||||||
|
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && (
|
||||||
|
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Current Task</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{(nextDueTask.next_due.item_code).substr(0,4)+'...'}
|
||||||
|
</p>
|
||||||
|
<p className="text-base text-white tracking-wide">
|
||||||
|
{nextDueTask.next_due.price * 0.01} Naira
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="w-[1px] h-full bg-white-opacity"></div>
|
||||||
|
<div className="flex flex-col justify-between">
|
||||||
|
<p className="text-base text-white tracking-wide">Next due in</p>
|
||||||
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
|
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
|
||||||
|
<CountDown lastDate={nextDueTask.next_due.due_date} />
|
||||||
|
</p>
|
||||||
|
<div className="text-base text-white tracking-wide flex gap-[23px]">
|
||||||
|
<span>Hrs</span>
|
||||||
|
<span>Min</span>
|
||||||
|
<span>Sec</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* action */}
|
||||||
|
<div className="flex lg:space-x-3 space-x-1 items-center">
|
||||||
|
<Link to="/mytask" className="text-white text-base">
|
||||||
|
<span className=" border-b dark:border-[#5356fb29] border-white">
|
||||||
|
{" "}
|
||||||
|
View All Task(s)
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<HomeSliders
|
||||||
|
settings={settings}
|
||||||
|
sideData={sildeData}
|
||||||
|
bannerList={bannerList}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import FamilyParentDashboard from "./FamilyParentDashboard";
|
||||||
|
import HomeDashboard from "./HomeDashboard";
|
||||||
|
import JobOwnerDashboard from "./JobOwnerDashboard";
|
||||||
|
import WorkerDashboard from "./WorkerDashboard";
|
||||||
|
|
||||||
|
export {
|
||||||
|
FamilyParentDashboard,
|
||||||
|
HomeDashboard,
|
||||||
|
JobOwnerDashboard,
|
||||||
|
WorkerDashboard,
|
||||||
|
};
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import ModalCom from '../../../Helpers/ModalCom';
|
||||||
|
import LoadingSpinner from '../../../Spinners/LoadingSpinner';
|
||||||
|
import InputCom from '../../../Helpers/Inputs/InputCom/index';
|
||||||
|
import { Formik, Form } from 'formik';
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import usersService from '../../../../services/UsersService';
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
email: Yup.string()
|
||||||
|
.email("Wrong email format")
|
||||||
|
.matches(
|
||||||
|
/^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/,
|
||||||
|
"Invalid email format"
|
||||||
|
)
|
||||||
|
.min(3, "Minimum 3 characters")
|
||||||
|
.max(50, "Maximum 50 characters")
|
||||||
|
.required("Email is required"),
|
||||||
|
firstname: Yup.string()
|
||||||
|
.min(3, "Minimum 3 characters")
|
||||||
|
.max(25, "Maximum 25 characters")
|
||||||
|
.required("Firstname is required"),
|
||||||
|
lastname: Yup.string()
|
||||||
|
.min(3, "Minimum 3 characters")
|
||||||
|
.max(25, "Maximum 25 characters")
|
||||||
|
.required("Lastname is required"),
|
||||||
|
family_type: Yup.string()
|
||||||
|
.min(3, "Minimum 3 characters")
|
||||||
|
.max(25, "Maximum 25 characters")
|
||||||
|
.required("Family Type is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
firstname: '',
|
||||||
|
lastname: '',
|
||||||
|
family_type: '',
|
||||||
|
email: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default function InviteRelative({action, situation, setReloadRelList, relativeList}) {
|
||||||
|
|
||||||
|
const api = new usersService()
|
||||||
|
|
||||||
|
let [requestStatus, setRequestStatus] = useState({
|
||||||
|
loading: false,
|
||||||
|
status: false,
|
||||||
|
message: "",
|
||||||
|
}); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
|
||||||
|
|
||||||
|
const handleInvite = (values) => {
|
||||||
|
setRequestStatus({loading: true, status: false, message: ""})
|
||||||
|
api.inviteFamilyRelative(values).then(response => {
|
||||||
|
let {status, data} = response
|
||||||
|
if(data?.internal_return < 0){
|
||||||
|
setRequestStatus({loading: false, status: false, message: "Unable to complete"})
|
||||||
|
return setTimeout(()=>{
|
||||||
|
setRequestStatus({ loading: false, status: false, message: ""})
|
||||||
|
},3000)
|
||||||
|
}
|
||||||
|
setRequestStatus({loading: false, status: true, message: "Relative Added"})
|
||||||
|
//RELOAD RELATIVE LSIT TABLE
|
||||||
|
setReloadRelList(prev => !prev)
|
||||||
|
setTimeout(()=>{
|
||||||
|
action()
|
||||||
|
},3000)
|
||||||
|
}).catch(error => {
|
||||||
|
setRequestStatus({loading: false, status: false, message: "Something went wrong, try again!"})
|
||||||
|
setTimeout(()=>{
|
||||||
|
setRequestStatus({ loading: false, status: false, message: ""})
|
||||||
|
},3000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalCom
|
||||||
|
action={action}
|
||||||
|
situation={situation}
|
||||||
|
>
|
||||||
|
<div className="lg:w-[600px] w-11/12 lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white dark:text-white">
|
||||||
|
<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">
|
||||||
|
Invite Parent/Relative
|
||||||
|
</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>
|
||||||
|
<div className="logout-modal-body w-full flex flex-col items-center px-10 py-8">
|
||||||
|
<div className="personal-info-tab w-full flex flex-col justify-between">
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={handleInvite}
|
||||||
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form>
|
||||||
|
<div className="w-full flex flex-col-reverse sm:flex-row">
|
||||||
|
<div className="fields w-full">
|
||||||
|
{/* inputs starts here */}
|
||||||
|
{/* Email */}
|
||||||
|
<div className="field w-full mb-6">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
label="Email"
|
||||||
|
type="text"
|
||||||
|
name="email"
|
||||||
|
placeholder="Email"
|
||||||
|
value={props.values.email}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={(props.errors.email && props.touched.email) ? props.errors.email : '' }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* first name and last name */}
|
||||||
|
<div className="md:flex md:space-x-7 mb-6">
|
||||||
|
<div className="field w-full mb-6 md:mb-0">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
label="First Name"
|
||||||
|
type="text"
|
||||||
|
name="firstname"
|
||||||
|
placeholder="First Name"
|
||||||
|
value={props.values.firstname}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={(props.errors.firstname && props.touched.firstname) ? props.errors.firstname : '' }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="field w-full">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
label="Last Name"
|
||||||
|
type="text"
|
||||||
|
name="lastname"
|
||||||
|
placeholder="Last Name"
|
||||||
|
value={props.values.lastname}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={(props.errors.lastname && props.touched.lastname) ? props.errors.lastname : '' }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Type */}
|
||||||
|
<div className="md:flex md:space-x-7 items-end mb-6">
|
||||||
|
{/* <div className="field w-full mb-6 md:mb-0">
|
||||||
|
<InputCom
|
||||||
|
fieldClass="px-6"
|
||||||
|
label="Type"
|
||||||
|
type="text"
|
||||||
|
name="family_type"
|
||||||
|
placeholder="Family Type"
|
||||||
|
value={props.values.family_type}
|
||||||
|
inputHandler={props.handleChange}
|
||||||
|
blurHandler={props.handleBlur}
|
||||||
|
error={(props.errors.family_type && props.touched.family_type) ? props.errors.family_type : '' }
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
<div className="field w-full mb-6 xl:mb-0">
|
||||||
|
<label
|
||||||
|
htmlFor="family_type"
|
||||||
|
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex item-center gap-1"
|
||||||
|
>
|
||||||
|
Family Type
|
||||||
|
{props.errors.family_type && props.touched.family_type && (
|
||||||
|
<span className="text-[12px] text-red-500">
|
||||||
|
{props.errors.family_type}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
id="family_type"
|
||||||
|
name="family_type"
|
||||||
|
value={props.values.family_type}
|
||||||
|
className={`input-field p-2 mt-3 rounded-full placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none border`}
|
||||||
|
onChange={props.handleChange}
|
||||||
|
onBlur={props.handleBlur}
|
||||||
|
>
|
||||||
|
{relativeList?.loading ? (
|
||||||
|
<option className="text-slate-500 text-lg" value="">
|
||||||
|
Loading...
|
||||||
|
</option>
|
||||||
|
) : relativeList?.family_types?.length ? (
|
||||||
|
<>
|
||||||
|
<option className="text-slate-500 text-lg" value="">
|
||||||
|
Select Family Type
|
||||||
|
</option>
|
||||||
|
{relativeList?.family_types?.map((item, index) => (
|
||||||
|
<option
|
||||||
|
key={index}
|
||||||
|
className="text-slate-500 text-lg"
|
||||||
|
value={item?.ty}
|
||||||
|
>
|
||||||
|
{item?.ty}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<option className="text-slate-500 text-lg" value="">
|
||||||
|
No Options Found! Try Again
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="field w-full flex justify-end">
|
||||||
|
<div className="flex">
|
||||||
|
{requestStatus.loading ? (
|
||||||
|
<LoadingSpinner size="8" color="sky-blue" />
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className={`text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full ${(requestStatus.status || requestStatus.loading) && 'opacity-50'}`}
|
||||||
|
disabled={requestStatus.status || requestStatus.loading}
|
||||||
|
>
|
||||||
|
Send Message
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
|
||||||
|
{requestStatus.message != "" &&
|
||||||
|
(!requestStatus.status ? (
|
||||||
|
<div
|
||||||
|
className={`w-full 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import { handlePagingFunc } from '../../../Pagination/HandlePagination';
|
||||||
|
import PaginatedList from '../../../Pagination/PaginatedList';
|
||||||
|
|
||||||
|
export default function RelativeTable({relativeList}) {
|
||||||
|
|
||||||
|
// Handle Pagination
|
||||||
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
|
const indexOfFirstItem = Number(currentPage);
|
||||||
|
const indexOfLastItem =Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
|
|
||||||
|
const currentRelativeList = relativeList?.slice(indexOfFirstItem, indexOfLastItem);
|
||||||
|
|
||||||
|
const handlePagination = (e) => {
|
||||||
|
handlePagingFunc(e, setCurrentPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`w-full overflow-hidden rounded-2xl`}>
|
||||||
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[400px]">
|
||||||
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
|
<tbody>
|
||||||
|
<>
|
||||||
|
{relativeList && relativeList?.length > 0 ? (
|
||||||
|
currentRelativeList.map((value, index) => (
|
||||||
|
<tr key={value.uid || index} className="border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||||
|
<td className='p-2'>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||||
|
{value.firstname && value.firstname} {value.lastname && value.lastname}
|
||||||
|
</h1>
|
||||||
|
<span className="text-sm text-thin-light-gray">
|
||||||
|
{value.email && value.email}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className='p-2'>
|
||||||
|
{/* <span>Family Type</span> */}
|
||||||
|
<span>{value.family_type && value.family_type.toUpperCase()}</span>
|
||||||
|
</td>
|
||||||
|
<td className='p-2 text-right'>
|
||||||
|
{value.status && value.status}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||||
|
<td className="p-2">No Members Found</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{/* PAGINATION BUTTON */}
|
||||||
|
<PaginatedList
|
||||||
|
onClick={handlePagination}
|
||||||
|
prev={currentPage == 0 ? true : false}
|
||||||
|
next={
|
||||||
|
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||||
|
relativeList?.length
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
data={relativeList}
|
||||||
|
start={indexOfFirstItem}
|
||||||
|
stop={indexOfLastItem}
|
||||||
|
/>
|
||||||
|
{/* END OF PAGINATION BUTTON */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,8 +1,68 @@
|
|||||||
import React from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import RelativeTable from './RelativeTable'
|
||||||
|
import InviteRelative from './InviteRelative'
|
||||||
|
import usersService from '../../../../services/UsersService'
|
||||||
|
import LoadingSpinner from '../../../Spinners/LoadingSpinner'
|
||||||
|
|
||||||
const Relatives = () => {
|
const Relatives = () => {
|
||||||
|
|
||||||
|
const api = new usersService()
|
||||||
|
|
||||||
|
const [reloadRelList, setReloadRelList] = useState(false)
|
||||||
|
|
||||||
|
const [invitePopout, setInvitePopout] = useState(false)
|
||||||
|
|
||||||
|
const [relativeList, setRelativeList] = useState({loading: true, result_list:[], family_types:[]})
|
||||||
|
|
||||||
|
const showInviteMemberPopout = () => {
|
||||||
|
setInvitePopout(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRelativeList = () => {
|
||||||
|
setRelativeList(prev => ({...prev, loading: true}))
|
||||||
|
api.getFamilyRelativeList().then(response => {
|
||||||
|
let {status, data} = response
|
||||||
|
if(status != 200 || !data){
|
||||||
|
setRelativeList({loading:false, result_list:[], family_types:[]})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setRelativeList({loading:false, result_list:data?.result_list, family_types:data?.family_types})
|
||||||
|
}).catch(error => {
|
||||||
|
setRelativeList({loading:false, result_list:[], family_types:[]})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
getRelativeList()
|
||||||
|
},[reloadRelList])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>Relatives</div>
|
<>
|
||||||
|
<div className=''>
|
||||||
|
<div className='py-4'>
|
||||||
|
<button onClick={showInviteMemberPopout} className='text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full'>Invite</button>
|
||||||
|
<div className='my-4 border-b-2'></div>
|
||||||
|
</div>
|
||||||
|
<div className='min-h-[500px]'>
|
||||||
|
{relativeList.loading ?
|
||||||
|
<LoadingSpinner size='8' height='h-full' />
|
||||||
|
:
|
||||||
|
<RelativeTable relativeList={relativeList.result_list} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* INVITE RELATIVE POPOUT */}
|
||||||
|
{invitePopout &&
|
||||||
|
<InviteRelative
|
||||||
|
action={()=>setInvitePopout(false)}
|
||||||
|
situation={invitePopout}
|
||||||
|
setReloadRelList={setReloadRelList}
|
||||||
|
relativeList={relativeList}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{/* END OF INVITE RELATIVE POPOUT */}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,14 @@ const FamilySettings = () => {
|
|||||||
<span className={``}>Family Settings</span>
|
<span className={``}>Family Settings</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<Link to="/acc-family">Go Back</Link>
|
<Link to="/acc-family" className="flex gap-2 items-center text-dark-gray dark:text-white">
|
||||||
|
<svg className="w-5 h-5 rtl:rotate-180" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M6.75 15.75L3 12m0 0l3.75-3.75M3 12h18" />
|
||||||
|
</svg>
|
||||||
|
Family
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{/* Something Here */}
|
|
||||||
{/* <form className="logout-modal-body w-full flex flex-col items-center px-10 py-8 gap-4"></form> */}
|
|
||||||
<div className="w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ">
|
<div className="w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ">
|
||||||
<div className="update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] lg:flex lg:px-10 px-4 justify-between">
|
<div className="update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] lg:flex lg:px-10 px-4 justify-between">
|
||||||
<div className="content-tab-items lg:w-[230px] w-full mr-2">
|
<div className="content-tab-items lg:w-[230px] w-full mr-2">
|
||||||
|
|||||||
@@ -560,6 +560,24 @@ export default function Icons({ name }) {
|
|||||||
src={localImgLoad("images/icons/family-pin.svg")}
|
src={localImgLoad("images/icons/family-pin.svg")}
|
||||||
alt="family-pin"
|
alt="family-pin"
|
||||||
/>
|
/>
|
||||||
|
) : name === "pending-job" ? (
|
||||||
|
<img
|
||||||
|
className="w-[19px] h-[19px]"
|
||||||
|
src={localImgLoad("images/icons/job_pending.svg")}
|
||||||
|
alt="Pending Job"
|
||||||
|
/>
|
||||||
|
) : name === "active-job" ? (
|
||||||
|
<img
|
||||||
|
className="w-[17px] h-[17px]"
|
||||||
|
src={localImgLoad("images/icons/job_active.svg")}
|
||||||
|
alt="Active Job"
|
||||||
|
/>
|
||||||
|
) : name === "job-list" ? (
|
||||||
|
<img
|
||||||
|
className="w-[17px] h-[17px]"
|
||||||
|
src={localImgLoad("images/icons/job_list.svg")}
|
||||||
|
alt="Job List"
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export default function InputCom({
|
|||||||
direction,
|
direction,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
error,
|
error,
|
||||||
|
autoComplete="on"
|
||||||
}) {
|
}) {
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
// Entry Validation
|
// Entry Validation
|
||||||
@@ -107,6 +108,7 @@ export default function InputCom({
|
|||||||
readOnly={disable}
|
readOnly={disable}
|
||||||
onBlur={blurHandler}
|
onBlur={blurHandler}
|
||||||
dir={direction}
|
dir={direction}
|
||||||
|
autoComplete={autoComplete}
|
||||||
/>
|
/>
|
||||||
{iconName && (
|
{iconName && (
|
||||||
<div className="absolute right-6 bottom-3 z-10 flex gap-2">
|
<div className="absolute right-6 bottom-3 z-10 flex gap-2">
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ParentWaiting from "../MyPendingJobs/ParentWaiting";
|
import ParentWaiting from "../MyOffers/ParentWaiting";
|
||||||
import MyOffersFamilyTable from "../MyTasks/MyOffersFamilyTable";
|
import MyOffersFamilyTable from "../MyTasks/MyOffersFamilyTable";
|
||||||
import FamilyActiveLSlde from "./FamilyActiveLSlde";
|
import FamilyActiveLSlde from "./FamilyActiveLSlde";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export default function FamilyDash({ familyOffers, MyActiveJobList }) {
|
export default function FamilyDash({ familyOffers, MyActiveJobList }) {
|
||||||
// console.log("PROPS IN FAMILY DASH->", familyOffers?.result_list);
|
// console.log("PROPS IN FAMILY DASH->", familyOffers?.result_list);
|
||||||
@@ -11,6 +12,30 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
|
|||||||
<div>
|
<div>
|
||||||
<div className="home-page-wrapper">
|
<div className="home-page-wrapper">
|
||||||
{/* <CommonHead commonHeadData={props.commonHeadData} /> */}
|
{/* <CommonHead commonHeadData={props.commonHeadData} /> */}
|
||||||
|
|
||||||
|
<div className="w-full mb-4 grid grid-cols-2 md:grid-cols-4 gap-2 md:gap-4">
|
||||||
|
{[1,2,3,4,5].map((item, index) => (
|
||||||
|
<Link to='/' className={`h-40 rounded-lg shadow-sm ${index%2==0 ? 'bg-red-200/50' : 'bg-sky-300/50'}`}>
|
||||||
|
<div >
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="my-4">
|
||||||
|
<h1 className="my-4 text-26 font-bold text-dark-gray dark:text-white tracking-wide">Resources</h1>
|
||||||
|
<div className="w-full grid grid-cols-2 md:grid-cols-3 gap-2 md:gap-4">
|
||||||
|
{[1,2,3,4,5].map((item, index) => (
|
||||||
|
<Link to='/' className={`h-40 rounded-lg shadow-sm ${index%2==0 ? 'bg-red-200/50' : 'bg-sky-300/50'}`}>
|
||||||
|
<div >
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{familyOffers?.result_list && familyOffers?.result_list.length > 0 && (
|
{familyOffers?.result_list && familyOffers?.result_list.length > 0 && (
|
||||||
<MyOffersFamilyTable
|
<MyOffersFamilyTable
|
||||||
familyOffers={familyOffers?.result_list}
|
familyOffers={familyOffers?.result_list}
|
||||||
@@ -19,7 +44,11 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{trending && trending.length > 0 && (
|
{trending && trending.length > 0 && (
|
||||||
<FamilyActiveLSlde trending={trending} className="mb-10" image_server={familyOffers?.session_image_server} />
|
<FamilyActiveLSlde
|
||||||
|
trending={trending}
|
||||||
|
className="mb-10"
|
||||||
|
image_server={familyOffers?.session_image_server}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/*<TopSellerTopBuyerSliderSection className="mb-10" />*/}
|
{/*<TopSellerTopBuyerSliderSection className="mb-10" />*/}
|
||||||
|
|||||||
@@ -4,22 +4,62 @@ import MyOffersTable from "../MyTasks/MyOffersTable";
|
|||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import Hero from "./Hero";
|
import Hero from "./Hero";
|
||||||
import HomeActivities from "./HomeActivities";
|
import HomeActivities from "./HomeActivities";
|
||||||
|
import { FamilyParentDashboard, HomeDashboard, JobOwnerDashboard, WorkerDashboard } from "../Dashboards";
|
||||||
|
|
||||||
export default function FullAccountDash(props) {
|
export default function FullAccountDash(props) {
|
||||||
// console.log("PROPS IN HOME->", props);
|
// console.log("PROPS IN HOME->", props);
|
||||||
|
|
||||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||||
|
|
||||||
|
const renderDashboard = () => {
|
||||||
|
switch (props.dashTypes) {
|
||||||
|
case "DEFAULT_HOME_DASH":
|
||||||
|
return (
|
||||||
|
<HomeDashboard
|
||||||
|
className="mb-10"
|
||||||
|
data={userDetails}
|
||||||
|
bannerList={props.bannerList}
|
||||||
|
nextDueTask={props.nextDueTask}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case "FAMILY_PARENT_DASH":
|
||||||
|
return (
|
||||||
|
<FamilyParentDashboard
|
||||||
|
className="mb-10"
|
||||||
|
data={userDetails}
|
||||||
|
bannerList={props.bannerList}
|
||||||
|
nextDueTask={props.nextDueTask}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case "WORKER_HOME_DASH":
|
||||||
|
return (
|
||||||
|
<WorkerDashboard
|
||||||
|
className="mb-10"
|
||||||
|
data={userDetails}
|
||||||
|
bannerList={props.bannerList}
|
||||||
|
nextDueTask={props.nextDueTask}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case "JOBOWNER_HOME_DASH":
|
||||||
|
return (
|
||||||
|
<JobOwnerDashboard
|
||||||
|
className="mb-10"
|
||||||
|
data={userDetails}
|
||||||
|
bannerList={props.bannerList}
|
||||||
|
nextDueTask={props.nextDueTask}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="home-page-wrapper">
|
<div className="home-page-wrapper">
|
||||||
<Hero
|
{renderDashboard()}
|
||||||
className="mb-10"
|
|
||||||
data={userDetails}
|
{props?.dashTypes !== "undefined" && props.offersList?.data?.result_list?.length ? (
|
||||||
bannerList={props.bannerList}
|
|
||||||
nextDueTask={props.nextDueTask}
|
|
||||||
/>
|
|
||||||
{props.offersList?.data?.result_list?.length ? (
|
|
||||||
<MyOffersTable
|
<MyOffersTable
|
||||||
MyActiveOffersList={props.offersList?.data}
|
MyActiveOffersList={props.offersList?.data}
|
||||||
className="mb-10"
|
className="mb-10"
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ export default function Home(props) {
|
|||||||
<FullAccountDash
|
<FullAccountDash
|
||||||
nextDueTask={nextDueTask}
|
nextDueTask={nextDueTask}
|
||||||
bannerList={props.bannerList}
|
bannerList={props.bannerList}
|
||||||
|
dashTypes={props.dashTypes}
|
||||||
offersList={MyOffersList}
|
offersList={MyOffersList}
|
||||||
MyActiveJobList={MyActiveJobList}
|
MyActiveJobList={MyActiveJobList}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default function DeleteGroup({action, situation, details}) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<p className="text-xl text-center tracking-wide text-dark-gray dark:text-white">
|
<p className="text-xl text-center tracking-wide text-dark-gray dark:text-white">
|
||||||
Are you sure, you want to delete <br /> <span>'{details?.group_name}'</span>
|
Are you sure, you want to delete <br /> <span>'{details?.group_name}'</span> group?
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-2.5">
|
<div className="flex space-x-2.5">
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default function DeleteMember({action, situation, details}) {
|
|||||||
<div className="logout-modal-wrapper lg:w-[500px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
<div className="logout-modal-wrapper lg:w-[500px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||||
<div className="logout-modal-header w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b border-light-purple dark:border-[#5356fb29] ">
|
<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">
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
Delete Member
|
Remove Member
|
||||||
</h1>
|
</h1>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -73,7 +73,7 @@ export default function DeleteMember({action, situation, details}) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<p className="text-xl text-center tracking-wide text-dark-gray dark:text-white">
|
<p className="text-xl text-center tracking-wide text-dark-gray dark:text-white">
|
||||||
Are you sure, you want to delete <br /> <span>'{details?.firstname} {details.lastname}'</span>
|
Are you sure, you want to remove <br /> <span>'{details?.firstname} {details.lastname}'</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-2.5">
|
<div className="flex space-x-2.5">
|
||||||
@@ -92,7 +92,7 @@ export default function DeleteMember({action, situation, details}) {
|
|||||||
type="button"
|
type="button"
|
||||||
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||||
>
|
>
|
||||||
Confirm Delete
|
Remove
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,72 +1,104 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import InputCom from '../../components/Helpers/Inputs/InputCom/index'
|
import AddGroup from "./AddGroup";
|
||||||
import DeleteGroup from './DeleteGroup'
|
import DeleteGroup from "./DeleteGroup";
|
||||||
import AddGroup from './AddGroup'
|
import { localImgLoad } from "../../lib";
|
||||||
|
|
||||||
export default function GroupList({groupList, selectedGroup, changeSelectedGroup, setUpdateList}) {
|
export default function GroupList({
|
||||||
|
groupList,
|
||||||
|
selectedGroup,
|
||||||
|
changeSelectedGroup,
|
||||||
|
setUpdateList,
|
||||||
|
}) {
|
||||||
|
const [deletePopout, setDeletePopout] = useState({
|
||||||
|
status: false,
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
const [deletePopout, setDeletePopout] = useState({
|
const [addGroupPopout, setAddGroupPopout] = useState(false);
|
||||||
status: false,
|
|
||||||
data: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const [addGroupPopout, setAddGroupPopout] = useState(false)
|
const handleAddGroup = () => {
|
||||||
|
setAddGroupPopout(true);
|
||||||
const handleAddGroup = () => {
|
};
|
||||||
setAddGroupPopout(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleDeleteGroup = (item) => {
|
|
||||||
setDeletePopout({
|
|
||||||
status: true,
|
|
||||||
data: {...item}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const handleDeleteGroup = (item) => {
|
||||||
|
setDeletePopout({
|
||||||
|
status: true,
|
||||||
|
data: { ...item },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='p-5 w-full lg:w-[400px] min-h-[300px] bg-sky-100 dark:bg-dark-gray rounded-2xl'>
|
<div className="p-5 w-full lg:w-[400px] min-h-[300px] bg-sky-100 dark:bg-dark-gray rounded-2xl flex flex-col">
|
||||||
{/* <h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>Jobs Groups</h1> */}
|
{/* <h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>Jobs Groups</h1> */}
|
||||||
<div className='flex justify-end items-center'>
|
<div className="flex justify-end items-center">
|
||||||
<button onClick={handleAddGroup} className='py-2 px-4 flex justify-center items-center bg-sky-blue hover:bg-sky-600 text-base rounded-full text-white font-bold'>Add Group</button>
|
<button
|
||||||
</div>
|
onClick={handleAddGroup}
|
||||||
|
className="py-2 px-4 flex justify-center items-center bg-sky-blue hover:bg-sky-600 text-base rounded-full text-white font-bold"
|
||||||
{groupList && groupList.length < 1 ?
|
>
|
||||||
<h1 className='my-5 text-lg tracking-wide text-slate-900 dark:text-slate-100'>No Group Found!</h1>
|
Add Group
|
||||||
:
|
</button>
|
||||||
<div className='my-4 max-h-[400px] overflow-y-auto'>
|
|
||||||
<div className='flex flex-col'>
|
|
||||||
{groupList.map(item=> (
|
|
||||||
<div key={item.group_uid} className='p-2 flex gap-2 items-center justify-between w-full'>
|
|
||||||
<div className='flex gap-2 items-center'>
|
|
||||||
<input type='radio' name='grouplist' value={item.group_id} checked={selectedGroup?.id == item?.group_id} onChange={changeSelectedGroup} className='w-[20px] h-[20px] outline-none' />
|
|
||||||
<p className='text-sm lg:text-base text-slate-900 dark:text-slate-100'>{item.group_name}</p>
|
|
||||||
</div>
|
|
||||||
<button onClick={()=>{handleDeleteGroup(item)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5 flex justify-center items-center'>X</button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{deletePopout.status &&
|
|
||||||
<DeleteGroup
|
|
||||||
action={()=>setDeletePopout({status:false, data:{}})}
|
|
||||||
situation={deletePopout.status}
|
|
||||||
details={deletePopout.data}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{addGroupPopout &&
|
{groupList && groupList.length < 1 ? (
|
||||||
<AddGroup
|
<h1 className="my-5 text-lg tracking-wide text-slate-900 dark:text-slate-100">
|
||||||
action={()=>setAddGroupPopout(false)}
|
No Group Found!
|
||||||
situation={addGroupPopout}
|
</h1>
|
||||||
setUpdateList={setUpdateList}
|
) : (
|
||||||
/>
|
<div className="my-4 max-h-[596px] bg-[#fffef6] rounded overflow-y-auto flex-1">
|
||||||
}
|
<div className="flex flex-col">
|
||||||
|
{groupList.map((item) => (
|
||||||
|
<div
|
||||||
|
key={item.group_uid}
|
||||||
|
className="p-2 flex gap-2 items-center justify-between w-full"
|
||||||
|
>
|
||||||
|
<div className="flex gap-2 items-center">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="grouplist"
|
||||||
|
value={item.group_id}
|
||||||
|
checked={selectedGroup?.id == item?.group_id}
|
||||||
|
onChange={changeSelectedGroup}
|
||||||
|
className="w-[20px] h-[20px] outline-none"
|
||||||
|
/>
|
||||||
|
<p className="text-sm lg:text-base text-slate-900 dark:text-slate-100">
|
||||||
|
{item.group_name}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
handleDeleteGroup(item);
|
||||||
|
}}
|
||||||
|
className="flex relative items-center justify-center border-0 w-6 h-6"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={localImgLoad("images/icons/remove_grp.svg")}
|
||||||
|
alt="remove-icon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deletePopout.status && (
|
||||||
|
<DeleteGroup
|
||||||
|
action={() => setDeletePopout({ status: false, data: {} })}
|
||||||
|
situation={deletePopout.status}
|
||||||
|
details={deletePopout.data}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{addGroupPopout && (
|
||||||
|
<AddGroup
|
||||||
|
action={() => setAddGroupPopout(false)}
|
||||||
|
situation={addGroupPopout}
|
||||||
|
setUpdateList={setUpdateList}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,98 +1,118 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import { handlePagingFunc } from '../Pagination/HandlePagination';
|
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||||
import PaginatedList from '../Pagination/PaginatedList';
|
import PaginatedList from "../Pagination/PaginatedList";
|
||||||
import DeleteMember from './DeleteMember';
|
import DeleteMember from "./DeleteMember";
|
||||||
|
import { localImgLoad } from "../../lib";
|
||||||
|
|
||||||
export default function GroupMemberTable({selectedList}) {
|
export default function GroupMemberTable({ selectedList }) {
|
||||||
|
// Handle Pagination
|
||||||
// Handle Pagination
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const indexOfFirstItem = Number(currentPage);
|
||||||
const indexOfFirstItem = Number(currentPage);
|
const indexOfLastItem =
|
||||||
const indexOfLastItem =Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
|
|
||||||
const currentSelectedList = selectedList?.slice(indexOfFirstItem, indexOfLastItem);
|
const currentSelectedList = selectedList?.slice(
|
||||||
|
indexOfFirstItem,
|
||||||
const handlePagination = (e) => {
|
indexOfLastItem
|
||||||
handlePagingFunc(e, setCurrentPage);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const [deletePopout, setDeletePopout] = useState({
|
const handlePagination = (e) => {
|
||||||
status: false,
|
handlePagingFunc(e, setCurrentPage);
|
||||||
data: {}
|
};
|
||||||
})
|
|
||||||
|
|
||||||
const handleDeleteMember = (item) => {
|
const [deletePopout, setDeletePopout] = useState({
|
||||||
setDeletePopout({
|
status: false,
|
||||||
status: true,
|
data: {},
|
||||||
data: {...item}
|
});
|
||||||
})
|
|
||||||
}
|
const handleDeleteMember = (item) => {
|
||||||
|
setDeletePopout({
|
||||||
return (
|
status: true,
|
||||||
<div className={`w-full p-8 bg-white dark:bg-dark-gray overflow-hidden rounded-2xl section-shadow`}>
|
data: { ...item },
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[400px]">
|
});
|
||||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
};
|
||||||
<tbody>
|
|
||||||
<>
|
return (
|
||||||
{selectedList && selectedList?.length > 0 ? (
|
<div
|
||||||
currentSelectedList.map((value, index) => (
|
className={`w-full p-8 dark:bg-dark-gray overflow-hidden rounded-2xl section-shado bg-[#fffef6]`}
|
||||||
<tr key={value.uid} className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
>
|
||||||
{/* <td className="p-1">{value?.firstname}</td>
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[400px]">
|
||||||
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
|
<tbody>
|
||||||
|
<>
|
||||||
|
{selectedList && selectedList?.length > 0 ? (
|
||||||
|
currentSelectedList.map((value, index) => (
|
||||||
|
<tr
|
||||||
|
key={value.uid}
|
||||||
|
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||||
|
>
|
||||||
|
{/* <td className="p-1">{value?.firstname}</td>
|
||||||
<td className="p-1">{value?.lastname}</td>
|
<td className="p-1">{value?.lastname}</td>
|
||||||
<td className="p-1">{value?.email}</td>
|
<td className="p-1">{value?.email}</td>
|
||||||
<td className="p-1 text-right">
|
<td className="p-1 text-right">
|
||||||
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button>
|
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button>
|
||||||
</td> */}
|
</td> */}
|
||||||
<td className='py-2'>
|
<td className="py-2">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||||
{value.firstname && value.firstname} {value.lastname && value.lastname}
|
{value.firstname && value.firstname}{" "}
|
||||||
</h1>
|
{value.lastname && value.lastname}
|
||||||
<span className="text-sm text-thin-light-gray">
|
</h1>
|
||||||
{value.email && value.email}
|
<span className="text-sm text-thin-light-gray">
|
||||||
</span>
|
{value.email && value.email}
|
||||||
</div>
|
</span>
|
||||||
</td>
|
</div>
|
||||||
<td className='py-2 text-right'>
|
</td>
|
||||||
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button>
|
<td className="py-2 text-right">
|
||||||
</td>
|
<button
|
||||||
</tr>
|
onClick={() => {
|
||||||
))
|
handleDeleteMember(value);
|
||||||
) : (
|
}}
|
||||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
className="flex relative items-center justify-center border-0 w-8 h-8"
|
||||||
<td className="p-2">No Members Found</td>
|
>
|
||||||
</tr>
|
<img
|
||||||
)}
|
src={localImgLoad("images/icons/remove_grp.svg")}
|
||||||
</>
|
alt="remove-icon"
|
||||||
</tbody>
|
/>
|
||||||
</table>
|
</button>
|
||||||
|
</td>
|
||||||
{/* PAGINATION BUTTON */}
|
</tr>
|
||||||
<PaginatedList
|
))
|
||||||
onClick={handlePagination}
|
) : (
|
||||||
prev={currentPage == 0 ? true : false}
|
<tr className="font-semibold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||||
next={
|
<td className="p-2">No Members Found. Please add</td>
|
||||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
</tr>
|
||||||
selectedList?.length
|
)}
|
||||||
? true
|
</>
|
||||||
: false
|
</tbody>
|
||||||
}
|
</table>
|
||||||
data={selectedList}
|
|
||||||
start={indexOfFirstItem}
|
{/* PAGINATION BUTTON */}
|
||||||
stop={indexOfLastItem}
|
<PaginatedList
|
||||||
/>
|
onClick={handlePagination}
|
||||||
{/* END OF PAGINATION BUTTON */}
|
prev={currentPage == 0 ? true : false}
|
||||||
</div>
|
next={
|
||||||
|
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||||
{/* DELETE MEMBER POPOUT */}
|
selectedList?.length
|
||||||
{deletePopout.status &&
|
? true
|
||||||
<DeleteMember
|
: false
|
||||||
action={()=>setDeletePopout({status:false, data:{}})}
|
}
|
||||||
situation={deletePopout.status}
|
data={selectedList}
|
||||||
details={deletePopout.data}
|
start={indexOfFirstItem}
|
||||||
/>
|
stop={indexOfLastItem}
|
||||||
}
|
/>
|
||||||
{/* END OF DELETE MEMBER POPOUT */}
|
{/* END OF PAGINATION BUTTON */}
|
||||||
</div>
|
</div>
|
||||||
);
|
|
||||||
};
|
{/* DELETE MEMBER POPOUT */}
|
||||||
|
{deletePopout.status && (
|
||||||
|
<DeleteMember
|
||||||
|
action={() => setDeletePopout({ status: false, data: {} })}
|
||||||
|
situation={deletePopout.status}
|
||||||
|
details={deletePopout.data}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{/* END OF DELETE MEMBER POPOUT */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,79 +1,119 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from "react";
|
||||||
import Layout from '../Partials/Layout'
|
import Layout from "../Partials/Layout";
|
||||||
|
|
||||||
import GroupList from './GroupList'
|
import GroupList from "./GroupList";
|
||||||
import MemberList from './MemberList'
|
import MemberList from "./MemberList";
|
||||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
import usersService from '../../services/UsersService'
|
import usersService from "../../services/UsersService";
|
||||||
|
|
||||||
export default function JobGroups() {
|
export default function JobGroups() {
|
||||||
|
const userApi = new usersService();
|
||||||
|
|
||||||
const userApi = new usersService();
|
const [updateList, setUpdateList] = useState(false);
|
||||||
|
|
||||||
const [updateList, setUpdateList] = useState(false)
|
const [groupList, setGroupList] = useState({
|
||||||
|
loading: true,
|
||||||
|
groups: [],
|
||||||
|
members: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const [selectedGroup, setSelectedGroup] = useState({
|
||||||
const [groupList, setGroupList] = useState({
|
id: "",
|
||||||
loading:true,
|
name: "",
|
||||||
groups: [],
|
data: [],
|
||||||
members: []
|
});
|
||||||
})
|
|
||||||
|
|
||||||
const [selectedGroup, setSelectedGroup] = useState({id:'', name:'', data: []})
|
const changeSelectedGroup = (e) => {
|
||||||
|
let groupID = e.target.value;
|
||||||
|
const activeMembers = groupList?.members?.filter(
|
||||||
|
(item) => item.group_id == groupID
|
||||||
|
);
|
||||||
|
const activeGroup = groupList?.groups?.filter(
|
||||||
|
(item) => item.group_id == groupID
|
||||||
|
);
|
||||||
|
setSelectedGroup({
|
||||||
|
id: groupID,
|
||||||
|
name: activeGroup[0]?.group_name,
|
||||||
|
data: activeMembers,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const changeSelectedGroup = (e) => {
|
useEffect(() => {
|
||||||
let groupID = e.target.value
|
setGroupList({ loading: true, groups: [], members: [] });
|
||||||
const activeMembers = groupList?.members?.filter(item => item.group_id == groupID)
|
userApi
|
||||||
const activeGroup = groupList?.groups?.filter(item => item.group_id == groupID)
|
.jobGroupList({})
|
||||||
setSelectedGroup({id: groupID, name:activeGroup[0]?.group_name, data:activeMembers})
|
.then((res) => {
|
||||||
}
|
const { status, data } = res;
|
||||||
|
if (status != 200 || data?.internal_return < 0) {
|
||||||
useEffect(()=>{
|
setGroupList({ loading: false, groups: [], members: [] });
|
||||||
setGroupList({loading: true, groups: [], members: []})
|
return;
|
||||||
userApi.jobGroupList({}).then(res => {
|
}
|
||||||
const {status, data} = res
|
if (data.result_list.length < 0) {
|
||||||
if(status != 200 || data?.internal_return < 0){
|
setGroupList({ loading: false, groups: [], members: [] });
|
||||||
setGroupList({loading: false, groups: [], members: []})
|
return;
|
||||||
return
|
}
|
||||||
}
|
setGroupList({
|
||||||
if(data.result_list.length < 0){
|
loading: false,
|
||||||
setGroupList({loading: false, groups: [], members: []})
|
groups: data.result_list,
|
||||||
return
|
members: data.result_list_member,
|
||||||
}
|
});
|
||||||
setGroupList({loading: false, groups: data.result_list, members: data.result_list_member})
|
if (selectedGroup.id == "") {
|
||||||
if(selectedGroup.id == ''){
|
let activeGroupId = data.result_list[0].group_id;
|
||||||
let activeGroupId = data.result_list[0].group_id
|
let activeGroup = data.result_list[0].group_name;
|
||||||
let activeGroup = data.result_list[0].group_name
|
let activeMembers = data.result_list_member?.filter(
|
||||||
let activeMembers = data.result_list_member?.filter(item => item.group_id == activeGroupId)
|
(item) => item.group_id == activeGroupId
|
||||||
setSelectedGroup({id: activeGroupId, name:activeGroup, data:activeMembers})
|
);
|
||||||
}else{
|
setSelectedGroup({
|
||||||
let activeMembers = data.result_list_member?.filter(item => item.group_id == selectedGroup?.id)
|
id: activeGroupId,
|
||||||
setSelectedGroup({id: selectedGroup?.id, name:selectedGroup?.name, data:activeMembers})
|
name: activeGroup,
|
||||||
}
|
data: activeMembers,
|
||||||
}).catch(error => {
|
});
|
||||||
setGroupList({loading: false, groups: [], members: []})
|
} else {
|
||||||
console.log(error)
|
let activeMembers = data.result_list_member?.filter(
|
||||||
})
|
(item) => item.group_id == selectedGroup?.id
|
||||||
},[updateList])
|
);
|
||||||
|
setSelectedGroup({
|
||||||
|
id: selectedGroup?.id,
|
||||||
|
name: selectedGroup?.name,
|
||||||
|
data: activeMembers,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setGroupList({ loading: false, groups: [], members: [] });
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}, [updateList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<div>
|
<div>
|
||||||
<h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>Jobs Groups</h1>
|
<h1 className="mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100">
|
||||||
</div>
|
Job Groups
|
||||||
<div className='p-5 w-full min-h-[400px] flex flex-col lg:flex-row gap-3 lg:gap-6 rounded-lg shadow-md bg-white dark:bg-dark-white'>
|
</h1>
|
||||||
{groupList.loading ?
|
</div>
|
||||||
<div className='w-full h-[400px] flex justify-center items-center'>
|
<div className="p-5 w-full min-h-[400px] flex flex-col lg:flex-row gap-3 lg:gap-6 rounded-lg shadow-md bg-white dark:bg-dark-white">
|
||||||
<LoadingSpinner size='16' />
|
{groupList.loading ? (
|
||||||
</div>
|
<div className="w-full h-[400px] flex justify-center items-center">
|
||||||
:
|
<LoadingSpinner size="16" />
|
||||||
<>
|
</div>
|
||||||
<GroupList groupList={groupList?.groups} selectedGroup={selectedGroup} changeSelectedGroup={changeSelectedGroup} setUpdateList={setUpdateList} />
|
) : (
|
||||||
<MemberList groupList={groupList?.groups} selectedGroup={selectedGroup} setUpdateList={setUpdateList} />
|
<>
|
||||||
</>
|
<GroupList
|
||||||
}
|
groupList={groupList?.groups}
|
||||||
</div>
|
selectedGroup={selectedGroup}
|
||||||
|
changeSelectedGroup={changeSelectedGroup}
|
||||||
|
setUpdateList={setUpdateList}
|
||||||
|
/>
|
||||||
|
<MemberList
|
||||||
|
groupList={groupList?.groups}
|
||||||
|
selectedGroup={selectedGroup}
|
||||||
|
setUpdateList={setUpdateList}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import GroupMemberTable from "./GroupMemberTable";
|
|||||||
|
|
||||||
import EmailValidator from "../../lib/EmailValidator";
|
import EmailValidator from "../../lib/EmailValidator";
|
||||||
|
|
||||||
import usersService from "../../services/UsersService";
|
|
||||||
import { apiConst } from "../../lib/apiConst";
|
import { apiConst } from "../../lib/apiConst";
|
||||||
|
import usersService from "../../services/UsersService";
|
||||||
|
|
||||||
export default function MemberList({
|
export default function MemberList({
|
||||||
groupList,
|
groupList,
|
||||||
@@ -277,7 +277,7 @@ export default function MemberList({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="my-2 flex flex-col min-h-[300px]">
|
<div className="my-2 flex flex-col min-h-[300px] h-full">
|
||||||
{selectedGroup?.data?.length < 1 ? (
|
{selectedGroup?.data?.length < 1 ? (
|
||||||
<h1 className="my-5 text-lg lg:text-xl tracking-wide text-slate-900 dark:text-slate-100">
|
<h1 className="my-5 text-lg lg:text-xl tracking-wide text-slate-900 dark:text-slate-100">
|
||||||
No Member Found, Please Add
|
No Member Found, Please Add
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import localImgLoad from "../../lib/localImgLoad";
|
|
||||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||||
import PaginatedList from "../Pagination/PaginatedList";
|
import PaginatedList from "../Pagination/PaginatedList";
|
||||||
|
|
||||||
export default function MyActiveJobTable({ MyJobList, className }) {
|
export default function MyActiveJobTable({ MyJobList, className }) {
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
let { pathname } = useLocation();
|
let { pathname } = useLocation();
|
||||||
|
|
||||||
@@ -45,7 +43,11 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
|||||||
value?.currency_code,
|
value?.currency_code,
|
||||||
value?.currency
|
value?.currency
|
||||||
);
|
);
|
||||||
let image = `${MyJobList.session_image_server}${localStorage.getItem('session_token')}/job/${value.job_uid}`
|
let image = `${
|
||||||
|
MyJobList.session_image_server
|
||||||
|
}${localStorage.getItem("session_token")}/job/${
|
||||||
|
value.job_uid
|
||||||
|
}`;
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={index}
|
key={index}
|
||||||
@@ -112,7 +114,7 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
|||||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
>
|
>
|
||||||
{value.owner_status == "OWNER"
|
{value.owner_status == "OWNER"
|
||||||
? "Manage"
|
? "Review"
|
||||||
: "Send Updates"}
|
: "Send Updates"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
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 usersService from "../../services/UsersService";
|
||||||
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
|
import SelectBox from "../Helpers/SelectBox";
|
||||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||||
import PaginatedList from "../Pagination/PaginatedList";
|
import PaginatedList from "../Pagination/PaginatedList";
|
||||||
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
|
||||||
import EditJobPopOut from "../jobPopout/EditJobPopout";
|
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";
|
import DeleteIcon from "../../assets/images/icon-delete.svg";
|
||||||
import localImgLoad from "../../lib/localImgLoad";
|
import EditIcon from "../../assets/images/icon-edit.svg";
|
||||||
|
import { tableReload } from "../AddJob/settings";
|
||||||
|
import CreditPopup from "../MyWallet/Popup/CreditPopup";
|
||||||
|
import JobListPopout from "../jobPopout/JobListPopout";
|
||||||
|
|
||||||
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
// Getting the categories
|
// Getting the categories
|
||||||
const currentJobCart = MyJobList?.data?.categories;
|
const currentJobCart = MyJobList?.data?.categories;
|
||||||
// DropDown Box
|
// DropDown Box
|
||||||
@@ -25,24 +27,46 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
Object.keys(filterCategories)[0]
|
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
|
const [jobPopout, setJobPopout] = useState({ show: false, data: {} });
|
||||||
|
|
||||||
let [deleteJobPopout, setDeleteJobPopout] = useState({
|
const [deleteJobPopout, setDeleteJobPopout] = useState({
|
||||||
show: false,
|
show: false,
|
||||||
data: {},
|
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 [editJob, setEditJob] = useState({ show: false, data: {} });
|
||||||
|
|
||||||
const [myCountry, setCountries] = useState("");
|
const [myCountry, setCountries] = useState("");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
userDetails: { country },
|
userDetails: { country },
|
||||||
} = useSelector((state) => state?.userDetails);
|
} = useSelector((state) => state?.userDetails);
|
||||||
|
|
||||||
const userApi = useMemo(() => new usersService(), []);
|
const userApi = useMemo(() => new usersService(), []);
|
||||||
|
|
||||||
|
const [creditPopup, setCreditPopup] = useState({ show: false, data: {} });
|
||||||
|
const [walletItem, setWalletItem] = useState(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the credit popup.
|
||||||
|
* @param {Object} value - The value object.
|
||||||
|
*/
|
||||||
|
const openPopUp = (value) => {
|
||||||
|
setCreditPopup({
|
||||||
|
show: true,
|
||||||
|
data: { ...value },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the credit popup and dispatches a table reload action.
|
||||||
|
*/
|
||||||
|
const closePopUp = () => {
|
||||||
|
setCreditPopup({ show: false, data: {} });
|
||||||
|
dispatch(tableReload({ type: "WALLETTABLE" }));
|
||||||
|
};
|
||||||
|
|
||||||
// Get Country Api
|
// Get Country Api
|
||||||
const getCountryList = useCallback(async () => {
|
const getCountryList = useCallback(async () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await userApi.getSignupCountryData();
|
const res = await userApi.getSignupCountryData();
|
||||||
if (res.status === 200 && res.data.internal_return >= 0) {
|
if (res.status === 200 && res.data.internal_return >= 0) {
|
||||||
@@ -59,7 +83,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}, [userApi, country]);
|
}, [userApi, country]);
|
||||||
console.log('MY COUNTRY', myCountry)
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCountryList();
|
getCountryList();
|
||||||
}, [getCountryList]);
|
}, [getCountryList]);
|
||||||
@@ -101,6 +125,121 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { MyJobListHeader, MyJobListTable } = myJobTableFeatures(
|
||||||
|
filterCategories,
|
||||||
|
selectedCategory,
|
||||||
|
handleSetCategory,
|
||||||
|
setDeleteJobPopout,
|
||||||
|
setEditJob,
|
||||||
|
setJobPopout,
|
||||||
|
MyJobList,
|
||||||
|
filteredCurrentJobList,
|
||||||
|
handlePagination,
|
||||||
|
currentPage,
|
||||||
|
currentJobList,
|
||||||
|
indexOfFirstItem,
|
||||||
|
indexOfLastItem
|
||||||
|
);
|
||||||
|
|
||||||
|
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 || ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<MyJobListHeader />
|
||||||
|
{MyJobList?.loading ? (
|
||||||
|
<LoadingSpinner size="16" color="sky-blue" />
|
||||||
|
) : (
|
||||||
|
<MyJobListTable />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Job List Popout */}
|
||||||
|
{jobPopout.show && (
|
||||||
|
<JobListPopout
|
||||||
|
details={jobPopout.data}
|
||||||
|
onClose={() => {
|
||||||
|
setJobPopout({ show: false, data: {} });
|
||||||
|
}}
|
||||||
|
setWalletItem={setWalletItem}
|
||||||
|
openWallet={openPopUp}
|
||||||
|
situation={jobPopout.show}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{/* End of Job List Popout */}
|
||||||
|
|
||||||
|
{/* Delete Job Popout */}
|
||||||
|
{deleteJobPopout.show && (
|
||||||
|
<DeleteJobPopout
|
||||||
|
details={deleteJobPopout.data}
|
||||||
|
onClose={() => {
|
||||||
|
setDeleteJobPopout({ show: false, data: {} });
|
||||||
|
}}
|
||||||
|
reloadJobList={reloadJobList}
|
||||||
|
situation={deleteJobPopout.show}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{/* END of Delete Job Popout */}
|
||||||
|
|
||||||
|
{editJob.show && (
|
||||||
|
<EditJobPopOut
|
||||||
|
details={editJob.data}
|
||||||
|
onClose={() => {
|
||||||
|
setEditJob({
|
||||||
|
show: false,
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
situation={editJob.show}
|
||||||
|
country={myCountry}
|
||||||
|
categories={currentJobCart}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{creditPopup.show && (
|
||||||
|
<CreditPopup
|
||||||
|
details={creditPopup.data}
|
||||||
|
walletItem={walletItem}
|
||||||
|
onClose={closePopUp}
|
||||||
|
situation={openPopUp}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function myJobTableFeatures(
|
||||||
|
filterCategories,
|
||||||
|
selectedCategory,
|
||||||
|
handleSetCategory,
|
||||||
|
setDeleteJobPopout,
|
||||||
|
setEditJob,
|
||||||
|
setJobPopout,
|
||||||
|
MyJobList,
|
||||||
|
filteredCurrentJobList,
|
||||||
|
handlePagination,
|
||||||
|
currentPage,
|
||||||
|
currentJobList,
|
||||||
|
indexOfFirstItem,
|
||||||
|
indexOfLastItem
|
||||||
|
) {
|
||||||
|
// List of job table features
|
||||||
|
const MyJobListHeader = () => (
|
||||||
|
<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">
|
||||||
|
{filterCategories[selectedCategory]} Jobs
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<SelectBox
|
||||||
|
action={handleSetCategory}
|
||||||
|
datas={Object.values(filterCategories)}
|
||||||
|
className="Update-table-dropdown"
|
||||||
|
contentBodyClasses="w-auto min-w-max"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const JobListItem = ({ value, index, image_server }) => {
|
const JobListItem = ({ value, index, image_server }) => {
|
||||||
let thePrice = PriceFormatter(
|
let thePrice = PriceFormatter(
|
||||||
value?.price * 0.01,
|
value?.price * 0.01,
|
||||||
@@ -190,7 +329,10 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setJobPopout({ show: true, data: { thePrice, ...value } });
|
setJobPopout({
|
||||||
|
show: true,
|
||||||
|
data: { thePrice, ...value },
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
>
|
>
|
||||||
@@ -201,117 +343,53 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const NoJobsRow = ({ text }) => (
|
||||||
<div
|
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
<td className="p-2">{text}</td>
|
||||||
className || ""
|
</tr>
|
||||||
}`}
|
);
|
||||||
>
|
|
||||||
<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">
|
|
||||||
{filterCategories[selectedCategory]} Jobs
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<SelectBox
|
|
||||||
action={handleSetCategory}
|
|
||||||
datas={Object.values(filterCategories)}
|
|
||||||
className="Update-table-dropdown"
|
|
||||||
contentBodyClasses="w-auto min-w-max"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{MyJobList?.loading ? (
|
|
||||||
<LoadingSpinner size="16" color="sky-blue" />
|
|
||||||
) : (
|
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[520px]">
|
|
||||||
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
|
||||||
<tbody>
|
|
||||||
<>
|
|
||||||
{MyJobList &&
|
|
||||||
MyJobList?.data?.result_list &&
|
|
||||||
MyJobList.data?.result_list.length > 0 ? (
|
|
||||||
filteredCurrentJobList?.length ? (
|
|
||||||
filteredCurrentJobList.map((value, index) => (
|
|
||||||
<JobListItem
|
|
||||||
index={index}
|
|
||||||
key={index}
|
|
||||||
value={value}
|
|
||||||
image_server={MyJobList?.data.session_image_server}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
|
||||||
<td className="p-2">
|
|
||||||
No Jobs Available In This Category!
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<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>
|
|
||||||
|
|
||||||
{/* PAGINATION BUTTON */}
|
const MyJobListTable = () => (
|
||||||
<PaginatedList
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[520px]">
|
||||||
onClick={handlePagination}
|
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
prev={currentPage == 0 ? true : false}
|
<tbody>
|
||||||
next={
|
<>
|
||||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
{MyJobList?.data?.result_list?.length > 0 ? (
|
||||||
currentJobList?.length
|
filteredCurrentJobList.length > 0 ? (
|
||||||
? true
|
filteredCurrentJobList.map((value, index) => (
|
||||||
: false
|
<JobListItem
|
||||||
}
|
key={index}
|
||||||
data={currentJobList}
|
index={index}
|
||||||
start={indexOfFirstItem}
|
value={value}
|
||||||
stop={indexOfLastItem}
|
image_server={MyJobList.data.session_image_server}
|
||||||
/>
|
/>
|
||||||
{/* END OF PAGINATION BUTTON */}
|
))
|
||||||
</div>
|
) : (
|
||||||
)}
|
<NoJobsRow text="No Jobs Available In This Category!" />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<NoJobsRow text="No Jobs Available!" />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
{/* Job List Popout */}
|
{/* PAGINATION BUTTON */}
|
||||||
{jobPopout.show && (
|
<PaginatedList
|
||||||
<JobListPopout
|
onClick={handlePagination}
|
||||||
details={jobPopout.data}
|
prev={currentPage == 0 ? true : false}
|
||||||
onClose={() => {
|
next={
|
||||||
setJobPopout({ show: false, data: {} });
|
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||||
}}
|
currentJobList?.length
|
||||||
situation={jobPopout.show}
|
? true
|
||||||
/>
|
: false
|
||||||
)}
|
}
|
||||||
{/* End of Job List Popout */}
|
data={currentJobList}
|
||||||
|
start={indexOfFirstItem}
|
||||||
{/* Delete Job Popout */}
|
stop={indexOfLastItem}
|
||||||
{deleteJobPopout.show && (
|
/>
|
||||||
<DeleteJobPopout
|
{/* END OF PAGINATION BUTTON */}
|
||||||
details={deleteJobPopout.data}
|
|
||||||
onClose={() => {
|
|
||||||
setDeleteJobPopout({ show: false, data: {} });
|
|
||||||
}}
|
|
||||||
reloadJobList={reloadJobList}
|
|
||||||
situation={deleteJobPopout.show}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{/* END of Delete Job Popout */}
|
|
||||||
|
|
||||||
{editJob.show && (
|
|
||||||
<EditJobPopOut
|
|
||||||
details={editJob.data}
|
|
||||||
onClose={() => {
|
|
||||||
setEditJob({
|
|
||||||
show: false,
|
|
||||||
data: {},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
situation={editJob.show}
|
|
||||||
country={myCountry}
|
|
||||||
categories={currentJobCart}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
return { MyJobListHeader, MyJobListTable };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
|
|||||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
import localImgLoad from "../../lib/localImgLoad";
|
import localImgLoad from "../../lib/localImgLoad";
|
||||||
|
|
||||||
|
|
||||||
export default function MyPendingJobTable({ MyJobList, className }) {
|
export default function MyPendingJobTable({ MyJobList, className }) {
|
||||||
|
|
||||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
@@ -19,7 +17,7 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
|||||||
indexOfFirstItem,
|
indexOfFirstItem,
|
||||||
indexOfLastItem
|
indexOfLastItem
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePagination = (e) => {
|
const handlePagination = (e) => {
|
||||||
handlePagingFunc(e, setCurrentPage);
|
handlePagingFunc(e, setCurrentPage);
|
||||||
};
|
};
|
||||||
@@ -46,7 +44,11 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
|||||||
value?.currency_code,
|
value?.currency_code,
|
||||||
value?.currency
|
value?.currency
|
||||||
);
|
);
|
||||||
let image = `${MyJobList.session_image_server}${localStorage.getItem('session_token')}/job/${value.job_uid}`
|
let image = `${
|
||||||
|
MyJobList.session_image_server
|
||||||
|
}${localStorage.getItem("session_token")}/job/${
|
||||||
|
value.job_uid
|
||||||
|
}`;
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={index}
|
key={index}
|
||||||
@@ -107,7 +109,9 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
|||||||
}}
|
}}
|
||||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
>
|
>
|
||||||
{value.owner_status == 'OWNER' ? 'Manage' : 'Send Updates'}
|
{value.owner_status == "OWNER"
|
||||||
|
? "Manage"
|
||||||
|
: "View"}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import Layout from "../Partials/Layout";
|
import Layout from "../Partials/Layout";
|
||||||
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import CommonHead from "../UserHeader/CommonHead";
|
import CommonHead from "../UserHeader/CommonHead";
|
||||||
import MyPendingJobTable from "./MyPendingJobTable";
|
import MyPendingJobTable from "./MyPendingJobTable";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
|
||||||
|
|
||||||
export default function MyPendingJobs(props) {
|
export default function MyOffers(props) {
|
||||||
const [selectTab, setValue] = useState("today");
|
const [selectTab, setValue] = useState("today");
|
||||||
const filterHandler = (value) => {
|
const filterHandler = (value) => {
|
||||||
setValue(value);
|
setValue(value);
|
||||||
@@ -13,9 +12,7 @@ export default function MyPendingJobs(props) {
|
|||||||
// console.log("AMEYE LOC1", props.MyJobList);
|
// console.log("AMEYE LOC1", props.MyJobList);
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<CommonHead
|
<CommonHead commonHeadData={props.commonHeadData} />
|
||||||
commonHeadData={props.commonHeadData}
|
|
||||||
/>
|
|
||||||
<div className="notification-page w-full mb-10">
|
<div className="notification-page w-full mb-10">
|
||||||
<div className="notification-wrapper w-full">
|
<div className="notification-wrapper w-full">
|
||||||
{/* heading */}
|
{/* heading */}
|
||||||
@@ -25,7 +22,7 @@ export default function MyPendingJobs(props) {
|
|||||||
<span
|
<span
|
||||||
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
className={`${selectTab === "today" ? "block" : "hidden"}`}
|
||||||
>
|
>
|
||||||
Pending Job(s)
|
Pending Offers
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
@@ -36,13 +33,17 @@ export default function MyPendingJobs(props) {
|
|||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{props.MyJobList.loading ?
|
{props.MyJobList.loading ? (
|
||||||
<div className="bg-white">
|
<div className="bg-white">
|
||||||
<LoadingSpinner size='16' color='sky-blue' height='min-h-[300px]' />
|
<LoadingSpinner
|
||||||
</div>
|
size="16"
|
||||||
:
|
color="sky-blue"
|
||||||
<MyPendingJobTable MyJobList={props.MyJobList.data} />
|
height="min-h-[300px]"
|
||||||
}
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<MyPendingJobTable MyJobList={props.MyJobList.data} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
@@ -66,6 +66,8 @@ const initialValues = {
|
|||||||
function AddFundDollars(props) {
|
function AddFundDollars(props) {
|
||||||
let MaxNoOfCards = process.env.REACT_APP_MAX_CREDIT_CARDS; // HOLDS THE VALUE OF THE MAX NUMBER OF CARDS USER CAN ADD
|
let MaxNoOfCards = process.env.REACT_APP_MAX_CREDIT_CARDS; // HOLDS THE VALUE OF THE MAX NUMBER OF CARDS USER CAN ADD
|
||||||
|
|
||||||
|
let [loadingState, setLoadingState] = useState(false)
|
||||||
|
|
||||||
const apiCall = new usersService();
|
const apiCall = new usersService();
|
||||||
let countryWallet = props.walletItem.country;
|
let countryWallet = props.walletItem.country;
|
||||||
const [selectedOption, setSelectedOption] = useState("previous");
|
const [selectedOption, setSelectedOption] = useState("previous");
|
||||||
@@ -162,10 +164,11 @@ function AddFundDollars(props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
props.setConfirmCredit((prev) => ({
|
// props.setConfirmCredit((prev) => ({
|
||||||
...prev,
|
// ...prev,
|
||||||
show: { awaitConfirm: { loader: true } },
|
// show: { awaitConfirm: { loader: true } },
|
||||||
}));
|
// }));
|
||||||
|
setLoadingState(true)
|
||||||
|
|
||||||
// Extracting card_uid from the previous card details
|
// Extracting card_uid from the previous card details
|
||||||
const paymentCardValue = prevCardDetails["payment-card"];
|
const paymentCardValue = prevCardDetails["payment-card"];
|
||||||
@@ -193,6 +196,18 @@ function AddFundDollars(props) {
|
|||||||
if (res.data.internal_return < 0) {
|
if (res.data.internal_return < 0) {
|
||||||
props.setInputError("An Error Occurred");
|
props.setInputError("An Error Occurred");
|
||||||
throw new Error("An Error Occurred");
|
throw new Error("An Error Occurred");
|
||||||
|
|
||||||
|
// use commented code when you when to display pop for failed start credit API
|
||||||
|
// props.setConfirmCredit((prev) => ({
|
||||||
|
// ...prev,
|
||||||
|
// show: {
|
||||||
|
// awaitConfirm: { loader: false, state: false },
|
||||||
|
// acceptConfirm: { loader: false, state: true },
|
||||||
|
// },
|
||||||
|
// data: {internal_return: -1}
|
||||||
|
// }));
|
||||||
|
setLoadingState(false)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const _response = res.data;
|
const _response = res.data;
|
||||||
@@ -204,6 +219,7 @@ function AddFundDollars(props) {
|
|||||||
stateData = { ...stateData, ..._response };
|
stateData = { ...stateData, ..._response };
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
setLoadingState(false)
|
||||||
props.setConfirmCredit({
|
props.setConfirmCredit({
|
||||||
show: {
|
show: {
|
||||||
awaitConfirm: { loader: false, state: true },
|
awaitConfirm: { loader: false, state: true },
|
||||||
@@ -213,6 +229,7 @@ function AddFundDollars(props) {
|
|||||||
});
|
});
|
||||||
}, 1500);
|
}, 1500);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
setLoadingState(false)
|
||||||
props.setInputError(error.message);
|
props.setInputError(error.message);
|
||||||
setTimeout(() => props.setInputError(""), 5000);
|
setTimeout(() => props.setInputError(""), 5000);
|
||||||
props.setConfirmCredit((prev) => ({
|
props.setConfirmCredit((prev) => ({
|
||||||
@@ -582,7 +599,7 @@ function AddFundDollars(props) {
|
|||||||
type="submit"
|
type="submit"
|
||||||
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
>
|
>
|
||||||
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
|
{loadingState ? (
|
||||||
<LoadingSpinner size="6" color="sky-blue" />
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -616,7 +633,7 @@ function AddFundDollars(props) {
|
|||||||
type="button"
|
type="button"
|
||||||
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="px-4 py-1 h-11 max-w-[115px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
>
|
>
|
||||||
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
|
{loadingState ? (
|
||||||
<LoadingSpinner size="6" color="sky-blue" />
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
) : (
|
) : (
|
||||||
<span className="text-white">Continue</span>
|
<span className="text-white">Continue</span>
|
||||||
|
|||||||
@@ -86,6 +86,16 @@ function AddFundPop({
|
|||||||
}));
|
}));
|
||||||
setInputError("An Error Occurred");
|
setInputError("An Error Occurred");
|
||||||
setTimeout(() => setInputError(""), 5000);
|
setTimeout(() => setInputError(""), 5000);
|
||||||
|
|
||||||
|
// use commented code when you when to display pop for failed start credit API
|
||||||
|
// setConfirmCredit((prev) => ({
|
||||||
|
// ...prev,
|
||||||
|
// show: {
|
||||||
|
// awaitConfirm: { loader: false, state: false },
|
||||||
|
// acceptConfirm: { loader: false, state: true },
|
||||||
|
// },
|
||||||
|
// data: {internal_return: -1}
|
||||||
|
// }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,8 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
|
|||||||
}`}
|
}`}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{data?.curr_balance &&
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
Wallet Balance
|
Wallet Balance
|
||||||
@@ -79,6 +80,7 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
|
|||||||
{data?.curr_balance * 0.01}
|
{data?.curr_balance * 0.01}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
{isSuccess && (
|
{isSuccess && (
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
|
|||||||
@@ -239,7 +239,8 @@ function ConfirmAddFund({
|
|||||||
setConfirmCredit((prev) => ({
|
setConfirmCredit((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
show: {
|
show: {
|
||||||
acceptConfirm: { loader: false },
|
awaitConfirm: { loader: false, state: false },
|
||||||
|
acceptConfirm: { loader: false, state: true },
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
return;
|
return;
|
||||||
@@ -261,7 +262,8 @@ function ConfirmAddFund({
|
|||||||
setConfirmCredit((prev) => ({
|
setConfirmCredit((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
show: {
|
show: {
|
||||||
acceptConfirm: { loader: false },
|
awaitConfirm: { loader: false, state: false },
|
||||||
|
acceptConfirm: { loader: false, state: true },
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -333,7 +335,8 @@ function ConfirmAddFund({
|
|||||||
setConfirmCredit((prev) => ({
|
setConfirmCredit((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
show: {
|
show: {
|
||||||
acceptConfirm: { loader: false },
|
awaitConfirm: { loader: false, state: false },
|
||||||
|
acceptConfirm: { loader: false, state: true },
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
setTimeout(() => onClose, 10000);
|
setTimeout(() => onClose, 10000);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const CreditPopup = ({ details, onClose, situation, walletItem }) => {
|
|||||||
<ConfirmAddFund
|
<ConfirmAddFund
|
||||||
confirmCredit={confirmCredit}
|
confirmCredit={confirmCredit}
|
||||||
setConfirmCredit={setConfirmCredit}
|
setConfirmCredit={setConfirmCredit}
|
||||||
walletItem={walletItem}
|
walletItem={walletItem || details}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
/>
|
/>
|
||||||
) : confirmCredit?.show?.acceptConfirm?.state ? (
|
) : confirmCredit?.show?.acceptConfirm?.state ? (
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const WalletRoutes = () => {
|
|||||||
}
|
}
|
||||||
setAllCountries((prev) => ({
|
setAllCountries((prev) => ({
|
||||||
loading: false,
|
loading: false,
|
||||||
data: res.data.result_list,
|
data: res?.data?.result_list,
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|||||||
@@ -5,6 +5,13 @@ function Default({ children }) {
|
|||||||
// dark mode setup
|
// dark mode setup
|
||||||
const [theme, setTheme] = useState(null);
|
const [theme, setTheme] = useState(null);
|
||||||
|
|
||||||
|
// country mode setup
|
||||||
|
const [countryMode, setCountryMode] = useState(localStorage.getItem('cnt') ? localStorage.getItem('cnt')?.toUpperCase() : '')
|
||||||
|
|
||||||
|
|
||||||
|
const queryParams = new URLSearchParams(location?.search);
|
||||||
|
const country = queryParams.get("cnt")?.toUpperCase();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
setTheme("dark");
|
setTheme("dark");
|
||||||
@@ -24,9 +31,17 @@ function Default({ children }) {
|
|||||||
const handleThemeSwitch = () => {
|
const handleThemeSwitch = () => {
|
||||||
setTheme(theme === "dark" ? "light" : "dark");
|
setTheme(theme === "dark" ? "light" : "dark");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(country){
|
||||||
|
setCountryMode(country)
|
||||||
|
localStorage.setItem('cnt', country)
|
||||||
|
}
|
||||||
|
},[countryMode])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DarkModeContext.Provider value={{ theme, handleThemeSwitch }}>
|
<DarkModeContext.Provider value={{ theme, handleThemeSwitch, countryMode }}>
|
||||||
{children && children}
|
{children && children}
|
||||||
</DarkModeContext.Provider>
|
</DarkModeContext.Provider>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
|
|||||||
|
|
||||||
// 9308RDR122
|
// 9308RDR122
|
||||||
|
|
||||||
|
|
||||||
const handlerBalance = () => {
|
const handlerBalance = () => {
|
||||||
setbalanceValue.toggle();
|
setbalanceValue.toggle();
|
||||||
if (notificationDropdown) {
|
if (notificationDropdown) {
|
||||||
@@ -238,9 +239,9 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{/* balance */}
|
{/* balance */}
|
||||||
|
|
||||||
{/* My Page Button */}
|
{/* My Page Button */}
|
||||||
<PageButton />
|
{userDetails.account_type === "FULL" ? <PageButton /> : null}
|
||||||
|
|
||||||
{/*<div className="lg:hidden block"></div>*/}
|
{/*<div className="lg:hidden block"></div>*/}
|
||||||
<WalletHeader
|
<WalletHeader
|
||||||
@@ -671,28 +672,28 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const PageButton = () => {
|
const PageButton = () => {
|
||||||
return (
|
return (
|
||||||
<Link to="/yourpage" className="lg:flex hidden user-balance cursor-pointer lg:w-[152px] w-[150px] h-[48px] items-center rounded-full relative bg-sky-blue pr-1.5 pl-4">
|
<Link
|
||||||
<div
|
to="/yourpage"
|
||||||
className="flex items-center lg:justify-between justify-center w-full h-full"
|
className="lg:flex hidden user-balance cursor-pointer lg:w-[152px] w-[150px] h-[48px] items-center rounded-full relative bg-sky-blue pr-1.5 pl-4"
|
||||||
>
|
>
|
||||||
<span className="lg:block hidden w-[25px]">
|
<div className="flex items-center lg:justify-between justify-center w-full h-full">
|
||||||
|
<span className="lg:block hidden w-[25px]">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 50" id="Page">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 50" id="Page">
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
d="M0 13V2a2 2 0 0 1 2-2h64a2 2 0 0 1 2 2v11H0Zm0 4v31a2 2 0 0 0 2 2h20V17H0Zm26 33h40a2 2 0 0 0 2-2V17H26v33Z"
|
d="M0 13V2a2 2 0 0 1 2-2h64a2 2 0 0 1 2 2v11H0Zm0 4v31a2 2 0 0 0 2 2h20V17H0Zm26 33h40a2 2 0 0 0 2-2V17H26v33Z"
|
||||||
fill="#ffffff"
|
fill="#ffffff"
|
||||||
className="color000000 svgShape"
|
className="color000000 svgShape"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<p className="lg:text-xl text-lg font-bold text-white">My Page</p>
|
<p className="lg:text-xl text-lg font-bold text-white">My Page</p>
|
||||||
<span className="lg:block hidden">
|
<span className="lg:block hidden">
|
||||||
{/* <Icons name="deep-plus" /> */}
|
{/* <Icons name="deep-plus" /> */}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default function Layout({ children }) {
|
|||||||
localStorage.removeItem("member_id");
|
localStorage.removeItem("member_id");
|
||||||
localStorage.removeItem("uid");
|
localStorage.removeItem("uid");
|
||||||
sessionStorage.removeItem("family_uid");
|
sessionStorage.removeItem("family_uid");
|
||||||
// localStorage.clear();
|
localStorage.clear();
|
||||||
// toast.success("Come Back Soon", {
|
// toast.success("Come Back Soon", {
|
||||||
// icon: `🙂`,
|
// icon: `🙂`,
|
||||||
// });
|
// });
|
||||||
|
|||||||
@@ -190,16 +190,21 @@ export default function MobileSidebar({
|
|||||||
<div className="items">
|
<div className="items">
|
||||||
<ul className="flex flex-col space-y-6">
|
<ul className="flex flex-col space-y-6">
|
||||||
{[
|
{[
|
||||||
{ name: "List", path: "/myjobs", iconName: "people-two" },
|
{ name: "List", path: "/myjobs", iconName: "job-list" },
|
||||||
{
|
{
|
||||||
name: "Pending",
|
name: "Offers",
|
||||||
path: "/my-pending-jobs",
|
path: "/my-offers",
|
||||||
iconName: "people-two",
|
iconName: "pending-job",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Waiting",
|
||||||
|
path: "/pend-interest",
|
||||||
|
iconName: "pending-job",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Active",
|
name: "Active",
|
||||||
path: "/my-active-jobs",
|
path: "/my-active-jobs",
|
||||||
iconName: "people-two",
|
iconName: "active-job",
|
||||||
},
|
},
|
||||||
].map(({ name, path, iconName }, idx) => (
|
].map(({ name, path, iconName }, idx) => (
|
||||||
<ListItem
|
<ListItem
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useState } from "react";
|
|||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { NavLink } from "react-router-dom";
|
import { NavLink } from "react-router-dom";
|
||||||
//import SideStatistics from "./SideStatistics";
|
//import SideStatistics from "./SideStatistics";
|
||||||
|
import { localImgLoad } from "../../lib";
|
||||||
|
|
||||||
export default function RightSideBar({myJobList}) {
|
export default function RightSideBar({myJobList}) {
|
||||||
const filterDatas = ["Last 15 days", "Last Month", "Last 6 month"];
|
const filterDatas = ["Last 15 days", "Last Month", "Last 6 month"];
|
||||||
@@ -169,24 +170,8 @@ export default function RightSideBar({myJobList}) {
|
|||||||
<div className="platform-list">
|
<div className="platform-list">
|
||||||
<div className="px-8 item flex space-x-3 items-center mb-4">
|
<div className="px-8 item flex space-x-3 items-center mb-4">
|
||||||
{/* image */}
|
{/* image */}
|
||||||
<div className="w-8 h-8 rounded-full">
|
<div className="w-8 h-8 p-[4px] rounded-full">
|
||||||
<svg
|
<img src={localImgLoad('images/icons/job_active.svg')} className="w-full h-full" alt='Active Task' />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
id="history"
|
|
||||||
>
|
|
||||||
<g data-name="14">
|
|
||||||
<circle cx="9" cy="14" r="7" fill="#ffd54f"></circle>
|
|
||||||
<path
|
|
||||||
fill="#ef6c00"
|
|
||||||
d="M21 9H17a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2zM21 5H3A1 1 0 0 1 3 3H21a1 1 0 0 1 0 2zM21 13H19a1 1 0 0 1 0-2h2a1 1 0 0 1 0 2zM21 17H19a1 1 0 0 1 0-2h2a1 1 0 0 1 0 2zM21 21H17a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#ff8f00"
|
|
||||||
d="M10,10a1,1,0,0,0-2,0v3.59L6.29,15.29a1,1,0,1,0,1.41,1.41l2-2A1,1,0,0,0,10,14Z"
|
|
||||||
></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
{/* name */}
|
{/* name */}
|
||||||
<div>
|
<div>
|
||||||
@@ -196,123 +181,48 @@ export default function RightSideBar({myJobList}) {
|
|||||||
</div>
|
</div>
|
||||||
{/* action */}
|
{/* action */}
|
||||||
</div>
|
</div>
|
||||||
{/* {userDetails && userDetails?.account_type !== "FAMILY" && (
|
|
||||||
<>
|
|
||||||
</>
|
|
||||||
)} */}
|
|
||||||
<div className="px-8 item flex space-x-3 items-center mb-4">
|
|
||||||
{/* image */}
|
|
||||||
<div className="w-8 h-8 rounded-full">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
id="add-user"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="#9bcb5b"
|
|
||||||
d="M12 13.4c-2 0-3.7-1.6-3.7-3.6s1.6-3.7 3.6-3.7 3.7 1.6 3.7 3.6-1.6 3.6-3.6 3.7zm0-6.2c-1.4 0-2.6 1.1-2.6 2.6 0 1.4 1.1 2.6 2.6 2.6s2.6-1.1 2.6-2.6c-.1-1.5-1.2-2.6-2.6-2.6z"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#9bcb5b"
|
|
||||||
d="M16.6 17.9c-.3 0-.5-.2-.6-.5 0-2.2-1.8-4-4-4s-4 1.8-4 4c0 .3-.3.5-.6.5-.2 0-.4-.2-.5-.5 0-2.8 2.3-5.1 5.1-5.1s5.1 2.3 5.1 5.1c0 .3-.2.5-.5.5z"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#0376bc"
|
|
||||||
d="M12 23.7C5.5 23.7.3 18.4.3 12 .3 5.5 5.6.3 12 .3c2.6 0 5.1.9 7.2 2.5.2.2.2.6 0 .8-.2.2-.4.2-.7.1-1.9-1.4-4.1-2.2-6.5-2.2C6.2 1.4 1.4 6.2 1.4 12S6.2 22.6 12 22.6 22.6 17.8 22.6 12c0-2.4-.8-4.6-2.2-6.5-.2-.3-.1-.6.2-.8.2-.1.5-.1.7.1 1.6 2 2.5 4.6 2.4 7.2 0 6.4-5.3 11.7-11.7 11.7z"
|
|
||||||
></path>
|
|
||||||
<circle cx="20.2" cy="20.3" r="2.4" fill="#fff"></circle>
|
|
||||||
<path
|
|
||||||
fill="#9bcb5b"
|
|
||||||
d="M18 18.1c.6-.6 1.4-.9 2.2-.9.8 0 1.6.3 2.2.9s1 1.4.9 2.2c0 .8-.3 1.6-.9 2.2s-1.4 1-2.2.9c-.8 0-1.6-.3-2.2-.9s-1-1.4-.9-2.2c-.1-.8.3-1.7.9-2.2zm3.8 2.5V20h-1.3v-1.3h-.6V20h-1.3v.6h1.3v1.3h.6v-1.3h1.3z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
{/* name */}
|
|
||||||
<div>
|
|
||||||
<p className="text-thin-light-gray text-base font-medium">
|
|
||||||
<NavLink to="/my-review-jobs">Review Pending</NavLink>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="px-8 item flex space-x-3 items-center mb-4">
|
<div className="px-8 item flex space-x-3 items-center mb-4">
|
||||||
{/* image */}
|
{/* image */}
|
||||||
<div className="w-8 h-8 rounded-full">
|
<div className="w-8 h-8 p-[4px] rounded-full">
|
||||||
<svg
|
<img src={localImgLoad('images/icons/job_pending.svg')} className="w-full h-full" alt='Review Task' />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 48 48"
|
|
||||||
id="InternationalUser"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="#e6e7f9"
|
|
||||||
d="M38.5 31.1c2.1-1.1 3.9-2.5 5.4-4.4h-3.2c-.6 1.6-1.3 3.1-2.2 4.4zm-5.8 1.4c2-.7 3.7-2.8 4.9-5.8h-4.9v5.8zm8.8-8.6h4.2c.9-1.8 1.5-3.7 1.7-5.8h-5.1c-.1 2-.4 4-.8 5.8zm2.4-17.3c-1.5-1.8-3.3-3.3-5.4-4.4.8 1.2 1.6 2.7 2.2 4.4h3.2zm-5.3 2.9h-5.9v5.8h6.7c-.1-2.1-.4-4.1-.8-5.8zm3.7 5.8h5.1c-.2-2.1-.8-4-1.7-5.8h-4.2c.4 1.8.7 3.7.8 5.8zM32.7.8v5.8h4.9c-1.2-2.9-2.9-5.1-4.9-5.8zm6.7 17.3h-6.7v5.8h5.9c.4-1.8.7-3.8.8-5.8zM25 6.6h4.9V.8c-2 .7-3.7 2.9-4.9 5.8zm-1.8 8.7h6.7V9.5H24c-.4 1.7-.7 3.7-.8 5.8zm6.7 17.2v-5.8H25c1.2 3 2.9 5.1 4.9 5.8zM24.1 2.3c-2.1 1.1-3.9 2.5-5.4 4.4H22c.5-1.7 1.3-3.2 2.1-4.4zM24 23.9h5.9v-5.8h-6.7c.1 2 .4 4 .8 5.8z"
|
|
||||||
className="colorc1e5ff svgShape"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#ff6699"
|
|
||||||
d="M3.7 44.7c0 1.6 1.2 2.8 2.8 2.8 1.3 0 2.4-.9 2.7-2.2.3 1.3 1.4 2.2 2.7 2.2 1.5 0 2.8-1.3 2.8-2.8V30.1h3.1V18.8c0-4.2-3.3-7.5-7.4-7.5H8c-4.1 0-7.4 3.4-7.4 7.5v11.3h3.1v14.6z"
|
|
||||||
className="colorff99b0 svgShape"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#998da0"
|
|
||||||
d="M9.2 10.3c2.4 0 4.4-2.2 4.4-4.9S11.6.5 9.2.5C6.8.5 4.8 2.7 4.8 5.4s2 4.9 4.4 4.9z"
|
|
||||||
className="colorffd499 svgShape"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#e6e7f9"
|
|
||||||
d="M16.9 9.5c-.3.6-.5 1.2-.8 1.8 1.3 1 2.3 2.4 2.9 4h1.3c.1-2 .3-4 .8-5.8h-4.2zm2.9 9.3v5.1h1.4c-.4-1.8-.7-3.8-.8-5.8h-.6c-.1.2 0 .4 0 .7zm2.2 7.9h-2.2v1.2c1.3 1.3 2.7 2.4 4.4 3.2-.9-1.3-1.7-2.8-2.2-4.4z"
|
|
||||||
className="colorc1e5ff svgShape"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
{/* name */}
|
|
||||||
<div>
|
|
||||||
<p className="text-thin-light-gray text-base font-medium">
|
|
||||||
<NavLink to="/my-pastdue-jobs">Past Due</NavLink>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
{/* name */}
|
||||||
{/* Line */}
|
<div>
|
||||||
<div className="my-4 mx-auto w-10/12 h-[2px] bg-slate-500 dark:bg-white rounded-full"></div>
|
<p className="text-thin-light-gray text-base font-medium">
|
||||||
|
<NavLink to="/my-review-jobs">Review</NavLink>
|
||||||
<div className="px-8 item flex space-x-3 items-center mb-4">
|
</p>
|
||||||
{/* image */}
|
|
||||||
<div className="w-8 h-8 rounded-full">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 48 48"
|
|
||||||
id="InternationalUser"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="#e6e7f9"
|
|
||||||
d="M38.5 31.1c2.1-1.1 3.9-2.5 5.4-4.4h-3.2c-.6 1.6-1.3 3.1-2.2 4.4zm-5.8 1.4c2-.7 3.7-2.8 4.9-5.8h-4.9v5.8zm8.8-8.6h4.2c.9-1.8 1.5-3.7 1.7-5.8h-5.1c-.1 2-.4 4-.8 5.8zm2.4-17.3c-1.5-1.8-3.3-3.3-5.4-4.4.8 1.2 1.6 2.7 2.2 4.4h3.2zm-5.3 2.9h-5.9v5.8h6.7c-.1-2.1-.4-4.1-.8-5.8zm3.7 5.8h5.1c-.2-2.1-.8-4-1.7-5.8h-4.2c.4 1.8.7 3.7.8 5.8zM32.7.8v5.8h4.9c-1.2-2.9-2.9-5.1-4.9-5.8zm6.7 17.3h-6.7v5.8h5.9c.4-1.8.7-3.8.8-5.8zM25 6.6h4.9V.8c-2 .7-3.7 2.9-4.9 5.8zm-1.8 8.7h6.7V9.5H24c-.4 1.7-.7 3.7-.8 5.8zm6.7 17.2v-5.8H25c1.2 3 2.9 5.1 4.9 5.8zM24.1 2.3c-2.1 1.1-3.9 2.5-5.4 4.4H22c.5-1.7 1.3-3.2 2.1-4.4zM24 23.9h5.9v-5.8h-6.7c.1 2 .4 4 .8 5.8z"
|
|
||||||
className="colorc1e5ff svgShape"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#ff6699"
|
|
||||||
d="M3.7 44.7c0 1.6 1.2 2.8 2.8 2.8 1.3 0 2.4-.9 2.7-2.2.3 1.3 1.4 2.2 2.7 2.2 1.5 0 2.8-1.3 2.8-2.8V30.1h3.1V18.8c0-4.2-3.3-7.5-7.4-7.5H8c-4.1 0-7.4 3.4-7.4 7.5v11.3h3.1v14.6z"
|
|
||||||
className="colorff99b0 svgShape"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#998da0"
|
|
||||||
d="M9.2 10.3c2.4 0 4.4-2.2 4.4-4.9S11.6.5 9.2.5C6.8.5 4.8 2.7 4.8 5.4s2 4.9 4.4 4.9z"
|
|
||||||
className="colorffd499 svgShape"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#e6e7f9"
|
|
||||||
d="M16.9 9.5c-.3.6-.5 1.2-.8 1.8 1.3 1 2.3 2.4 2.9 4h1.3c.1-2 .3-4 .8-5.8h-4.2zm2.9 9.3v5.1h1.4c-.4-1.8-.7-3.8-.8-5.8h-.6c-.1.2 0 .4 0 .7zm2.2 7.9h-2.2v1.2c1.3 1.3 2.7 2.4 4.4 3.2-.9-1.3-1.7-2.8-2.2-4.4z"
|
|
||||||
className="colorc1e5ff svgShape"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
{/* name */}
|
|
||||||
<div>
|
|
||||||
<p className="text-thin-light-gray text-base font-medium">
|
|
||||||
<NavLink to="/job-groups">Job Groups</NavLink>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="px-8 item flex space-x-3 items-center mb-4">
|
||||||
|
{/* image */}
|
||||||
|
<div className="w-8 h-8 p-[4px] rounded-full">
|
||||||
|
<img src={localImgLoad('images/icons/job_past_due.svg')} className="w-full h-full" alt='Past Due Task' />
|
||||||
|
</div>
|
||||||
|
{/* name */}
|
||||||
|
<div>
|
||||||
|
<p className="text-thin-light-gray text-base font-medium">
|
||||||
|
<NavLink to="/my-pastdue-jobs">Past Due</NavLink>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Line */}
|
||||||
|
<div className="my-4 mx-auto w-10/12 h-[2px] bg-slate-500 dark:bg-white rounded-full"></div>
|
||||||
|
|
||||||
|
<div className="px-8 item flex space-x-3 items-center mb-4">
|
||||||
|
{/* image */}
|
||||||
|
<div className="w-8 h-8 p-[4px] rounded-full">
|
||||||
|
<img src={localImgLoad('images/icons/job_group.svg')} className="w-full h-full" alt='Job Groups' />
|
||||||
|
</div>
|
||||||
|
{/* name */}
|
||||||
|
<div>
|
||||||
|
<p className="text-thin-light-gray text-base font-medium">
|
||||||
|
<NavLink to="/job-groups">Job Groups</NavLink>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,13 @@ import {
|
|||||||
import DarkModeContext from "../Contexts/DarkModeContext";
|
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||||
import Icons from "../Helpers/Icons";
|
import Icons from "../Helpers/Icons";
|
||||||
|
|
||||||
|
|
||||||
export default function Sidebar({
|
export default function Sidebar({
|
||||||
sidebar,
|
sidebar,
|
||||||
action,
|
action,
|
||||||
logoutModalHandler,
|
logoutModalHandler,
|
||||||
myJobList,
|
myJobList,
|
||||||
}) {
|
}) {
|
||||||
const darkMode = useContext(DarkModeContext);
|
const darkMode = useContext(DarkModeContext);
|
||||||
|
|
||||||
let { userDetails } = useSelector((state) => state.userDetails);
|
let { userDetails } = useSelector((state) => state.userDetails);
|
||||||
//const jobLists = getJobList(); // pass from upper - we need in a lot of places
|
//const jobLists = getJobList(); // pass from upper - we need in a lot of places
|
||||||
@@ -215,17 +214,22 @@ export default function Sidebar({
|
|||||||
{
|
{
|
||||||
name: "List",
|
name: "List",
|
||||||
path: "/myjobs",
|
path: "/myjobs",
|
||||||
iconName: "people-two",
|
iconName: "job-list",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Pending",
|
name: "Waiting",
|
||||||
path: "/my-pending-jobs",
|
path: "/pend-interest",
|
||||||
iconName: "people-two",
|
iconName: "pending-job",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Offers",
|
||||||
|
path: "/my-offers",
|
||||||
|
iconName: "pending-job",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Active",
|
name: "Active",
|
||||||
path: "/my-active-jobs",
|
path: "/my-active-jobs",
|
||||||
iconName: "people-two",
|
iconName: "active-job",
|
||||||
},
|
},
|
||||||
].map(({ name, path, iconName }, idx) => (
|
].map(({ name, path, iconName }, idx) => (
|
||||||
<ListItem
|
<ListItem
|
||||||
@@ -291,7 +295,7 @@ export default function Sidebar({
|
|||||||
className="signout-btn w-full flex items-center justify-center"
|
className="signout-btn w-full flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<span className="p-[1px] w-[40px] h-[40px] border border-purple rounded-full">
|
<span className="p-[1px] w-[40px] h-[40px] border border-purple rounded-full">
|
||||||
<Icons name='new-logout' />
|
<Icons name="new-logout" />
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { Field, Form, Formik } from "formik";
|
import { Field, Form, Formik } from "formik";
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
|
import { tableReload } from "../../store/TableReloads";
|
||||||
import InputCom from "../Helpers/Inputs/InputCom/index";
|
import InputCom from "../Helpers/Inputs/InputCom/index";
|
||||||
import ModalCom from "../Helpers/ModalCom";
|
import ModalCom from "../Helpers/ModalCom";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import Detail from "./popoutcomponent/Detail";
|
import Detail from "./popoutcomponent/Detail";
|
||||||
import { tableReload } from "../../store/TableReloads";
|
|
||||||
import { useDispatch } from "react-redux";
|
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
family: Yup.string().required("This is required "),
|
family: Yup.string().required("This is required "),
|
||||||
@@ -22,14 +22,22 @@ const validationSchema = Yup.object().shape({
|
|||||||
group: Yup.string(),
|
group: Yup.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
function JobListPopout({ details, onClose, situation }) {
|
function JobListPopout({
|
||||||
|
details,
|
||||||
|
onClose,
|
||||||
|
situation,
|
||||||
|
openWallet,
|
||||||
|
setWalletItem,
|
||||||
|
}) {
|
||||||
|
const [selectedTab, setSelectedTab] = useState("public");
|
||||||
|
const tabs = ["public", "individual", "group"];
|
||||||
|
|
||||||
const [selectedTab, setSelectedTab] = useState('public')
|
const dispatch = useDispatch();
|
||||||
const tabs = ['public', 'individual', 'group']
|
|
||||||
|
|
||||||
const dispatch = useDispatch()
|
const [requestStatus, setRequestStatus] = useState({
|
||||||
|
message: "",
|
||||||
const [requestStatus, setRequestStatus] = useState({message:'', status:false})
|
status: false,
|
||||||
|
});
|
||||||
|
|
||||||
const [familyList, setFamilyList] = useState([]);
|
const [familyList, setFamilyList] = useState([]);
|
||||||
let [loader, setLoader] = useState({
|
let [loader, setLoader] = useState({
|
||||||
@@ -43,6 +51,30 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
|
|||||||
});
|
});
|
||||||
|
|
||||||
const apiCall = useMemo(() => new usersService(), []);
|
const apiCall = useMemo(() => new usersService(), []);
|
||||||
|
const { walletDetails } = useSelector((state) => state.walletDetails);
|
||||||
|
|
||||||
|
const getWalletDetail = (currency) => {
|
||||||
|
// A FUNCTION TO GET USER BALANCE BASED ON TASK CURRENCY
|
||||||
|
const walletChecker = walletDetails?.data.find(
|
||||||
|
(item) => item.description === currency
|
||||||
|
);
|
||||||
|
return walletChecker
|
||||||
|
? {
|
||||||
|
description: walletChecker.description,
|
||||||
|
country: walletChecker.country,
|
||||||
|
code: walletChecker.code,
|
||||||
|
amount: walletChecker.amount,
|
||||||
|
}
|
||||||
|
: 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const taskWalletSelector = getWalletDetail(details?.currency);
|
||||||
|
|
||||||
|
const openCreditPopup = () => {
|
||||||
|
onClose();
|
||||||
|
setWalletItem(taskWalletSelector);
|
||||||
|
openWallet();
|
||||||
|
};
|
||||||
|
|
||||||
// member listing
|
// member listing
|
||||||
const memberList = useCallback(async () => {
|
const memberList = useCallback(async () => {
|
||||||
@@ -117,6 +149,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
|
|||||||
job_uid,
|
job_uid,
|
||||||
job_description: textArea,
|
job_description: textArea,
|
||||||
};
|
};
|
||||||
|
|
||||||
let reqData;
|
let reqData;
|
||||||
|
|
||||||
// for family input
|
// for family input
|
||||||
@@ -147,7 +180,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
|
|||||||
// for group input
|
// for group input
|
||||||
reqData = {
|
reqData = {
|
||||||
...jobReq,
|
...jobReq,
|
||||||
email: '',
|
email: "",
|
||||||
group_id: values?.group,
|
group_id: values?.group,
|
||||||
assign_mode: 110044,
|
assign_mode: 110044,
|
||||||
duration: details?.timeline_days,
|
duration: details?.timeline_days,
|
||||||
@@ -161,52 +194,106 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
|
|||||||
try {
|
try {
|
||||||
const res = await apiCall.assignJobTask(reqData);
|
const res = await apiCall.assignJobTask(reqData);
|
||||||
let { status, data } = await res;
|
let { status, data } = await res;
|
||||||
if(status != 200 || data.internal_return < 0){
|
if (status != 200 || data.internal_return < 0) {
|
||||||
setRequestStatus({message:'Unable to complete', status:false})
|
setRequestStatus({ message: data?.status ? data?.status : "Unable to assign offer", status: false });
|
||||||
return setTimeout(()=>{
|
return setTimeout(() => {
|
||||||
setLoader({ jobFields: false });
|
setLoader({ jobFields: false });
|
||||||
setRequestStatus({message:'', status:false})
|
setRequestStatus({ message: "", status: false });
|
||||||
},3000)
|
}, 3000);
|
||||||
}
|
}
|
||||||
dispatch(tableReload({ type: "JOBTABLE" }));
|
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||||
setRequestStatus({message:'Successful', status:true})
|
setRequestStatus({ message: data?.status_msg ? data?.status_msg : "Offer Assigned Successful", status: true });
|
||||||
setTimeout(()=>{
|
setTimeout(() => {
|
||||||
setLoader({ jobFields: false });
|
setLoader({ jobFields: false });
|
||||||
onClose();
|
onClose();
|
||||||
throw new Response(data);
|
// throw new Response(data);
|
||||||
},3000)
|
}, 3000);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setRequestStatus({message:'Unable to complete', status:false})
|
setRequestStatus({ message: "Unable to complete", status: false });
|
||||||
setTimeout(()=>{
|
setTimeout(() => {
|
||||||
setRequestStatus({message:'', status:false})
|
setRequestStatus({ message: "", status: false });
|
||||||
setLoader({ jobFields: false });
|
setLoader({ jobFields: false });
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
},3000)
|
}, 3000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [groupList, setGroupList] = useState({loading: true, groups: [], members: []})
|
const [groupList, setGroupList] = useState({
|
||||||
|
loading: true,
|
||||||
|
groups: [],
|
||||||
|
members: [],
|
||||||
|
});
|
||||||
|
|
||||||
// FUNCTION TO POPULATE USER GROUP LIST
|
// FUNCTION TO POPULATE USER GROUP LIST
|
||||||
useEffect(()=>{
|
useEffect(() => {
|
||||||
// setGroupList({loading: true, groups: [], members: []})
|
// setGroupList({loading: true, groups: [], members: []})
|
||||||
apiCall.jobGroupList({}).then(res => {
|
apiCall
|
||||||
const {status, data} = res
|
.jobGroupList({})
|
||||||
if(status != 200 || data?.internal_return < 0){
|
.then((res) => {
|
||||||
setGroupList({loading: false, groups: [], members: []})
|
const { status, data } = res;
|
||||||
return
|
if (status != 200 || data?.internal_return < 0) {
|
||||||
|
setGroupList({ loading: false, groups: [], members: [] });
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if(data.result_list.length < 0){
|
if (data.result_list.length < 0) {
|
||||||
setGroupList({loading: false, groups: [], members: []})
|
setGroupList({ loading: false, groups: [], members: [] });
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
setGroupList({loading: false, groups: data.result_list, members: data.result_list_member})
|
setGroupList({
|
||||||
}).catch(error => {
|
loading: false,
|
||||||
setGroupList({loading: false, groups: [], members: []})
|
groups: data.result_list,
|
||||||
})
|
members: data.result_list_member,
|
||||||
},[])
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setGroupList({ loading: false, groups: [], members: [] });
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const DetailsSection = ({ label, value }) => (
|
||||||
|
<div className="my-3 md:flex">
|
||||||
|
<Detail label={label} value={value} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const DetailsComponent = () => {
|
||||||
|
const detailsArray = [
|
||||||
|
{ label: "Description", value: details.description },
|
||||||
|
{ label: "Price", value: details.thePrice },
|
||||||
|
{ label: "Timeline", value: `${details.timeline_days} day(s)` },
|
||||||
|
{ label: "Created", value: new Date(details?.created).toDateString() },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="px-4 pb-3 w-full md:border-r-2">
|
||||||
|
{/* <p className='text-lg font-semibold text-slate-900 tracking-wide'>{details.title}</p> */}
|
||||||
|
|
||||||
|
{/* INPUT SECTION */}
|
||||||
|
{detailsArray.map((detail, index) => (
|
||||||
|
<DetailsSection
|
||||||
|
key={index}
|
||||||
|
label={detail.label}
|
||||||
|
value={detail.value}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div className="">
|
||||||
|
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
|
||||||
|
Delivery Detail
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
className={`p-2 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
|
||||||
|
rows="7"
|
||||||
|
style={{ resize: "none" }}
|
||||||
|
value={textArea}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
<p>{errMsg.deliveryDetail}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// console.log("Job List P >> ", details)
|
|
||||||
return (
|
return (
|
||||||
<ModalCom action={onClose} situation={situation} className="">
|
<ModalCom action={onClose} situation={situation} className="">
|
||||||
<div className="logout-modal-wrapper w-[90%] md:w-[768px] bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
<div className="logout-modal-wrapper w-[90%] md:w-[768px] bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||||
@@ -240,211 +327,185 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="md:grid grid-cols-2 bg-white dark:bg-dark-white rounded-lg shadow-lg">
|
<div className="md:grid grid-cols-2 bg-white dark:bg-dark-white rounded-lg shadow-lg">
|
||||||
<div className="p-4 pb-3 w-full md:border-r-2">
|
<DetailsComponent />
|
||||||
{/* <p className='text-lg font-semibold text-slate-900 tracking-wide'>{details.title}</p> */}
|
<>
|
||||||
|
{/* ACTION SECTION */}
|
||||||
|
{+taskWalletSelector.amount > +details.price ? (
|
||||||
|
<div className="px-4 pb-3 w-full flex flex-col justify-between">
|
||||||
|
<h1 className="text-lg mt-3 font-medium tracking-wide text-black dark:text-white">
|
||||||
|
Send this Task to:
|
||||||
|
</h1>
|
||||||
|
<div className="flex flex-col grow">
|
||||||
|
<div className="grid grid-cols-3 mt-4">
|
||||||
|
{tabs.map((item) => (
|
||||||
|
<TabButton
|
||||||
|
key={item}
|
||||||
|
item={item}
|
||||||
|
selectedTab={selectedTab}
|
||||||
|
setSelectedTab={setSelectedTab}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="grow flex flex-col bg-red-50 dark:bg-[#D85A5A] rounded-b-2xl">
|
||||||
|
{selectedTab == "family" && (
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues}
|
||||||
|
validationSchema={validationSchema.fields.family}
|
||||||
|
onSubmit={jobFieldHandler}
|
||||||
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form className="hidden">
|
||||||
|
{/* Assign to Family */}
|
||||||
|
<JobFieldInput
|
||||||
|
label="Assign to family"
|
||||||
|
select={true}
|
||||||
|
inputName="family"
|
||||||
|
value={props?.values.family}
|
||||||
|
data={familyList}
|
||||||
|
btnText="Assign to family"
|
||||||
|
optionText="Select Family"
|
||||||
|
loader={loader?.jobFields?.family}
|
||||||
|
errorHandler={errorHandler}
|
||||||
|
parentClass="w-full flex flex-col gap-4"
|
||||||
|
/>
|
||||||
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
|
{" "}
|
||||||
|
{props?.values?.family === "" && (
|
||||||
|
<span>{errMsg?.jobFields?.family}</span>
|
||||||
|
)}
|
||||||
|
</p>{" "}
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* INPUT SECTION */}
|
{selectedTab == "public" && (
|
||||||
<div className="my-3 md:flex">
|
<Formik
|
||||||
<Detail label="Description" value={details.description} />
|
initialValues={initialValues}
|
||||||
</div>
|
validationSchema={validationSchema.fields.public}
|
||||||
|
onSubmit={jobFieldHandler}
|
||||||
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form className="">
|
||||||
|
{/* Offer this job to public input */}
|
||||||
|
<JobFieldInput
|
||||||
|
label="Offer this job to public"
|
||||||
|
select={true}
|
||||||
|
inputName="public"
|
||||||
|
value={props?.values.public}
|
||||||
|
data={publicArray}
|
||||||
|
btnText="Show Task to Public"
|
||||||
|
optionText="Select Duration"
|
||||||
|
loader={loader?.jobFields?.public}
|
||||||
|
errorHandler={errorHandler}
|
||||||
|
parentClass="w-full flex flex-col gap-4"
|
||||||
|
/>
|
||||||
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
|
{" "}
|
||||||
|
{props?.values.public === "" && (
|
||||||
|
<span>{errMsg?.jobFields?.public}</span>
|
||||||
|
)}
|
||||||
|
</p>{" "}
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="my-3 md:flex">
|
{selectedTab == "individual" && (
|
||||||
<Detail label="Price" value={details.thePrice} />
|
<Formik
|
||||||
</div>
|
initialValues={initialValues}
|
||||||
|
validationSchema={validationSchema.fields.individual}
|
||||||
|
onSubmit={jobFieldHandler}
|
||||||
|
>
|
||||||
|
{(props) => {
|
||||||
|
return (
|
||||||
|
<Form className="">
|
||||||
|
{/* Offer this job to individual input */}
|
||||||
|
<JobFieldInput
|
||||||
|
label="Offer this job to individual"
|
||||||
|
input={true}
|
||||||
|
inputName="individual"
|
||||||
|
value={props?.values.individual}
|
||||||
|
placeholder="Enter email of individual"
|
||||||
|
inputHandler={props?.handleChange}
|
||||||
|
btnText="Send Offer to Individual"
|
||||||
|
loader={loader?.jobFields?.individual}
|
||||||
|
errorHandler={errorHandler}
|
||||||
|
parentClass="w-full flex flex-col gap-4"
|
||||||
|
/>
|
||||||
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
|
{" "}
|
||||||
|
{props?.values.individual === "" && (
|
||||||
|
<span>{errMsg?.jobFields?.individual}</span>
|
||||||
|
)}
|
||||||
|
</p>{" "}
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="my-3 md:flex">
|
{/* { process.env.REACT_APP_SHOW_OFFER_GROUP_JOB != 0 && } */}
|
||||||
<Detail
|
{selectedTab == "group" && (
|
||||||
label="Timeline"
|
<Formik
|
||||||
value={`${details.timeline_days} day(s)`}
|
initialValues={initialValues}
|
||||||
/>
|
validationSchema={validationSchema.fields.group}
|
||||||
</div>
|
onSubmit={jobFieldHandler}
|
||||||
|
>
|
||||||
<div className="my-3 md:flex">
|
{(props) => {
|
||||||
<Detail
|
return (
|
||||||
label="Created"
|
<Form className="">
|
||||||
value={new Date(details?.created).toDateString()}
|
{/* Offer this job to your group input */}
|
||||||
/>
|
<JobFieldInput
|
||||||
</div>
|
label="Offer this job to your Group"
|
||||||
|
select={true}
|
||||||
<div className="">
|
inputName="group"
|
||||||
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
|
value={props?.values.group}
|
||||||
Delivery Detail
|
btnText="Send Order to Group"
|
||||||
</label>
|
optionText="Select Group"
|
||||||
<textarea
|
loader={loader?.jobFields?.group}
|
||||||
className={`p-2 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
|
errorHandler={errorHandler}
|
||||||
rows="7"
|
data={groupList}
|
||||||
style={{ resize: "none" }}
|
parentClass="w-full flex flex-col gap-4"
|
||||||
value={textArea}
|
/>
|
||||||
onChange={handleInputChange}
|
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||||
/>
|
{" "}
|
||||||
<p>{errMsg.deliveryDetail}</p>
|
{props?.values.group === "" && (
|
||||||
</div>
|
<span>{errMsg?.jobFields?.group}</span>
|
||||||
</div>
|
)}
|
||||||
|
</p>
|
||||||
{/* ACTION SECTION */}
|
</Form>
|
||||||
<div className="p-4 w-ful flex flex-col justify-between">
|
);
|
||||||
<h1 className="text-lg mt-3 font-medium tracking-wide text-black dark:text-white">Send this Task to:</h1>
|
}}
|
||||||
<div className="flex flex-col grow">
|
</Formik>
|
||||||
<div className="grid grid-cols-3 mt-4">
|
)}
|
||||||
{tabs.map(item => (
|
<p
|
||||||
<button
|
className={`text-center w-full text-lg ${
|
||||||
// className={`px-4 py-1 rounded-t-2xl ${selectedTab == item ? 'btn-gradient border-[2px] text-white' : 'bg-white text-[#000] border-t-[2px]'}`}
|
requestStatus.status
|
||||||
className={`px-4 py-1 rounded-t-2xl border-t-[2px] transition-all duration-200 flex flex-col justify-center items-center ${selectedTab == item ? 'bg-red-50 dark:bg-[#D85A5A] text-slate-600 font-extrabold' : 'bg-white text-[#000]'}`}
|
? "text-emerald-600"
|
||||||
value={item}
|
: "text-red-600"
|
||||||
name={item}
|
}`}
|
||||||
onClick={()=>setSelectedTab(item)}
|
>
|
||||||
>
|
{requestStatus.message && requestStatus.message}
|
||||||
<div className={`mb-[1px] h-6 w-6 border-4 rounded-full transition-all duration-200 ${selectedTab == item ? 'border-white bg-emerald-500' : 'border-red-50 dark:border-[#D85A5A] bg-white'}`}></div>
|
</p>
|
||||||
{item[0].toUpperCase() + item.slice(1)}
|
</div>
|
||||||
</button>
|
</div>
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grow flex flex-col bg-red-50 dark:bg-[#D85A5A] rounded-b-2xl">
|
) : (
|
||||||
{selectedTab == 'family' &&
|
<ZeroBalanceChecker
|
||||||
<Formik
|
{...taskWalletSelector}
|
||||||
initialValues={initialValues}
|
openCreditPopup={openCreditPopup}
|
||||||
validationSchema={validationSchema.fields.family}
|
/>
|
||||||
onSubmit={jobFieldHandler}
|
)}
|
||||||
>
|
|
||||||
{(props) => {
|
|
||||||
return (
|
|
||||||
<Form className="hidden">
|
|
||||||
{/* Assign to Family */}
|
|
||||||
<JobFieldInput
|
|
||||||
label="Assign to family"
|
|
||||||
select={true}
|
|
||||||
inputName="family"
|
|
||||||
value={props?.values.family}
|
|
||||||
data={familyList}
|
|
||||||
btnText="Assign to family"
|
|
||||||
optionText="Select Family"
|
|
||||||
loader={loader?.jobFields?.family}
|
|
||||||
errorHandler={errorHandler}
|
|
||||||
parentClass='w-full flex flex-col gap-4'
|
|
||||||
/>
|
|
||||||
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
|
||||||
{" "}
|
|
||||||
{props?.values?.family === "" && (
|
|
||||||
<span>{errMsg?.jobFields?.family}</span>
|
|
||||||
)}
|
|
||||||
</p>{" "}
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Formik>
|
|
||||||
}
|
|
||||||
|
|
||||||
{selectedTab == 'public' &&
|
|
||||||
<Formik
|
|
||||||
initialValues={initialValues}
|
|
||||||
validationSchema={validationSchema.fields.public}
|
|
||||||
onSubmit={jobFieldHandler}
|
|
||||||
>
|
|
||||||
{(props) => {
|
|
||||||
return (
|
|
||||||
<Form className="">
|
|
||||||
{/* Offer this job to public input */}
|
|
||||||
<JobFieldInput
|
|
||||||
label="Offer this job to public"
|
|
||||||
select={true}
|
|
||||||
inputName="public"
|
|
||||||
value={props?.values.public}
|
|
||||||
data={publicArray}
|
|
||||||
btnText="Show Task to Public"
|
|
||||||
optionText="Select Duration"
|
|
||||||
loader={loader?.jobFields?.public}
|
|
||||||
errorHandler={errorHandler}
|
|
||||||
parentClass='w-full flex flex-col gap-4'
|
|
||||||
/>
|
|
||||||
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
|
||||||
{" "}
|
|
||||||
{props?.values.public === "" && (
|
|
||||||
<span>{errMsg?.jobFields?.public}</span>
|
|
||||||
)}
|
|
||||||
</p>{" "}
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Formik>
|
|
||||||
}
|
|
||||||
|
|
||||||
{selectedTab == 'individual' &&
|
{/* END OF ACTION SECTION */}
|
||||||
<Formik
|
</>
|
||||||
initialValues={initialValues}
|
|
||||||
validationSchema={validationSchema.fields.individual}
|
|
||||||
onSubmit={jobFieldHandler}
|
|
||||||
>
|
|
||||||
{(props) => {
|
|
||||||
return (
|
|
||||||
<Form className="">
|
|
||||||
{/* Offer this job to individual input */}
|
|
||||||
<JobFieldInput
|
|
||||||
label="Offer this job to individual"
|
|
||||||
input={true}
|
|
||||||
inputName="individual"
|
|
||||||
value={props?.values.individual}
|
|
||||||
placeholder="Enter email of individual"
|
|
||||||
inputHandler={props?.handleChange}
|
|
||||||
btnText="Send Offer to Individual"
|
|
||||||
loader={loader?.jobFields?.individual}
|
|
||||||
errorHandler={errorHandler}
|
|
||||||
parentClass='w-full flex flex-col gap-4'
|
|
||||||
/>
|
|
||||||
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
|
||||||
{" "}
|
|
||||||
{props?.values.individual === "" && (
|
|
||||||
<span>{errMsg?.jobFields?.individual}</span>
|
|
||||||
)}
|
|
||||||
</p>{" "}
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Formik>
|
|
||||||
}
|
|
||||||
|
|
||||||
{/* { process.env.REACT_APP_SHOW_OFFER_GROUP_JOB != 0 && } */}
|
|
||||||
{selectedTab == 'group' &&
|
|
||||||
<Formik
|
|
||||||
initialValues={initialValues}
|
|
||||||
validationSchema={validationSchema.fields.group}
|
|
||||||
onSubmit={jobFieldHandler}
|
|
||||||
>
|
|
||||||
{(props) => {
|
|
||||||
return (
|
|
||||||
<Form className="">
|
|
||||||
{/* Offer this job to your group input */}
|
|
||||||
<JobFieldInput
|
|
||||||
label="Offer this job to your Group"
|
|
||||||
select={true}
|
|
||||||
inputName="group"
|
|
||||||
value={props?.values.group}
|
|
||||||
btnText="Send Order to Group"
|
|
||||||
optionText="Select Group"
|
|
||||||
loader={loader?.jobFields?.group}
|
|
||||||
errorHandler={errorHandler}
|
|
||||||
data={groupList}
|
|
||||||
parentClass='w-full flex flex-col gap-4'
|
|
||||||
/>
|
|
||||||
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
|
||||||
{" "}
|
|
||||||
{props?.values.group === "" && (
|
|
||||||
<span>{errMsg?.jobFields?.group}</span>
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Formik>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{requestStatus.message &&
|
|
||||||
<p className={`mt-4 w-full text-lg ${requestStatus.status ? 'text-emerald-600' : 'text-red-600'}`}>{requestStatus.message}</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
{/* END OF ACTION SECTION */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ModalCom>
|
</ModalCom>
|
||||||
@@ -480,7 +541,7 @@ const JobFieldInput = ({
|
|||||||
>
|
>
|
||||||
{label && (
|
{label && (
|
||||||
<label
|
<label
|
||||||
className="input-label border-2 w-full border-sky-700 py-4 px-2 text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block tracking-wide"
|
className="input-label border-2 w-full border-sky-700 rounded py-4 px-2 text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block tracking-wide"
|
||||||
htmlFor={inputName}
|
htmlFor={inputName}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
@@ -497,51 +558,49 @@ const JobFieldInput = ({
|
|||||||
value={value}
|
value={value}
|
||||||
>
|
>
|
||||||
{/* <option value="">{optionText}</option> */}
|
{/* <option value="">{optionText}</option> */}
|
||||||
{(inputName == 'family' || inputName == 'public') &&
|
{(inputName == "family" || inputName == "public") &&
|
||||||
Array.isArray(data) &&
|
Array.isArray(data) && (
|
||||||
<>
|
|
||||||
<option value="">{optionText}</option>
|
|
||||||
{ data?.map((item, idx) => (
|
|
||||||
<React.Fragment key={idx}>
|
|
||||||
{inputName === "family" && item?.last_login !== "" && (
|
|
||||||
<option value={item?.family_uid} key={idx}>
|
|
||||||
{`${item?.firstname} ${item?.lastname}`}
|
|
||||||
</option>
|
|
||||||
)}
|
|
||||||
{inputName === "public" && (
|
|
||||||
<option value={item?.duration} key={idx}>
|
|
||||||
{item?.name}
|
|
||||||
</option>
|
|
||||||
)}
|
|
||||||
{/* {inputName === "group" && (
|
|
||||||
<option value={item?.group_id} key={idx}>
|
|
||||||
{item?.group_name}
|
|
||||||
</option>
|
|
||||||
)} */}
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
{(inputName == 'group') &&
|
|
||||||
<>
|
|
||||||
{data.loading ?
|
|
||||||
<option value={''}>
|
|
||||||
Loading...
|
|
||||||
</option>
|
|
||||||
: data?.groups?.length > 0 ?
|
|
||||||
<>
|
<>
|
||||||
<option value="">{optionText}</option>
|
<option value="">{optionText}</option>
|
||||||
{ data?.groups?.map((item, index)=>(
|
{data?.map((item, idx) => (
|
||||||
<option value={item?.group_id} key={index}>
|
<React.Fragment key={idx}>
|
||||||
{item?.group_name}
|
{inputName === "family" &&
|
||||||
</option>
|
item?.last_login !== "" && (
|
||||||
|
<option value={item?.family_uid} key={idx}>
|
||||||
|
{`${item?.firstname} ${item?.lastname}`}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
{inputName === "public" && (
|
||||||
|
<option value={item?.duration} key={idx}>
|
||||||
|
{item?.name}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
:
|
)}
|
||||||
<option value="">No Group Found</option>
|
{inputName == "group" && (
|
||||||
}
|
<>
|
||||||
</>
|
{data.loading ? (
|
||||||
}
|
<option value={""}>Loading...</option>
|
||||||
|
) : data?.groups?.length > 0 ? (
|
||||||
|
<>
|
||||||
|
<option value="">{optionText}</option>
|
||||||
|
{data?.groups?.map((item, index) => (
|
||||||
|
<option value={item?.group_id} key={index}>
|
||||||
|
{`${item?.group_name} (${
|
||||||
|
item?.member_count == null
|
||||||
|
? "0"
|
||||||
|
: ' ' + item.member_count + ' '
|
||||||
|
})`}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<option value="">No Group Found</option>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -597,3 +656,44 @@ const publicArray = [
|
|||||||
{ duration: 21, name: "3 weeks" },
|
{ duration: 21, name: "3 weeks" },
|
||||||
{ duration: 28, name: "4 weeks" },
|
{ duration: 28, name: "4 weeks" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const ZeroBalanceChecker = ({ amount, code, country, openCreditPopup }) => {
|
||||||
|
return (
|
||||||
|
<div className="px-4 pb-3 w-full flex flex-col gap-5 items-center">
|
||||||
|
<h1 className="text-lg mt-3 font-medium tracking-wide text-black dark:text-white">
|
||||||
|
Wallet Balance:{` ${code} ${(+amount * 0.01).toFixed(2)}`}
|
||||||
|
</h1>
|
||||||
|
<p className="font-semibold text-center text-red-500 text-lg">
|
||||||
|
You do not have sufficient balance to assign this task
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={openCreditPopup}
|
||||||
|
className="btn-gradient w-48 h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center"
|
||||||
|
>
|
||||||
|
Add Credit to Wallet
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const TabButton = ({ item, selectedTab, setSelectedTab }) => (
|
||||||
|
<button
|
||||||
|
className={`px-4 py-1 rounded-t-2xl border-t-[2px] transition-all duration-200 flex flex-col justify-center items-center ${
|
||||||
|
selectedTab === item
|
||||||
|
? "bg-red-50 dark:bg-[#D85A5A] text-slate-600 font-extrabold"
|
||||||
|
: "bg-white text-[#000]"
|
||||||
|
}`}
|
||||||
|
value={item}
|
||||||
|
name={item}
|
||||||
|
onClick={() => setSelectedTab(item)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`mb-[1px] h-6 w-6 border-4 rounded-full transition-all duration-200 ${
|
||||||
|
selectedTab === item
|
||||||
|
? "border-white bg-emerald-500"
|
||||||
|
: "border-red-50 dark:border-[#D85A5A] bg-white"
|
||||||
|
}`}
|
||||||
|
></div>
|
||||||
|
{item[0].toUpperCase() + item.slice(1)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|||||||
@@ -143,6 +143,9 @@ export const apiConst = {
|
|||||||
WRENCHBOARD_RESOURCE_MYFILES: 11307,
|
WRENCHBOARD_RESOURCE_MYFILES: 11307,
|
||||||
WRENCHBOARD_MYFILES_LIST: 11309,
|
WRENCHBOARD_MYFILES_LIST: 11309,
|
||||||
|
|
||||||
|
WRENCHBOARD_RELATIVE_LIST: 22032,
|
||||||
|
WRENCHBOARD_RELATIVE_INVITE: 22031,
|
||||||
|
|
||||||
WRENCHBOARD_USER_DELETEACC: 11990,
|
WRENCHBOARD_USER_DELETEACC: 11990,
|
||||||
WRENCHBOARD_ACCOUNT_END: 11999,
|
WRENCHBOARD_ACCOUNT_END: 11999,
|
||||||
WRENCHBOARD_JOB_POSTAGREE: 13002,
|
WRENCHBOARD_JOB_POSTAGREE: 13002,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
|||||||
localStorage.removeItem("member_id");
|
localStorage.removeItem("member_id");
|
||||||
localStorage.removeItem("session_token");
|
localStorage.removeItem("session_token");
|
||||||
sessionStorage.removeItem("family_uid");
|
sessionStorage.removeItem("family_uid");
|
||||||
|
localStorage.clear();
|
||||||
navigate("/login", { replace: true }); // redirects user to login page after session expires
|
navigate("/login", { replace: true }); // redirects user to login page after session expires
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -226,7 +227,7 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
|||||||
console.log("ERROR ", error);
|
console.log("ERROR ", error);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
//
|
|
||||||
//FUNCTION TO GET COMMON HEAD DATA
|
//FUNCTION TO GET COMMON HEAD DATA
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
apiCall
|
apiCall
|
||||||
|
|||||||
@@ -1225,6 +1225,30 @@ class usersService {
|
|||||||
return this.postAuxEnd("/groupmemberadd", postData);
|
return this.postAuxEnd("/groupmemberadd", postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API FUNCTION TO GET FAMILY RELATIVE
|
||||||
|
getFamilyRelativeList() {
|
||||||
|
var postData = {
|
||||||
|
uid: localStorage.getItem("uid"),
|
||||||
|
member_id: localStorage.getItem("member_id"),
|
||||||
|
sessionid: localStorage.getItem("session_token"),
|
||||||
|
offset: 1,
|
||||||
|
limit: 20,
|
||||||
|
action: apiConst.WRENCHBOARD_RELATIVE_LIST,
|
||||||
|
};
|
||||||
|
return this.postAuxEnd("/familyrellist", postData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// API FUNCTION TO ADD/INVITE FAMILY RELATIVE
|
||||||
|
inviteFamilyRelative(reqData) {
|
||||||
|
var postData = {
|
||||||
|
uid: localStorage.getItem("uid"),
|
||||||
|
member_id: localStorage.getItem("member_id"),
|
||||||
|
sessionid: localStorage.getItem("session_token"),
|
||||||
|
action: apiConst.WRENCHBOARD_RELATIVE_INVITE,
|
||||||
|
...reqData
|
||||||
|
};
|
||||||
|
return this.postAuxEnd("/familyrelinvite", postData);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
|
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
|
||||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
|
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import React, {useState, useEffect} from 'react'
|
import { useSelector } from "react-redux";
|
||||||
import Home from "../components/Home";
|
import Home from "../components/Home";
|
||||||
import usersService from "../services/UsersService";
|
|
||||||
|
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
|
|
||||||
export default function HomePages() {
|
export default function HomePages() {
|
||||||
|
const { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
||||||
|
|
||||||
const {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
|
const bannerOptions = {
|
||||||
|
bannerList: commonHeadBanner?.result_list,
|
||||||
|
dashTypes: commonHeadBanner?.home_dash_type,
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Home
|
<Home {...bannerOptions} />
|
||||||
bannerList={commonHeadBanner?.result_list}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
import React, { useContext, useState, useEffect } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import usersService from "../services/UsersService";
|
|
||||||
import MyPendingJobs from "../components/MyPendingJobs";
|
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
import MyOffers from "../components/MyOffers";
|
||||||
|
import usersService from "../services/UsersService";
|
||||||
|
|
||||||
export default function MyPendingJobsPage() {
|
export default function MyOffersPage() {
|
||||||
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
||||||
let { pendingListTable } = useSelector((state) => state.tableReload);
|
let { pendingListTable } = useSelector((state) => state.tableReload);
|
||||||
|
|
||||||
const [MyJobList, setMyJobList] = useState({loading: true, data: []});
|
const [MyJobList, setMyJobList] = useState({ loading: true, data: [] });
|
||||||
const api = new usersService();
|
const api = new usersService();
|
||||||
|
|
||||||
const getMyJobList = async () => {
|
const getMyJobList = async () => {
|
||||||
setMyJobList({loading: true, data: []});
|
setMyJobList({ loading: true, data: [] });
|
||||||
try {
|
try {
|
||||||
const res = await api.getMyPendingJobList();
|
const res = await api.getMyPendingJobList();
|
||||||
setMyJobList({loading: false, data: res.data});
|
setMyJobList({ loading: false, data: res.data });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setMyJobList({loading: false, data: []});
|
setMyJobList({ loading: false, data: [] });
|
||||||
console.log("Error getting mode");
|
console.log("Error getting mode");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getMyJobList();
|
getMyJobList();
|
||||||
}, [pendingListTable]);
|
}, [pendingListTable]);
|
||||||
|
|
||||||
// debugger;
|
// debugger;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MyPendingJobs
|
<MyOffers
|
||||||
MyJobList={MyJobList}
|
MyJobList={MyJobList}
|
||||||
commonHeadData={commonHeadBanner.result_list}
|
commonHeadData={commonHeadBanner.result_list}
|
||||||
/>
|
/>
|
||||||