Compare commits

..

8 Commits

7 changed files with 855 additions and 656 deletions
File diff suppressed because it is too large Load Diff
@@ -1,10 +1,16 @@
import React, { useState, useRef } from 'react'
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import ModalCom from '../../Helpers/ModalCom'
import LoadingSpinner from '../../Spinners/LoadingSpinner'
import usersService from '../../../services/UsersService'
function CurrentTaskAction({jobDetails}) {
const apiCall = new usersService()
const navigate = useNavigate()
const [checked, setChecked] = useState(false)
const [reqStatus, setReqStatus] = useState({loading:false, status: false, message: ''})
@@ -20,16 +26,37 @@ function CurrentTaskAction({jobDetails}) {
// FUNCTION TO HANDLE WHEN USER CLICKS ON SEND FOR REVIEW AND ACCEPTANCE
const taskCompletedSubmit = () => {
setReqStatus({loading:true, status: false, message: ''})
if(!checked){
setReqStatus({loading:true, status: false, message: ''}) // Sets loading spinner active
let reqData = {
contract: jobDetails.contract,
contract_uid: jobDetails.contract_uid,
job_action: 'NOTIFY_COMPLETE',
}
if(!checked){ // checks that checkbox is selected
setReqStatus({loading:false, status: false, message: 'Please check the box above'})
return setTimeout(()=>{
setReqStatus({loading:false, status: false, message: ''})
}, 3000)
}
setTimeout(()=>{
setReqStatus({loading:false, status: false, message: ''})
}, 3000)
// API CALL TO MARK TASK AS COMPLETED BY WORKER
apiCall.taskCompleted(reqData).then((res)=>{
if(res.status != 200 || res.data.internal_return < 0){
setReqStatus({loading:false, status: false, message: 'unable to complete request. Try again'})
return
}
setReqStatus({loading:false, status: true, message: 'Task marked completed successfully'})
setTimeout(()=>{ // Sets popout to false and navigates user to /mytask after 3 seconds
popUpHandler()
navigate('/mytask', {replace: true})
}, 3000)
}).catch(err => {
setReqStatus({loading:false, status: false, message: 'Opps! Network error. Try again'})
}).finally(()=>{
setTimeout(()=>{
setReqStatus({loading:false, status: false, message: ''})
}, 3000)
})
}
return (
@@ -1,9 +1,14 @@
import React,{useState} from 'react'
import ModalCom from '../../Helpers/ModalCom'
import LoadingSpinner from '../../Spinners/LoadingSpinner'
import { useNavigate } from 'react-router-dom'
import usersService from '../../../services/UsersService'
function PastDueJobAction({jobDetails}) {
const apiCall = new usersService()
const navigate = useNavigate()
const [checked, setChecked] = useState(false)
const [extendedTime, setExtendedTime] = useState('') // VALUE OF NEW EXTENDED TIME
@@ -21,7 +26,7 @@ function PastDueJobAction({jobDetails}) {
setPopUp(prev => !prev)
}
// FUNCTION TO HANDLE WHEN USER CLICKS ON SEND FOR REVIEW AND ACCEPTANCE
// FUNCTION TO HANDLE WHEN OWNER CANCELS JOB
const cancelTask = () => {
setAction('cancel')
setReqStatus({loading:true, status: false, message: ''})
@@ -37,21 +42,41 @@ function PastDueJobAction({jobDetails}) {
}, 3000)
}
// FUNCTION TO HANDLE WHEN USER CLICKS ON SEND FOR REVIEW AND ACCEPTANCE
// FUNCTION TO HANDLE WHEN USER/OWNER CLICKS ON EXTEND TIMELINE FOR A JOB
const extendTime = () => {
setAction('extend')
setReqStatus({loading:true, status: false, message: ''})
if(!extendedTime){ // CHECKS IF EXTENDED TIME IS SELECTED
setReqStatus({loading:false, status: false, message: 'Please select extension duration'})
setReqStatus({loading:true, status: false, message: ''}) // Sets loading spinner active
let reqData = {
contract: jobDetails.contract,
contract_uid: jobDetails.contract_uid,
job_action: 'EXTEND_TIMELINE',
duration: Number(extendedTime)
}
if(!extendedTime){ // checks that timeline duration is selected
setReqStatus({loading:false, status: false, message: 'Please select timeline duration'})
return setTimeout(()=>{
setReqStatus({loading:false, status: false, message: ''})
}, 3000)
}
setTimeout(()=>{
setReqStatus({loading:false, status: false, message: ''})
}, 3000)
// API CALL EXTEND TIMELINE BY OWNER
apiCall.extendJobTimeline(reqData).then((res)=>{
if(res.status != 200 || res.data.internal_return < 0){
setReqStatus({loading:false, status: false, message: 'unable to complete request. Try again'})
return
}
setReqStatus({loading:false, status: true, message: 'Timeline extended successfully'})
setTimeout(()=>{ // Sets popout to false and navigates user to /my-pastdue-jobs after 3 seconds
popUpHandler()
navigate('/my-pastdue-jobs', {replace: true})
}, 3000)
}).catch(err => {
setReqStatus({loading:false, status: false, message: 'Opps! Network error. Try again'})
}).finally(()=>{
setTimeout(()=>{
setReqStatus({loading:false, status: false, message: ''})
}, 3000)
})
}
return (
@@ -149,7 +174,7 @@ function PastDueJobAction({jobDetails}) {
<option className='text-slate-500 text-lg' value='2'>1 days</option>
<option className='text-slate-500 text-lg' value='3'>3 days</option>
<option className='text-slate-500 text-lg' value='5'>5 days</option>
<option className='text-slate-500 text-lg' value='1'>1 week</option>
<option className='text-slate-500 text-lg' value='7'>1 week</option>
</select>
</div>
{reqStatus.loading && action=='extend' ?
@@ -1,17 +1,12 @@
import React, { useState } from "react";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import { useNavigate, useLocation } from "react-router-dom";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
export default function MyActiveJobTable({ MyJobList, className }) {
const navigate = useNavigate();
let {pathname} = useLocation()
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
let { pathname } = useLocation();
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
@@ -44,82 +39,88 @@ export default function MyActiveJobTable({ MyJobList, className }) {
{
<>
{MyJobList &&
MyJobList?.result_list &&
MyJobList.result_list.length > 0 ?
currentActiveJobList.map((value, index) => (
<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 w-full">
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px]">
<img
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.title}
</h1>
<div>{value.description}</div>
<span className="text-sm text-thin-light-gray">
Price:{" "}
<span className="text-purple">
{value.price * 0.01}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
</span>
</span>
<span className="text-sm text-thin-light-gray">
Expire:{" "}
<span className="text-purple">
{" "}
{value.expire}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Send to:{" "}
<span className="text-purple">
{" "}
{value.job_to}
</span>
</span>
</div>
</div>
</td>
MyJobList?.result_list &&
MyJobList.result_list.length > 0 ? (
currentActiveJobList.map((value, index) => {
let deliveryDate = value?.delivery_date?.split(" ")[0];
<td className="text-right py-4 px-2">
<div className="flex justify-center items-center">
<button
type="button"
onClick={() => {
navigate("/manage-active-job", {
state: {...value, pathname},
});
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
View
</button>
</div>
</td>
</tr>
))
:
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 w-full">
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px]">
<img
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.title}
</h1>
<div>{value.description}</div>
<span className="text-sm text-thin-light-gray">
Price:{" "}
<span className="text-purple">
{value.price * 0.01}
</span>
</span>
<div className="flex gap-4 items-center">
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
</span>
</span>
<span className="text-sm text-thin-light-gray">
Due:{" "}
<span className="text-purple">
{" "}
{deliveryDate}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Send to:{" "}
<span className="text-purple">
{" "}
{value.job_to === null
? "public"
: value.job_to}
</span>
</span>
</div>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<div className="flex justify-center items-center">
<button
type="button"
onClick={() => {
navigate("/manage-active-job", {
state: { ...value, pathname },
});
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
View
</button>
</div>
</td>
</tr>
);
})
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">
No Active Task!
</td>
<td className="p-2">No Active Task!</td>
</tr>
}
)}
</>
}
</tbody>
+1 -3
View File
@@ -12,9 +12,7 @@ export default function MyActiveJobs(props) {
console.log("AMEYE LOC1", props.MyJobList);
return (
<Layout>
<CommonHead
commonHeadData={props.commonHeadData}
/>
<CommonHead commonHeadData={props.commonHeadData} />
<div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full">
{/* heading */}
+105 -102
View File
@@ -45,123 +45,126 @@ export default function MyJobTable({ className, ActiveJobList }) {
: "none",
}}
>
{/* Adding this dark overlay in order to see the texts properly */}
{!ActiveJobList?.data.length && (
<div class="absolute inset-0 bg-black opacity-30"></div>
)}
{ActiveJobList.loading ? (
{ActiveJobList?.data.length > 0 && ActiveJobList.loading && (
<div className="w-full h-[520px] flex items-center justify-center">
<LoadingSpinner size="16" color="sky-blue" />
</div>
) : (
<div className="relative w-full sm:rounded-lg">
<div className="h-auto w-full">
{ActiveJobList?.data?.length > 0 ? (
currentTask?.map((task, idx) => (
<div
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] w-full flex justify-between items-center hover:bg-gray-50"
key={idx}
>
<div className="py-4 max-w-[80%]">
<div className="flex space-x-2 items-center">
<div className="w-full min-w-[60px] max-w-[60px] flex-[0.1] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage1}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{task?.title}
</h1>
<span className="text-base text-gray-600">
{task?.description}
)}
<div className="relative w-full sm:rounded-lg">
<div className="h-auto w-full">
{ActiveJobList?.data?.length > 0 &&
currentTask?.map((task, idx) => (
<div
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] w-full flex justify-between items-center hover:bg-gray-50"
key={idx}
>
<div className="py-4 max-w-[80%]">
<div className="flex space-x-2 items-center">
<div className="w-full min-w-[60px] max-w-[60px] flex-[0.1] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage1}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{task?.title}
</h1>
<span className="text-base text-gray-600">
{task?.description}
</span>
<span className="text-sm text-thin-light-gray">
Price:
<span className="text-purple ml-1">
{Number(task?.price) * 0.01}
</span>
<span className="text-sm text-thin-light-gray">
Price:
<span className="text-purple ml-1">
{Number(task?.price) * 0.01}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Duration:
<span className="text-purple ml-1">
{Number(task?.timeline_days) === 1
? `${task?.timeline_days} day`
: `${task?.timeline_days} day(s)`}
</span>
<span className="text-sm text-thin-light-gray">
Duration:
<span className="text-purple ml-1">
{Number(task?.timeline_days) === 1
? `${task?.timeline_days} day`
: `${task?.timeline_days} day(s)`}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Due Date:
<span className="text-purple ml-1">
{task?.delivery_date}
</span>
<span className="text-sm text-thin-light-gray">
Due Date:
<span className="text-purple ml-1">
{task?.delivery_date}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Confirmation:
<span className="text-purple ml-1">
{task?.contract}
</span>
<span className="text-sm text-thin-light-gray">
Confirmation:
<span className="text-purple ml-1">
{task?.contract}
</span>
</span>
</div>
</span>
</div>
</div>
<div className="flex justify-center items-center py-4 px-2">
<button
type="button"
onClick={() => {
navigate("/manage-active-job", {
state: { ...task, pathname },
});
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button>
</div>
</div>
))
) : ActiveJobList.status ? (
<div className="flex flex-col items-center justify-center gap-9 my-5">
<div className="p-2 font-bold text-3xl text-white whitespace-nowrap">
You currently have "0" task
</div>
<button
className="w-[115px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
onClick={navigateMarket}
>
{btnLoader ? (
<div className="signup btn-loader"></div>
) : (
"Find Task"
)}
</button>
</div>
) : (
<div className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<p className="p-2">Error Occurred! Unable to display Tasks!</p>
</div>
)}
</div>
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
ActiveJobList?.data?.length
? true
: false
}
data={ActiveJobList?.data}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
<div className="flex justify-center items-center py-4 px-2">
<button
type="button"
onClick={() => {
navigate("/manage-active-job", {
state: { ...task, pathname },
});
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button>
</div>
</div>
))}
{ActiveJobList?.data?.length <= 0 && (
<div className="flex flex-col items-center justify-center gap-9 my-5">
<div className="p-2 font-bold text-3xl text-white whitespace-nowrap">
You currently have "0" task
</div>
<button
className="w-[115px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
onClick={navigateMarket}
>
{btnLoader ? (
<div className="signup btn-loader"></div>
) : (
"Find Task"
)}
</button>
</div>
)}
{ActiveJobList?.internal_return < 0 && (
<div className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<p className="p-2">Error Occurred! Unable to display Tasks!</p>
</div>
)}
</div>
)}
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
ActiveJobList?.data?.length
? true
: false
}
data={ActiveJobList?.data}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
</div>
);
}
+24
View File
@@ -653,6 +653,30 @@ class usersService {
return this.postAuxEnd("/offersresponse", postData);
}
// END POINT FOR WORKER TO MARK TASK AS COMPLETED
taskCompleted(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 14015,
...reqData,
};
return this.postAuxEnd("/activetaskstatus", postData);
}
// END POINT FOR OWNER TO EXTEND TIMELINE/DURATON OF JOB
extendJobTimeline(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 14015,
...reqData,
};
return this.postAuxEnd("/activejobstatus ", postData);
}
/*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)