-
- {label && (
-
- {label}
-
- )}
-
@@ -616,8 +655,6 @@ const JobFieldInput = ({
{input && (
)}
-
- {/* btn */}
-
-
- {loader ? : btnText}
-
-
);
};
diff --git a/src/components/jobPopout/NewJobListPopout.jsx b/src/components/jobPopout/NewJobListPopout.jsx
new file mode 100644
index 0000000..dc22701
--- /dev/null
+++ b/src/components/jobPopout/NewJobListPopout.jsx
@@ -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 }) => (
+
+
+
+ );
+
+ // 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 (
+
+ {/*
{details.title}
*/}
+
+ {/* INPUT SECTION */}
+ {detailsArray.map((detail, index) => (
+
+ ))}
+
+
+
+ Delivery Detail
+
+
+
{errMsg.deliveryDetail}
+
+
+ );
+ };
+
+ return (
+
+
+
+
+ {details.title}
+
+
+
+
+
+
+
+
+
+
+
+ <>
+ {/* ACTION SECTION */}
+ {+taskWalletSelector.amount > +details.price ? (
+
+
+ Send this Task to:
+
+
+
+ {tabs.map((item) => (
+
+ ))}
+
+
+
+
+ {selectedTab == 'family' ?
+ 'Assign to family'
+ : selectedTab == 'public' ?
+ 'Place in Market'
+ : selectedTab == 'individual' ?
+ 'Assign to individual'
+ : selectedTab == 'group' ?
+ 'Preferred List'
+ :
+ null
+ }
+
+
+
+ {selectedTab == 'family' &&
+
+ }
+
+ {selectedTab == 'individual' &&
+
+ }
+
+ {selectedTab == 'public' &&
+
+ }
+
+ {selectedTab == 'group' &&
+
+ }
+
+
+ {requestStatus.message && requestStatus.message}
+
+
+
+
+ ) : (
+
+ )}
+
+ {/* END OF ACTION SECTION */}
+ >
+
+
+
+ );
+}
+
+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 (
+
+
+ Wallet Balance:{` ${code} ${(+amount * 0.01).toFixed(2)}`}
+
+
+ You do not have sufficient balance to assign this task
+
+
+ Add Credit to Wallet
+
+
+ );
+};
+
+const TabButton = ({ item, selectedTab, setSelectedTab }) => (
+
setSelectedTab(item)}
+ >
+
+ {item[0].toUpperCase() + item.slice(1)}
+
+);
diff --git a/src/components/jobPopout/popoutcomponent/AssignToFamily.jsx b/src/components/jobPopout/popoutcomponent/AssignToFamily.jsx
new file mode 100644
index 0000000..361104d
--- /dev/null
+++ b/src/components/jobPopout/popoutcomponent/AssignToFamily.jsx
@@ -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 (
+
+ {(props) => {
+ return (
+
+ );
+ }}
+
+ )
+}
diff --git a/src/components/jobPopout/popoutcomponent/AssignToGroup.jsx b/src/components/jobPopout/popoutcomponent/AssignToGroup.jsx
new file mode 100644
index 0000000..6530b69
--- /dev/null
+++ b/src/components/jobPopout/popoutcomponent/AssignToGroup.jsx
@@ -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 (
+
+ {(props) => {
+ return (
+
+ );
+ }}
+
+ )
+}
diff --git a/src/components/jobPopout/popoutcomponent/AssignToIndividual.jsx b/src/components/jobPopout/popoutcomponent/AssignToIndividual.jsx
new file mode 100644
index 0000000..fda6405
--- /dev/null
+++ b/src/components/jobPopout/popoutcomponent/AssignToIndividual.jsx
@@ -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 (
+
+ {(props) => {
+ return (
+
+ );
+ }}
+
+ )
+}
diff --git a/src/components/jobPopout/popoutcomponent/AssignToPublic.jsx b/src/components/jobPopout/popoutcomponent/AssignToPublic.jsx
new file mode 100644
index 0000000..574c0e0
--- /dev/null
+++ b/src/components/jobPopout/popoutcomponent/AssignToPublic.jsx
@@ -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 (
+
+ {(props) => {
+ return (
+
+ );
+ }}
+
+ )
+}
+
+
+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" },
+ ];
\ No newline at end of file
diff --git a/src/components/jobPopout/popoutcomponent/JobFieldInput.jsx b/src/components/jobPopout/popoutcomponent/JobFieldInput.jsx
new file mode 100644
index 0000000..b5bf527
--- /dev/null
+++ b/src/components/jobPopout/popoutcomponent/JobFieldInput.jsx
@@ -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 (
+
+ {select && (
+ <>
+
+
+
+ {/* {optionText} */}
+ {(inputName == "family" || inputName == "public" || inputName == "timeline") &&
+ Array.isArray(data) && (
+ <>
+ {inputName != "timeline" &&
+ {optionText}
+ }
+ {data?.map((item, idx) => (
+
+ {inputName === "family" &&
+ item?.last_login !== "" && (
+
+ {`${item?.firstname} ${item?.lastname}`}
+
+ )}
+ {inputName === "public" && (
+
+ {item?.name}
+
+ )}
+ {inputName == "timeline" && (
+
+ {item?.name}
+
+ )}
+
+ ))}
+ >
+ )}
+ {inputName == "group" && (
+ <>
+ {data.loading ? (
+ Loading...
+ ) : data?.groups?.length > 0 ? (
+ <>
+ {optionText}
+ {data?.groups?.map((item, index) => (
+
+ {`${item?.group_name} (${
+ item?.member_count == null
+ ? "0"
+ : ' ' + item.member_count + ' '
+ })`}
+
+ ))}
+ >
+ ) : (
+ No Group Found
+ )}
+ >
+ )}
+
+
+
+ >
+ )}
+
+ {input && (
+
+ )}
+
+ );
+}
diff --git a/src/lib/apiConst.js b/src/lib/apiConst.js
index bb779c0..60f717d 100644
--- a/src/lib/apiConst.js
+++ b/src/lib/apiConst.js
@@ -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,
@@ -277,5 +278,8 @@ export const apiConst = {
PAY_MODE_CCARD: 1,
PAY_MODE_BONUS: 9,
APPROVED_BALANCE: 5,
- DISAPROVE_BALANCE: 3
+ DISAPROVE_BALANCE: 3,
+
+ WRENCHBOARD_VERIFY_PROMO: 55056,
+ WRENCHBOARD_LOGIN_PROMO: 55057,
};
\ No newline at end of file
diff --git a/src/services/UsersService.js b/src/services/UsersService.js
index a708886..a3742a2 100644
--- a/src/services/UsersService.js
+++ b/src/services/UsersService.js
@@ -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() {
@@ -208,7 +208,7 @@ class usersService {
// }
getHeroJBanners() {
var postData = {
- uuid: localStorage.getItem("uid"),
+ uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page: 0,
@@ -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,36 @@ 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);
+ }
+
+ // API FUNCTION TO VERIFY PROMO LINK
+ verifyPromo(reqData) {
+ var postData = {
+ action: apiConst.WRENCHBOARD_VERIFY_PROMO,
+ ...reqData
+ };
+ return this.postAuxEnd("/promoverify", postData);
+ }
+
+ // API FUNCTION TO LOGIN USER THROUGH PROMO LINK
+ loginPromo(reqData) {
+ var postData = {
+ action: apiConst.WRENCHBOARD_LOGIN_PROMO,
+ ...reqData
+ };
+ return this.postAuxEnd("/loginpromo", postData);
+ }
+
/*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
@@ -1529,7 +1559,7 @@ class usersService {
*/
getUserReminders() {
- return this.getAuxEnd("/reminders", null);
+ return this.getAuxEnd("/reminders", {});
}
//---------------------------------------- -----
//---------------------------------------- -----
diff --git a/src/views/PromoPage.jsx b/src/views/PromoPage.jsx
new file mode 100644
index 0000000..55184c6
--- /dev/null
+++ b/src/views/PromoPage.jsx
@@ -0,0 +1,10 @@
+import React from 'react'
+import Promo from '../components/AuthPages/Promo/Promo'
+
+export default function PromoPage() {
+ return (
+ <>
+
+ >
+ )
+}