Compare commits

..

23 Commits

Author SHA1 Message Date
Ebube 129cdc8cba Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into Jobs-Manager-Side 2024-01-26 19:17:58 +01:00
Ebube 9d42ebebab added sidebar menu 2024-01-26 19:17:28 +01:00
ameye 6193f0b492 Merge branch 'Jobs-Manager-Side' of WrenchBoard/Users-Wrench into master 2024-01-26 18:03:56 +00:00
Ebube 1d86465812 Changed my pending jobs to offers and changed its routes 2024-01-26 17:44:24 +01:00
CHIEFSOFT\ameye 7a6f43ad20 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench 2024-01-26 10:31:56 -05:00
CHIEFSOFT\ameye 37b94a68ca new layout 2024-01-26 10:31:45 -05:00
ameye a1b63c5d0c Merge branch 'Jobs-Manager-Side' of WrenchBoard/Users-Wrench into master 2024-01-26 14:49:22 +00:00
Ebube e5162a2aaf refactored some things 2024-01-26 01:46:56 +01:00
Ebube 6ee9c7e7d8 added .toFixed(2)} 2024-01-26 01:08:07 +01:00
Ebube 5928ddb3c1 added the popup component 2024-01-26 01:07:20 +01:00
ameye 06c1e339b1 Merge branch 'login-box-fix' of WrenchBoard/Users-Wrench into master 2024-01-25 22:18:49 +00:00
victorAnumudu 29cec58122 login box adjustment 2024-01-25 21:54:31 +01:00
ameye d258158a13 Merge branch 'bg-change' of WrenchBoard/Users-Wrench into master 2024-01-25 18:01:41 +00:00
victorAnumudu 1c47fa283a Merge branch 'master' into bg-change 2024-01-25 18:57:08 +01:00
victorAnumudu d1b07e6e66 added background based on country 2024-01-25 18:55:51 +01:00
ameye 648f228e45 Merge branch 'Jobs-Manager-Side' of WrenchBoard/Users-Wrench into master 2024-01-25 15:50:17 +00:00
Ebube 551a302ede added the amount checker 2024-01-25 16:39:13 +01:00
ameye 108c82b2f8 Merge branch 'family-type' of WrenchBoard/Users-Wrench into master 2024-01-25 12:44:16 +00:00
victorAnumudu f46713ef00 Merge branch 'master' into family-type 2024-01-25 08:17:59 +01:00
victorAnumudu 992993b710 family type dropdown added 2024-01-25 08:16:55 +01:00
ameye 617df4200e Merge branch 'Jobs-Manager-Side' of WrenchBoard/Users-Wrench into master 2024-01-24 21:57:28 +00:00
Ebube a47e398e87 Added background color to the group list component 2024-01-24 20:41:25 +01:00
ameye 281c4c7ab7 Merge branch 'relative-list' of WrenchBoard/Users-Wrench into master 2024-01-24 13:12:48 +00:00
35 changed files with 759 additions and 490 deletions
+1 -1
View File
@@ -72,4 +72,4 @@ REACT_APP_FAMILY_MINIMUM_AGE=4
REACT_APP_FAMILY_MAXIMUM_AGE=18
#CHANGE LOGIN LAYOUT
REACT_APP_NEW_LOGIN_LAYOUT=0
REACT_APP_NEW_LOGIN_LAYOUT=1
+111 -76
View File
@@ -1,65 +1,61 @@
import { Route, Routes } from "react-router-dom";
import FourZeroFour from "./components/FourZeroFour";
import ScrollToTop from "./components/Helpers/ScrollToTop";
import MyCollection from "./components/MyCollection";
import StartJob from "./components/MyJobs/StartJob";
import Notification from "./components/Notification";
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 AuthRedirect from "./views/AuthRedirect";
import BlogPage from "./views/BlogPage";
import CalendarPage from "./views/CalendarPage";
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 ForgotPasswordPagesTwo from "./views/ForgotPasswordPagesTwo";
import HistoryPage from "./views/HistoryPage";
import HomePages from "./views/HomePages";
import JobGroupsPage from "./views/JobGroupsPage";
import LndPage from "./views/LndPage";
import LoginPage from "./views/LoginPage";
import LoginPageTwo from "./views/LoginPageTwo";
import ManageActiveJobs from "./views/ManageActiveJobs";
import ManageInterestOfferPage from "./views/ManageInterestOfferPage";
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 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 SellPage from "./views/SellPage";
import SettingsPage from "./views/SettingsPage";
import ShopDetailsPage from "./views/ShopDetailsPage";
import SignupPage from "./views/SignupPage";
import SignupPageTwo from "./views/SignupPageTwo";
import TrackingPage from "./views/TrackingPage";
import UpdatePasswordPages from "./views/UpdatePasswordPages";
import UpdatePasswordPagesTwo from "./views/UpdatePasswordPagesTwo";
import UploadProductPage from "./views/UploadProductPage";
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 VerifyLinkPagesTwo from "./views/VerifyLinkPagesTwo";
import MyActiveJobsPage from "./views/MyActiveJobsPage";
import FamilyAccPage from "./views/FamilyAccPage";
import StartJob from "./components/MyJobs/StartJob";
import AddJobPage from "./views/AddJobPage";
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 VerifyPasswordPages from "./views/VerifyPasswordPages";
import VerifyPasswordPagesTwo from "./views/VerifyPasswordPagesTwo";
import VerifyYouPages from "./views/VerifyYouPages";
import VerifyYouPagesTwo from "./views/VerifyYouPagesTwo";
import YourPages from "./views/YourPage_";
export default function Routers() {
@@ -67,31 +63,47 @@ export default function Routers() {
<ScrollToTop>
<Routes>
{/* guest routes */}
{process.env.REACT_APP_NEW_LOGIN_LAYOUT == 1 ?
<>
<Route exact path="/login" element={<LoginPageTwo />} />
<Route exact path="/signup" element={<SignupPageTwo />} />
<Route exact path="/forgot-password" element={<ForgotPasswordPagesTwo />} />
<Route exact path="/update-password" element={<UpdatePasswordPagesTwo />} />
<Route path="/vemail" element={<VerifyLinkPagesTwo />} />
<Route path="/complereset" element={<VerifyPasswordPagesTwo />} />
<Route exact path="/outmessage" element={<VerifyYouPagesTwo />} />
<Route exact path="/eoffer" element={<LoginPageTwo />} />
<Route exact path="/invite" element={<LoginPageTwo />} />
</>
:
<>
<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 />} />
</>
}
{process.env.REACT_APP_NEW_LOGIN_LAYOUT == 1 ? (
<>
<Route exact path="/login" element={<LoginPageTwo />} />
<Route exact path="/signup" element={<SignupPageTwo />} />
<Route
exact
path="/forgot-password"
element={<ForgotPasswordPagesTwo />}
/>
<Route
exact
path="/update-password"
element={<UpdatePasswordPagesTwo />}
/>
<Route path="/vemail" element={<VerifyLinkPagesTwo />} />
<Route path="/complereset" element={<VerifyPasswordPagesTwo />} />
<Route exact path="/outmessage" element={<VerifyYouPagesTwo />} />
<Route exact path="/eoffer" element={<LoginPageTwo />} />
<Route exact path="/invite" element={<LoginPageTwo />} />
</>
) : (
<>
<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/flogin" element={<FacebookRedirect />} />
<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" element={<MarketPlacePage />} />
<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="/mytask" element={<MyTaskPage />} />
<Route exact path="/myjobs" element={<MyJobsPage />} />
{/* <Route exact path="/add-job" element={<AddJobPage />} /> */}
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
<Route exact path="/my-review-jobs" element={<MyReviewDueJobsPage />} />
<Route exact path="/acc-family" element={<FamilyAccPage />} />
<Route exact path="/manage-family" element={<FamilyManagePage />} />
<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 exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
<Route
exact
path="/my-pastdue-jobs"
element={<MyPastDueJobsPage />}
/>
<Route exact path="/my-offers" element={<MyOffersPage />} />
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
<Route
exact
path="/my-review-jobs"
element={<MyReviewDueJobsPage />}
/>
<Route exact path="/acc-family" element={<FamilyAccPage />} />
<Route exact path="/manage-family" element={<FamilyManagePage />} />
<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
exact
Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

+16 -8
View File
@@ -1,20 +1,28 @@
import React, { lazy } from "react";
import React, { lazy, useContext } from "react";
import { Link } from "react-router-dom";
import { localImgLoad } from "../../lib";
import DarkModeContext from "../Contexts/DarkModeContext";
export default function LoginLayout({ slogan, children }) {
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 (
<div className={`layout-wrapper login`}>
<div className={`w-full min-h-screen overflow-y-auto lg:grid grid-cols-2`}>
<div
<div className={`h-screen overflow-y-auto bg-cover bg-center`}
style={{backgroundImage: `url(${ countryMode == 'NG' ? bgImgNig : bgImgCom})`}}
>
<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`}
style={{backgroundImage: `url(${bgImg})`}}
>
</div>
<div className="p-5 sm:p-7 flex place-content-center">
<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> */}
<div className="p-5 sm:p-7 flex place-content-center lg:col-start-2">
<div className="py-10 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">
{children && children}
</div>
@@ -48,7 +56,7 @@ export default function LoginLayout({ slogan, children }) {
</div>
</div>
<p className="py-1 text-black text-[15px] px-2 font-medium flex items-center gap-1">
<span className="">&copy; {new Date().getFullYear()} -</span>
<span className="dark:text-white">&copy; {new Date().getFullYear()} -</span>
<Link to="/" className="text-[#009ef7] ml-1">
WrenchBoard
</Link>{" "}
@@ -99,7 +99,7 @@ export default function ForgotPassword() {
</Link>
</div>
<div className="flex place-content-center">
<div className="w-11/12 sm:max-w-[400px]">
<div className="w-10/12">
{msgSuccess == null ?
<>
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
+1 -1
View File
@@ -264,7 +264,7 @@ export default function Login() {
</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="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 */}
{sessionExpired != "true" && (
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
+1 -1
View File
@@ -158,7 +158,7 @@ export default function SignUp() {
</Link>
</div>
<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">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
Create Account
@@ -19,7 +19,7 @@ export default function UpdatePassword() {
<AuthLayout slogan="Welcome to myFit">
{updated === false ? (
<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">
<h1 className="sm:text-5xl text-4xl font-bold leading-[74px] text-dark-gray dark:text-white">
Update Password
@@ -132,7 +132,7 @@ export default function VerifyLink() {
</Link>
</div>
<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">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
{linkSuccess
@@ -152,7 +152,7 @@ const VerifyPassword = () => {
{requestStatus.loading ? (
<LoadingSpinner color="sky-blue" size="16" height="h-300px" />
) : !requestStatus.loading && requestStatus.status ? (
<div className="w-11/12 sm:max-w-[500px]">
<div className="w-10/12">
{linkSuccess == null ? (
<>
<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>
</div>
<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">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
Let's verify your email now
@@ -38,7 +38,7 @@ const validationSchema = Yup.object().shape({
};
export default function InviteRelative({action, situation, setReloadRelList}) {
export default function InviteRelative({action, situation, setReloadRelList, relativeList}) {
const api = new usersService()
@@ -167,7 +167,7 @@ export default function InviteRelative({action, situation, setReloadRelList}) {
{/* Type */}
<div className="md:flex md:space-x-7 items-end mb-6">
<div className="field w-full mb-6 md:mb-0">
{/* <div className="field w-full mb-6 md:mb-0">
<InputCom
fieldClass="px-6"
label="Type"
@@ -179,6 +179,52 @@ export default function InviteRelative({action, situation, setReloadRelList}) {
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">
@@ -12,7 +12,7 @@ const Relatives = () => {
const [invitePopout, setInvitePopout] = useState(false)
const [relativeList, setRelativeList] = useState({loading: true, data:[]})
const [relativeList, setRelativeList] = useState({loading: true, result_list:[], family_types:[]})
const showInviteMemberPopout = () => {
setInvitePopout(true)
@@ -21,14 +21,14 @@ const Relatives = () => {
const getRelativeList = () => {
setRelativeList(prev => ({...prev, loading: true}))
api.getFamilyRelativeList().then(response => {
let {data:{result_list}} = response
if(!result_list || result_list?.length <= 0){
setRelativeList({loading:false, data:[]})
let {status, data} = response
if(status != 200 || !data){
setRelativeList({loading:false, result_list:[], family_types:[]})
return
}
setRelativeList({loading:false, data:result_list})
setRelativeList({loading:false, result_list:data?.result_list, family_types:data?.family_types})
}).catch(error => {
setRelativeList({loading:false, data:[]})
setRelativeList({loading:false, result_list:[], family_types:[]})
})
}
@@ -47,7 +47,7 @@ const Relatives = () => {
{relativeList.loading ?
<LoadingSpinner size='8' height='h-full' />
:
<RelativeTable relativeList={relativeList.data} />
<RelativeTable relativeList={relativeList.result_list} />
}
</div>
</div>
@@ -58,6 +58,7 @@ const Relatives = () => {
action={()=>setInvitePopout(false)}
situation={invitePopout}
setReloadRelList={setReloadRelList}
relativeList={relativeList}
/>
}
{/* END OF INVITE RELATIVE POPOUT */}
+6 -2
View File
@@ -1,5 +1,5 @@
import React from "react";
import ParentWaiting from "../MyPendingJobs/ParentWaiting";
import ParentWaiting from "../MyOffers/ParentWaiting";
import MyOffersFamilyTable from "../MyTasks/MyOffersFamilyTable";
import FamilyActiveLSlde from "./FamilyActiveLSlde";
@@ -19,7 +19,11 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
/>
)}
{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" />*/}
+2 -2
View File
@@ -30,7 +30,7 @@ export default function GroupList({
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> */}
<div className="flex justify-end items-center">
<button
@@ -46,7 +46,7 @@ export default function GroupList({
No Group Found!
</h1>
) : (
<div className="my-4 max-h-[400px] overflow-y-auto">
<div className="my-4 max-h-[596px] bg-[#fffef6] rounded overflow-y-auto flex-1">
<div className="flex flex-col">
{groupList.map((item) => (
<div
@@ -34,7 +34,7 @@ export default function GroupMemberTable({ selectedList }) {
return (
<div
className={`w-full p-8 bg-white dark:bg-dark-gray overflow-hidden rounded-2xl section-shadow`}
className={`w-full p-8 dark:bg-dark-gray overflow-hidden rounded-2xl section-shado bg-[#fffef6]`}
>
<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">
@@ -79,8 +79,8 @@ export default function GroupMemberTable({ selectedList }) {
</tr>
))
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Members Found</td>
<tr className="font-semibold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Members Found. Please add</td>
</tr>
)}
</>
+1 -1
View File
@@ -90,7 +90,7 @@ export default function JobGroups() {
<Layout>
<div>
<h1 className="mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100">
Jobs Groups
Job Groups
</h1>
</div>
<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">
+1 -1
View File
@@ -277,7 +277,7 @@ export default function MemberList({
)}
</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 ? (
<h1 className="my-5 text-lg lg:text-xl tracking-wide text-slate-900 dark:text-slate-100">
No Member Found, Please Add
+202 -124
View File
@@ -1,21 +1,23 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import SelectBox from "../Helpers/SelectBox";
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
import JobListPopout from "../jobPopout/JobListPopout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import usersService from "../../services/UsersService";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import SelectBox from "../Helpers/SelectBox";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
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 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 }) {
const dispatch = useDispatch();
// Getting the categories
const currentJobCart = MyJobList?.data?.categories;
// DropDown Box
@@ -25,24 +27,46 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
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,
data: {},
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
});
const [editJob, setEditJob] = useState({ show: false, data: {} });
const [myCountry, setCountries] = useState("");
const {
userDetails: { country },
} = useSelector((state) => state?.userDetails);
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
const getCountryList = useCallback(async () => {
try {
const res = await userApi.getSignupCountryData();
if (res.status === 200 && res.data.internal_return >= 0) {
@@ -59,7 +83,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
throw new Error(error);
}
}, [userApi, country]);
console.log('MY COUNTRY', myCountry)
useEffect(() => {
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 }) => {
let thePrice = PriceFormatter(
value?.price * 0.01,
@@ -190,7 +329,10 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
<button
type="button"
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"
>
@@ -201,117 +343,53 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
);
};
return (
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
className || ""
}`}
>
<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>
const NoJobsRow = ({ text }) => (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">{text}</td>
</tr>
);
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
currentJobList?.length
? true
: false
}
data={currentJobList}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
)}
const MyJobListTable = () => (
<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?.data?.result_list?.length > 0 ? (
filteredCurrentJobList.length > 0 ? (
filteredCurrentJobList.map((value, index) => (
<JobListItem
key={index}
index={index}
value={value}
image_server={MyJobList.data.session_image_server}
/>
))
) : (
<NoJobsRow text="No Jobs Available In This Category!" />
)
) : (
<NoJobsRow text="No Jobs Available!" />
)}
</>
</tbody>
</table>
{/* Job List Popout */}
{jobPopout.show && (
<JobListPopout
details={jobPopout.data}
onClose={() => {
setJobPopout({ show: false, data: {} });
}}
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}
/>
)}
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
currentJobList?.length
? true
: false
}
data={currentJobList}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
);
return { MyJobListHeader, MyJobListTable };
}
@@ -1,11 +1,10 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import CommonHead from "../UserHeader/CommonHead";
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 filterHandler = (value) => {
setValue(value);
@@ -13,9 +12,7 @@ export default function MyPendingJobs(props) {
// console.log("AMEYE LOC1", props.MyJobList);
return (
<Layout>
<CommonHead
commonHeadData={props.commonHeadData}
/>
<CommonHead commonHeadData={props.commonHeadData} />
<div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full">
{/* heading */}
@@ -25,7 +22,7 @@ export default function MyPendingJobs(props) {
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
Pending Job(s)
Pending Offers
</span>
</h1>
</div>
@@ -36,13 +33,17 @@ export default function MyPendingJobs(props) {
></div>
</div>
</div>
{props.MyJobList.loading ?
<div className="bg-white">
<LoadingSpinner size='16' color='sky-blue' height='min-h-[300px]' />
</div>
:
<MyPendingJobTable MyJobList={props.MyJobList.data} />
}
{props.MyJobList.loading ? (
<div className="bg-white">
<LoadingSpinner
size="16"
color="sky-blue"
height="min-h-[300px]"
/>
</div>
) : (
<MyPendingJobTable MyJobList={props.MyJobList.data} />
)}
</div>
</div>
</Layout>
@@ -79,7 +79,7 @@ const CreditPopup = ({ details, onClose, situation, walletItem }) => {
<ConfirmAddFund
confirmCredit={confirmCredit}
setConfirmCredit={setConfirmCredit}
walletItem={walletItem}
walletItem={walletItem || details}
onClose={onClose}
/>
) : confirmCredit?.show?.acceptConfirm?.state ? (
+16 -1
View File
@@ -5,6 +5,13 @@ function Default({ children }) {
// dark mode setup
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(() => {
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setTheme("dark");
@@ -24,9 +31,17 @@ function Default({ children }) {
const handleThemeSwitch = () => {
setTheme(theme === "dark" ? "light" : "dark");
};
useEffect(()=>{
if(country){
setCountryMode(country)
localStorage.setItem('cnt', country)
}
},[countryMode])
return (
<>
<DarkModeContext.Provider value={{ theme, handleThemeSwitch }}>
<DarkModeContext.Provider value={{ theme, handleThemeSwitch, countryMode }}>
{children && children}
</DarkModeContext.Provider>
</>
+1 -1
View File
@@ -24,7 +24,7 @@ export default function Layout({ children }) {
localStorage.removeItem("member_id");
localStorage.removeItem("uid");
sessionStorage.removeItem("family_uid");
// localStorage.clear();
localStorage.clear();
// toast.success("Come Back Soon", {
// icon: `🙂`,
// });
+7 -2
View File
@@ -192,8 +192,13 @@ export default function MobileSidebar({
{[
{ name: "List", path: "/myjobs", iconName: "job-list" },
{
name: "Pending",
path: "/my-pending-jobs",
name: "Offers",
path: "/my-offers",
iconName: "pending-job",
},
{
name: "Waiting",
path: "/pend-interest",
iconName: "pending-job",
},
{
+1 -1
View File
@@ -190,7 +190,7 @@ export default function RightSideBar({myJobList}) {
{/* name */}
<div>
<p className="text-thin-light-gray text-base font-medium">
<NavLink to="/my-review-jobs">Review Pending</NavLink>
<NavLink to="/my-review-jobs">Review</NavLink>
</p>
</div>
</div>
+9 -5
View File
@@ -8,14 +8,13 @@ import {
import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons";
export default function Sidebar({
sidebar,
action,
logoutModalHandler,
myJobList,
}) {
const darkMode = useContext(DarkModeContext);
const darkMode = useContext(DarkModeContext);
let { userDetails } = useSelector((state) => state.userDetails);
//const jobLists = getJobList(); // pass from upper - we need in a lot of places
@@ -218,8 +217,13 @@ export default function Sidebar({
iconName: "job-list",
},
{
name: "Pending",
path: "/my-pending-jobs",
name: "Waiting",
path: "/pend-interest",
iconName: "pending-job",
},
{
name: "Offers",
path: "/my-offers",
iconName: "pending-job",
},
{
@@ -291,7 +295,7 @@ export default function Sidebar({
className="signout-btn w-full flex items-center justify-center"
>
<span className="p-[1px] w-[40px] h-[40px] border border-purple rounded-full">
<Icons name='new-logout' />
<Icons name="new-logout" />
</span>
</button>
)}
+291 -220
View File
@@ -1,6 +1,6 @@
import { Field, Form, Formik } from "formik";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useDispatch } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import * as Yup from "yup";
import usersService from "../../services/UsersService";
import { tableReload } from "../../store/TableReloads";
@@ -22,7 +22,13 @@ const validationSchema = Yup.object().shape({
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"];
@@ -45,6 +51,30 @@ function JobListPopout({ details, onClose, situation }) {
});
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
const memberList = useCallback(async () => {
@@ -119,6 +149,7 @@ function JobListPopout({ details, onClose, situation }) {
job_uid,
job_description: textArea,
};
let reqData;
// for family input
@@ -175,7 +206,7 @@ function JobListPopout({ details, onClose, situation }) {
setTimeout(() => {
setLoader({ jobFields: false });
onClose();
throw new Response(data);
// throw new Response(data);
}, 3000);
} catch (error) {
setRequestStatus({ message: "Unable to complete", status: false });
@@ -219,7 +250,50 @@ function JobListPopout({ details, onClose, situation }) {
});
}, []);
// console.log("Job List P >> ", details)
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>
);
};
return (
<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">
@@ -253,230 +327,186 @@ function JobListPopout({ details, onClose, situation }) {
</svg>
</button>
</div>
<div className="md:grid grid-cols-2 bg-white dark:bg-dark-white rounded-lg shadow-lg">
<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> */}
<DetailsComponent />
{/* INPUT SECTION */}
<div className="my-3 md:flex">
<Detail label="Description" value={details.description} />
</div>
<>
{/* 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>
)}
<div className="my-3 md:flex">
<Detail label="Price" value={details.thePrice} />
</div>
{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>
)}
<div className="my-3 md:flex">
<Detail
label="Timeline"
value={`${details.timeline_days} day(s)`}
/>
</div>
{selectedTab == "individual" && (
<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>
)}
<div className="my-3 md:flex">
<Detail
label="Created"
value={new Date(details?.created).toDateString()}
/>
</div>
<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>
{/* ACTION SECTION */}
<div className="px-4 pb-3 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">
<div className="grid grid-cols-3 mt-4">
{tabs.map((item) => (
<button
// className={`px-4 py-1 rounded-t-2xl ${selectedTab == item ? 'btn-gradient border-[2px] text-white' : 'bg-white text-[#000] border-t-[2px]'}`}
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"
{/* { 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>
)}
<p
className={`text-center w-full text-lg ${
requestStatus.status
? "text-emerald-600"
: "text-red-600"
}`}
></div>
{item[0].toUpperCase() + item.slice(1)}
</button>
))}
>
{requestStatus.message && requestStatus.message}
</p>
</div>
</div>
</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>
)}
) : (
<ZeroBalanceChecker
{...taskWalletSelector}
openCreditPopup={openCreditPopup}
/>
)}
{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" && (
<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>
)}
<p
className={`text-center w-full text-lg ${
requestStatus.status ? "text-emerald-600" : "text-red-600"
}`}
>
{requestStatus.message && requestStatus.message}
</p>
</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 */}
{/* END OF ACTION SECTION */}
</>
</div>
</div>
</ModalCom>
@@ -628,3 +658,44 @@ const publicArray = [
{ duration: 21, name: "3 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>
);
+1
View File
@@ -38,6 +38,7 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
localStorage.removeItem("member_id");
localStorage.removeItem("session_token");
sessionStorage.removeItem("family_uid");
localStorage.clear();
navigate("/login", { replace: true }); // redirects user to login page after session expires
};
@@ -1,34 +1,34 @@
import React, { useContext, useState, useEffect } from "react";
import usersService from "../services/UsersService";
import MyPendingJobs from "../components/MyPendingJobs";
import React, { useEffect, useState } from "react";
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 { pendingListTable } = useSelector((state) => state.tableReload);
const [MyJobList, setMyJobList] = useState({loading: true, data: []});
const [MyJobList, setMyJobList] = useState({ loading: true, data: [] });
const api = new usersService();
const getMyJobList = async () => {
setMyJobList({loading: true, data: []});
setMyJobList({ loading: true, data: [] });
try {
const res = await api.getMyPendingJobList();
setMyJobList({loading: false, data: res.data});
setMyJobList({ loading: false, data: res.data });
} catch (error) {
setMyJobList({loading: false, data: []});
setMyJobList({ loading: false, data: [] });
console.log("Error getting mode");
}
};
useEffect(() => {
getMyJobList();
getMyJobList();
}, [pendingListTable]);
// debugger;
return (
<>
<MyPendingJobs
<MyOffers
MyJobList={MyJobList}
commonHeadData={commonHeadBanner.result_list}
/>