Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d081dd73d6 | |||
| 9b9e10efbb | |||
| 07040832d7 | |||
| f928f45615 | |||
| 1b0f6c0b89 | |||
| 8315e226dd | |||
| 13da84099c | |||
| 3b6f2a4ca0 | |||
| bdc67590d1 | |||
| 89d2682eaf | |||
| 41a617a265 | |||
| c72765b38c | |||
| fe3306cb98 | |||
| 13b96a3b8d | |||
| f4c0c5bf15 | |||
| bc2a4340f2 | |||
| a4b85e9c85 | |||
| 6dab5412c7 | |||
| 4949bd28aa |
+12
-3
@@ -6,9 +6,18 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
|
||||
|
||||
<meta name="description" content="wrenchboard.com is an online marketplace to make money from your skills, find, buy and sell professional services. Connect with freelancers to get work done faster. Trade your freelance services."/>
|
||||
<meta name="title" content="WrenchBoard: Find a Freelancer | Sell Professional Services"/><meta name="keywords" content="Online Jobs, Online Workers, work online Nigeria, hire a freelancer, hire freelancers, freelance marketplace, freelancer hire, freelance service, freelance professional services, How to make money online, find workers online, Online Services, digital services, freelancers community in Ghana, freelancers community in Nigeria, freelancer site in Africa, Best freelance website in Africa, Freelance Designers, Photographers, Writers in Nigeria, freelancers, freelance outsourcing in Nigeria, freelance IT services in Nigeria, hire freelancers online in Nigeria, freelance services online in Nigeria, freelance contractor in Nigeria, freelance sites in Nigeria, freelance jobs in Nigeria, freelance projects in Nigeria, freelance jobs online in Nigeria, professional freelancers in Nigeria, buy professional services in Nigeria, professional services jobs, professional business services, professional service providers in Nigeria, freelancing services, freelancing sites in Nigeria, freelancers for hire in Nigeria, freelancer search in Nigeria, search freelancer in Nigeria, find freelancers in Nigeria, Find workers US. Outsource from US to Nigeria, find a freelancer in Nigeria, freelancing projects in Nigeria, web freelancing in Nigeria, outsourcing sites freelancers in Nigeria, website for freelancers in Nigeria, marketplace for freelancers "/>
|
||||
<meta
|
||||
name="description"
|
||||
content="WrenchBoard.com is the place to set family goals and reward achievements. Find tasks to earn from, or send tasks for others to perform for you."
|
||||
/>
|
||||
<meta
|
||||
name="title"
|
||||
content="WrenchBoard: Reward Accomplishments | Get Family Engaged"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="Empower families to reward accomplishment, set goals, and encourage kids to understand goals, earning, and the benefit of savings – in one app experience."
|
||||
/>
|
||||
<link rel="manifest" href="/manifest.json"/>
|
||||
<script>
|
||||
!function(e,a,t,n,g,c,o){e.GoogleAnalyticsObject=g,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(t),o=a.getElementsByTagName(t)[0],c.async=1,c.src="https://www.google-analytics.com/analytics.js",o.parentNode.insertBefore(c,o)}(window,document,"script",0,"ga"),ga("create","UA-54829827-4","auto"),ga("send","pageview")</script><script defer="defer" src="/static/js/main.787e423f.js"></script><link href="/static/css/main.418eaf65.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body><script>var LHC_API=LHC_API||{};LHC_API.args={mode:"widget",lhc_base_url:"//chat.live.wrenchboard.com/",wheight:450,wwidth:350,pheight:520,pwidth:500,leaveamessage:!0,check_messages:!1},function(){var e=document.createElement("script");e.type="text/javascript",e.setAttribute("crossorigin","anonymous"),e.async=!0;var t=new Date;e.src="//chat.live.wrenchboard.com/design/defaulttheme/js/widgetv2/index.js?"+t.getFullYear()+t.getMonth()+t.getDate();var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(e,a)}()
|
||||
|
||||
@@ -13,11 +13,12 @@ export default function LoginLayout({ slogan, children }) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`h-screen overflow-y-auto bg-cover bg-center`}
|
||||
className={`min-h-screen overflow-y-auto bg-cover bg-center flex flex-col justify-between items-center`}
|
||||
style={{
|
||||
backgroundImage: `url(${countryMode == "NG" ? bgImgNig : bgImgCom})`,
|
||||
}}
|
||||
>
|
||||
|
||||
<div className={`w-full grid grid-cols-1 xl:grid-cols-2`}>
|
||||
{/* <div
|
||||
className={`auth-bg hidden xl:block bg-blue-50 relative bg-cover bg-no-repeat border-0 after:content-[''] after:absolute after:inset-0`}
|
||||
@@ -29,47 +30,51 @@ export default function LoginLayout({ slogan, children }) {
|
||||
<div className="w-full flex justify-center items-center">
|
||||
{children && children}
|
||||
</div>
|
||||
<div className="w-full flex flex-col justify-center items-center px-10">
|
||||
<div className="w-full flex justify-center items-center pt-5">
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href="https://www.wrenchboard.com/about-us"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/service"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/contact"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Contact Us
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p className="py-1 text-black text-[15px] px-2 font-medium flex items-center gap-1">
|
||||
<span className="dark:text-white">
|
||||
© {new Date().getFullYear()} -
|
||||
</span>
|
||||
<Link to="/" className="text-[#009ef7] ml-1">
|
||||
WrenchBoard
|
||||
</Link>{" "}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='w-full shadow-md bg-slate-50 dark:bg-dark-white'>
|
||||
<div className="w-full flex flex-col md:flex-row justify-center items-center px-10 py-2">
|
||||
<div className="flex justify-center items-center">
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href="https://www.wrenchboard.com/about-us"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/service"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/contact"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Contact Us
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-black text-[15px] px-2 font-medium flex items-center gap-1">
|
||||
<span className="dark:text-white">
|
||||
© {new Date().getFullYear()} -
|
||||
</span>
|
||||
<Link to="/" className="text-[#009ef7] ml-1">
|
||||
WrenchBoard
|
||||
</Link>{" "}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -563,7 +563,7 @@ export default function Login() {
|
||||
{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
|
||||
This site is protected by a Captcha. <br />Our Privacy Policy and
|
||||
Terms of Service apply.
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -10,6 +10,7 @@ export default function AvailableJobsCard({
|
||||
hidden = false,
|
||||
contentDisplay,
|
||||
image_server,
|
||||
marketPlaceProduct
|
||||
}) {
|
||||
//debugger;
|
||||
const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} });
|
||||
@@ -103,9 +104,10 @@ export default function AvailableJobsCard({
|
||||
{/* <div className="product-two-options flex justify-between mb-5 relative"></div> */}
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div>
|
||||
<p className="w-full font-bold text-xl tracking-wide text-dark-gray dark:text-white">
|
||||
<div className='w-full'>
|
||||
<p className="w-full flex gap-1 items-center font-bold text-xl tracking-wide text-dark-gray dark:text-white">
|
||||
{/* {thePrice} | {datas.timeline_days} day(s) */}
|
||||
{datas?.offer_depend_uid && <i className="fa-solid fa-lock p-1 text-red-500 text-[12px]"></i>}
|
||||
{thePrice}
|
||||
</p>
|
||||
<p className="text-sm text-lighter-gray">
|
||||
@@ -171,7 +173,8 @@ export default function AvailableJobsCard({
|
||||
</div>
|
||||
|
||||
<div className="block sm:flex flex-wrap gap-4">
|
||||
<p className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||
<p className="text-sm text-thin-light-gray flex flext-start gap-1 items-center">
|
||||
{datas?.offer_depend_uid && <i className="fa-solid fa-lock p-1 text-red-500 text-[12px]"></i>}
|
||||
Price: <span className="text-purple">{thePrice}</span>
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray">
|
||||
@@ -220,6 +223,7 @@ export default function AvailableJobsCard({
|
||||
setMarketPopUp({ show: false, data: {} });
|
||||
}}
|
||||
situation={marketPopUp.show}
|
||||
marketPlaceProduct={marketPlaceProduct}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ export default function MainSection({
|
||||
contentDisplay={contentDisplay}
|
||||
image_server={image_server}
|
||||
datas={datum}
|
||||
marketPlaceProduct={marketPlaceProduct}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
|
||||
|
||||
export default function LockJob({details, marketPlaceProduct, ManageInterest, manageInt, handleInputChange, MarketDetail, marketMsg, errMsg, textValue}) {
|
||||
const apiCall = new usersService()
|
||||
|
||||
const [completedTask, setCompletedTask] = useState({
|
||||
loading: true,
|
||||
data: []
|
||||
})
|
||||
|
||||
let thePrice = PriceFormatter(
|
||||
details?.price * 0.01,
|
||||
details?.currency_code,
|
||||
details?.currency
|
||||
);
|
||||
|
||||
let cleanedText = details?.job_description
|
||||
?.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, '"')
|
||||
.replace(/&/g, "&");
|
||||
|
||||
let dependOn = marketPlaceProduct?.filter(item => item?.job_uid == details?.offer_depend_uid)[0]
|
||||
|
||||
useEffect(()=>{
|
||||
apiCall.getVerifyCompletedTask({offer_depend_uid:details?.offer_depend_uid}).then(res => {
|
||||
console.log('RES', res.data)
|
||||
setCompletedTask({loading:false, data:res?.data?.result_list})
|
||||
}).catch(err =>{
|
||||
setCompletedTask({loading:false, data:[]})
|
||||
})
|
||||
},[])
|
||||
|
||||
return (
|
||||
<>
|
||||
{completedTask.loading ?
|
||||
<div className='w-full md:col-span-4 flex justify-center items-center min-h-[500px]'>
|
||||
<LoadingSpinner
|
||||
size='10'
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
<>
|
||||
<div className="px-4 py-2 w-full md:col-span-3 md:border-r-1">
|
||||
<div className="min-h-[200px]">
|
||||
<h2 className="w-full flex gap-1 items-center font-semibold text-slate-900 dark:text-white tracking-wide">
|
||||
{details?.offer_depend_uid && <i className="fa-solid fa-lock p-1 text-red-500 text-[12px]"></i>}
|
||||
{details?.title}
|
||||
</h2>
|
||||
|
||||
{/* INPUT SECTION */}
|
||||
{[
|
||||
{
|
||||
name: "Description",
|
||||
content: details.description,
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
content: {
|
||||
text: `Timeline: ${details.timeline_days} day(s) -- `,
|
||||
bold: `Budget: ${thePrice}`,
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name: "Delivery Detail",
|
||||
// content: cleanedText,
|
||||
// danger: true,
|
||||
// },
|
||||
].map(({ name, content, danger }, idx) => (
|
||||
<div className={`my-1 flex flex-col items-start`} key={idx}>
|
||||
<label className="py-1 job-label w-full">
|
||||
{name}
|
||||
</label>
|
||||
<div
|
||||
className={`w-full p-2 text-slate-900 dark:text-white market-pop rounded-2xl ${
|
||||
name == "Description"
|
||||
? "min-h-[100px] max-h-[100px] h-full overflow-y-auto break-words bg-slate-50"
|
||||
: name == "Delivery Detail" ? " overflow-y-auto h-full min-h-[100px] max-h-[100px] bg-slate-50"
|
||||
: "h-full flex items-center"
|
||||
}`}
|
||||
>
|
||||
{danger ? (
|
||||
<p
|
||||
className={`dark:text-black`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: danger && content,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<p className={`w-full text-slate-900 dark:text-black`}>
|
||||
{name !== "Delivery Detail" ? (
|
||||
<>
|
||||
{typeof content !== "object" ? content : null}
|
||||
{typeof content === "object" && (
|
||||
<>
|
||||
{/* <hr className="mb-1" /> */}
|
||||
<span className='flex w-full mb-1 h-[1px] bg-slate-500'></span>
|
||||
<span className="flex items-center gap-2 dark:text-white">
|
||||
{content?.text}
|
||||
<strong>{thePrice}</strong>
|
||||
</span>
|
||||
<span className='flex w-full mt-1 h-[1px] bg-slate-500'></span>
|
||||
{/* <hr className="mt-1" /> */}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* <hr className='my-3' /> */}
|
||||
{completedTask.loading ?
|
||||
<p className='py-3 w-full text-center text-lg'>Loading...</p>
|
||||
:completedTask?.data?.filter(item => item?.job_uid == details.offer_depend_uid).length > 0 ?
|
||||
<div className='w-full'>
|
||||
<label className="job-label w-full flex gap-2 items-center">
|
||||
If you have any questions about this task:
|
||||
<span className={`text-sm ${marketMsg.state ? 'text-[#57cd89]' : 'text-red-500'}`}>
|
||||
{marketMsg.state && "Message Sent!"}
|
||||
{errMsg.market && "Failed to send"}
|
||||
</span>
|
||||
</label>
|
||||
<div className="w-full flex items-center gap-3">
|
||||
<div className="w-full">
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 dark:text-white ${
|
||||
marketMsg.loading && "italic text-[#9CA3AF]"
|
||||
} bg-transparent outline-none border-2 border-slate-300 rounded-md`}
|
||||
rows="3"
|
||||
style={{ resize: "none" }}
|
||||
placeholder="Enter message here ..."
|
||||
value={marketMsg.loading ? "Sending..." : textValue}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex flex-col">
|
||||
<button
|
||||
className="rounded-full flex justify-center items-center w-12 h-11 bg-yellow-500 text-white"
|
||||
name="market-message"
|
||||
onClick={MarketDetail}
|
||||
disabled={marketMsg.loading}
|
||||
>
|
||||
{marketMsg.loading ? (
|
||||
<LoadingSpinner size={5} color="white" />
|
||||
) : (
|
||||
// "Send Message"
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 11 20"
|
||||
id="Arrow"
|
||||
className="w-[0.7rem]"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M.366 19.708c.405.39 1.06.39 1.464 0l8.563-8.264a1.95 1.95 0 0 0 0-2.827L1.768.292A1.063 1.063 0 0 0 .314.282a.976.976 0 0 0-.011 1.425l7.894 7.617a.975.975 0 0 1 0 1.414L.366 18.295a.974.974 0 0 0 0 1.413"
|
||||
// fill=""
|
||||
className="color000000 svgShape fill-[#fff]"
|
||||
></path>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className='w-full'>
|
||||
<h1 className='text-red-600 text-lg'>This task depends on the task below</h1>
|
||||
<div className='rounded-2xl bg-red-50'>
|
||||
<div className='my-1 w-full'>
|
||||
<h2 className="p-2 w-full flex gap-1 items-center font-semibold text-slate-900 dark:text-black tracking-wide">
|
||||
{dependOn?.offer_depend_uid && <i className="fa-solid fa-lock p-1 text-red-500 text-[12px]"></i>}
|
||||
{dependOn?.title}
|
||||
</h2>
|
||||
</div>
|
||||
<div className={`p-2 flex flex-col items-start`}>
|
||||
<p className="py-1 job-label w-full dark:text-black">Description</p>
|
||||
<div className={`w-full p-2 text-slate-900 dark:text-black market-pop rounded-2xl bg-white break-words min-h-[100px] max-h-[100px]`}>
|
||||
{dependOn?.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="py-2 w-full md:col-span-1 h-full flex flex-col rounded-2xl">
|
||||
<div className="mx-auto bg-[#f1f8ff] dark:bg-[#C2C8D3] px-4 rounded-md w-full h-full md:min-h-[420px] flex flex-col justify-between">
|
||||
<div className="w-full flex flex-col justify-center pb-4 gap-2">
|
||||
<p className="job-label w-full">
|
||||
Interested?
|
||||
</p>
|
||||
<hr />
|
||||
{completedTask.loading ?
|
||||
<p className='py-3 w-full text-center text-lg'>Loading...</p>
|
||||
:completedTask?.data?.filter(item => item?.job_uid == details.offer_depend_uid).length > 0 ?
|
||||
<button
|
||||
className="btn-gradient text-white px-2 py-2 border-4 border-slate-300 text-lg lg:text-xl font-medium rounded-2xl"
|
||||
name="market-interest"
|
||||
onClick={ManageInterest}
|
||||
>
|
||||
{" "}
|
||||
<div className="flex md:flex-col justify-center gap-2">
|
||||
<span>Notify</span>
|
||||
<span>Owner</span>
|
||||
</div>
|
||||
</button>
|
||||
:
|
||||
<h1 className='text-red-600 text-base font-bold'>This task depends on completion of another task</h1>
|
||||
}
|
||||
<>
|
||||
{manageInt.loading ? (
|
||||
<p className="text-sm italic">please wait...</p>
|
||||
) : (
|
||||
<>
|
||||
{manageInt?.msg !== "" && (
|
||||
<p
|
||||
className={`text-sm italic ${
|
||||
manageInt?.state ? "text-green-500" : "text-red-500"
|
||||
}`}
|
||||
>
|
||||
{manageInt?.msg}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
|
||||
<div className="text-slate-900">
|
||||
<p className="flex items-center tracking-wide">
|
||||
<span className="job-label">Interest: </span> <b className="ml-1">{details.interest_count}</b>
|
||||
</p>
|
||||
<hr />
|
||||
<p className="my-1 flex flex-col">
|
||||
<span className="job-label">Expire: </span>
|
||||
<span> {new Date(details.expire).toLocaleString()} </span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -5,8 +5,9 @@ import ModalCom from "../../Helpers/ModalCom";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import { SocketValues } from "../../Contexts/SocketIOContext";
|
||||
import LockJob from "./LockJob";
|
||||
|
||||
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
const MarketPopUp = ({ details, onClose, situation, marketInt, marketPlaceProduct }) => {
|
||||
|
||||
let {sendJobInterestToOwner} = SocketValues() // function to emit job interest request
|
||||
const emitOfferInterest = () => {
|
||||
@@ -143,185 +144,202 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</div>
|
||||
|
||||
<div className="md:grid md:grid-cols-4 bg-white dark:bg-dark-white text-slate-900 dark:text-white rounded-lg">
|
||||
<div className="px-4 py-1 w-full md:col-span-3 md:border-r-1">
|
||||
<div className="min-h-[300px]">
|
||||
<h2 className="font-semibold text-slate-900 dark:text-white tracking-wide">
|
||||
{details?.title}
|
||||
</h2>
|
||||
{details?.offer_depend_uid ?
|
||||
<LockJob
|
||||
marketPlaceProduct={marketPlaceProduct}
|
||||
details={details}
|
||||
ManageInterest={ManageInterest}
|
||||
manageInt={manageInt}
|
||||
marketMsg={marketMsg}
|
||||
errMsg={errMsg}
|
||||
textValue={textValue}
|
||||
MarketDetail={MarketDetail}
|
||||
handleInputChange={handleInputChange}
|
||||
/>
|
||||
:
|
||||
<>
|
||||
<div className="px-4 py-2 w-full md:col-span-3 md:border-r-1">
|
||||
<div className="min-h-[300px]">
|
||||
<h2 className="w-full flex gap-1 items-center font-semibold text-slate-900 dark:text-white tracking-wide">
|
||||
{details?.offer_depend_uid && <i className="fa-solid fa-lock p-1 text-red-500 text-[12px]"></i>}
|
||||
{details?.title}
|
||||
</h2>
|
||||
|
||||
{/* INPUT SECTION */}
|
||||
{[
|
||||
{
|
||||
name: "Description",
|
||||
content: details.description,
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
content: {
|
||||
text: `Timeline: ${details.timeline_days} day(s) -- `,
|
||||
bold: `Budget: ${thePrice}`,
|
||||
{/* INPUT SECTION */}
|
||||
{[
|
||||
{
|
||||
name: "Description",
|
||||
content: details.description,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Delivery Detail",
|
||||
content: cleanedText,
|
||||
danger: true,
|
||||
},
|
||||
].map(({ name, content, danger }, idx) => (
|
||||
<div className={`my-3 md:flex items-start`} key={idx}>
|
||||
<label className="py-2 job-label w-full md:w-[19%]">
|
||||
{name}
|
||||
</label>
|
||||
<div
|
||||
className={`w-full p-2 md:w-3/4 text-slate-900 dark:text-white market-pop rounded-2xl ${
|
||||
name == "Description"
|
||||
? "min-h-[150px] max-h-[150px] h-full overflow-y-auto break-words bg-slate-50"
|
||||
: name == "Delivery Detail" ? " overflow-y-auto h-full min-h-[150px] max-h-[150px] bg-slate-50"
|
||||
: "h-full flex items-center"
|
||||
}`}
|
||||
>
|
||||
{danger ? (
|
||||
<p
|
||||
className={`dark:text-white`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: danger && content,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<p className={`w-full text-slate-900 dark:text-white`}>
|
||||
{name !== "Delivery Detail" ? (
|
||||
<>
|
||||
{typeof content !== "object" ? content : null}
|
||||
{typeof content === "object" && (
|
||||
<>
|
||||
{/* <hr className="mb-1" /> */}
|
||||
<span className='flex w-full mb-1 h-[1px] bg-slate-500'></span>
|
||||
<span className="flex items-center gap-2 dark:text-white">
|
||||
{content?.text}
|
||||
<strong>{thePrice}</strong>
|
||||
</span>
|
||||
<span className='flex w-full mt-1 h-[1px] bg-slate-500'></span>
|
||||
{/* <hr className="mt-1" /> */}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<hr className='my-1' />
|
||||
<div className='w-full'>
|
||||
<label className="job-label w-full flex gap-2 items-center">
|
||||
If you have any questions about this task:
|
||||
<span className={`text-sm ${marketMsg.state ? 'text-[#57cd89]' : 'text-red-500'}`}>
|
||||
{marketMsg.state && "Message Sent!"}
|
||||
{errMsg.market && "Failed to send"}
|
||||
</span>
|
||||
</label>
|
||||
<div className="w-full flex items-center gap-3">
|
||||
<div className="w-full">
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 dark:text-white ${
|
||||
marketMsg.loading && "italic text-[#9CA3AF]"
|
||||
} bg-transparent outline-none border-2 border-slate-300 rounded-md`}
|
||||
rows="3"
|
||||
style={{ resize: "none" }}
|
||||
placeholder="Enter message here ..."
|
||||
value={marketMsg.loading ? "Sending..." : textValue}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex flex-col">
|
||||
<button
|
||||
className="rounded-full flex justify-center items-center w-12 h-11 bg-yellow-500 text-white"
|
||||
name="market-message"
|
||||
onClick={MarketDetail}
|
||||
disabled={marketMsg.loading}
|
||||
>
|
||||
{marketMsg.loading ? (
|
||||
<LoadingSpinner size={5} color="white" />
|
||||
) : (
|
||||
// "Send Message"
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 11 20"
|
||||
id="Arrow"
|
||||
className="w-[0.7rem]"
|
||||
{
|
||||
name: "",
|
||||
content: {
|
||||
text: `Timeline: ${details.timeline_days} day(s) -- `,
|
||||
bold: `Budget: ${thePrice}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Delivery Detail",
|
||||
content: cleanedText,
|
||||
danger: true,
|
||||
},
|
||||
].map(({ name, content, danger }, idx) => (
|
||||
<div className={`my-3 md:flex items-start`} key={idx}>
|
||||
<label className="py-2 job-label w-full md:w-[19%]">
|
||||
{name}
|
||||
</label>
|
||||
<div
|
||||
className={`w-full p-2 md:w-3/4 text-slate-900 dark:text-white market-pop rounded-2xl ${
|
||||
name == "Description"
|
||||
? "min-h-[150px] max-h-[150px] h-full overflow-y-auto break-words bg-slate-50"
|
||||
: name == "Delivery Detail" ? " overflow-y-auto h-full min-h-[150px] max-h-[150px] bg-slate-50"
|
||||
: "h-full flex items-center"
|
||||
}`}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M.366 19.708c.405.39 1.06.39 1.464 0l8.563-8.264a1.95 1.95 0 0 0 0-2.827L1.768.292A1.063 1.063 0 0 0 .314.282a.976.976 0 0 0-.011 1.425l7.894 7.617a.975.975 0 0 1 0 1.414L.366 18.295a.974.974 0 0 0 0 1.413"
|
||||
// fill=""
|
||||
className="color000000 svgShape fill-[#fff]"
|
||||
></path>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
{/* <span className="text-sm text-[#57cd89]">
|
||||
{marketMsg.state && "Sent!"}
|
||||
{errMsg.market && "Failed"}
|
||||
</span> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="py-2 w-full md:col-span-1 h-full flex flex-col rounded-2xl">
|
||||
<div className="mx-auto bg-[#f1f8ff] dark:bg-[#C2C8D3] px-4 rounded-md w-full h-full md:min-h-[420px] flex flex-col justify-between">
|
||||
<div className="w-full flex flex-col justify-center pb-4 gap-2">
|
||||
<p className="job-label w-full">
|
||||
Interested?
|
||||
</p>
|
||||
<hr />
|
||||
<button
|
||||
className="btn-gradient text-white px-2 py-2 border-4 border-slate-300 text-lg lg:text-xl font-medium rounded-2xl"
|
||||
name="market-interest"
|
||||
onClick={ManageInterest}
|
||||
>
|
||||
{" "}
|
||||
<div className="flex md:flex-col justify-center gap-2">
|
||||
<span>Notify</span>
|
||||
<span>Owner</span>
|
||||
</div>
|
||||
</button>
|
||||
<>
|
||||
{manageInt.loading ? (
|
||||
<p className="text-sm italic">please wait...</p>
|
||||
) : (
|
||||
<>
|
||||
{manageInt?.msg !== "" && (
|
||||
{danger ? (
|
||||
<p
|
||||
className={`text-sm italic ${
|
||||
manageInt?.state ? "text-green-500" : "text-red-500"
|
||||
}`}
|
||||
>
|
||||
{manageInt?.msg}
|
||||
className={`dark:text-black`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: danger && content,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<p className={`w-full text-slate-900 dark:text-black`}>
|
||||
{name !== "Delivery Detail" ? (
|
||||
<>
|
||||
{typeof content !== "object" ? content : null}
|
||||
{typeof content === "object" && (
|
||||
<>
|
||||
{/* <hr className="mb-1" /> */}
|
||||
<span className='flex w-full mb-1 h-[1px] bg-slate-500'></span>
|
||||
<span className="flex items-center gap-2 dark:text-white">
|
||||
{content?.text}
|
||||
<strong>{thePrice}</strong>
|
||||
</span>
|
||||
<span className='flex w-full mt-1 h-[1px] bg-slate-500'></span>
|
||||
{/* <hr className="mt-1" /> */}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="text-slate-900">
|
||||
<p className="flex items-center tracking-wide">
|
||||
<span className="job-label">Interest: </span> <b className="ml-1">{details.interest_count}</b>
|
||||
</p>
|
||||
<hr />
|
||||
<p className="my-1 flex flex-col">
|
||||
<span className="job-label">Expire: </span>
|
||||
<span> {new Date(details.expire).toLocaleString()} </span>
|
||||
</p>
|
||||
<hr className='my-1' />
|
||||
<div className='w-full'>
|
||||
<label className="job-label w-full flex gap-2 items-center">
|
||||
If you have any questions about this task:
|
||||
<span className={`text-sm ${marketMsg.state ? 'text-[#57cd89]' : 'text-red-500'}`}>
|
||||
{marketMsg.state && "Message Sent!"}
|
||||
{errMsg.market && "Failed to send"}
|
||||
</span>
|
||||
</label>
|
||||
<div className="w-full flex items-center gap-3">
|
||||
<div className="w-full">
|
||||
<textarea
|
||||
className={`p-1 w-full text-sm text-slate-900 dark:text-white ${
|
||||
marketMsg.loading && "italic text-[#9CA3AF]"
|
||||
} bg-transparent outline-none border-2 border-slate-300 rounded-md`}
|
||||
rows="3"
|
||||
style={{ resize: "none" }}
|
||||
placeholder="Enter message here ..."
|
||||
value={marketMsg.loading ? "Sending..." : textValue}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex flex-col">
|
||||
<button
|
||||
className="rounded-full flex justify-center items-center w-12 h-11 bg-yellow-500 text-white"
|
||||
name="market-message"
|
||||
onClick={MarketDetail}
|
||||
disabled={marketMsg.loading}
|
||||
>
|
||||
{marketMsg.loading ? (
|
||||
<LoadingSpinner size={5} color="white" />
|
||||
) : (
|
||||
// "Send Message"
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 11 20"
|
||||
id="Arrow"
|
||||
className="w-[0.7rem]"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M.366 19.708c.405.39 1.06.39 1.464 0l8.563-8.264a1.95 1.95 0 0 0 0-2.827L1.768.292A1.063 1.063 0 0 0 .314.282a.976.976 0 0 0-.011 1.425l7.894 7.617a.975.975 0 0 1 0 1.414L.366 18.295a.974.974 0 0 0 0 1.413"
|
||||
// fill=""
|
||||
className="color000000 svgShape fill-[#fff]"
|
||||
></path>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
{/* <span className="text-sm text-[#57cd89]">
|
||||
{marketMsg.state && "Sent!"}
|
||||
{errMsg.market && "Failed"}
|
||||
</span> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* END OF ACTION SECTION */}
|
||||
|
||||
<div className="py-2 w-full md:col-span-1 h-full flex flex-col rounded-2xl">
|
||||
<div className="mx-auto bg-[#f1f8ff] dark:bg-[#C2C8D3] px-4 rounded-md w-full h-full md:min-h-[420px] flex flex-col justify-between">
|
||||
<div className="w-full flex flex-col justify-center pb-4 gap-2">
|
||||
<p className="job-label w-full">
|
||||
Interested?
|
||||
</p>
|
||||
<hr />
|
||||
<button
|
||||
className="btn-gradient text-white px-2 py-2 border-4 border-slate-300 text-lg lg:text-xl font-medium rounded-2xl"
|
||||
name="market-interest"
|
||||
onClick={ManageInterest}
|
||||
>
|
||||
{" "}
|
||||
<div className="flex md:flex-col justify-center gap-2">
|
||||
<span>Notify</span>
|
||||
<span>Owner</span>
|
||||
</div>
|
||||
</button>
|
||||
<>
|
||||
{manageInt.loading ? (
|
||||
<p className="text-sm italic">please wait...</p>
|
||||
) : (
|
||||
<>
|
||||
{manageInt?.msg !== "" && (
|
||||
<p
|
||||
className={`text-sm italic ${
|
||||
manageInt?.state ? "text-green-500" : "text-red-500"
|
||||
}`}
|
||||
>
|
||||
{manageInt?.msg}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
|
||||
<div className="text-slate-900">
|
||||
<p className="flex items-center tracking-wide">
|
||||
<span className="job-label">Interest: </span> <b className="ml-1">{details.interest_count}</b>
|
||||
</p>
|
||||
<hr />
|
||||
<p className="my-1 flex flex-col">
|
||||
<span className="job-label">Expire: </span>
|
||||
<span> {new Date(details.expire).toLocaleString()} </span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="modal-footer-wrapper">
|
||||
<button
|
||||
className="custom-btn bg-transparent border border-red-500 text-red-500 ml-auto"
|
||||
|
||||
@@ -13,7 +13,8 @@ import DeleteIcon from "../../assets/images/icon-delete.svg";
|
||||
import EditIcon from "../../assets/images/icon-edit.svg";
|
||||
import { tableReload } from "../AddJob/settings";
|
||||
import CreditPopup from "../MyWallet/Popup/CreditPopup";
|
||||
import JobListPopout from "../jobPopout/JobListPopout";
|
||||
// import JobListPopout from "../jobPopout/JobListPopout";
|
||||
import NewJobListPopout from "../jobPopout/NewJobListPopout";
|
||||
import EditJobPopoutNew from "../jobPopout/EditJobPopoutNew";
|
||||
|
||||
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
@@ -157,7 +158,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
|
||||
{/* Job List Popout */}
|
||||
{jobPopout.show && (
|
||||
<JobListPopout
|
||||
<NewJobListPopout
|
||||
details={jobPopout.data}
|
||||
onClose={() => {
|
||||
setJobPopout({ show: false, data: {} });
|
||||
@@ -165,6 +166,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||
setWalletItem={setWalletItem}
|
||||
openWallet={openPopUp}
|
||||
situation={jobPopout.show}
|
||||
myJobList={MyJobList}
|
||||
/>
|
||||
)}
|
||||
{/* End of Job List Popout */}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||
import axios from 'axios'
|
||||
|
||||
function Default({ children }) {
|
||||
// dark mode setup
|
||||
@@ -12,6 +13,32 @@ function Default({ children }) {
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const country = queryParams.get("cnt")?.toUpperCase();
|
||||
|
||||
const getLocation = () => {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(data) => {
|
||||
const pos = data.coords;
|
||||
const position = {
|
||||
lat: pos.latitude,
|
||||
long: pos.longitude,
|
||||
};
|
||||
axios.get(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${position.lat}&lon=${position.long}&zoom=18&addressdetails=1`).then(res =>{
|
||||
localStorage.setItem("myloc", res?.data?.address?.country);
|
||||
// console.log('LOC', res?.data?.address?.country)
|
||||
// localStorage.setItem("myloc", JSON.stringify(position));
|
||||
}).catch(err => {
|
||||
console.log('ERR', err)
|
||||
})
|
||||
},
|
||||
(err) => {
|
||||
localStorage.setItem("myloc", JSON.stringify('not supported'));
|
||||
}
|
||||
);
|
||||
} else {
|
||||
localStorage.setItem("myloc", JSON.stringify('not supported'));
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
setTheme("dark");
|
||||
@@ -39,6 +66,10 @@ function Default({ children }) {
|
||||
}
|
||||
},[countryMode])
|
||||
|
||||
useEffect(()=>{
|
||||
getLocation()
|
||||
},[])
|
||||
|
||||
return (
|
||||
<>
|
||||
<DarkModeContext.Provider value={{ theme, handleThemeSwitch, countryMode }}>
|
||||
|
||||
@@ -10,17 +10,19 @@ import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import Detail from "./popoutcomponent/Detail";
|
||||
import { SocketValues } from "../Contexts/SocketIOContext";
|
||||
|
||||
// .required("This is required ")
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
family: Yup.string().required("This is required "),
|
||||
family: Yup.string(),
|
||||
public: Yup.string(),
|
||||
individual: Yup.string()
|
||||
.email("Invalid email format")
|
||||
.matches(
|
||||
/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
|
||||
"Invalid email format"
|
||||
)
|
||||
.required("Email is required"),
|
||||
),
|
||||
group: Yup.string(),
|
||||
depend_uid: Yup.string(),
|
||||
});
|
||||
|
||||
function JobListPopout({
|
||||
@@ -29,6 +31,7 @@ function JobListPopout({
|
||||
situation,
|
||||
openWallet,
|
||||
setWalletItem,
|
||||
myJobList
|
||||
}) {
|
||||
|
||||
let {marketUpdate} = SocketValues() // destructures 'SEND MESSAGE' and 'JOIN ROOM' FUNCTIONS FROM SOCKET
|
||||
@@ -46,12 +49,7 @@ function JobListPopout({
|
||||
const [familyList, setFamilyList] = useState([]);
|
||||
let [loader, setLoader] = useState({
|
||||
member: false,
|
||||
jobFields: {
|
||||
family: false,
|
||||
public: false,
|
||||
individual: false,
|
||||
group: false,
|
||||
},
|
||||
jobFields: false
|
||||
});
|
||||
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
@@ -106,6 +104,7 @@ function JobListPopout({
|
||||
public: "",
|
||||
individual: "",
|
||||
group: "",
|
||||
depend_uid: ''
|
||||
};
|
||||
|
||||
let [textArea, setTextArea] = useState(details?.job_detail);
|
||||
@@ -136,11 +135,12 @@ function JobListPopout({
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
setErrMsg({ jobFields: "" });
|
||||
}, 3000);
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
const jobFieldHandler = async (values, helpers) => {
|
||||
setLoader({ jobFields: true });
|
||||
let { job_id, job_uid } = details;
|
||||
|
||||
if (!textArea) {
|
||||
@@ -163,15 +163,14 @@ function JobListPopout({
|
||||
family_uid: values?.family,
|
||||
assign_mode: 110011,
|
||||
};
|
||||
setLoader({ jobFields: { family: true } });
|
||||
} else if (values?.public !== "") {
|
||||
// for public input
|
||||
reqData = {
|
||||
...jobReq,
|
||||
duration: Number(values?.public),
|
||||
assign_mode: 110022,
|
||||
depend_uid: values?.depend_uid
|
||||
};
|
||||
setLoader({ jobFields: { public: true } });
|
||||
} else if (values?.individual !== "") {
|
||||
// for individual input
|
||||
reqData = {
|
||||
@@ -179,7 +178,6 @@ function JobListPopout({
|
||||
email: values?.individual,
|
||||
assign_mode: 110033,
|
||||
};
|
||||
setLoader({ jobFields: { individual: true } });
|
||||
} else if (values?.group !== "") {
|
||||
// for group input
|
||||
reqData = {
|
||||
@@ -190,8 +188,8 @@ function JobListPopout({
|
||||
duration: details?.timeline_days,
|
||||
// duration: 0,
|
||||
};
|
||||
setLoader({ jobFields: { group: true } });
|
||||
} else {
|
||||
setLoader({ jobFields: false });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,7 +201,7 @@ function JobListPopout({
|
||||
return setTimeout(() => {
|
||||
setLoader({ jobFields: false });
|
||||
setRequestStatus({ message: "", status: false });
|
||||
}, 3000);
|
||||
}, 5000);
|
||||
}
|
||||
marketUpdate('market', 'full-markets-jobs') // sends an event to the socket to update market lists
|
||||
dispatch(tableReload({ type: "JOBTABLE" })); // reloads my job page
|
||||
@@ -213,14 +211,14 @@ function JobListPopout({
|
||||
setLoader({ jobFields: false });
|
||||
onClose();
|
||||
// throw new Response(data);
|
||||
}, 3000);
|
||||
}, 5000);
|
||||
} catch (error) {
|
||||
setRequestStatus({ message: "Unable to complete", status: false });
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ message: "", status: false });
|
||||
setLoader({ jobFields: false });
|
||||
throw new Error(error);
|
||||
}, 3000);
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -355,142 +353,198 @@ function JobListPopout({
|
||||
))}
|
||||
</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>
|
||||
)}
|
||||
|
||||
{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>
|
||||
)}
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema.fields.public}
|
||||
onSubmit={jobFieldHandler}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="p-3">
|
||||
<div className='flex items-center justify-start mt-1 mb-2.5'>
|
||||
<label
|
||||
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={''}
|
||||
>
|
||||
{selectedTab == 'family' ?
|
||||
'Assign to family'
|
||||
: selectedTab == 'public' ?
|
||||
'Offer this job to public'
|
||||
: selectedTab == 'individual' ?
|
||||
'Offer this job to individual'
|
||||
: selectedTab == 'group' ?
|
||||
'Offer this job to your Group'
|
||||
:
|
||||
null
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
<div className='w-full'>
|
||||
{/* ASSIGN TO FAMILY */}
|
||||
{selectedTab == "family" && (
|
||||
<div className='hidden w-full'>
|
||||
<JobFieldInput
|
||||
select={true}
|
||||
inputName="family"
|
||||
value={props?.values.family}
|
||||
data={familyList}
|
||||
optionText="Select 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>{" "}
|
||||
</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>
|
||||
)}
|
||||
{/* ASSIGN TO PUBLIC/MARKET */}
|
||||
{selectedTab == "public" && (
|
||||
<div className='w-full'>
|
||||
<div className='mb-3 w-full flex flex-col xxs:flex-row items-center gap-1'>
|
||||
<label className='w-full xxs:max-w-[120px] xxs:text-right'>Depends on</label>
|
||||
{/* <JobFieldInput
|
||||
input={true}
|
||||
select={true}
|
||||
inputName="depend_uid"
|
||||
value={props?.values.depend_uid}
|
||||
data={myJobList}
|
||||
optionText="None"
|
||||
parentClass="w-full flex flex-col gap-4"
|
||||
/> */}
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-[1rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className='px-2 w-full h-full bg-white border-0 outline-0'
|
||||
name="depend_uid"
|
||||
value={props?.values.depend_uid}
|
||||
onChange={props.handleChange}
|
||||
>
|
||||
<>
|
||||
{myJobList.loading ? (
|
||||
<option value={""}>Loading...</option>
|
||||
) : myJobList?.data?.result_list?.length > 0 ? (
|
||||
<>
|
||||
<option value="">None</option>
|
||||
{myJobList?.data?.result_list?.filter(item => item.job_uid != details.job_uid)?.map((item, index) => (
|
||||
<option value={item?.job_uid} key={item.job_uid}>
|
||||
{item?.title}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option value="">No Job Found</option>
|
||||
)}
|
||||
</>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mb-3 w-full flex flex-col xxs:flex-row items-center gap-1'>
|
||||
<label className='w-full xxs:max-w-[120px] xxs:text-right'>Duration <span className='text-red-600 tracking-wide'>{(props?.values.public === "" && errMsg?.jobFields?.public) && '*'}</span></label>
|
||||
<div className='w-full'>
|
||||
<JobFieldInput
|
||||
select={true}
|
||||
inputName="public"
|
||||
value={props?.values.public}
|
||||
data={publicArray}
|
||||
optionText="Select Duration"
|
||||
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>{" "} */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* { 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>
|
||||
)}
|
||||
{/* ASSIGN TO INDIVIDUAL */}
|
||||
{selectedTab == "individual" && (
|
||||
<div className='w-full'>
|
||||
<JobFieldInput
|
||||
input={true}
|
||||
inputName="individual"
|
||||
value={props?.values.individual}
|
||||
placeholder="Enter email of individual"
|
||||
inputHandler={props?.handleChange}
|
||||
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>{" "}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* ASSIGN TO GROUP */}
|
||||
{selectedTab == "group" && (
|
||||
<div className='w-full'>
|
||||
<JobFieldInput
|
||||
select={true}
|
||||
inputName="group"
|
||||
value={props?.values.group}
|
||||
optionText="Select Group"
|
||||
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>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-3 mb-1 flex justify-end items-center">
|
||||
<button
|
||||
className={`px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
|
||||
type="submit"
|
||||
name={
|
||||
selectedTab == 'family' ?
|
||||
'family'
|
||||
: selectedTab == 'public' ?
|
||||
'public'
|
||||
: selectedTab == 'individual' ?
|
||||
'individual'
|
||||
: selectedTab == 'group' ?
|
||||
'group'
|
||||
:
|
||||
null
|
||||
}
|
||||
onClick={errorHandler}
|
||||
// disabled={!value}
|
||||
>
|
||||
{loader?.jobFields ?
|
||||
<LoadingSpinner size={5} />
|
||||
: selectedTab == 'family' ?
|
||||
'Assign to family'
|
||||
: selectedTab == 'public' ?
|
||||
'Show Task to Public'
|
||||
: selectedTab == 'individual' ?
|
||||
'Send Offer to Individual'
|
||||
: selectedTab == 'group' ?
|
||||
'Send Order to Group'
|
||||
:
|
||||
null
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
<p
|
||||
className={`text-center w-full text-lg ${
|
||||
requestStatus.status
|
||||
@@ -530,30 +584,15 @@ const JobFieldInput = ({
|
||||
select,
|
||||
label,
|
||||
labelClass,
|
||||
btnText,
|
||||
parentClass,
|
||||
optionText,
|
||||
errorHandler,
|
||||
loader,
|
||||
data,
|
||||
}) => {
|
||||
return (
|
||||
<div className="field w-full h-full px-3 pt-5 pb-3 flex flex-col justify-between gap-4">
|
||||
<div className="field w-full flex flex-col justify-between gap-4">
|
||||
{select && (
|
||||
<>
|
||||
<div className={`input-com ${parentClass}`}>
|
||||
<div
|
||||
className={`flex items-center justify-start mb-2.5 ${labelClass}`}
|
||||
>
|
||||
{label && (
|
||||
<label
|
||||
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}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-[1rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base ${inputClass}`}
|
||||
>
|
||||
@@ -616,8 +655,6 @@ const JobFieldInput = ({
|
||||
{input && (
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label={label}
|
||||
labelClass="tracking-wide border-2 w-full border-sky-700 py-4 px-2"
|
||||
type="email"
|
||||
name={inputName}
|
||||
placeholder={placeholder}
|
||||
@@ -627,25 +664,6 @@ const JobFieldInput = ({
|
||||
parentClass={`${parentClass}`}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* btn */}
|
||||
<div className="my-1 flex justify-end items-center">
|
||||
<button
|
||||
type="submit"
|
||||
name={inputName}
|
||||
onClick={errorHandler}
|
||||
// className={`px-2 py-1 text-sm text-white btn-gradient tracking-wide rounded-md ${
|
||||
// !value && "disabled:grayscale-[65%] transition duration-300"
|
||||
// }`}
|
||||
className={`px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white ${
|
||||
!value && ""
|
||||
}
|
||||
`}
|
||||
// disabled={!value}
|
||||
>
|
||||
{loader ? <LoadingSpinner size={5} /> : btnText}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,472 @@
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import * as Yup from "yup";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
import InputCom from "../Helpers/Inputs/InputCom/index";
|
||||
import ModalCom from "../Helpers/ModalCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import Detail from "./popoutcomponent/Detail";
|
||||
import { SocketValues } from "../Contexts/SocketIOContext";
|
||||
import JobFieldInput from "./popoutcomponent/JobFieldInput";
|
||||
import AssignToFamily from "./popoutcomponent/AssignToFamily";
|
||||
import AssignToIndividual from "./popoutcomponent/AssignToIndividual";
|
||||
import AssignToPublic from "./popoutcomponent/AssignToPublic";
|
||||
import AssignToGroup from "./popoutcomponent/AssignToGroup";
|
||||
|
||||
function NewJobListPopout({
|
||||
details,
|
||||
onClose,
|
||||
situation,
|
||||
openWallet,
|
||||
setWalletItem,
|
||||
myJobList
|
||||
}) {
|
||||
|
||||
let {marketUpdate} = SocketValues() // destructures 'SEND MESSAGE' and 'JOIN ROOM' FUNCTIONS FROM SOCKET
|
||||
|
||||
const [selectedTab, setSelectedTab] = useState("public");
|
||||
const tabs = ["public", "individual", "group"];
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [requestStatus, setRequestStatus] = useState({
|
||||
message: "",
|
||||
status: false,
|
||||
});
|
||||
|
||||
const [familyList, setFamilyList] = useState([]);
|
||||
let [loader, setLoader] = useState({
|
||||
member: false,
|
||||
jobFields: false
|
||||
});
|
||||
|
||||
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 () => {
|
||||
setLoader({ member: true, jobFields: false });
|
||||
try {
|
||||
let res = await apiCall.familyListings();
|
||||
const { data } = res;
|
||||
if (data?.internal_return >= 0 && data?.status == "OK") {
|
||||
let { result_list } = data;
|
||||
setFamilyList(result_list);
|
||||
setLoader({ member: false, jobFields: false });
|
||||
} else return;
|
||||
} catch (error) {
|
||||
setLoader({ member: false, jobFields: false });
|
||||
throw new Error(error);
|
||||
}
|
||||
}, [apiCall]);
|
||||
|
||||
useEffect(() => {
|
||||
memberList();
|
||||
}, [memberList]);
|
||||
|
||||
let [textArea, setTextArea] = useState(details?.job_detail);
|
||||
const [errMsg, setErrMsg] = useState({
|
||||
deliveryDetail: "",
|
||||
jobFields: {
|
||||
family: "",
|
||||
public: "",
|
||||
individual: "",
|
||||
group: "",
|
||||
},
|
||||
});
|
||||
|
||||
const handleInputChange = ({ target: { value } }) => {
|
||||
setTextArea(value);
|
||||
};
|
||||
|
||||
const errorHandler = ({ target: { name } }) => {
|
||||
try {
|
||||
if (name === "family")
|
||||
setErrMsg({ jobFields: { family: "please select a family member" } });
|
||||
else if (name === "public")
|
||||
setErrMsg({ jobFields: { public: "please select duration" } });
|
||||
else if (name === "individual")
|
||||
setErrMsg({ jobFields: { individual: "please enter email" } });
|
||||
else if (name === "group")
|
||||
setErrMsg({ jobFields: { group: "please select a group" } });
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
setErrMsg({ jobFields: "" });
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
const jobFieldHandler = async (values, helpers) => {
|
||||
setLoader({ jobFields: true });
|
||||
let { job_id, job_uid } = details;
|
||||
|
||||
if (!textArea) {
|
||||
setErrMsg({ deliveryDetail: "delivery detail is required!" });
|
||||
return;
|
||||
}
|
||||
|
||||
let jobReq = {
|
||||
job_id,
|
||||
job_uid,
|
||||
job_description: textArea,
|
||||
};
|
||||
|
||||
let reqData;
|
||||
|
||||
// for family input
|
||||
if (values?.family) {
|
||||
reqData = {
|
||||
...jobReq,
|
||||
family_uid: values?.family,
|
||||
assign_mode: 110011,
|
||||
};
|
||||
} else if (values?.public) {
|
||||
// for public input
|
||||
reqData = {
|
||||
...jobReq,
|
||||
duration: Number(values?.public),
|
||||
assign_mode: 110022,
|
||||
depend_uid: values?.depend_uid,
|
||||
strict_timeline: values?.timeline,
|
||||
};
|
||||
} else if (values?.individual) {
|
||||
// for individual input
|
||||
reqData = {
|
||||
...jobReq,
|
||||
email: values?.individual,
|
||||
assign_mode: 110033,
|
||||
};
|
||||
} else if (values?.group) {
|
||||
// for group input
|
||||
reqData = {
|
||||
...jobReq,
|
||||
email: "",
|
||||
group_id: values?.group,
|
||||
assign_mode: 110044,
|
||||
duration: details?.timeline_days,
|
||||
// duration: 0,
|
||||
};
|
||||
} else {
|
||||
setLoader({ jobFields: false });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await apiCall.assignJobTask(reqData);
|
||||
let { status, data } = await res;
|
||||
if (status != 200 || data.internal_return < 0) {
|
||||
setRequestStatus({ message: data?.status ? data?.status : "Unable to assign offer", status: false });
|
||||
return setTimeout(() => {
|
||||
setLoader({ jobFields: false });
|
||||
setRequestStatus({ message: "", status: false });
|
||||
}, 5000);
|
||||
}
|
||||
marketUpdate('market', 'full-markets-jobs') // sends an event to the socket to update market lists
|
||||
dispatch(tableReload({ type: "JOBTABLE" })); // reloads my job page
|
||||
dispatch(tableReload({ type: "MARKETTABLELIST" })); // reloads market page
|
||||
setRequestStatus({ message: data?.status_msg ? data?.status_msg : "Offer Assigned Successful", status: true });
|
||||
setTimeout(() => {
|
||||
setLoader({ jobFields: false });
|
||||
onClose();
|
||||
// throw new Response(data);
|
||||
}, 5000);
|
||||
} catch (error) {
|
||||
setRequestStatus({ message: "Unable to complete", status: false });
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ message: "", status: false });
|
||||
setLoader({ jobFields: false });
|
||||
throw new Error(error);
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
const [groupList, setGroupList] = useState({
|
||||
loading: true,
|
||||
groups: [],
|
||||
members: [],
|
||||
});
|
||||
|
||||
const DetailsSection = ({ label, value }) => (
|
||||
<div className="my-3 md:flex">
|
||||
<Detail label={label} value={value} />
|
||||
</div>
|
||||
);
|
||||
|
||||
// FUNCTION TO POPULATE USER GROUP LIST
|
||||
useEffect(() => {
|
||||
// setGroupList({loading: true, groups: [], members: []})
|
||||
apiCall
|
||||
.jobGroupList({})
|
||||
.then((res) => {
|
||||
const { status, data } = res;
|
||||
if (status != 200 || data?.internal_return < 0) {
|
||||
setGroupList({ loading: false, groups: [], members: [] });
|
||||
return;
|
||||
}
|
||||
if (data.result_list.length < 0) {
|
||||
setGroupList({ loading: false, groups: [], members: [] });
|
||||
return;
|
||||
}
|
||||
setGroupList({
|
||||
loading: false,
|
||||
groups: data.result_list,
|
||||
members: data.result_list_member,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
setGroupList({ loading: false, groups: [], members: [] });
|
||||
});
|
||||
}, []);
|
||||
|
||||
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 h-full md:border-r-2 flex flex-col justify-between">
|
||||
{/* <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">
|
||||
<div className="modal-header-con">
|
||||
<h1 className="modal-title">
|
||||
{details.title}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="modal-close-btn"
|
||||
onClick={onClose}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="md:grid grid-cols-2 bg-white dark:bg-dark-white rounded-lg shadow-lg">
|
||||
<DetailsComponent />
|
||||
<>
|
||||
{/* ACTION SECTION */}
|
||||
{+taskWalletSelector.amount > +details.price ? (
|
||||
<div className="px-4 pb-3 w-full flex flex-col justify-between h-auto md:min-h-[450px]">
|
||||
<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="p-3 grow flex flex-col bg-red-50 dark:bg-[#D85A5A] rounded-b-2xl">
|
||||
<div className='flex items-center justify-start mt-1 mb-2.5'>
|
||||
<label
|
||||
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={''}
|
||||
>
|
||||
{selectedTab == 'family' ?
|
||||
'Assign to family'
|
||||
: selectedTab == 'public' ?
|
||||
'Offer this job to public'
|
||||
: selectedTab == 'individual' ?
|
||||
'Offer this job to individual'
|
||||
: selectedTab == 'group' ?
|
||||
'Offer this job to your Group'
|
||||
:
|
||||
null
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{selectedTab == 'family' &&
|
||||
<AssignToFamily
|
||||
jobFieldHandler={jobFieldHandler}
|
||||
familyList={familyList}
|
||||
loader={loader}
|
||||
/>
|
||||
}
|
||||
|
||||
{selectedTab == 'individual' &&
|
||||
<AssignToIndividual
|
||||
jobFieldHandler={jobFieldHandler}
|
||||
familyList={familyList}
|
||||
loader={loader}
|
||||
/>
|
||||
}
|
||||
|
||||
{selectedTab == 'public' &&
|
||||
<AssignToPublic
|
||||
jobFieldHandler={jobFieldHandler}
|
||||
myJobList={myJobList}
|
||||
details={details}
|
||||
loader={loader}
|
||||
/>
|
||||
}
|
||||
|
||||
{selectedTab == 'group' &&
|
||||
<AssignToGroup
|
||||
jobFieldHandler={jobFieldHandler}
|
||||
groupList={groupList}
|
||||
loader={loader}
|
||||
/>
|
||||
}
|
||||
|
||||
<p
|
||||
className={`text-center w-full text-lg ${
|
||||
requestStatus.status
|
||||
? "text-emerald-600"
|
||||
: "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{requestStatus.message && requestStatus.message}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<ZeroBalanceChecker
|
||||
{...taskWalletSelector}
|
||||
openCreditPopup={openCreditPopup}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* END OF ACTION SECTION */}
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
</ModalCom>
|
||||
);
|
||||
}
|
||||
|
||||
export default NewJobListPopout;
|
||||
|
||||
const publicArray = [
|
||||
{ duration: 1, name: "1 day" },
|
||||
{ duration: 2, name: "2 days" },
|
||||
{ duration: 3, name: "3 days" },
|
||||
{ duration: 4, name: "4 days" },
|
||||
{ duration: 5, name: "5 days" },
|
||||
{ duration: 6, name: "6 days" },
|
||||
{ duration: 7, name: "1 week" },
|
||||
{ duration: 14, name: "2 weeks" },
|
||||
{ duration: 21, name: "3 weeks" },
|
||||
{ duration: 28, name: "4 weeks" },
|
||||
];
|
||||
|
||||
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>
|
||||
);
|
||||
@@ -0,0 +1,67 @@
|
||||
import React from 'react'
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import JobFieldInput from './JobFieldInput';
|
||||
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
family: Yup.string().required("This is required "),
|
||||
});
|
||||
|
||||
|
||||
let initialValues = {
|
||||
family: "",
|
||||
};
|
||||
|
||||
export default function AssignToFamily({
|
||||
jobFieldHandler,
|
||||
familyList,
|
||||
loader
|
||||
}) {
|
||||
return (
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={jobFieldHandler}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="w-full h-auto md:h-full flex flex-col justify-between">
|
||||
<div className='w-full'>
|
||||
<div className='hidden w-full'>
|
||||
<JobFieldInput
|
||||
select={true}
|
||||
inputName="family"
|
||||
value={props?.values.family}
|
||||
data={familyList}
|
||||
optionText="Select Family"
|
||||
parentClass="w-full flex flex-col gap-4"
|
||||
/>
|
||||
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||
{(props.errors.family && props.touched.family) && (
|
||||
<span>{props.errors.family}</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 mb-1 flex justify-end items-center">
|
||||
<button
|
||||
className={`px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
|
||||
type="submit"
|
||||
name='family'
|
||||
>
|
||||
{loader?.jobFields ?
|
||||
<LoadingSpinner size={5} />
|
||||
:
|
||||
'Assign to family'
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import React from 'react'
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import JobFieldInput from './JobFieldInput';
|
||||
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
group: Yup.string().required("This is required "),
|
||||
});
|
||||
|
||||
|
||||
let initialValues = {
|
||||
group: "",
|
||||
};
|
||||
|
||||
export default function AssignToGroup({
|
||||
jobFieldHandler,
|
||||
groupList,
|
||||
loader
|
||||
}) {
|
||||
return (
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={jobFieldHandler}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="w-full h-auto md:h-full flex flex-col justify-between">
|
||||
<div className='w-full'>
|
||||
<div className='w-full'>
|
||||
<JobFieldInput
|
||||
select={true}
|
||||
inputName="group"
|
||||
value={props?.values.group}
|
||||
optionText="Select Group"
|
||||
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.errors.group && props.touched.group) && (
|
||||
<span>{props.errors.group}</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 mb-1 flex justify-end items-center">
|
||||
<button
|
||||
className={`px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
|
||||
type="submit"
|
||||
name='group'
|
||||
>
|
||||
{loader?.jobFields ?
|
||||
<LoadingSpinner size={5} />
|
||||
:
|
||||
'Send Order to Group'
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import React from 'react'
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import JobFieldInput from './JobFieldInput';
|
||||
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
individual: Yup.string().required("This is required ")
|
||||
.email("Invalid email format")
|
||||
.matches(
|
||||
/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
|
||||
"Invalid email format"
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
let initialValues = {
|
||||
individual: "",
|
||||
};
|
||||
|
||||
export default function AssignToIndividual({
|
||||
jobFieldHandler,
|
||||
loader
|
||||
}) {
|
||||
return (
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={jobFieldHandler}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="w-full h-auto md:h-full flex flex-col justify-between">
|
||||
<div className='w-full'>
|
||||
<div className='w-full'>
|
||||
<JobFieldInput
|
||||
input={true}
|
||||
inputName="individual"
|
||||
value={props?.values.individual}
|
||||
placeholder="Enter email of individual"
|
||||
inputHandler={props?.handleChange}
|
||||
parentClass="w-full"
|
||||
labelClass="mb-0"
|
||||
/>
|
||||
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
|
||||
{(props.errors.individual && props.touched.individual) && (
|
||||
<span>{props.errors.individual}</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 mb-1 flex justify-end items-center">
|
||||
<button
|
||||
className={`px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
|
||||
type="submit"
|
||||
name='individual'
|
||||
>
|
||||
{loader?.jobFields ?
|
||||
<LoadingSpinner size={5} />
|
||||
:
|
||||
'Send Offer to Individual'
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import React, {useState} from 'react'
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import JobFieldInput from './JobFieldInput';
|
||||
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
public: Yup.string().required("This is required "),
|
||||
depend_uid: Yup.string(),
|
||||
timeline: Yup.string().required("This is required "),
|
||||
});
|
||||
|
||||
|
||||
let initialValues = {
|
||||
public: "",
|
||||
depend_uid: "",
|
||||
timeline: "0"
|
||||
};
|
||||
|
||||
export default function AssignToPublic({
|
||||
jobFieldHandler,
|
||||
myJobList,
|
||||
loader,
|
||||
details
|
||||
}) {
|
||||
|
||||
const [timeline, setTimeline] = useState('')
|
||||
console.log('timeline', timeline)
|
||||
return (
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={jobFieldHandler}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="w-full h-auto md:h-full flex flex-col justify-between">
|
||||
<div className='w-full'>
|
||||
<div className='mb-3 w-full flex flex-col xxs:flex-row items-center gap-1'>
|
||||
<label className='w-full xxs:max-w-[120px] xxs:text-right'>Depends on:</label>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-[1rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className='px-2 w-full h-full bg-white border-0 outline-0'
|
||||
name="depend_uid"
|
||||
value={props?.values.depend_uid}
|
||||
onChange={props.handleChange}
|
||||
>
|
||||
<>
|
||||
{myJobList.loading ? (
|
||||
<option value={""}>Loading...</option>
|
||||
) : myJobList?.data?.result_list?.length > 0 ? (
|
||||
<>
|
||||
<option value="">None</option>
|
||||
{myJobList?.data?.result_list?.filter(item => item.job_uid != details.job_uid)?.map((item, index) => (
|
||||
<option value={item?.job_uid} key={item.job_uid}>
|
||||
{item?.title}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option value="">No Job Found</option>
|
||||
)}
|
||||
</>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mb-3 w-full flex flex-col xxs:flex-row items-center gap-1'>
|
||||
<label className='w-full xxs:max-w-[120px] xxs:text-right'>Duration:</label>
|
||||
<div className='w-full'>
|
||||
<JobFieldInput
|
||||
select={true}
|
||||
inputName="public"
|
||||
value={props?.values.public}
|
||||
data={publicArray}
|
||||
optionText="Select Duration"
|
||||
parentClass="w-full flex flex-col gap-4"
|
||||
inputClass={(props.errors.public && props.touched.public) && 'border-red-500 dark:border-red-500'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mb-3 w-full flex flex-col xxs:flex-row items-center gap-1'>
|
||||
<label className='w-full xxs:max-w-[120px] xxs:text-right'>Timeline:</label>
|
||||
<div className='w-full'>
|
||||
<JobFieldInput
|
||||
select={true}
|
||||
inputName="timeline"
|
||||
value={props?.values.timeline}
|
||||
data={timelineArray}
|
||||
optionText="Select Timeline"
|
||||
parentClass="w-full flex flex-col gap-4"
|
||||
inputClass={(props.errors.timeline && props.touched.timeline) && 'border-red-500 dark:border-red-500'}
|
||||
// disabled={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 mb-1 flex justify-end items-center">
|
||||
<button
|
||||
className={`px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
|
||||
type="submit"
|
||||
name='public'
|
||||
>
|
||||
{loader?.jobFields ?
|
||||
<LoadingSpinner size={5} />
|
||||
:
|
||||
'Show Task to Public'
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const publicArray = [
|
||||
{ duration: 1, name: "1 day" },
|
||||
{ duration: 2, name: "2 days" },
|
||||
{ duration: 3, name: "3 days" },
|
||||
{ duration: 4, name: "4 days" },
|
||||
{ duration: 5, name: "5 days" },
|
||||
{ duration: 6, name: "6 days" },
|
||||
{ duration: 7, name: "1 week" },
|
||||
{ duration: 14, name: "2 weeks" },
|
||||
{ duration: 21, name: "3 weeks" },
|
||||
{ duration: 28, name: "4 weeks" },
|
||||
];
|
||||
|
||||
const timelineArray = [
|
||||
{ duration: "0", name: "Not Strict" },
|
||||
{ duration: "1", name: "Strict Timeline" },
|
||||
];
|
||||
@@ -0,0 +1,108 @@
|
||||
import React from 'react'
|
||||
import { Field } from "formik";
|
||||
import InputCom from '../../Helpers/Inputs/InputCom/index'
|
||||
|
||||
export default function JobFieldInput({
|
||||
value,
|
||||
inputHandler,
|
||||
inputName,
|
||||
inputClass,
|
||||
placeholder,
|
||||
input,
|
||||
select,
|
||||
label,
|
||||
labelClass,
|
||||
parentClass,
|
||||
optionText,
|
||||
data,
|
||||
disabled
|
||||
}) {
|
||||
return (
|
||||
<div className="field w-full flex flex-col justify-between gap-4">
|
||||
{select && (
|
||||
<>
|
||||
<div className={`input-com ${parentClass}`}>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-[1rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base ${inputClass}`}
|
||||
>
|
||||
<Field
|
||||
component="select"
|
||||
name={inputName}
|
||||
className={`options-default`}
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
>
|
||||
{/* <option value="">{optionText}</option> */}
|
||||
{(inputName == "family" || inputName == "public" || inputName == "timeline") &&
|
||||
Array.isArray(data) && (
|
||||
<>
|
||||
{inputName != "timeline" &&
|
||||
<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 == "timeline" && (
|
||||
<option value={item?.duration} key={idx}>
|
||||
{item?.name}
|
||||
</option>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
{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>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{input && (
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
type="email"
|
||||
name={inputName}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
inputHandler={inputHandler}
|
||||
inputBg="bg-white"
|
||||
parentClass={`${parentClass}`}
|
||||
disable={disabled}
|
||||
labelClass={labelClass}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -183,6 +183,7 @@ export const apiConst = {
|
||||
WRENCHBOARD_JOB_EXTEND_EXPIRE: 13041,
|
||||
WRENCHBOARD_JOB_RESEND_MESSAGE: 13042,
|
||||
WRENCHBOARD_JOB_CANCEL_OFFER: 13043,
|
||||
WRENCHBOARD_VERIFY_COMPLETED_TASK: 13033,
|
||||
|
||||
WRENCHBOARD_JOB_JOBGROUPS: 13045,
|
||||
WRENCHBOARD_JOB_JOBGROUPADD: 13046,
|
||||
|
||||
@@ -32,7 +32,7 @@ class usersService {
|
||||
}
|
||||
|
||||
blogData() {
|
||||
return this.getAuxEnd("/blogdata", null);
|
||||
return this.getAuxEnd("/blogdata", {});
|
||||
}
|
||||
|
||||
CompleteOauthLogin(reqData) {
|
||||
@@ -130,7 +130,7 @@ class usersService {
|
||||
}
|
||||
getApiGate() {
|
||||
// localStorage.setItem("session_token", ``);
|
||||
return this.postAuxEnd("/apigate", null);
|
||||
return this.postAuxEnd("/apigate", {});
|
||||
}
|
||||
|
||||
getLoadProfile() {
|
||||
@@ -141,7 +141,7 @@ class usersService {
|
||||
page: 0,
|
||||
limit: 100,
|
||||
};
|
||||
return this.postAuxEnd("/loadprofile", null);
|
||||
return this.postAuxEnd("/loadprofile", {});
|
||||
}
|
||||
|
||||
getUploadedList() {
|
||||
@@ -791,7 +791,7 @@ class usersService {
|
||||
|
||||
// Country Data {GET}
|
||||
getSignupCountryData() {
|
||||
return this.postAuxEnd("/signupcountry", null);
|
||||
return this.postAuxEnd("/signupcountry", {});
|
||||
}
|
||||
|
||||
// END POINT TO GET BANK NAME
|
||||
@@ -1481,6 +1481,18 @@ class usersService {
|
||||
return this.postAuxEnd("/jobmanagerfiles", postData);
|
||||
}
|
||||
|
||||
// API FUNCTION FOR GETTING LIST OF VERIFY COMPLETED TASK
|
||||
getVerifyCompletedTask(reqData) {
|
||||
var postData = {
|
||||
member_uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: apiConst.WRENCHBOARD_VERIFY_COMPLETED_TASK,
|
||||
...reqData
|
||||
};
|
||||
return this.postAuxEnd("/verifycompleted", postData);
|
||||
}
|
||||
|
||||
/*
|
||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
|
||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
|
||||
@@ -1529,7 +1541,7 @@ class usersService {
|
||||
*/
|
||||
|
||||
getUserReminders() {
|
||||
return this.getAuxEnd("/reminders", null);
|
||||
return this.getAuxEnd("/reminders", {});
|
||||
}
|
||||
//---------------------------------------- -----
|
||||
//---------------------------------------- -----
|
||||
@@ -1588,6 +1600,9 @@ class usersService {
|
||||
// Axios.defaults.headers.post['Access-Control-Allow-Origin'] = '*'; //,axiosConfig
|
||||
// Axios.defaults.withCredentials = true;
|
||||
//debugger;
|
||||
if(localStorage && localStorage.getItem('myloc')){
|
||||
reqData.loc = localStorage.getItem('myloc')
|
||||
}
|
||||
return Axios.post(endPoint, reqData)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
|
||||
Reference in New Issue
Block a user