Compare commits

...

12 Commits

Author SHA1 Message Date
victorAnumudu ac027a3228 changed font weight 2024-03-25 12:45:55 +01:00
victorAnumudu 001492eeb5 changed price to reward 2024-03-25 12:40:01 +01:00
victorAnumudu 72fe2cad5f changed assign new job popout style 2024-03-25 12:36:10 +01:00
ameye eac693eba6 Merge branch 'pagination-item' of WrenchBoard/Users-Wrench into master 2024-03-24 19:25:43 +00:00
victorAnumudu d3b1462fe3 increased number of item to show in pagination 2024-03-24 15:57:21 +01:00
ameye 748546641d Merge branch 'market-pagination' of WrenchBoard/Users-Wrench into master 2024-03-24 12:35:26 +00:00
victorAnumudu 48a50fd47c added pagination for market list 2024-03-23 20:06:30 +01:00
tokslaw e87cb95b43 Merge branch 'offer-interest-refresh-fixed' of WrenchBoard/Users-Wrench into master 2024-03-22 17:09:35 +00:00
victorAnumudu 7638d68a7d merged branch with master, offer interest refresh fixed 2024-03-22 16:20:38 +01:00
victorAnumudu 3541363f9f added dummy pagination 2024-03-22 16:18:19 +01:00
victorAnumudu 30ce6a7d6e initial commit 2024-03-22 15:07:13 +01:00
ameye 115366672a Merge branch 'return-link' of WrenchBoard/Users-Wrench into master 2024-03-22 13:16:19 +00:00
16 changed files with 381 additions and 123 deletions
+4 -1
View File
@@ -114,4 +114,7 @@ REACT_APP_SHOW_NEW_FAMILY_DASH=1
REACT_APP_SHOW_ACCOUNT_DASH=1 REACT_APP_SHOW_ACCOUNT_DASH=1
# Displays the slider banners # 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
View File
@@ -82,4 +82,7 @@ REACT_APP_SHOW_NEW_FAMILY_DASH=1
REACT_APP_SHOW_ACCOUNT_DASH=1 REACT_APP_SHOW_ACCOUNT_DASH=1
# Displays the slider banners # 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
View File
@@ -88,4 +88,7 @@ REACT_APP_SHOW_NEW_FAMILY_DASH=1
REACT_APP_SHOW_ACCOUNT_DASH=1 REACT_APP_SHOW_ACCOUNT_DASH=1
# Displays the slider banners # 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 '
+80
View File
@@ -36,6 +36,7 @@
"react-toastify": "^9.0.1", "react-toastify": "^9.0.1",
"redux": "^4.2.0", "redux": "^4.2.0",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"socket.io-client": "^4.4.1",
"web-vitals": "^1.0.1", "web-vitals": "^1.0.1",
"yup": "^1.1.1" "yup": "^1.1.1"
} }
@@ -3717,6 +3718,11 @@
"@sinonjs/commons": "^1.7.0" "@sinonjs/commons": "^1.7.0"
} }
}, },
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"node_modules/@surma/rollup-plugin-off-main-thread": { "node_modules/@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
@@ -7078,6 +7084,46 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/engine.io-client": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
"integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.11.0",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"node_modules/engine.io-client/node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/engine.io-parser": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz",
"integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/enhanced-resolve": { "node_modules/enhanced-resolve": {
"version": "5.12.0", "version": "5.12.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
@@ -16099,6 +16145,32 @@
"jquery": ">=1.8.0" "jquery": ">=1.8.0"
} }
}, },
"node_modules/socket.io-client": {
"version": "4.7.5",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz",
"integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/sockjs": { "node_modules/sockjs": {
"version": "0.3.24", "version": "0.3.24",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@@ -18111,6 +18183,14 @@
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
}, },
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/xtend": { "node_modules/xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+3 -2
View File
@@ -78,11 +78,12 @@ export default function SocketIOContextProvider({children}) {
}); });
socket.on("marketjob_actions", (data) => { // Triggers refresh on owner side, when somebody sends/shows interest in a job 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 user_uid = userDetails.account_type == 'FULL' ? userDetails.uid : sessionStorage.getItem('family_uid') // gets user UID
let {message} = data let {message} = data
if(message.action == "REFRESH_OFFERS" && message.audience == "MERCHANT"){ // for refreshing job owner offer interest list when any worker sends interest 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'})) dispatch(tableReload({type:'OFFERINTERESTLISTRELOAD'}))
} }
console.log('data', data)
}); });
}, [socket]); }, [socket]);
@@ -300,7 +300,7 @@ const AssignTaskPopout = ({
) : ( ) : (
<> <>
<div <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" taskType !== "new" ? "md:grid-cols-2" : "md:grid-cols-1"
}`} }`}
> >
@@ -315,7 +315,7 @@ const AssignTaskPopout = ({
checked={taskType == "select"} checked={taskType == "select"}
onChange={switchTaskType} onChange={switchTaskType}
/> />
<span>Select Task</span> <span className="text-lg tracking-wide font-semibold">Select Task</span>
</div> </div>
<div className="flex items-center gap-2 text-sky-blue text-base"> <div className="flex items-center gap-2 text-sky-blue text-base">
<input <input
@@ -326,12 +326,12 @@ const AssignTaskPopout = ({
checked={taskType == "new"} checked={taskType == "new"}
onChange={switchTaskType} onChange={switchTaskType}
/> />
<span>New Task</span> <span className="text-lg tracking-wide font-semibold">New Task</span>
</div> </div>
</div> </div>
{/* Task Type === select */} {/* Task Type === select */}
{taskType == "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?.length ? (
familyTask?.data?.map((item, index) => ( familyTask?.data?.map((item, index) => (
<div <div
@@ -364,7 +364,7 @@ const AssignTaskPopout = ({
</div> </div>
)} )}
{taskType == "new" && ( {taskType == "new" && (
<div className="p-4 w-full h-[400px]"> <div className="p-4 w-full">
<NewTasks <NewTasks
formState={formState} formState={formState}
setFormState={setFormState} 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"> <p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide border-b-2">
{activeTask?.data?.title} {activeTask?.data?.title}
</p> </p>
<div className="my-3"> {/* <div className="my-3">
<Detail <Detail
label="Description" label="Description"
value={activeTask?.data?.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>
<div className="grid grid-cols-2"> <div className="grid grid-cols-2">
<div className="w-full"> <div className="w-full">
<div className="my-3 w-full flex items-center gap-1"> <div className="my-3 w-full flex items-center gap-1">
<label className="job-label"> <label className="job-label">
Price Reward
</label> </label>
<p className="p-1 text-sm text-slate-900 dark:text-white"> <p className="p-1 text-sm text-slate-900 dark:text-white">
{PriceFormatter( {PriceFormatter(
@@ -49,11 +49,91 @@ export default function NewTasks({ formState, setFormState }) {
return ( return (
<form className="w-full flex justify-between items-start"> <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 */} {/* 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 */} {/* Currency */}
<div className="field w-full mb-6 xl:mb-0"> <div className="field w-full">
<label <label
htmlFor="country" htmlFor="country"
className="job-label" className="job-label"
@@ -65,7 +145,7 @@ export default function NewTasks({ formState, setFormState }) {
id="country" id="country"
name="country" name="country"
value={formState.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} onChange={handleInputChange}
// onBlur={props.handleBlur} // onBlur={props.handleBlur}
> >
@@ -115,7 +195,7 @@ export default function NewTasks({ formState, setFormState }) {
</div> </div>
{/* Duration */} {/* Duration */}
<div className="field w-full mb-6 xl:mb-0"> <div className="field w-full">
<label <label
htmlFor="timeline_days" htmlFor="timeline_days"
className="job-label" className="job-label"
@@ -127,7 +207,7 @@ export default function NewTasks({ formState, setFormState }) {
id="timeline_days" id="timeline_days"
name="timeline_days" name="timeline_days"
value={formState.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} onChange={handleInputChange}
// onBlur={props.handleBlur} // onBlur={props.handleBlur}
> >
@@ -138,6 +218,7 @@ export default function NewTasks({ formState, setFormState }) {
</option> </option>
{publicArray.map(({ name, duration }, idx) => ( {publicArray.map(({ name, duration }, idx) => (
<option <option
key={idx}
className="text-slate-500 text-[13.975px]" className="text-slate-500 text-[13.975px]"
value={duration} value={duration}
> >
@@ -148,74 +229,19 @@ export default function NewTasks({ formState, setFormState }) {
)} )}
</select> </select>
</div> </div>
</div>
{/* Title */} {/* Banner Image */}
<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">
<div className="w-full"> <div className="w-full">
<label <div className="h-32 w-full">
htmlFor="Job Delivery Details" <img
className='job-label' src={selectImage}
> alt="task_banner_img"
Job Delivery Details className="w-full h-full object-contain"
{/* {props.errors.job_detail && props.touched.job_detail && <span className="text-[12px] text-red-500">{props.errors.job_detail}</span>} */} />
</label> </div>
<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> </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> </div>
</form> </form>
); );
+45 -5
View File
@@ -5,6 +5,7 @@ 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"; import NewPaginatedList from "../Pagination/NewPaginatedList";
import InfiniteScroll from "../infiniteScroll/InfiniteScroll";
export default function MainSection({ export default function MainSection({
className, className,
@@ -96,7 +97,9 @@ export default function MainSection({
</div> </div>
{/* end of contentDisplay toggler */} {/* end of contentDisplay toggler */}
</div> </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 <div
className={ className={
contentDisplay == "grid" contentDisplay == "grid"
@@ -120,11 +123,13 @@ export default function MainSection({
)} )}
</DataIteration> </DataIteration>
</div> </div>
</div> </div> */}
{/* {products?.length && {/* END OF OLD MARKET JOB LISTING */}
{products?.length ?
<NewPaginatedList <NewPaginatedList
data={products} data={products}
itemsPerPage={6} itemsPerPage={9}
filterItem='' filterItem=''
tableTitle='' tableTitle=''
> >
@@ -154,7 +159,42 @@ export default function MainSection({
) )
} }
</NewPaginatedList> </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>
</div> </div>
); );
@@ -16,6 +16,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
"offer_code": details?.offer_code, "offer_code": details?.offer_code,
"offer_uid": details?.offer_uid, "offer_uid": details?.offer_uid,
"job_uid": details?.job_uid, "job_uid": details?.job_uid,
"market_uid": details?.market_uid
} }
let room = `INTEREST-${details?.market_uid}` let room = `INTEREST-${details?.market_uid}`
sendJobInterestToOwner(message, room) sendJobInterestToOwner(message, room)
+7
View File
@@ -3,6 +3,7 @@ import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
import MainSection from "./MainSection"; import MainSection from "./MainSection";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb"; import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
import LoadingSpinner from "../Spinners/LoadingSpinner";
export default function MarketPlace({ commonHeadData }) { export default function MarketPlace({ commonHeadData }) {
let { jobLists } = useSelector((state) => state.jobLists); let { jobLists } = useSelector((state) => state.jobLists);
@@ -25,12 +26,18 @@ export default function MarketPlace({ commonHeadData }) {
} }
/> />
</div> </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 <MainSection
marketPlaceProduct={marketData} marketPlaceProduct={marketData}
categories={categories} categories={categories}
image_server={image_server} image_server={image_server}
className="mb-10" className="mb-10"
/> />
}
</Layout> </Layout>
</> </>
); );
+45 -22
View File
@@ -42,7 +42,11 @@ export default function NewPaginatedList({
filteredData?.slice(currentPage, numberOfSelection + currentPage) filteredData?.slice(currentPage, numberOfSelection + currentPage)
); );
}, [currentPage, filteredData]); }, [currentPage, filteredData]);
console.log("newData", newData, filteredData);
useEffect(()=>{
setCurrentPage(0)
},[itemsPerPage])
return ( return (
<div className="w-full"> <div className="w-full">
<h1 className="text-2xl mb-5 font-semibold">{tableTitle}</h1> <h1 className="text-2xl mb-5 font-semibold">{tableTitle}</h1>
@@ -74,27 +78,46 @@ export default function NewPaginatedList({
{/* show prev and next button if data exist */} {/* show prev and next button if data exist */}
{data.length > 0 && ( {data.length > 0 && (
<div className="mt-10 w-full flex gap-4 justify-center items-center"> <div className="mt-10 w-full flex gap-4 justify-center items-center">
<button <button
onClick={handlePrev} onClick={handlePrev}
className={`w-12 h-12 rounded-full flex justify-center items-center border ${ className={`w-12 h-12 rounded-full flex justify-center items-center transition-all duration-300 ${
currentPage == 0 currentPage == 0
? "text-slate-300 border-slate-300 dark:text-slate-400 dark:border-slate-400 pointer-events-none" ? "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-slate-300 dark:border-slate-300" : "text-slate-600 border-slate-600 dark:text-white dark:border-white"
} transition-all duration-500`} }`}
> >
&lt; &lt;
</button> </button>
<button
onClick={handleNext} {data.length && data.map((item, index)=>{
className={`w-12 h-12 rounded-full flex justify-center items-center border ${ if(index%itemsPerPage == 0 && index >= currentPage && index <= currentPage+itemsPerPage){
currentPage + numberOfSelection >= data.length return (
? "text-slate-300 border-slate-300 dark:text-slate-400 dark:border-slate-400 pointer-events-none" <button
: "text-slate-600 border-slate-600 dark:text-slate-300 dark:border-slate-300" key={index}
} transition-all duration-500`} onClick={handleNext}
> className={`w-12 h-12 rounded-full flex justify-center items-center border transition-all duration-300 ${
&gt; currentPage != index
</button> ? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400"
</div> : "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"
}`}
>
&gt;
</button>
</div>
)} )}
</div> </div>
); );
@@ -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 ( return (
<ModalCom action={onClose} situation={situation}> <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-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"> <div className="modal-header-con">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide"> <h1 className="modal-title">
Start Task Start Task
</h1> </h1>
<button <button
type="button" type="button"
className="text-[#374557] dark:text-red-500" className="modal-close-btn"
onClick={onClose} onClick={onClose}
> >
<svg <svg
@@ -153,7 +153,7 @@ function FamilyOfferJobPopout({ details, onClose, situation }) {
</svg> </svg>
</button> </button>
</div> </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="p-4 w-full md:w-3/4 md:border-r-2">
<div className="flex gap-2"> <div className="flex gap-2">
<div className="image-wrapper w-32"> <div className="image-wrapper w-32">
@@ -261,12 +261,12 @@ function FamilyOfferJobPopout({ details, onClose, situation }) {
</div> </div>
{/* close button */} {/* close button */}
<div className="p-6 flex justify-end"> <div className="modal-footer-wrapper flex justify-end">
<button <button
onClick={onClose} onClick={onClose}
disabled={requestStatus.loading} disabled={requestStatus.loading}
type="button" 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> <span className="text-gradient">Cancel</span>
</button> </button>
+6 -6
View File
@@ -103,13 +103,13 @@ function OfferJobPopout({ details, onClose, situation }) {
return ( return (
<ModalCom action={onClose} situation={situation}> <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-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"> <div className="modal-header-con">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide"> <h1 className="modal-title">
Start Task Start Task
</h1> </h1>
<button <button
type="button" type="button"
className="text-[#374557] dark:text-red-500" className="modal-close-btn"
onClick={onClose} onClick={onClose}
> >
<svg <svg
@@ -133,7 +133,7 @@ function OfferJobPopout({ details, onClose, situation }) {
</svg> </svg>
</button> </button>
</div> </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"> <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"> <p className="text-lg my-5 font-semibold text-slate-900 dark:text-white tracking-wide">
{details.title} {details.title}
@@ -234,12 +234,12 @@ function OfferJobPopout({ details, onClose, situation }) {
</div> </div>
{/* close button */} {/* close button */}
<div className="p-6 flex justify-end"> <div className="modal-footer-wrapper flex justify-end">
<button <button
onClick={onClose} onClick={onClose}
disabled={requestStatus.loading} disabled={requestStatus.loading}
type="button" 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> <span className="text-gradient">Cancel</span>
</button> </button>
+2 -1
View File
@@ -219,8 +219,9 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
const getMarketActiveJobList = async () => { const getMarketActiveJobList = async () => {
try { try {
const res = await apiCall.getActiveJobList(); const res = await apiCall.getActiveJobList();
dispatch(updateJobs(res.data)); dispatch(updateJobs({loading: false, ...res.data}));
} catch (error) { } catch (error) {
dispatch(updateJobs({loading: false}));
console.log("Error getting mode"); console.log("Error getting mode");
} }
}; };
+1 -1
View File
@@ -1,7 +1,7 @@
import { createSlice } from "@reduxjs/toolkit"; import { createSlice } from "@reduxjs/toolkit";
const initialState = { const initialState = {
jobLists: {} jobLists: {loading: true}
}; };
export const jobSlice = createSlice({ export const jobSlice = createSlice({