Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c99e416ea | |||
| fd531d7d10 | |||
| ac027a3228 | |||
| 001492eeb5 | |||
| 72fe2cad5f | |||
| eac693eba6 | |||
| d3b1462fe3 | |||
| 748546641d | |||
| 48a50fd47c | |||
| e87cb95b43 | |||
| 7638d68a7d | |||
| 3541363f9f | |||
| 30ce6a7d6e | |||
| 115366672a | |||
| 3cd8b6e574 | |||
| 9850cdd392 | |||
| 6d98141c39 | |||
| 5fe5ccbd4d | |||
| 76c0994eb0 | |||
| a1bc6db381 | |||
| 6f5d72e033 | |||
| 762de4c23e | |||
| 2a8b7ba6ec | |||
| 50e44dab43 | |||
| 7649a90c47 | |||
| 3c2c46e293 | |||
| 8dc634d900 | |||
| 3a9cb4667e | |||
| 5f4b032f68 | |||
| 8ab3e9ae50 | |||
| 01b5fba75b | |||
| 66b8c96592 | |||
| 616352e1ac | |||
| acc4417835 | |||
| 7da693f298 | |||
| b0423c665c | |||
| 2c2e2b0ca5 | |||
| ba3dd91d81 | |||
| 3f04c9f9f8 |
@@ -114,4 +114,7 @@ REACT_APP_SHOW_NEW_FAMILY_DASH=1
|
||||
REACT_APP_SHOW_ACCOUNT_DASH=1
|
||||
|
||||
# Displays the slider banners
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
|
||||
# FOR MEDIA LINK
|
||||
REACT_APP_MEDIA_LINK='https://dev-media.wrenchboard.com '
|
||||
+4
-1
@@ -82,4 +82,7 @@ REACT_APP_SHOW_NEW_FAMILY_DASH=1
|
||||
REACT_APP_SHOW_ACCOUNT_DASH=1
|
||||
|
||||
# Displays the slider banners
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
|
||||
# FOR MEDIA LINK
|
||||
REACT_APP_MEDIA_LINK='https://dev-media.wrenchboard.com '
|
||||
+4
-1
@@ -88,4 +88,7 @@ REACT_APP_SHOW_NEW_FAMILY_DASH=1
|
||||
REACT_APP_SHOW_ACCOUNT_DASH=1
|
||||
|
||||
# Displays the slider banners
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
|
||||
# FOR MEDIA LINK
|
||||
REACT_APP_MEDIA_LINK='https://media.wrenchboard.com '
|
||||
@@ -34,7 +34,7 @@ export default function SocketIOContextProvider({children}) {
|
||||
|
||||
const marketUpdate = (message, room) => {
|
||||
if(message && room){
|
||||
socket.emit("marketjob_addded", { message, room });
|
||||
socket.emit("marketjob_added", { message, room });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,6 +44,12 @@ export default function SocketIOContextProvider({children}) {
|
||||
}
|
||||
};
|
||||
|
||||
const sendJobInterestToOwner = (message, room) => {
|
||||
if(message && room){
|
||||
socket.emit("marketjob", { message:{...message}, room });
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
socket.on("receive_message", (data) => {
|
||||
// setSocketMsgReceived(data.message);
|
||||
@@ -70,6 +76,16 @@ export default function SocketIOContextProvider({children}) {
|
||||
}
|
||||
// console.log('DATA', data)
|
||||
});
|
||||
|
||||
socket.on("marketjob_actions", (data) => { // Triggers refresh on owner side, when somebody sends/shows interest in a job
|
||||
let user_uid = userDetails.account_type == 'FULL' ? userDetails.uid : sessionStorage.getItem('family_uid') // gets user UID
|
||||
let {message} = data
|
||||
if(message.action == "REFRESH_OFFERS" && message.audience == "MERCHANT" && message.market_uid == user_uid){ // for refreshing job owner offer interest list when any worker sends interest
|
||||
dispatch(tableReload({type:'OFFERINTERESTLISTRELOAD'}))
|
||||
}
|
||||
console.log('data', data)
|
||||
});
|
||||
|
||||
}, [socket]);
|
||||
|
||||
let values = {
|
||||
@@ -79,6 +95,7 @@ export default function SocketIOContextProvider({children}) {
|
||||
setSocketMsgReceived,
|
||||
marketUpdate,
|
||||
parentAssignJobToKid,
|
||||
sendJobInterestToOwner,
|
||||
socketMsgReceived,
|
||||
// room,
|
||||
// setRoom,
|
||||
|
||||
@@ -29,14 +29,15 @@ const AccountDashboard = ({ className, bannerList }) => {
|
||||
props;
|
||||
|
||||
return (
|
||||
<TopBanner
|
||||
btn={short_button_text}
|
||||
image={image}
|
||||
title={short_title}
|
||||
desc={short_description}
|
||||
link_path={link_path}
|
||||
key={idx}
|
||||
/>
|
||||
<div key={idx}>
|
||||
<TopBanner
|
||||
btn={short_button_text}
|
||||
image={image}
|
||||
title={short_title}
|
||||
desc={short_description}
|
||||
link_path={link_path}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
@@ -48,14 +49,15 @@ const AccountDashboard = ({ className, bannerList }) => {
|
||||
props;
|
||||
|
||||
return (
|
||||
<LowerBanner
|
||||
btn={short_button_text}
|
||||
image={image}
|
||||
title={short_title}
|
||||
desc={short_description}
|
||||
link_path={link_path}
|
||||
key={idx}
|
||||
/>
|
||||
<div key={idx}>
|
||||
<LowerBanner
|
||||
btn={short_button_text}
|
||||
image={image}
|
||||
title={short_title}
|
||||
desc={short_description}
|
||||
link_path={link_path}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import Layout from "../Partials/Layout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import FamilyManageTabs from "./FamilyManageTabs";
|
||||
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
|
||||
|
||||
export default function FamilyManage() {
|
||||
const [selectTab, setValue] = useState("today");
|
||||
@@ -34,7 +35,7 @@ export default function FamilyManage() {
|
||||
<div className="notification-page w-full mb-10">
|
||||
<div className="notification-wrapper w-full">
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
{/* <div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="mb-5 sm:mb-0">
|
||||
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||
<span
|
||||
@@ -50,6 +51,40 @@ export default function FamilyManage() {
|
||||
className="relative"
|
||||
></div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="w-full mb-5 flex justify-between items-center">
|
||||
<div className="">
|
||||
<CustomBreadcrumb
|
||||
title = {'Manage Family'}
|
||||
breadcrumb={
|
||||
[
|
||||
{ link: "/", title: "Home" },
|
||||
{ link: "/manage-family", title: "Manage Family", active: true},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Link
|
||||
className="item-content relative text-[18px] transition-all duration-300 ease-in-out bg-[#76a5df] text-white font-medium dark:text-white h-12 px-2 flex items-center gap-2 rounded-md shadow-sm justify-center cursor-pointer dark:bg-[linear-gradient(134.38deg,#f539f8_0%,#c342f9_43.55%,#5356fb_104.51%)]"
|
||||
to="/acc-family"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span>Family</span>
|
||||
</Link>
|
||||
</div>
|
||||
<FamilyManageTabs accountDetails={accountDetails} />
|
||||
</div>
|
||||
|
||||
@@ -300,7 +300,7 @@ const AssignTaskPopout = ({
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
className={`job-action-modal-body w-full md:grid ${
|
||||
className={`job-action-modal-body w-full min-h-[450px] max-h-[450px] overflow-y-auto md:grid ${
|
||||
taskType !== "new" ? "md:grid-cols-2" : "md:grid-cols-1"
|
||||
}`}
|
||||
>
|
||||
@@ -315,7 +315,7 @@ const AssignTaskPopout = ({
|
||||
checked={taskType == "select"}
|
||||
onChange={switchTaskType}
|
||||
/>
|
||||
<span>Select Task</span>
|
||||
<span className="text-lg tracking-wide font-semibold">Select Task</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sky-blue text-base">
|
||||
<input
|
||||
@@ -326,12 +326,12 @@ const AssignTaskPopout = ({
|
||||
checked={taskType == "new"}
|
||||
onChange={switchTaskType}
|
||||
/>
|
||||
<span>New Task</span>
|
||||
<span className="text-lg tracking-wide font-semibold">New Task</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Task Type === select */}
|
||||
{taskType == "select" && (
|
||||
<div className="p-4 w-full h-[400px] overflow-y-auto bg-slate-100 rounded-md dark:bg-[#11131f] dark:text-white">
|
||||
<div className="p-4 w-full h-[380px] overflow-y-auto bg-slate-100 rounded-md dark:bg-[#11131f] dark:text-white">
|
||||
{familyTask?.data?.length ? (
|
||||
familyTask?.data?.map((item, index) => (
|
||||
<div
|
||||
@@ -364,7 +364,7 @@ const AssignTaskPopout = ({
|
||||
</div>
|
||||
)}
|
||||
{taskType == "new" && (
|
||||
<div className="p-4 w-full h-[400px]">
|
||||
<div className="p-4 w-full">
|
||||
<NewTasks
|
||||
formState={formState}
|
||||
setFormState={setFormState}
|
||||
@@ -382,17 +382,25 @@ const AssignTaskPopout = ({
|
||||
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">
|
||||
{activeTask?.data?.title}
|
||||
</p>
|
||||
<div className="my-3">
|
||||
{/* <div className="my-3">
|
||||
<Detail
|
||||
label="Description"
|
||||
value={activeTask?.data?.description}
|
||||
/>
|
||||
</div> */}
|
||||
<div className="my-3 w-full">
|
||||
<label className="job-label">
|
||||
Description
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">
|
||||
{activeTask?.data?.description}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-2">
|
||||
<div className="w-full">
|
||||
<div className="my-3 w-full flex items-center gap-1">
|
||||
<label className="job-label">
|
||||
Price
|
||||
Reward
|
||||
</label>
|
||||
<p className="p-1 text-sm text-slate-900 dark:text-white">
|
||||
{PriceFormatter(
|
||||
@@ -453,7 +461,7 @@ const AssignTaskPopout = ({
|
||||
</div>
|
||||
|
||||
{/* BTN */}
|
||||
<div className="py-2 px-4 border-t-2 flex justify-between items-center">
|
||||
<div className="modal-footer-wrapper">
|
||||
{/* error or success display */}
|
||||
<div className="w-auto h-auto flex items-center">
|
||||
{requestStatus.message != "" &&
|
||||
@@ -480,7 +488,7 @@ const AssignTaskPopout = ({
|
||||
disabled={requestStatus.loading}
|
||||
onClick={action}
|
||||
type="button"
|
||||
className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white cursor-pointer"
|
||||
className="custom-btn border-gradient"
|
||||
>
|
||||
<span className="text-gradient">Close</span>
|
||||
</button>
|
||||
@@ -492,7 +500,7 @@ const AssignTaskPopout = ({
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={assignFamilyTask}
|
||||
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||
className="custom-btn btn-gradient text-white"
|
||||
>
|
||||
Assign
|
||||
</button>
|
||||
|
||||
@@ -49,11 +49,91 @@ export default function NewTasks({ formState, setFormState }) {
|
||||
|
||||
return (
|
||||
<form className="w-full flex justify-between items-start">
|
||||
<div className="flex flex-col gap-3 max-w-[77%]">
|
||||
<div className="w-full block sm:grid grid-cols-3 gap-2">
|
||||
|
||||
<div className="w-full flex flex-col gap-2 col-span-2">
|
||||
{/* Title */}
|
||||
<div className="field w-full">
|
||||
<label htmlFor="title" className="job-label">Title</label>
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
// label="Title"
|
||||
// labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="title"
|
||||
value={formState.title}
|
||||
inputHandler={handleInputChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
// error={props.errors.title && props.touched.title && props.errors.title}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
{/* <div className="field w-full mb-[5px]">
|
||||
<label htmlFor="description" className="job-label">Description</label>
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
// label="Description"
|
||||
// labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="description"
|
||||
value={formState.description}
|
||||
inputHandler={handleInputChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
// error={props.errors.description && props.touched.description && props.errors.description}
|
||||
/>
|
||||
</div> */}
|
||||
<div className="field flex flex-col sm:flex-row w-full gap-2">
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="description"
|
||||
className='job-label'
|
||||
>
|
||||
Description
|
||||
</label>
|
||||
<textarea
|
||||
id="description"
|
||||
rows="5"
|
||||
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px]`}
|
||||
style={{ resize: "none" }}
|
||||
name="description"
|
||||
value={formState.description}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
<div className="field flex flex-col sm:flex-row w-full gap-2">
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="Job Delivery Details"
|
||||
className='job-label'
|
||||
>
|
||||
Job Delivery Details
|
||||
{/* {props.errors.job_detail && props.touched.job_detail && <span className="text-[12px] text-red-500">{props.errors.job_detail}</span>} */}
|
||||
</label>
|
||||
<textarea
|
||||
id="Job Delivery Details"
|
||||
rows="5"
|
||||
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px]`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={formState.job_detail}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* inputs starts here */}
|
||||
<div className="grid md:grid-cols-3 grid-cols-1 gap-6 mb-[5px]">
|
||||
<div className="w-full flex flex-col gap-2">
|
||||
{/* Currency */}
|
||||
<div className="field w-full mb-6 xl:mb-0">
|
||||
<div className="field w-full">
|
||||
<label
|
||||
htmlFor="country"
|
||||
className="job-label"
|
||||
@@ -65,7 +145,7 @@ export default function NewTasks({ formState, setFormState }) {
|
||||
id="country"
|
||||
name="country"
|
||||
value={formState.country}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
className={`input-field w-full h-[42px] flex items-center px-2 mt-2 rounded-full placeholder:text-base text-dark-gray dark:text-white bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
>
|
||||
@@ -115,7 +195,7 @@ export default function NewTasks({ formState, setFormState }) {
|
||||
</div>
|
||||
|
||||
{/* Duration */}
|
||||
<div className="field w-full mb-6 xl:mb-0">
|
||||
<div className="field w-full">
|
||||
<label
|
||||
htmlFor="timeline_days"
|
||||
className="job-label"
|
||||
@@ -127,7 +207,7 @@ export default function NewTasks({ formState, setFormState }) {
|
||||
id="timeline_days"
|
||||
name="timeline_days"
|
||||
value={formState.timeline_days}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
className={`input-field w-full h-[42px] flex items-center px-2 mt-2 rounded-full placeholder:text-base text-dark-gray dark:text-white bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
>
|
||||
@@ -138,6 +218,7 @@ export default function NewTasks({ formState, setFormState }) {
|
||||
</option>
|
||||
{publicArray.map(({ name, duration }, idx) => (
|
||||
<option
|
||||
key={idx}
|
||||
className="text-slate-500 text-[13.975px]"
|
||||
value={duration}
|
||||
>
|
||||
@@ -148,74 +229,19 @@ export default function NewTasks({ formState, setFormState }) {
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<label htmlFor="title" className="job-label">Title</label>
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
// label="Title"
|
||||
// labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="title"
|
||||
value={formState.title}
|
||||
inputHandler={handleInputChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
// error={props.errors.title && props.touched.title && props.errors.title}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<label htmlFor="description" className="job-label">Description</label>
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
// label="Description"
|
||||
// labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="description"
|
||||
value={formState.description}
|
||||
inputHandler={handleInputChange}
|
||||
// blurHandler={props.handleBlur}
|
||||
// error={props.errors.description && props.touched.description && props.errors.description}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
|
||||
{/* Banner Image */}
|
||||
<div className="w-full">
|
||||
<label
|
||||
htmlFor="Job Delivery Details"
|
||||
className='job-label'
|
||||
>
|
||||
Job Delivery Details
|
||||
{/* {props.errors.job_detail && props.touched.job_detail && <span className="text-[12px] text-red-500">{props.errors.job_detail}</span>} */}
|
||||
</label>
|
||||
<textarea
|
||||
id="Job Delivery Details"
|
||||
rows="5"
|
||||
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px]`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={formState.job_detail}
|
||||
onChange={handleInputChange}
|
||||
// onBlur={props.handleBlur}
|
||||
/>
|
||||
<div className="h-32 w-full">
|
||||
<img
|
||||
src={selectImage}
|
||||
alt="task_banner_img"
|
||||
className="w-full h-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Banner Image */}
|
||||
<div className="max-w-[20%] w-full">
|
||||
<div className="h-32 w-full">
|
||||
<img
|
||||
src={selectImage}
|
||||
alt="task_banner_img"
|
||||
className="w-full h-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ function DataIteration(props) {
|
||||
{datas &&
|
||||
datas?.length >= endLength &&
|
||||
datas?.slice(startLength, endLength)
|
||||
.map((value) => children({ datas: value }))}
|
||||
.map((value, index) => children({ datas: value, index }))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import ListView from "../../assets/images/list-view.png";
|
||||
import AvailableJobsCard from "../Cards/AvailableJobsCard";
|
||||
import DataIteration from "../Helpers/DataIteration";
|
||||
import SelectBox from "../Helpers/SelectBox";
|
||||
import NewPaginatedList from "../Pagination/NewPaginatedList";
|
||||
import InfiniteScroll from "../infiniteScroll/InfiniteScroll";
|
||||
|
||||
export default function MainSection({
|
||||
className,
|
||||
@@ -95,7 +97,9 @@ export default function MainSection({
|
||||
</div>
|
||||
{/* end of contentDisplay toggler */}
|
||||
</div>
|
||||
<div className="filter-navigate-content w-full min-h-screen">
|
||||
|
||||
{/* OLD MARKET JOB LISTING */}
|
||||
{/* <div className="filter-navigate-content w-full min-h-screen">
|
||||
<div
|
||||
className={
|
||||
contentDisplay == "grid"
|
||||
@@ -108,8 +112,8 @@ export default function MainSection({
|
||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||
endLength={products?.length}
|
||||
>
|
||||
{({ datas }) => (
|
||||
<div key={datas.job_uid}>
|
||||
{({ datas, index }) => (
|
||||
<div key={datas.job_uid+index}>
|
||||
<AvailableJobsCard
|
||||
contentDisplay={contentDisplay}
|
||||
image_server={image_server}
|
||||
@@ -119,7 +123,78 @@ export default function MainSection({
|
||||
)}
|
||||
</DataIteration>
|
||||
</div>
|
||||
</div> */}
|
||||
{/* END OF OLD MARKET JOB LISTING */}
|
||||
|
||||
{products?.length ?
|
||||
<NewPaginatedList
|
||||
data={products}
|
||||
itemsPerPage={9}
|
||||
filterItem=''
|
||||
tableTitle=''
|
||||
>
|
||||
{
|
||||
({data})=>(
|
||||
<div className="filter-navigate-content w-full min-h-[600px]">
|
||||
<div
|
||||
className={
|
||||
contentDisplay == "grid"
|
||||
? "grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]"
|
||||
: "w-full"
|
||||
}
|
||||
>
|
||||
{
|
||||
data.map((datum, index) => (
|
||||
<div key={datum.job_uid+index}>
|
||||
<AvailableJobsCard
|
||||
contentDisplay={contentDisplay}
|
||||
image_server={image_server}
|
||||
datas={datum}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</NewPaginatedList>
|
||||
// <InfiniteScroll
|
||||
// allData={products}
|
||||
// addItemBy={3}
|
||||
// intialItemsToShow={9}
|
||||
// >
|
||||
// {
|
||||
// ({dataToShow})=>(
|
||||
// <div className="filter-navigate-content w-full min-h-[600px]">
|
||||
// <div
|
||||
// className={
|
||||
// contentDisplay == "grid"
|
||||
// ? "grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]"
|
||||
// : "w-full"
|
||||
// }
|
||||
// >
|
||||
// {
|
||||
// dataToShow.map((datum, index) => (
|
||||
// <div key={datum.job_uid+index}>
|
||||
// <AvailableJobsCard
|
||||
// contentDisplay={contentDisplay}
|
||||
// image_server={image_server}
|
||||
// datas={datum}
|
||||
// />
|
||||
// </div>
|
||||
// ))
|
||||
// }
|
||||
// </div>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// </InfiniteScroll>
|
||||
:
|
||||
<div className="w-full h-[40rem] bg-white dark:bg-dark-white flex justify-center items-center">
|
||||
No Jobs Found!
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
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 { SocketValues } from "../../Contexts/SocketIOContext";
|
||||
|
||||
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
|
||||
let {sendJobInterestToOwner} = SocketValues() // function to emit job interest request
|
||||
const emitOfferInterest = () => {
|
||||
let message = {
|
||||
"audience": "MERCHANT",
|
||||
"action": "REFRESH_OFFERS",
|
||||
"offer_code": details?.offer_code,
|
||||
"offer_uid": details?.offer_uid,
|
||||
"job_uid": details?.job_uid,
|
||||
"market_uid": details?.market_uid
|
||||
}
|
||||
let room = `INTEREST-${details?.market_uid}`
|
||||
sendJobInterestToOwner(message, room)
|
||||
}
|
||||
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [errMsg, setErrMsg] = useState({
|
||||
market: false,
|
||||
@@ -88,7 +104,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
state: true,
|
||||
});
|
||||
}
|
||||
|
||||
emitOfferInterest() // FUNCTIONS TO EMIT EVENT INDICATING SOMEONE SENDS AN INTEREST IN YOUR JOB
|
||||
setTimeout(() => setManageInt({ msg: "" }), 3000);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
@@ -118,7 +134,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation}>
|
||||
<div className="logout-modal-wrapper w-11/12 md:w-[650px] md:h-[580px] h-full bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="w-11/12 md:w-[650px] bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="modal-header-con">
|
||||
<h1 className="modal-title">
|
||||
{details.offer_code}
|
||||
@@ -128,7 +144,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
|
||||
<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="max-h-[240px] h-full">
|
||||
<div className="min-h-[240px]">
|
||||
<h2 className="font-semibold text-slate-900 dark:text-white tracking-wide">
|
||||
{details?.title}
|
||||
</h2>
|
||||
@@ -218,7 +234,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
{errMsg.market && "Something went wrong"}
|
||||
</span>
|
||||
<button
|
||||
className="self-end w-[150px] h-[48px] rounded-full text-base bg-yellow-500 text-white"
|
||||
className="custom-btn self-end bg-yellow-500 text-white"
|
||||
name="market-message"
|
||||
onClick={MarketDetail}
|
||||
>
|
||||
@@ -279,21 +295,24 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="self-center w-[150px] mt-2 h-[48px] rounded-full text-base bg-transparent border border-red-500 text-red-500 mx-auto"
|
||||
name="cancel"
|
||||
onClick={onClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
{/* END OF ACTION SECTION */}
|
||||
</div>
|
||||
<div className="modal-footer-wrapper">
|
||||
<button
|
||||
className="custom-btn bg-transparent border border-red-500 text-red-500 ml-auto"
|
||||
name="cancel"
|
||||
onClick={onClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalCom>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default MarketPopUp;
|
||||
|
||||
const CloseIcon = ({ onClose }) => (
|
||||
|
||||
@@ -3,6 +3,7 @@ import Layout from "../Partials/Layout";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import MainSection from "./MainSection";
|
||||
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
export default function MarketPlace({ commonHeadData }) {
|
||||
let { jobLists } = useSelector((state) => state.jobLists);
|
||||
@@ -25,12 +26,18 @@ export default function MarketPlace({ commonHeadData }) {
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{jobLists.loading ?
|
||||
<div className="w-full flex justify-center items-center bg-white dark:bg-dark-white">
|
||||
<LoadingSpinner size='20' height='h-[40rem]' />
|
||||
</div>
|
||||
:
|
||||
<MainSection
|
||||
marketPlaceProduct={marketData}
|
||||
categories={categories}
|
||||
image_server={image_server}
|
||||
className="mb-10"
|
||||
/>
|
||||
}
|
||||
</Layout>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,6 +4,7 @@ import Layout from "../Partials/Layout";
|
||||
import MyJobTable from "./MyJobTable";
|
||||
import CommonHead from "../UserHeader/CommonHead";
|
||||
import AddJobPage from "../../views/AddJobPage";
|
||||
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
|
||||
|
||||
export default function MyJobs(props) {
|
||||
let { state } = useLocation();
|
||||
@@ -32,8 +33,8 @@ export default function MyJobs(props) {
|
||||
<div className="notification-page w-full mb-10">
|
||||
<div className="notification-wrapper w-full">
|
||||
{/* heading */}
|
||||
<div className="sm:flex items-center mb-6">
|
||||
<div className="mb-5 sm:mb-0">
|
||||
<div className="sm:flex items-center mb-2">
|
||||
<div className="w-full">
|
||||
<h1 className="text-26 font-bold flex items-center space-x-1 text-dark-gray dark:text-white gap-2">
|
||||
<span>My Jobs</span>
|
||||
|
||||
@@ -46,6 +47,17 @@ export default function MyJobs(props) {
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<CustomBreadcrumb
|
||||
// title = 'My Jobs'
|
||||
breadcrumb={
|
||||
[
|
||||
{ link: "/", title: "Home" },
|
||||
{ link: "/myjobs", title: "My Jobs", active: true},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<MyJobTable MyJobList={props.MyJobList} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,6 +28,7 @@ export default function OffersInterestTable({offerInterestList, className}) {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
let imgServer = offerInterestList?.imgServer // FOR RENDERING IMAGE FROM SERVER
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full my-8 p-8 bg-white dark:bg-dark-white rounded-2xl section-shadow min-h-[520px] ${
|
||||
@@ -54,14 +55,19 @@ export default function OffersInterestTable({offerInterestList, className}) {
|
||||
</thead>
|
||||
<tbody className="h-full">
|
||||
{currentOfferInterestList?.map((item, index) => {
|
||||
let image = item.banner ? item.banner : 'default.jpg'
|
||||
// let image = item.banner ? item.banner : 'default.jpg'
|
||||
const image = localStorage.getItem("session_token")
|
||||
? `${imgServer}${localStorage.getItem("session_token")}/job/${
|
||||
item.job_uid
|
||||
}`
|
||||
: "";
|
||||
return (
|
||||
<tr key={index} className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<div className="min-w-[60px] max-w-[60px] min-h-[60px] max-h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={localImgLoad(`images/taskbanners/${image}`)}
|
||||
src={`${image}`}
|
||||
alt="data"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
@@ -90,7 +96,7 @@ export default function OffersInterestTable({offerInterestList, className}) {
|
||||
<button
|
||||
onClick={() => {
|
||||
navigate("/manage-offer", {
|
||||
state: { ...item, pathname },
|
||||
state: { ...item, pathname, jobImage:image },
|
||||
});
|
||||
}}
|
||||
type="button"
|
||||
|
||||
@@ -56,13 +56,18 @@ export default function OthersInterestTable({othersInterestedList, className}) {
|
||||
</thead>
|
||||
<tbody className="h-full">
|
||||
{currentOthersInterestedList?.map((item, index) => {
|
||||
const image = localStorage.getItem("session_token")
|
||||
? `${othersInterestedList.imageServer}${localStorage.getItem("session_token")}/job/${
|
||||
item.job_uid
|
||||
}`
|
||||
: "";
|
||||
return (
|
||||
<tr key={index} className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||
<td className=" py-4">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<div className="min-w-[60px] min-h-[60px] rounded-full overflow-hidden flex justify-center items-center">
|
||||
<img
|
||||
src={dataImage1}
|
||||
src={image}
|
||||
alt="data"
|
||||
className="w-full h-full"
|
||||
/>
|
||||
|
||||
@@ -9,6 +9,7 @@ export default function OffersInterest(props) {
|
||||
const filterHandler = (value) => {
|
||||
setValue(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<CommonHead
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const data1 = [];
|
||||
|
||||
export default function NewPaginatedList({
|
||||
data = data1,
|
||||
itemsPerPage = 5,
|
||||
filterItem,
|
||||
tableTitle,
|
||||
children,
|
||||
}) {
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [filteredData, setFilteredData] = useState(data);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const [newData, setNewData] = useState([]);
|
||||
|
||||
const numberOfSelection = itemsPerPage;
|
||||
|
||||
const handlePrev = () => {
|
||||
if (currentPage != 0) {
|
||||
setCurrentPage((prev) => prev - numberOfSelection);
|
||||
}
|
||||
};
|
||||
const handleNext = () => {
|
||||
if (currentPage < data.length) {
|
||||
setCurrentPage((prev) => prev + numberOfSelection);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSearch = ({ target: { value } }, name) => {
|
||||
setSearchTerm(value);
|
||||
let newFilteredData = data.filter((item) =>
|
||||
item[name].toLowerCase().startsWith(value.toLowerCase())
|
||||
);
|
||||
setFilteredData(newFilteredData);
|
||||
setCurrentPage(0);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setNewData(
|
||||
filteredData?.slice(currentPage, numberOfSelection + currentPage)
|
||||
);
|
||||
}, [currentPage, filteredData]);
|
||||
|
||||
useEffect(()=>{
|
||||
setCurrentPage(0)
|
||||
},[itemsPerPage])
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<h1 className="text-2xl mb-5 font-semibold">{tableTitle}</h1>
|
||||
|
||||
{data.length > 0 && filterItem && (
|
||||
<div className="mb-10 flex justify-end items-center gap-2">
|
||||
{filterItem.map((item, index) => (
|
||||
<label
|
||||
key={index}
|
||||
className="flex flex-col sm:flex-row items-center gap-2 text-slate-600 dark:text-slate-100 transition-all duration-500"
|
||||
>
|
||||
Search by {item[0].toUpperCase() + item.slice(1)}
|
||||
<input
|
||||
name={item}
|
||||
type="text"
|
||||
className="py-1 px-2 text-sm min-w-[100px] text-black dark:text-white bg-white dark:bg-slate-800 rounded-full border-0 outline-none ring-1 ring-slate-300 dark:ring-white transition-all duration-500"
|
||||
value={searchTerm}
|
||||
onChange={(e) => {
|
||||
handleSearch(e, item);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{children({ data: newData })}
|
||||
|
||||
{/* show prev and next button if data exist */}
|
||||
{data.length > 0 && (
|
||||
<div className="mt-10 w-full flex gap-4 justify-center items-center">
|
||||
<button
|
||||
onClick={handlePrev}
|
||||
className={`w-12 h-12 rounded-full flex justify-center items-center transition-all duration-300 ${
|
||||
currentPage == 0
|
||||
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pointer-events-none"
|
||||
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||
}`}
|
||||
>
|
||||
<
|
||||
</button>
|
||||
|
||||
{data.length && data.map((item, index)=>{
|
||||
if(index%itemsPerPage == 0 && index >= currentPage && index <= currentPage+itemsPerPage){
|
||||
return (
|
||||
<button
|
||||
key={index}
|
||||
onClick={handleNext}
|
||||
className={`w-12 h-12 rounded-full flex justify-center items-center border transition-all duration-300 ${
|
||||
currentPage != index
|
||||
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400"
|
||||
: "text-slate-600 border-slate-600 dark:text-white dark:border-white pointer-events-none"
|
||||
}`}
|
||||
>
|
||||
{index/itemsPerPage +1}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
})}
|
||||
|
||||
<button
|
||||
onClick={handleNext}
|
||||
className={`w-12 h-12 rounded-full flex justify-center items-center transition-all duration-300 ${
|
||||
currentPage + numberOfSelection >= data.length
|
||||
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pointer-events-none"
|
||||
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||
}`}
|
||||
>
|
||||
>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -89,7 +89,9 @@ export default function MobileSidebar({
|
||||
<ul className="flex flex-col space-y-6">
|
||||
{/* Using mini component reduces the bulk amount of html */}
|
||||
<ListItem
|
||||
title= {userDetails?.account_type == "FULL" ? "Dashboard" : "Home"}
|
||||
title={
|
||||
userDetails?.account_type == "FULL" ? "Dashboard" : "Home"
|
||||
}
|
||||
route="/"
|
||||
sidebar={sidebar}
|
||||
iconName="new-dashboard"
|
||||
@@ -190,17 +192,21 @@ export default function MobileSidebar({
|
||||
<div className="items">
|
||||
<ul className="flex flex-col space-y-6">
|
||||
{[
|
||||
{ name: "List", path: "/myjobs", iconName: "job-list" },
|
||||
{
|
||||
name: "List",
|
||||
path: "/myjobs",
|
||||
iconName: "job-list",
|
||||
},
|
||||
// {
|
||||
// name: "Waiting",
|
||||
// path: "/pend-interest",
|
||||
// iconName: "pending-job",
|
||||
// },
|
||||
{
|
||||
name: "Offers",
|
||||
path: "/my-offers",
|
||||
iconName: "pending-job",
|
||||
},
|
||||
{
|
||||
name: "Waiting",
|
||||
path: "/pend-interest",
|
||||
iconName: "pending-job",
|
||||
},
|
||||
{
|
||||
name: "Active",
|
||||
path: "/my-active-jobs",
|
||||
|
||||
@@ -4,6 +4,7 @@ import { NavLink } from "react-router-dom";
|
||||
//import SideStatistics from "./SideStatistics";
|
||||
import { localImgLoad } from "../../lib";
|
||||
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||
import Icons from "../Helpers/Icons";
|
||||
|
||||
export default function RightSideBar({ myJobList }) {
|
||||
const filterDatas = ["Last 15 days", "Last Month", "Last 6 month"];
|
||||
@@ -81,6 +82,19 @@ export default function RightSideBar({ myJobList }) {
|
||||
{/* action */}
|
||||
</div>
|
||||
|
||||
<div className="item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 rounded-full flex items-center justify-center">
|
||||
<Icons name="pending-job" />
|
||||
</div>
|
||||
{/* name */}
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-base font-medium">
|
||||
<NavLink to="/pend-interest">Waiting</NavLink>
|
||||
</p>
|
||||
</div>
|
||||
{/* action */}
|
||||
</div>
|
||||
<div className="item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 rounded-full">
|
||||
@@ -235,6 +249,7 @@ export default function RightSideBar({ myJobList }) {
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
|
||||
</span>
|
||||
<p className="text-thin-light-gray text-base font-medium">
|
||||
{darkMode.theme === "light" ? "Dark" : "Light"} Mode
|
||||
@@ -274,6 +289,24 @@ export default function RightSideBar({ myJobList }) {
|
||||
{/* action */}
|
||||
</div>
|
||||
|
||||
<div className="px-8 item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 p-[4px] rounded-full">
|
||||
<img
|
||||
src={localImgLoad("images/icons/job_active.svg")}
|
||||
className="w-full h-full"
|
||||
alt="Active Task"
|
||||
/>
|
||||
</div>
|
||||
{/* name */}
|
||||
<div>
|
||||
<p className="text-thin-light-gray text-base font-medium">
|
||||
<NavLink to="/offer-interest">Offers Interest</NavLink>
|
||||
</p>
|
||||
</div>
|
||||
{/* action */}
|
||||
</div>
|
||||
|
||||
<div className="px-8 item flex space-x-3 items-center mb-4">
|
||||
{/* image */}
|
||||
<div className="w-8 h-8 p-[4px] rounded-full">
|
||||
|
||||
@@ -216,11 +216,11 @@ export default function Sidebar({
|
||||
path: "/myjobs",
|
||||
iconName: "job-list",
|
||||
},
|
||||
{
|
||||
name: "Waiting",
|
||||
path: "/pend-interest",
|
||||
iconName: "pending-job",
|
||||
},
|
||||
// {
|
||||
// name: "Waiting",
|
||||
// path: "/pend-interest",
|
||||
// iconName: "pending-job",
|
||||
// },
|
||||
{
|
||||
name: "Offers",
|
||||
path: "/my-offers",
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
||||
|
||||
export default function InfiniteScroll({
|
||||
allData=data,
|
||||
addItemBy=12,
|
||||
intialItemsToShow=39,
|
||||
children
|
||||
}) {
|
||||
|
||||
let [currentPage, setCurrentPage] = useState(intialItemsToShow)
|
||||
|
||||
let [loading, setLoading] = useState(false)
|
||||
|
||||
let dataToShow = allData.slice(0, currentPage)
|
||||
|
||||
// let [winScr, setWinScr] = useState(0)
|
||||
|
||||
const customScroll = ()=>{
|
||||
let wi = window.innerHeight + window.scrollY
|
||||
// let scrollContainer = document.querySelector('.scroll-container').scrollHeight
|
||||
let scrollBody = document.body.offsetHeight
|
||||
if(wi >= scrollBody && allData.length > currentPage){
|
||||
setLoading(true)
|
||||
setTimeout(()=>{
|
||||
setCurrentPage(prev => prev+addItemBy)
|
||||
setLoading(false)
|
||||
},2000)
|
||||
}
|
||||
// else if(window.scrollY < winScr && currentPage > intialItemsToShow){
|
||||
// setCurrentPage(prev => prev-addItemBy)
|
||||
// window.scrollTo(0,wi)
|
||||
// setWinScr(window.scrollY)
|
||||
// }
|
||||
// else if(winScr == 0 && currentPage > intialItemsToShow){
|
||||
// setCurrentPage(prev => intialItemsToShow)
|
||||
// window.scrollTo(0,0)
|
||||
// setWinScr(window.scrollY)
|
||||
// }
|
||||
}
|
||||
useEffect(()=>{
|
||||
window.addEventListener('scroll', customScroll)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', customScroll)
|
||||
}
|
||||
},[currentPage])
|
||||
|
||||
return (
|
||||
<div className='w-full'>
|
||||
|
||||
{children({ dataToShow })}
|
||||
|
||||
{loading &&
|
||||
<div className='w-full my-2 p-2 flex justify-center items-center'>
|
||||
<LoadingSpinner size='8' />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// let data = new Array(100).fill(0).map((_,i) => i )
|
||||
@@ -123,13 +123,13 @@ function FamilyOfferJobPopout({ details, onClose, situation }) {
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation}>
|
||||
<div className="logout-modal-wrapper w-[90%] md:w-[768px] bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 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">
|
||||
<div className="modal-header-con">
|
||||
<h1 className="modal-title">
|
||||
Start Task
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
className="modal-close-btn"
|
||||
onClick={onClose}
|
||||
>
|
||||
<svg
|
||||
@@ -153,7 +153,7 @@ function FamilyOfferJobPopout({ details, onClose, situation }) {
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="md:flex bg-white rounded-lg shadow-lg">
|
||||
<div className="md:flex bg-white rounded-lg">
|
||||
<div className="p-4 w-full md:w-3/4 md:border-r-2">
|
||||
<div className="flex gap-2">
|
||||
<div className="image-wrapper w-32">
|
||||
@@ -261,12 +261,12 @@ function FamilyOfferJobPopout({ details, onClose, situation }) {
|
||||
</div>
|
||||
|
||||
{/* close button */}
|
||||
<div className="p-6 flex justify-end">
|
||||
<div className="modal-footer-wrapper flex justify-end">
|
||||
<button
|
||||
onClick={onClose}
|
||||
disabled={requestStatus.loading}
|
||||
type="button"
|
||||
className="border-gradient text-18 tracking-wide px-2 py-2 rounded-full"
|
||||
className="custom-btn border-gradient"
|
||||
>
|
||||
<span className="text-gradient">Cancel</span>
|
||||
</button>
|
||||
|
||||
@@ -103,13 +103,13 @@ function OfferJobPopout({ details, onClose, situation }) {
|
||||
return (
|
||||
<ModalCom action={onClose} situation={situation}>
|
||||
<div className="logout-modal-wrapper w-[90%] md:w-[768px] bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 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">
|
||||
<div className="modal-header-con">
|
||||
<h1 className="modal-title">
|
||||
Start Task
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
className="modal-close-btn"
|
||||
onClick={onClose}
|
||||
>
|
||||
<svg
|
||||
@@ -133,7 +133,7 @@ function OfferJobPopout({ details, onClose, situation }) {
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="md:flex bg-white dark:bg-dark-white rounded-lg shadow-lg">
|
||||
<div className="md:flex bg-white dark:bg-dark-white rounded-lg">
|
||||
<div className="p-4 w-full md:w-3/4 md:border-r-2">
|
||||
<p className="text-lg my-5 font-semibold text-slate-900 dark:text-white tracking-wide">
|
||||
{details.title}
|
||||
@@ -234,12 +234,12 @@ function OfferJobPopout({ details, onClose, situation }) {
|
||||
</div>
|
||||
|
||||
{/* close button */}
|
||||
<div className="p-6 flex justify-end">
|
||||
<div className="modal-footer-wrapper flex justify-end">
|
||||
<button
|
||||
onClick={onClose}
|
||||
disabled={requestStatus.loading}
|
||||
type="button"
|
||||
className="border-gradient text-18 tracking-wide px-2 py-2 rounded-full"
|
||||
className="custom-btn border-gradient"
|
||||
>
|
||||
<span className="text-gradient">Cancel</span>
|
||||
</button>
|
||||
|
||||
+13
-2
@@ -160,7 +160,8 @@
|
||||
@apply flex items-center gap-2
|
||||
}
|
||||
|
||||
/* style for all modal header */
|
||||
/* STYLES FOR MODAL */
|
||||
/* Modal Header */
|
||||
.modal-header-con{
|
||||
@apply w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] bg-sky-blue/50 border-b dark:border-[#5356fb29] border-light-purple
|
||||
}
|
||||
@@ -170,7 +171,17 @@
|
||||
.modal-close-btn{
|
||||
@apply text-[#000] dark:text-red-500
|
||||
}
|
||||
/* end of style for all modal header */
|
||||
|
||||
/* modal footer */
|
||||
.modal-footer-wrapper{
|
||||
@apply py-2 px-4 border-t-2 flex justify-between items-center
|
||||
}
|
||||
/* END OF STYLES FOR MODAL BOX */
|
||||
|
||||
/* STYLES FOR BUTTON */
|
||||
.custom-btn {
|
||||
@apply px-2 min-w-[80px] h-11 flex justify-center items-center text-base rounded-full cursor-pointer
|
||||
}
|
||||
}
|
||||
|
||||
/* ===================== EXTRA ===================== */
|
||||
|
||||
@@ -219,8 +219,9 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
||||
const getMarketActiveJobList = async () => {
|
||||
try {
|
||||
const res = await apiCall.getActiveJobList();
|
||||
dispatch(updateJobs(res.data));
|
||||
dispatch(updateJobs({loading: false, ...res.data}));
|
||||
} catch (error) {
|
||||
dispatch(updateJobs({loading: false}));
|
||||
console.log("Error getting mode");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ const initialState = {
|
||||
marketTableList: false,
|
||||
familyOfferList: false,
|
||||
parentFamilyTaskList: false,
|
||||
offerInterestListReload: false,
|
||||
};
|
||||
|
||||
export const tableReloadSlice = createSlice({
|
||||
@@ -57,6 +58,9 @@ export const tableReloadSlice = createSlice({
|
||||
case "PARENTFAMILYTASKLIST": // reloads list of active family task on parent side
|
||||
state.parentFamilyTaskList = !state.parentFamilyTaskList;
|
||||
return;
|
||||
case "OFFERINTERESTLISTRELOAD": // to reload offer interest list of owner when a worker sends interest in a job
|
||||
state.offerInterestListReload = !state.offerInterestListReload;
|
||||
return;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
jobLists: {}
|
||||
jobLists: {loading: true}
|
||||
};
|
||||
|
||||
export const jobSlice = createSlice({
|
||||
|
||||
@@ -12,7 +12,7 @@ export default function MyReviewDueJobsPage() {
|
||||
let { othersInterestedTable } = useSelector((state) => state.tableReload); // FOR OTHERS INTERESTED TABLE RELOAD
|
||||
|
||||
const apiCall = new usersService();
|
||||
const [othersInterestedList, setOthersInterestedList] = useState({loading: true, data: []})
|
||||
const [othersInterestedList, setOthersInterestedList] = useState({loading: true, data: [], imageServer:''})
|
||||
|
||||
useEffect(() => {
|
||||
if(!state){
|
||||
@@ -26,9 +26,9 @@ export default function MyReviewDueJobsPage() {
|
||||
}else{
|
||||
newData = []
|
||||
}
|
||||
setOthersInterestedList({loading: false, data: newData})
|
||||
setOthersInterestedList({loading: false, data: newData, imageServer:res.data.session_image_server})
|
||||
}).catch(err => {
|
||||
setOthersInterestedList({loading: false, data: []})
|
||||
setOthersInterestedList({loading: false, data: [], imageServer:''})
|
||||
console.log('Error: ', err)
|
||||
})
|
||||
}, [othersInterestedTable]);
|
||||
|
||||
@@ -5,20 +5,33 @@ import OffersInterest from "../components/OffersInterest";
|
||||
|
||||
import usersService from "../services/UsersService";
|
||||
|
||||
import { SocketValues } from "../components/Contexts/SocketIOContext"; // for reading socket context values
|
||||
|
||||
export default function OffersInterestPage() {
|
||||
|
||||
const { offerInterestListReload } = useSelector((state) => state.tableReload); // table/list reload variable
|
||||
|
||||
const {userDetails} = useSelector((state) => state?.userDetails); // Gets USER Details
|
||||
|
||||
let {joinRoom} = SocketValues() // function to join room for socket
|
||||
|
||||
const apiCall = new usersService()
|
||||
|
||||
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
|
||||
|
||||
let [offerInterestList, setOfferInterestList] = useState({loading: true, data: []})
|
||||
let [offerInterestList, setOfferInterestList] = useState({loading: true, data: [], imgServer:''})
|
||||
|
||||
useEffect(()=>{
|
||||
apiCall.offersInterestList().then(res => {
|
||||
setOfferInterestList({loading: false, data: res.data.result_list})
|
||||
setOfferInterestList({loading: false, data: res.data.result_list, imgServer:res.data.session_image_server})
|
||||
}).catch(err => {
|
||||
setOfferInterestList({loading: false, data: []})
|
||||
setOfferInterestList({loading: false, data: [], imgServer:''})
|
||||
console.log('Error: ', err)
|
||||
})
|
||||
},[offerInterestListReload])
|
||||
|
||||
useEffect(()=>{
|
||||
joinRoom(`INTEREST-${userDetails?.uid}`)
|
||||
},[])
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user