Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cd8b6e574 | |||
| 9850cdd392 | |||
| 6d98141c39 | |||
| 5fe5ccbd4d | |||
| 76c0994eb0 | |||
| a1bc6db381 |
@@ -44,6 +44,12 @@ export default function SocketIOContextProvider({children}) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sendJobInterestToOwner = (message, room) => {
|
||||||
|
if(message && room){
|
||||||
|
socket.emit("marketjob", { message:{...message}, room });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
socket.on("receive_message", (data) => {
|
socket.on("receive_message", (data) => {
|
||||||
// setSocketMsgReceived(data.message);
|
// setSocketMsgReceived(data.message);
|
||||||
@@ -70,6 +76,15 @@ export default function SocketIOContextProvider({children}) {
|
|||||||
}
|
}
|
||||||
// console.log('DATA', data)
|
// 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"){ // for refreshing job owner offer interest list when any worker sends interest
|
||||||
|
dispatch(tableReload({type:'OFFERINTERESTLISTRELOAD'}))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}, [socket]);
|
}, [socket]);
|
||||||
|
|
||||||
let values = {
|
let values = {
|
||||||
@@ -79,6 +94,7 @@ export default function SocketIOContextProvider({children}) {
|
|||||||
setSocketMsgReceived,
|
setSocketMsgReceived,
|
||||||
marketUpdate,
|
marketUpdate,
|
||||||
parentAssignJobToKid,
|
parentAssignJobToKid,
|
||||||
|
sendJobInterestToOwner,
|
||||||
socketMsgReceived,
|
socketMsgReceived,
|
||||||
// room,
|
// room,
|
||||||
// setRoom,
|
// setRoom,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
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 Layout from "../Partials/Layout";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import FamilyManageTabs from "./FamilyManageTabs";
|
import FamilyManageTabs from "./FamilyManageTabs";
|
||||||
|
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
|
||||||
|
|
||||||
export default function FamilyManage() {
|
export default function FamilyManage() {
|
||||||
const [selectTab, setValue] = useState("today");
|
const [selectTab, setValue] = useState("today");
|
||||||
@@ -34,7 +35,7 @@ export default function FamilyManage() {
|
|||||||
<div className="notification-page w-full mb-10">
|
<div className="notification-page w-full mb-10">
|
||||||
<div className="notification-wrapper w-full">
|
<div className="notification-wrapper w-full">
|
||||||
{/* heading */}
|
{/* 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">
|
<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">
|
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||||
<span
|
<span
|
||||||
@@ -50,6 +51,40 @@ export default function FamilyManage() {
|
|||||||
className="relative"
|
className="relative"
|
||||||
></div>
|
></div>
|
||||||
</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>
|
</div>
|
||||||
<FamilyManageTabs accountDetails={accountDetails} />
|
<FamilyManageTabs accountDetails={accountDetails} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ function DataIteration(props) {
|
|||||||
{datas &&
|
{datas &&
|
||||||
datas?.length >= endLength &&
|
datas?.length >= endLength &&
|
||||||
datas?.slice(startLength, endLength)
|
datas?.slice(startLength, endLength)
|
||||||
.map((value) => children({ datas: value }))}
|
.map((value, index) => children({ datas: value, index }))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import ListView from "../../assets/images/list-view.png";
|
|||||||
import AvailableJobsCard from "../Cards/AvailableJobsCard";
|
import AvailableJobsCard from "../Cards/AvailableJobsCard";
|
||||||
import DataIteration from "../Helpers/DataIteration";
|
import DataIteration from "../Helpers/DataIteration";
|
||||||
import SelectBox from "../Helpers/SelectBox";
|
import SelectBox from "../Helpers/SelectBox";
|
||||||
|
import NewPaginatedList from "../Pagination/NewPaginatedList";
|
||||||
|
|
||||||
export default function MainSection({
|
export default function MainSection({
|
||||||
className,
|
className,
|
||||||
@@ -108,8 +109,8 @@ export default function MainSection({
|
|||||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||||
endLength={products?.length}
|
endLength={products?.length}
|
||||||
>
|
>
|
||||||
{({ datas }) => (
|
{({ datas, index }) => (
|
||||||
<div key={datas.job_uid}>
|
<div key={datas.job_uid+index}>
|
||||||
<AvailableJobsCard
|
<AvailableJobsCard
|
||||||
contentDisplay={contentDisplay}
|
contentDisplay={contentDisplay}
|
||||||
image_server={image_server}
|
image_server={image_server}
|
||||||
@@ -120,6 +121,40 @@ export default function MainSection({
|
|||||||
</DataIteration>
|
</DataIteration>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/* {products?.length &&
|
||||||
|
<NewPaginatedList
|
||||||
|
data={products}
|
||||||
|
itemsPerPage={6}
|
||||||
|
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>
|
||||||
|
} */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,26 @@
|
|||||||
import { useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import ModalCom from "../../Helpers/ModalCom";
|
import ModalCom from "../../Helpers/ModalCom";
|
||||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||||
|
import { SocketValues } from "../../Contexts/SocketIOContext";
|
||||||
|
|
||||||
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
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,
|
||||||
|
}
|
||||||
|
let room = `INTEREST-${details?.market_uid}`
|
||||||
|
sendJobInterestToOwner(message, room)
|
||||||
|
}
|
||||||
|
|
||||||
const [textValue, setTextValue] = useState("");
|
const [textValue, setTextValue] = useState("");
|
||||||
const [errMsg, setErrMsg] = useState({
|
const [errMsg, setErrMsg] = useState({
|
||||||
market: false,
|
market: false,
|
||||||
@@ -88,7 +103,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
state: true,
|
state: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
emitOfferInterest() // FUNCTIONS TO EMIT EVENT INDICATING SOMEONE SENDS AN INTEREST IN YOUR JOB
|
||||||
setTimeout(() => setManageInt({ msg: "" }), 3000);
|
setTimeout(() => setManageInt({ msg: "" }), 3000);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
@@ -296,6 +311,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default MarketPopUp;
|
export default MarketPopUp;
|
||||||
|
|
||||||
const CloseIcon = ({ onClose }) => (
|
const CloseIcon = ({ onClose }) => (
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
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]);
|
||||||
|
console.log("newData", newData, filteredData);
|
||||||
|
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 border ${
|
||||||
|
currentPage == 0
|
||||||
|
? "text-slate-300 border-slate-300 dark:text-slate-400 dark:border-slate-400 pointer-events-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-slate-300 dark:border-slate-300"
|
||||||
|
} transition-all duration-500`}
|
||||||
|
>
|
||||||
|
<
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleNext}
|
||||||
|
className={`w-12 h-12 rounded-full flex justify-center items-center border ${
|
||||||
|
currentPage + numberOfSelection >= data.length
|
||||||
|
? "text-slate-300 border-slate-300 dark:text-slate-400 dark:border-slate-400 pointer-events-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-slate-300 dark:border-slate-300"
|
||||||
|
} transition-all duration-500`}
|
||||||
|
>
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ const initialState = {
|
|||||||
marketTableList: false,
|
marketTableList: false,
|
||||||
familyOfferList: false,
|
familyOfferList: false,
|
||||||
parentFamilyTaskList: false,
|
parentFamilyTaskList: false,
|
||||||
|
offerInterestListReload: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const tableReloadSlice = createSlice({
|
export const tableReloadSlice = createSlice({
|
||||||
@@ -57,6 +58,9 @@ export const tableReloadSlice = createSlice({
|
|||||||
case "PARENTFAMILYTASKLIST": // reloads list of active family task on parent side
|
case "PARENTFAMILYTASKLIST": // reloads list of active family task on parent side
|
||||||
state.parentFamilyTaskList = !state.parentFamilyTaskList;
|
state.parentFamilyTaskList = !state.parentFamilyTaskList;
|
||||||
return;
|
return;
|
||||||
|
case "OFFERINTERESTLISTRELOAD": // to reload offer interest list of owner when a worker sends interest in a job
|
||||||
|
state.offerInterestListReload = !state.offerInterestListReload;
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,16 @@ import OffersInterest from "../components/OffersInterest";
|
|||||||
|
|
||||||
import usersService from "../services/UsersService";
|
import usersService from "../services/UsersService";
|
||||||
|
|
||||||
|
import { SocketValues } from "../components/Contexts/SocketIOContext"; // for reading socket context values
|
||||||
|
|
||||||
export default function OffersInterestPage() {
|
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()
|
const apiCall = new usersService()
|
||||||
|
|
||||||
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
|
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
|
||||||
@@ -19,6 +28,10 @@ export default function OffersInterestPage() {
|
|||||||
setOfferInterestList({loading: false, data: [], imgServer:''})
|
setOfferInterestList({loading: false, data: [], imgServer:''})
|
||||||
console.log('Error: ', err)
|
console.log('Error: ', err)
|
||||||
})
|
})
|
||||||
|
},[offerInterestListReload])
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
joinRoom(`INTEREST-${userDetails?.uid}`)
|
||||||
},[])
|
},[])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user