Compare commits

...

9 Commits

15 changed files with 149 additions and 145 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="1200" height="1227" viewBox="0 0 1200 1227" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 430 B

+3 -26
View File
@@ -1,9 +1,7 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
import usersService from "../../services/UsersService";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import { useEffect, useState } from "react";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
export default function AvailableJobsCard({
className,
@@ -156,27 +154,6 @@ export default function AvailableJobsCard({
</p>
</div>
{/* <div className="card-two-info flex gap-2 items-center">
<div className="owned-by flex space-x-2 items-center">
<div>
<p className="text-thin-light-gray text-sm leading-3">Added</p>
<p className="text-base text-dark-gray dark:text-white">
{datas.offer_added}
</p>
</div>
</div>
<div className="w-[1px] bg-light-purple dark:bg-dark-light-purple h-7"></div>
<div className="created-by flex space-x-2 items-center flex-row-reverse">
<div>
<p className="text-thin-light-gray text-sm leading-3 text-right">
Expires
</p>
<p className="text-base text-dark-gray dark:text-white text-right">
{datas.expire}
</p>
</div>
</div>
</div> */}
<div className="block sm:flex flex-wrap gap-4">
<p className="text-sm text-thin-light-gray flex flext-start gap-1">
Price: <span className="text-purple">{thePrice}</span>
@@ -197,7 +197,7 @@ const AssignTaskPopout = React.memo(({ action, details, situation, familyDetail
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Assign task to {familyDetails?.firstname || details.firstName}
Assign task to {familyDetails?.firstname || details?.firstName}
</h1>
<button
type="button"
@@ -263,7 +263,7 @@ const AssignTaskPopout = React.memo(({ action, details, situation, familyDetail
</div>
{/* Task Type === select */}
{taskType == "select" && (
<div className="p-4 w-full h-[400px] overflow-y-auto bg-slate-100">
<div className="p-4 w-full h-[400px] overflow-y-auto bg-slate-100 rounded-md dark:bg-[#11131f] dark:text-white">
{familyTask?.data?.length ? (
familyTask?.data?.map((item, index) => (
<div
@@ -283,7 +283,7 @@ const AssignTaskPopout = React.memo(({ action, details, situation, familyDetail
}
className="w-[15px] h-[15px] cursor-pointer"
/>
<p className="w-full text-dark-gray tracking-wide">
<p className="w-full text-dark-gray dark:text-white tracking-wide">
{item?.title}
</p>
</div>
@@ -354,7 +354,7 @@ const AssignTaskPopout = React.memo(({ action, details, situation, familyDetail
Delivery Detail
</label>
<textarea
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
className={`p-1 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
rows="5"
style={{ resize: "none" }}
value={activeTask?.data?.job_detail}
@@ -1,7 +1,10 @@
import { forwardRef } from "react";
import QRCode from "react-qr-code";
import { useSelector } from "react-redux";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint, loader }, ref) => {
const { userDetails } = useSelector((state) => state.userDetails);
return (
<div
className="w-full lg:min-h-[538px] p-3 h-full flex flex-col items-center justify-center"
@@ -32,12 +35,19 @@ const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
Scan the code from mobile app
</p>
{loader ?
<div className="w-full">
<LoadingSpinner size='8' color='sky-blue' />
</div>
:
<QRCode
size={256}
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
value={`https://www.google.com`}
// value={`https://www.google.com`}
value={`${userDetails?.uid}@${familyData?.username}@${familyData?.pin}`}
viewBox={`0 0 256 256`}
/>
}
</div>
</div>
<div className="h-[50px] w-full flex justify-center items-center">
@@ -92,8 +92,8 @@ export default function InputCom({
value={value}
onChange={inputHandler}
className={`input-field placeholder:text-base text-dark-gray w-full h-full ${
inputBg ? inputBg : "bg-[#FAFAFA] tracking-wide"
} dark:bg-[#11131F] focus:ring-0 focus:outline-none ${fieldClass}`}
inputBg ? inputBg : "bg-[#FAFAFA] dark:bg-[#11131F] tracking-wide"
} focus:ring-0 focus:outline-none ${fieldClass}`}
type={type}
id={name}
name={name}
+4 -1
View File
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react";
import dataImage1 from "../../assets/images/data-table-user-1.png";
import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner";
export default function HomeActivities({ className }) {
const [recentActivitiesData, setRecentActivitiesData] = useState({
@@ -78,7 +79,9 @@ export default function HomeActivities({ className }) {
{/*</tr>*/}
{recentActivitiesData.loading ? (
<></>
<div className="h-[100px] w-full flex justify-center items-center">
<LoadingSpinner color="sky-blue" size="16" />
</div>
) : recentActivitiesData.data ? (
recentActivitiesData.data?.map((item) => {
let addedDate = item?.added?.split(" ")[0];
+3 -3
View File
@@ -1,8 +1,8 @@
import React, { useEffect, useMemo, useState } from "react";
import DataIteration from "../Helpers/DataIteration";
import AvailableJobsCard from "../Cards/AvailableJobsCard";
import ListView from "../../assets/images/list-view.png";
import GridView from "../../assets/images/grid-view.svg";
import ListView from "../../assets/images/list-view.png";
import AvailableJobsCard from "../Cards/AvailableJobsCard";
import DataIteration from "../Helpers/DataIteration";
import SelectBox from "../Helpers/SelectBox";
export default function MainSection({
@@ -125,10 +125,10 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
<CloseIcon onClose={onClose} />
</div>
<div className="md:flex bg-white rounded-lg">
<div className="md:flex bg-white dark:bg-dark-white text-slate-900 dark:text-white rounded-lg">
<div className="p-4 w-full md:w-[75%] md:border-r-1">
<div className="min-h-[263px]">
<h2 className="font-semibold text-slate-900 dark:text-black tracking-wide">
<h2 className="font-semibold text-slate-900 dark:text-white tracking-wide">
{details?.title}
</h2>
@@ -152,11 +152,11 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
},
].map(({ name, content, danger }, idx) => (
<div className={`my-3 md:flex items-center`} key={idx}>
<label className="w-full md:w-[19%] text-slate-900 tracking-wide font-semibold whitespace-pre-wrap">
<label className="w-full md:w-[19%] tracking-wide font-semibold whitespace-pre-wrap">
{name}
</label>
<div
className={`w-full md:w-3/4 text-slate-900 market-pop ${
className={`w-full md:w-3/4 text-slate-900 dark:text-white market-pop ${
name !== "Delivery Detail"
? " h-full max-h-28 flex items-center"
: " overflow-y-auto max-h-[100px]"
@@ -164,20 +164,20 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
>
{danger ? (
<p
className={``}
className={`dark:text-white`}
dangerouslySetInnerHTML={{
__html: danger && content,
}}
/>
) : (
<p className={`w-full text-slate-900`}>
<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 items-center gap-2">
<span className="flex items-center gap-2 dark:text-white">
{content?.text}
<strong>{thePrice}</strong>
</span>
@@ -197,11 +197,11 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
<hr />
<div className="my-3 w-full flex flex-col gap-3">
<div className="w-full">
<label className="w-full text-slate-900 tracking-wide">
<label className="w-full text-slate-900 dark:text-white tracking-wide">
If you have any questions about this task:
</label>
<textarea
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
className={`p-1 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
rows="5"
style={{ resize: "none" }}
placeholder="Enter message here ..."
@@ -226,7 +226,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
</div>
<div className="w-full md:w-[23%] h-full ">
<div className="mx-auto bg-[#f1f8ff] p-4 rounded-md md:min-h-[498px] flex flex-col justify-between">
<div className="mx-auto bg-[#f1f8ff] dark:bg-[#C2C8D3] p-4 rounded-md md:min-h-[498px] flex flex-col justify-between">
<div className="w-full flex flex-col justify-center py-4 gap-2">
<p className="w-full text-slate-900 tracking-wide my-1">
Interested in the task?
@@ -261,7 +261,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
</>
</div>
<div className="">
<div className="text-slate-900">
<p className="flex items-center tracking-wide">
Interest: <b className="ml-1">{details.interest_count}</b>
</p>
+4 -4
View File
@@ -1,7 +1,7 @@
import Layout from "../Partials/Layout";
import MainSection from "./MainSection";
import CommonHead from "../UserHeader/CommonHead";
import { useSelector } from "react-redux";
import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead";
import MainSection from "./MainSection";
export default function MarketPlace({ commonHeadData }) {
let { jobLists } = useSelector((state) => state.jobLists);
@@ -20,4 +20,4 @@ export default function MarketPlace({ commonHeadData }) {
</Layout>
</>
);
}
}
@@ -33,11 +33,6 @@ export default function MyPendingJobTable({ MyJobList, className }) {
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{/*<tr className="text-base text-thin-light-gray border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
{/* <td className="py-4">All Product</td>*/}
{/* <td className="py-4 text-right">.</td>*/}
{/*</tr>*/}
{
<>
{MyJobList &&
+14 -11
View File
@@ -1,11 +1,11 @@
import { Field, Form, Formik } from "formik";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import Detail from "./popoutcomponent/Detail";
import ModalCom from "../Helpers/ModalCom";
import InputCom from "../Helpers/Inputs/InputCom/index";
import SiteService from "../../services/SiteService";
import { Form, Formik, Field } from "formik";
import * as Yup from "yup";
import SiteService from "../../services/SiteService";
import InputCom from "../Helpers/Inputs/InputCom/index";
import ModalCom from "../Helpers/ModalCom";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import Detail from "./popoutcomponent/Detail";
const validationSchema = Yup.object().shape({
family: Yup.string().required("This is required "),
@@ -202,7 +202,7 @@ function JobListPopout({ details, onClose, situation }) {
</svg>
</button>
</div>
<div className="md:flex bg-white rounded-lg shadow-lg">
<div className="md:flex bg-white dark:bg-dark-white rounded-lg shadow-lg">
<div className="p-4 w-full md:w-2/4 md:border-r-2">
{/* <p className='text-lg font-semibold text-slate-900 tracking-wide'>{details.title}</p> */}
@@ -230,11 +230,11 @@ function JobListPopout({ details, onClose, situation }) {
</div>
<div className="my-3">
<label className="w-full text-slate-900 tracking-wide font-semibold">
<label className="w-full text-slate-900 dark:text-white tracking-wide font-semibold">
Delivery Detail
</label>
<textarea
className={`p-1 w-full text-sm text-slate-900 outline-none border border-slate-300 rounded-md`}
className={`p-1 w-full text-sm text-slate-900 dark:text-white bg-transparent outline-none border border-slate-300 rounded-md`}
rows="5"
style={{ resize: "none" }}
value={textArea}
@@ -322,7 +322,7 @@ function JobListPopout({ details, onClose, situation }) {
input={true}
inputName="individual"
value={props?.values.individual}
placeholder="enter email of individual"
placeholder="Enter email of individual"
inputHandler={props?.handleChange}
btnText="Send Offer to Individual"
loader={loader?.jobFields.individual}
@@ -396,7 +396,7 @@ const JobFieldInput = ({
data,
}) => {
return (
<div className="field w-full p-3 mb-2 bg-red-50 rounded-md">
<div className="field w-full p-3 mb-2 bg-red-50 dark:bg-[#D85A5A] rounded-md">
{select && (
<>
<div className={`input-com ${parentClass}`}>
@@ -468,7 +468,10 @@ const JobFieldInput = ({
type="submit"
name={inputName}
onClick={errorHandler}
className="px-2 py-1 text-sm text-white btn-gradient tracking-wide rounded-md"
className={`px-2 py-1 text-sm text-white btn-gradient tracking-wide rounded-md ${
!value && "disabled:grayscale-[65%] transition duration-300"
}`}
disabled={!value}
>
{loader ? <LoadingSpinner size={5} /> : btnText}
</button>
+89 -75
View File
@@ -1,11 +1,11 @@
import React, { useMemo, useState } from "react";
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import usersService from "../../services/UsersService";
import ModalCom from "../Helpers/ModalCom";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import Detail from "./popoutcomponent/Detail";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads";
@@ -18,85 +18,95 @@ const showSuccessToast = (message) => {
};
function PendingJobsPopout({ details, onClose, situation }) {
const dispatch = useDispatch()
const navigate = useNavigate()
const dispatch = useDispatch();
const navigate = useNavigate();
const [pendingJobLoader, setPendingJobLoader] = useState({
extend: false,
offer: false,
});
let [requestMessage, setRequestMessage] = useState({status: false, message: ''})
let [requestMessage, setRequestMessage] = useState({
status: false,
message: "",
});
const apiCall = new usersService();
const handlePendingJobsBtn = ({ target: { name } }) => {
let { job_uid, offer_code } = details;
let { job_uid, offer_code } = details;
let reqData;
let reqData;
let pendingData = { job_uid, offer_code };
if(name=='extend'){ // RUNS THIS TO EXTEND JOB EXPIRY BY ONE WEEK
reqData = { ...pendingData };
setPendingJobLoader({ extend: true });
apiCall.pendingJobExtend(reqData).then(res => {
setRequestMessage({status: true, message: res.data.status})
let pendingData = { job_uid, offer_code };
if (name == "extend") {
// RUNS THIS TO EXTEND JOB EXPIRY BY ONE WEEK
reqData = { ...pendingData };
setPendingJobLoader({ extend: true });
apiCall
.pendingJobExtend(reqData)
.then((res) => {
setRequestMessage({ status: true, message: res.data.status });
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
setRequestMessage({ status: false, message: "" });
onClose();
dispatch(tableReload({ type: "PENDINGTABLE" }));
}, 4000);
}).catch(error => {
setRequestMessage({status: false, message:'Try Again'})
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
}, 3000);
})
}else if(name=='offer'){ // RUNS THIS IF JOB IS SENT TO USER
reqData = { ...pendingData };
setPendingJobLoader({ offer: true });
apiCall.pendingJobSendTome(reqData).then(res => {
setRequestMessage({status: true, message: res.data.status})
.catch((error) => {
setRequestMessage({ status: false, message: "Try Again" });
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
setRequestMessage({ status: false, message: "" });
}, 3000);
});
} else if (name == "offer") {
// RUNS THIS IF JOB IS SENT TO USER
reqData = { ...pendingData };
setPendingJobLoader({ offer: true });
apiCall
.pendingJobSendTome(reqData)
.then((res) => {
setRequestMessage({ status: true, message: res.data.status });
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({ status: false, message: "" });
}, 4000);
}).catch(error => {
setRequestMessage('Try Again')
})
.catch((error) => {
setRequestMessage("Try Again");
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
setRequestMessage({ status: false, message: "" });
}, 3000);
})
} else return
// try {
// if (name === "extend") {
// setPendingJobLoader({ extend: true });
// reqData = { ...pendingData };
// // let { data } =
// await apiCall.pendingJobExtend(reqData);
// showSuccessToast("Job has been extended by a week!");
// dispatch(tableReload({ type: "PENDINGTABLE" }));
// } else if (name === "offer") {
// setPendingJobLoader({ offer: true });
// reqData = { ...pendingData };
// // let { data } =
// await apiCall.pendingJobSendTome(reqData);
// showSuccessToast("Offer sent, check your email");
// } else return;
});
} else return;
// try {
// if (name === "extend") {
// setPendingJobLoader({ extend: true });
// reqData = { ...pendingData };
// // let { data } =
// await apiCall.pendingJobExtend(reqData);
// showSuccessToast("Job has been extended by a week!");
// dispatch(tableReload({ type: "PENDINGTABLE" }));
// } else if (name === "offer") {
// setPendingJobLoader({ offer: true });
// reqData = { ...pendingData };
// // let { data } =
// await apiCall.pendingJobSendTome(reqData);
// showSuccessToast("Offer sent, check your email");
// } else return;
// setTimeout(() => {
// setPendingJobLoader({ extend: false, offer: false });
// onClose();
// }, 2700);
// } catch (error) {
// setPendingJobLoader({ extend: false, offer: false });
// throw new Error(error);
// }
}
// setTimeout(() => {
// setPendingJobLoader({ extend: false, offer: false });
// onClose();
// }, 2700);
// } catch (error) {
// setPendingJobLoader({ extend: false, offer: false });
// throw new Error(error);
// }
};
return (
<ModalCom action={onClose} situation={situation} className="edit-popup">
@@ -131,9 +141,9 @@ function PendingJobsPopout({ details, onClose, situation }) {
</svg>
</button>
</div>
<div className="md:flex bg-white rounded-lg shadow-lg">
<div className="md:flex bg-white dark:bg-dark-white rounded-lg shadow-lg">
<div className="p-4 w-full md:w-3/4 md:border-r-2">
<p className="text-base font-semibold text-slate-900 tracking-wide">
<p className="text-base font-semibold text-slate-900 dark:text-white tracking-wide">
{details.title}
</p>
<div className="my-2 p-2 flex justify-start items-center space-x-2 bg-red-100 border-2 border-red-300">
@@ -177,7 +187,11 @@ function PendingJobsPopout({ details, onClose, situation }) {
<Detail
label="Price"
// value={`${details.price * 0.01} ${details.currency}`}
value={PriceFormatter(details.price * 0.01, details?.currency_code, details.currency)}
value={PriceFormatter(
details.price * 0.01,
details?.currency_code,
details.currency
)}
/>
</div>
@@ -194,19 +208,11 @@ function PendingJobsPopout({ details, onClose, situation }) {
value={details.job_description || details.description}
/>
</div>
{/* <div className="my-2 md:flex">
<Detail
label="Public Link"
value="https://work.wrenchboard.com/plb/viewjob/218B4BWB83"
bg="bg-slate-200"
/>
</div> */}
</div>
{/* ACTION SECTION */}
<div className="p-4 w-full md:w-1/4 h-full">
<p className="mb-6 text-sm">Actions</p>
<p className="mb-6 text-sm dark:text-white">Actions</p>
<div className="mb-3">
<p className="px-2 py-1 text-sm bg-slate-100">
@@ -229,11 +235,15 @@ function PendingJobsPopout({ details, onClose, situation }) {
)}
</button>
</div>
{pendingJobLoader.extend && requestMessage.message &&
<div className={`p-1 ${requestMessage.status ? 'bg-green-500':'bg-red-500'} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
{pendingJobLoader.extend && requestMessage.message && (
<div
className={`p-1 ${
requestMessage.status ? "bg-green-500" : "bg-red-500"
} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
<p>{requestMessage.message}</p>
</div>
}
)}
<div className="my-3">
<button
@@ -251,11 +261,15 @@ function PendingJobsPopout({ details, onClose, situation }) {
</button>
</div>
{pendingJobLoader.offer && requestMessage.message &&
<div className={`p-1 ${requestMessage.status ? 'bg-green-500':'bg-red-500'} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
{pendingJobLoader.offer && requestMessage.message && (
<div
className={`p-1 ${
requestMessage.status ? "bg-green-500" : "bg-red-500"
} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
<p>{requestMessage.message}</p>
</div>
}
)}
<div className="mt-10 md:mt-32 md:flex md:justify-center">
<button
@@ -284,4 +298,4 @@ function PendingJobsPopout({ details, onClose, situation }) {
);
}
export default PendingJobsPopout;
export default PendingJobsPopout;
-1
View File
@@ -1,5 +1,4 @@
import MarketPlace from "../components/MarketPlace";
import { useSelector } from "react-redux";
export default function MarketPlacePage() {