Compare commits

...

25 Commits

Author SHA1 Message Date
victorAnumudu a166ff87f1 Link task manage button to manage job page 2023-05-19 23:48:48 +01:00
ameye 3105320685 Merge branch 'edit-job' of WrenchBoard/Users-Wrench into master 2023-05-19 21:35:56 +00:00
Ebube 619dbcd1f9 pending title 2023-05-19 17:15:37 +01:00
Ebube f292baae23 edit job complete with corrected image sizes 2023-05-19 17:06:00 +01:00
ameye c0aad0a40e Merge branch 'table_reloading' of WrenchBoard/Users-Wrench into master 2023-05-19 13:48:39 +00:00
victorAnumudu e59ba567e7 made Job List Table to reload when user deletes or edits job 2023-05-19 14:44:14 +01:00
Ebube e109b2f8e5 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into edit-job 2023-05-19 11:29:01 +01:00
Ebube 688f10e4a4 clean up 1 2023-05-19 11:28:40 +01:00
ameye 9bbf5db544 Merge branch 'send_task_message' of WrenchBoard/Users-Wrench into master 2023-05-19 09:29:51 +00:00
victorAnumudu ffc6a23ac5 consumed sendtaskmessage and activejobmsglist APIs in manage active job list page 2023-05-19 10:10:35 +01:00
ameye ed7bd861de Merge branch 'edit-job' of WrenchBoard/Users-Wrench into master 2023-05-19 00:23:04 +00:00
Ebube 4f107df131 Merge branch 'master' into edit-job 2023-05-19 01:16:43 +01:00
ameye f64cdcb316 Merge branch 'user-country-display' of WrenchBoard/Users-Wrench into master 2023-05-19 00:07:16 +00:00
Ebube 7998eaf52d implemented api and fixed interface bug 2023-05-19 00:11:44 +01:00
CHIEFSOFT\ameye 2ac82ee20b Layout change 2023-05-18 17:14:56 -04:00
victorAnumudu f5575ecce5 disabled user country 2023-05-18 16:33:18 +01:00
victorAnumudu b5b95a9040 duplicate info removed 2023-05-18 16:15:37 +01:00
victorAnumudu 24f3a40a43 Only returns User Country as Default Country in Add Job Page 2023-05-18 16:12:14 +01:00
ameye 6803059ee5 Merge branch 'edit-job' of WrenchBoard/Users-Wrench into master 2023-05-18 10:52:39 +00:00
ameye 9d6533167a Merge branch 'text-underline' of WrenchBoard/Users-Wrench into master 2023-05-18 10:52:02 +00:00
Ebube 89399aa29a done with layout, needs an api 2023-05-18 10:22:34 +01:00
victorAnumudu a4236aeb5a paragraph text underlined 2023-05-17 22:24:16 +01:00
ameye 9ccac4b0aa Merge branch 'task-layout' of WrenchBoard/Users-Wrench into master 2023-05-17 08:03:44 +00:00
ameye 4b2f9d6e22 Merge branch 'sidemenu-bug-fix' of WrenchBoard/Users-Wrench into master 2023-05-17 08:02:50 +00:00
victorAnumudu 87523beba9 Side bar Menu Close Bug Fixed 2023-05-17 05:05:27 +01:00
24 changed files with 1564 additions and 2264 deletions
+373 -326
View File
@@ -1,351 +1,398 @@
import React, {useState, useEffect} from 'react'
import { Link, useNavigate } from 'react-router-dom';
import InputCom from '../Helpers/Inputs/InputCom';
import LoadingSpinner from '../Spinners/LoadingSpinner';
import usersService from '../../services/UsersService';
import React, { useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom";
import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService";
import { useSelector } from "react-redux";
import { Form, Formik } from "formik";
import * as Yup from "yup";
const validationSchema = Yup.object().shape({
country: Yup.string()
.min(1, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Country is required"),
price: Yup.number()
.typeError("you must specify a number")
.min(1, "Price must be greater than 0")
.required("Price is required"),
title: Yup.string()
.min(3, "Minimum 3 characters")
.max(100, "Maximum 25 characters")
.required("Title is required"),
description: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.required("Description is required"),
job_detail: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.required("Details is required"),
timeline_days: Yup.number()
country: Yup.string()
.min(1, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Country is required"),
price: Yup.number()
.typeError("you must specify a number")
.min(1, "Price must be greater than 0")
.required("Price is required"),
});
title: Yup.string()
.min(3, "Minimum 3 characters")
.max(100, "Maximum 25 characters")
.required("Title is required"),
description: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.required("Description is required"),
job_detail: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.required("Details is required"),
timeline_days: Yup.number()
.typeError("you must specify a number")
.min(1, "Price must be greater than 0")
.required("Timeline is required"),
});
let initialValues = { // initial values for formik
country: '',
price: 0,
title: '',
description: '',
job_detail: '',
timeline_days: ''
}
// let initialValues = {
// // initial values for formik
// country: "NG",
// price: 0,
// title: "",
// description: "",
// job_detail: "",
// timeline_days: "",
// };
function AddJob() {
const ApiCall = new usersService()
const navigate = useNavigate()
const ApiCall = new usersService();
const navigate = useNavigate();
let [pageLoading, setPageLoading] = useState(true) // State used for knowing when the page is mounting
let {userDetails} = useSelector((state)=> state.userDetails)
let [country, setCountry] = useState({loading: false, status: false, data:[]}) // To Hold the array of country getUserCountry returns
let [pageLoading, setPageLoading] = useState(true); // State used for knowing when the page is mounting
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message:''}) // Holds state when submit button is pressed
let [country, setCountry] = useState({
loading: true,
status: false,
data: [],
}); // To Hold the array of country getUserCountry returns
// FUNCTION TO GET COUNTRY
const getUserCountry = () =>{
setCountry(prev => ({...prev, loading:true}))
ApiCall.getSignupCountryData().then(res => {
if(res.data.internal_return < 1){
setCountry({loading: false, status: true, data:[]})
return
}
setCountry({loading: false, status: true, data:res.data.signup_country})
}).catch(err => {
setCountry({loading: false, status: false, data:[]})
})
}
let initialValues = {
// initial values for formik
country: userDetails.country,
price: "",
title: "",
description: "",
job_detail: "",
timeline_days: "",
};
// FUNCTION TO HANDLE ADD JOB FORM
const handleAddJob = (values, helpers) => {
setRequestStatus({loading: true, status: false, message:''})
ApiCall.jobManagerCreateJob(values).then(res => {
if(res.data.internal_return < 1){
setRequestStatus({loading: false, status: false, message:'Could not complete your request at the moment'})
return
}
setRequestStatus({loading: false, status: true, message:'Job Added Successfully'})
setTimeout(()=>{
navigate('/myjobs', {replace: true})
},1000)
let [requestStatus, setRequestStatus] = useState({
loading: false,
status: false,
message: "",
}); // Holds state when submit button is pressed
}).catch(err => {
setRequestStatus({loading: false, status: false, message:'Opps! soemthing went wrong. Try Again'})
}).finally(()=>{
setTimeout(()=>{
setRequestStatus({loading: false, status: false, message:''})
}, 5000)
})
}
// FUNCTION TO GET COUNTRY
const getUserCountry = () => {
setCountry((prev) => ({ ...prev, loading: true }));
ApiCall.getSignupCountryData()
.then((res) => {
if (res.data.internal_return < 1) {
setCountry({ loading: false, status: true, data: [] });
return;
}
setCountry({
loading: false,
status: true,
data: res.data.signup_country,
});
})
.catch((err) => {
setCountry({ loading: false, status: false, data: [] });
});
};
useEffect(()=>{
setPageLoading(false)
getUserCountry()
},[])
// FUNCTION TO HANDLE ADD JOB FORM
const handleAddJob = (values, helpers) => {
setRequestStatus({ loading: true, status: false, message: "" });
ApiCall.jobManagerCreateJob(values)
.then((res) => {
if (res.data.internal_return < 1) {
setRequestStatus({
loading: false,
status: false,
message: "Could not complete your request at the moment",
});
return;
}
setRequestStatus({
loading: false,
status: true,
message: "Job Added Successfully",
});
setTimeout(() => {
navigate("/myjobs", { replace: true });
}, 1000);
})
.catch((err) => {
setRequestStatus({
loading: false,
status: false,
message: "Opps! soemthing went wrong. Try Again",
});
})
.finally(() => {
setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
}, 5000);
});
};
return pageLoading.loading ? (
<div className="personal-info-tab w-full flex flex-col justify-between">
<div className="p-3">
<LoadingSpinner size="32" color="sky-blue" />
</div>
</div>
) : (
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleAddJob}
>
{(props) => {
return (
<Form>
<h1 className='py-2 my-4 text-lg md:text-xl font-bold tracking-wide'>Create New Job</h1>
<div className="flex flex-col-reverse sm:flex-row">
<div className="fields w-full">
{/* inputs starts here */}
{/* country */}
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
{/* <InputCom
fieldClass="px-6"
label="Country"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="text"
name="country"
// placeholder="Select Country"
value={props.values.country}
inputHandler={props.handleChange}
/> */}
<label
htmlFor='country'
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block">
Country
</label>
<select
id='country'
name='country'
value={props.values.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`}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{country.loading ? (
<option className="text-slate-500 text-lg" value="">
Loading...
</option>
) : country.data.length ? (
<>
<option className="text-slate-500 text-lg" value="">
Select...
</option>
{country.data.map((item, index) => (
<option
key={index}
className="text-slate-500 text-lg"
value={item[0]}
>
{item[1]}
</option>
))}
</>
) : (
<option className="text-slate-500 text-lg" value="">
No Options Found! Try Again
</option>
)}
</select>
{props.errors.country && props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)}
</div>
{/* Price */}
<div className="field w-full">
<InputCom
fieldClass="px-6"
label="Price"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="number"
name="price"
fieldClass='text-right'
// placeholder="Please Enter Amount"
value={props.values.price}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.price && props.touched.price && (
<p className="text-sm text-red-500">
{props.errors.price}
</p>
)}
</div>
</div>
useEffect(() => {
getUserCountry();
setPageLoading(false);
}, []);
{/* Title */}
return pageLoading.loading ? (
<div className="personal-info-tab w-full flex flex-col justify-between">
<div className="p-3">
<LoadingSpinner size="32" color="sky-blue" />
</div>
</div>
) : (
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleAddJob}
>
{(props) => {
return (
<Form>
<h1 className="py-2 my-4 text-lg md:text-xl font-bold tracking-wide">
Create New Job
</h1>
<div className="flex flex-col-reverse sm:flex-row">
<div className="fields w-full">
{/* inputs starts here */}
{/* country */}
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
{/* <InputCom
fieldClass="px-6 cursor-not-allowed"
label="Country"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="text"
name="country"
disable={true}
value={country.loading ? 'loading' : country.data ? country.data : 'no country found!'}
inputHandler={(e)=> setCountry((prev) => ({...prev, data:e.target.value}))}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Title"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="text"
name="title"
// placeholder="Enter Job Title"
value={props.values.title}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.title && props.touched.title && (
<p className="text-sm text-red-500">
{props.errors.title}
</p>
)}
</div>
{/* Description */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Description"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="text"
name="description"
// placeholder="Enter a description"
value={props.values.description}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.description && props.touched.description && (
<p className="text-sm text-red-500">
{props.errors.description}
</p>
)}
</div>
{/* Details */}
<div className="field w-full mb-6">
{/* <InputCom
fieldClass="px-6"
label="Job Delivery Details"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="text"
name="details"
// placeholder="Please Enter Detail Description of Job"
value={props.values.details}
inputHandler={props.handleChange}
/> */}
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'>
Job Delivery Details
</label>
<textarea name="details" id="Job Delivery Details" rows="7"
className={`input-field p-6 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
style={{resize:'none'}}
name='job_detail'
value={props.values.job_detail}
onChange={props.handleChange}
onBlur={props.handleBlur}
/>
{props.errors.job_detail && props.touched.job_detail && (
<p className="text-sm text-red-500">
{props.errors.job_detail}
</p>
)}
</div>
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Timeline"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="text"
name="timeline_days"
spanTag = ' - Expected duration of this task'
// placeholder="Please Enter Detail Description of Job"
value={props.values.timeline_days}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.timeline_days && props.touched.timeline_days && (
<p className="text-sm text-red-500">
{props.errors.timeline_days}
</p>
)}
</div>
{/* inputs ends here */}
</div>
</div>
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
<div className="content-footer w-full">
{/* error or success display */}
{requestStatus.message != "" && (
!requestStatus.status ?
(<div className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
{requestStatus.message}
</div>)
:
requestStatus.status &&
(<div className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
{requestStatus.message}
</div>
)
/> */}
<label
htmlFor="country"
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
>
Country
</label>
<select
id="country"
name="country"
disabled
value={props.values.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`}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{country.loading ? (
<option className="text-slate-500 text-lg" value="">
Loading...
</option>
) : country.data.length ? (
<>
<option className="text-slate-500 text-lg" value="">
Select...
</option>
{country.data.map((item, index) => {
if(item[0] == userDetails.country){
return (
<option
key={index}
className="text-slate-500 text-lg"
value={item[0]}
>
{item[1]}
</option>
)
}
})}
</>
) : (
<option className="text-slate-500 text-lg" value="">
No Options Found! Try Again
</option>
)}
{/* End of error or success display */}
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
<div className="flex items-center space-x-4 mr-9">
<Link
to="/myjobs"
className="text-18 text-light-red tracking-wide "
>
<span className="border-b dark:border-[#5356fb29] border-light-red">
{" "}
Cancel
</span>
</Link>
{requestStatus.loading ? (
<LoadingSpinner size="8" color="sky-blue" />
) : (
<button
type="submit"
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
// className='w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white'
>
Add Job
</button>
)}
</div>
</div>
</select>
{props.errors.country && props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)}
</div>
</Form>
);
}}
</Formik>
</div>
)
{/* Price */}
<div className="field w-full">
<InputCom
fieldClass="px-6 text-right"
label="Price"
labelClass="tracking-wide"
inputBg="bg-slate-100"
type="number"
name="price"
placeholder="0"
value={props.values.price}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.price && props.touched.price && (
<p className="text-sm text-red-500">
{props.errors.price}
</p>
)}
</div>
</div>
{/* Title */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Title"
labelClass="tracking-wide"
inputBg="bg-slate-100"
type="text"
name="title"
// placeholder="Enter Job Title"
value={props.values.title}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.title && props.touched.title && (
<p className="text-sm text-red-500">
{props.errors.title}
</p>
)}
</div>
{/* Description */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Description"
labelClass="tracking-wide"
inputBg="bg-slate-100"
type="text"
name="description"
// placeholder="Enter a description"
value={props.values.description}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.description && props.touched.description && (
<p className="text-sm text-red-500">
{props.errors.description}
</p>
)}
</div>
{/* Details */}
<div className="field w-full mb-6">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
>
Job Delivery Details
</label>
<textarea
id="Job Delivery Details"
rows="7"
className={`input-field p-6 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
style={{ resize: "none" }}
name="job_detail"
value={props.values.job_detail}
onChange={props.handleChange}
onBlur={props.handleBlur}
/>
{props.errors.job_detail && props.touched.job_detail && (
<p className="text-sm text-red-500">
{props.errors.job_detail}
</p>
)}
</div>
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Timeline"
labelClass="tracking-wide"
inputBg="bg-slate-100"
type="text"
name="timeline_days"
spanTag=" - Expected duration of this task"
// placeholder="Please Enter Detail Description of Job"
value={props.values.timeline_days}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.timeline_days &&
props.touched.timeline_days && (
<p className="text-sm text-red-500">
{props.errors.timeline_days}
</p>
)}
</div>
{/* inputs ends here */}
</div>
</div>
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
<div className="content-footer w-full">
{/* error or success display */}
{requestStatus.message != "" &&
(!requestStatus.status ? (
<div
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
) : (
requestStatus.status && (
<div
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
)
))}
{/* End of error or success display */}
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
<div className="flex items-center space-x-4 mr-9">
<Link
to="/myjobs"
className="text-18 text-light-red tracking-wide "
>
<span className="border-b dark:border-[#5356fb29] border-light-red">
{" "}
Cancel
</span>
</Link>
{requestStatus.loading ? (
<LoadingSpinner size="8" color="sky-blue" />
) : (
<button
type="submit"
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
// className='w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white'
>
Add Job
</button>
)}
</div>
</div>
</div>
</Form>
);
}}
</Formik>
</div>
);
}
export default AddJob
export default AddJob;
+66 -57
View File
@@ -4,7 +4,6 @@ import LoadingSpinner from "../Spinners/LoadingSpinner";
export default function FamilyTable({ className, familyList, loader }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
return (
<div
@@ -13,12 +12,12 @@ export default function FamilyTable({ className, familyList, loader }) {
}`}
>
<div className="relative w-full overflow-x-auto sm:rounded-lg">
{loader ? (
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
<LoadingSpinner size='16' color='sky-blue' />
</div>
) : (
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 relative">
{loader ? (
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
<LoadingSpinner size="16" color="sky-blue" />
</div>
) : (
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 relative">
<>
<thead className="sticky top-0">
<tr className="text-base text-thin-light-gray whitespace-nowrap border-b dark:border-[#5356fb29] default-border-bottom ">
@@ -31,55 +30,65 @@ export default function FamilyTable({ className, familyList, loader }) {
<tbody className="overflow-y-scroll h-auto">
<>
{familyList?.length > 0 ? (
familyList?.map(({ firstname, lastname, age }, idx) => (
<tr
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
key={idx}
>
<td className=" py-4">
<div className="flex space-x-2 items-center">
<div className="w-[60px] 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">
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
{`${firstname} ${lastname} (${age})`}
</h1>
<span className="text-sm text-thin-light-gray">
Added{" "}
<span className="text-purple">10-10-2029</span>
</span>
</div>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
10-10-2019
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
100
</span>
</div>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
familyList?.map(
(
{ firstname, lastname, age, added, last_login },
idx
) => {
let addedDate = added?.split(" ")[0];
return (
<tr
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
key={idx}
>
Manage
</button>
</td>
</tr>
))
<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={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 whitespace-nowrap">
{`${firstname} ${lastname} (${age})`}
</h1>
<span className="text-sm text-thin-light-gray">
Added:{" "}
<span className="text-purple ml-1">
{addedDate}
</span>
</span>
</div>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
{last_login}
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
100
</span>
</div>
</td>
<td className="text-right py-4 px-2 flex items-center justify-center">
<button
type="button"
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button>
</td>
</tr>
);
}
)
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2" colSpan="4">
@@ -90,8 +99,8 @@ export default function FamilyTable({ className, familyList, loader }) {
</>
</tbody>
</>
</table>
)}
</table>
)}
</div>
</div>
);
+4 -4
View File
@@ -211,7 +211,7 @@ const FamilyForm = ({
type="text"
parentClass="flex items-center gap-1 w-full"
labelClass="flex-[0.2] mb-0"
inputClass="flex-[0.8]"
inputClass="flex-[0.8] input-curve lg border border-[#dce4e9]"
fieldClass="px-2"
value={first_name}
inputHandler={inputHandler}
@@ -223,7 +223,7 @@ const FamilyForm = ({
type="text"
parentClass="flex items-center gap-1 w-full"
labelClass="flex-[0.2] mb-0"
inputClass="flex-[0.8]"
inputClass="flex-[0.8] input-curve lg border border-[#dce4e9]"
fieldClass="px-2"
value={last_name}
inputHandler={inputHandler}
@@ -242,11 +242,11 @@ const FamilyForm = ({
<select
name="age-selection"
id="age-selection"
className="input-wrapper border border-[#f5f8fa]] dark:border-[#5e6278] w-full rounded-[0.475rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent px-2"
className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-[35px] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent px-4"
onChange={ageHandler}
value={ageValue}
>
<option value={""}>Select your age</option>
<option value={""}>Select age</option>
{ageRange?.length > 0 &&
ageRange?.map((age) => (
<option value={age} key={age}>
@@ -82,7 +82,7 @@ export default function InputCom({
name={name}
minLength={minLengthValidation()}
maxLength={maxLengthValidation()}
pattern={() => inputPatterns}
// pattern={inputPatterns()}
ref={inputRef}
readOnly={disable}
onBlur={blurHandler}
+2 -2
View File
@@ -1,6 +1,6 @@
import React, { useEffect } from "react";
export default function ModalCom({ action, children, situation, isOpen }) {
export default function ModalCom({ action, children, situation, isOpen, className }) {
useEffect(() => {
if (situation) {
document.body.style.overflowY = "hidden";
@@ -16,7 +16,7 @@ export default function ModalCom({ action, children, situation, isOpen }) {
onClick={action || isOpen}
className="fixed top-0 left-0 w-full lg:h-[100vh] h-full bg-black bg-opacity-40 backdrop-filter backdrop-blur-sm z-50"
></div>
<div className="children-element fixed lg:h-100vh h-full z-[99999999999999] w-full lg:w-auto ">
<div className={`children-element fixed lg:h-100vh h-full z-[99999999999999] w-full lg:w-auto ${className}`}>
{children && children}
</div>
</div>
File diff suppressed because it is too large Load Diff
+103 -40
View File
@@ -1,38 +1,66 @@
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import ModalCom from "../Helpers/ModalCom";
import Layout from "../Partials/Layout";
import { useLocation, useNavigate } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import ActiveJobMessage from "./ActiveJobMessage";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService";
function ActiveJobs(props) {
const ApiCall = new usersService()
function ActiveJobs() {
let { userDetails } = useSelector((state) => state.userDetails);
let navigate = useNavigate()
let {state} = useLocation()
let [details, setDetails] = useState({})
let [messageToSend, setMessageToSend] = useState('') // State to hold the value of message to be sent
// console.log(state, userDetails);
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: ''})
useEffect(()=>{
if(!state){
navigate('/my-active-jobs', {replace: true})
// FUNCTION TO HANDLE MESSAGE CHANGE
const handleMessageChange = ({target:{value}}) => {
setMessageToSend(value)
}
// FUNCTION TO SEND TASK MESSAGE
const sendTaskMessage = () => {
let reqData={message: messageToSend, msg_type: 'TEXT', contract:props.details.contract}
if(!reqData.message){
setRequestStatus({loading: false, status: false, message: 'Message is empty'})
return setTimeout(()=>{
setRequestStatus({loading: false, status: false, message: ''})
}, 5000)
}
setDetails(state)
},[])
setRequestStatus({loading: true, status: false, message: ''})
ApiCall.sendTaskMessage(reqData).then((res)=>{
if(res.status != 200 || res.data.internal_return < 0){
setRequestStatus({loading: false, status: false, message: 'Message could not be sent, try again later'})
return
}
setRequestStatus({loading: false, status: true, message: 'Message Sent Successfully'})
props.reloadActiveJobList(prev => !prev) // MAKES ACTIVE JOB MESSAGE LIST TO RELOAD
setMessageToSend('') // SENDS MESSAGE TO SEND BACK TO EMPTY STRINGS
}).catch(error => {
setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong'})
}).finally(()=>{
setTimeout(()=>{
setRequestStatus({loading: false, status: false, message: ''})
}, 5000)
})
}
return (
<Layout>
{/* <div className="logout-modal-wrapper min-w-[850px] h-full lg:h-auto lg:rounded-2xl overflow-y-auto"> */}
<div className="p-4 lg:flex justify-between items-start space-y-4 lg:space-x-4 lg:space-y-0 rounded-lg shadow-lg bg-slate-100">
<div className="w-full lg:w-3/4">
<div className="w-full lg:w-1/2">
<div className="py-[20px] bg-white px-4 rounded-md shadow-md">
{/* back btn and title */}
<div className="w-full flex justify-start space-x-3 items-center">
<button
type="button"
className="text-[#374557] border border-sky-blue p-1 rounded-full"
onClick={() => navigate('/my-active-jobs', {replace: true})}
onClick={() => navigate(props.details.pathname, {replace: true})}
>
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -45,57 +73,84 @@ function ActiveJobs() {
</svg>
</button>
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
{details.title && details.title}
{props.details?.title && props.details.title}
</h1>
</div>
{/* END of back btn and title */}
<div className="mt-2 w-full lg:flex lg:justify-between lg:items-center lg:space-x-2">
<div className="my-2 lg:my-0">
<div className="mt-2 w-full flex flex-col-reverse lg:flex-row lg:justify-between lg:items-start lg:space-x-2">
<div className="w-full lg:w-2/3 my-2 lg:my-0">
<p className="text-base text-slate-700 dark:text-black">
{details.contract && details.contract}
{props.details?.contract && props.details.contract}
</p>
<p className="text-base text-slate-700 dark:text-black">
<span className="font-semibold">Description: </span>
{details.description && details.description}
{props.details?.description && props.details.description}
</p>
<p className="text-base text-sky-blue">Delivery Detail</p>
<div className="">
<p className="text-base text-slate-700 dark:text-black">
<span className="font-semibold">Due: </span>
{props.details?.delivery_date &&
props.details.delivery_date.split(" ")[0]}
</p>
<p className="text-base text-slate-700 dark:text-black">
{props.details?.delivery_date &&
props.details.delivery_date.split(" ")[1]}
</p>
<p className="text-base text-slate-700 dark:text-black">
{props.details?.timeline_days && props.details.timeline_days} day(s)
</p>
</div>
</div>
<div className="">
<div className="w-full lg:w-1/3 lg:text-center">
<p className="text-base text-sky-blue">
{userDetails.firstname && userDetails.firstname}
</p>
<p className="text-base text-slate-700 dark:text-black">
<span className="font-semibold">Due: </span>
{details.delivery_date &&
details.delivery_date.split(" ")[0]}
</p>
<p className="text-base text-slate-700 dark:text-black">
{details.delivery_date &&
details.delivery_date.split(" ")[1]}
</p>
<p className="text-base text-slate-700 dark:text-black">
{details.timeline_days && details.timeline_days} day(s)
</p>
</div>
</div>
</div>
<div className="mt-5 bg-white p-4 rounded-md shadow-md">
<div className="">
<p className="text-lg font-bold text-slate-600 dark:text-blask tracking-wide">Message(s)</p>
<p className="relative py-2 my-2 text-lg font-bold text-slate-600 dark:text-black border-b-2 border-slate-300 tracking-wide after:absolute after:-bottom-0.5 after:content-[''] after:w-[100px] after:h-[2px] after:bg-sky-blue after:left-0">Message(s)</p>
<textarea
className="p-4 w-full text-base text-slate-600 border border-slate-300 outline-none rounded-md"
className="p-4 w-full text-base text-slate-600 border-y border-slate-300 outline-none"
rows="10"
style={{ resize: "none" }}
name='message'
onChange={handleMessageChange}
value={messageToSend}
/>
</div>
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
<div className="w-full">
{/* error or success display */}
{requestStatus.message != "" &&
(!requestStatus.status ? (
<div
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
) : (
requestStatus.status && (
<div
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
)
))}
</div>
{/* End of error or success display */}
{/* Buttons Sections */}
<div className="py-2 mb-8 sm:flex sm:justify-center sm:items-center">
<div className="w-full sm:w-3/4 mb-5 sm:mb-0">
<div className="w-full sm:w-2/4 mb-5 sm:mb-0">
<button
onClick={()=> console.log('working')}
onClick={()=>{console.log('working')}}
type="button"
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-md flex justify-center items-center"
>
@@ -107,7 +162,7 @@ function ActiveJobs() {
</button>
</div>
<div className="w-full sm:w-1/4 flex justify-between items-center space-x-2">
<div className="w-full sm:w-2/4 flex justify-between items-center space-x-2">
<button
type="button"
className="bg-red-600 text-base text-white tracking-wide px-4 py-2 rounded-md hover:opacity-90"
@@ -115,10 +170,15 @@ function ActiveJobs() {
<span className="text-white">Clear</span>
</button>
<button
onClick={sendTaskMessage}
type="button"
className="btn-gradient text-base text-white tracking-wide px-4 py-2 rounded-md"
>
{requestStatus.loading ?
<LoadingSpinner size='6' color='sky-blue' />
:
<span className="text-white">Send</span>
}
</button>
</div>
@@ -128,7 +188,7 @@ function ActiveJobs() {
</div>
{/* ACTION SECTION */}
<div className="w-full lg:w-1/4 h-full">
<div className="w-full lg:w-1/2 h-full">
<div className="py-[20px] bg-white px-4 rounded-md shadow-md">
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">Actions</h1>
@@ -140,14 +200,17 @@ function ActiveJobs() {
<div className="mt-5 bg-white p-4 rounded-md shadow-md">
<div className="">
<p className="text-lg font-bold text-dark-gray dark:text-black tracking-wide">Message</p>
<ActiveJobMessage />
{props.activeJobMesList.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
<ActiveJobMessage activeJobMesList={props.activeJobMesList} />
}
</div>
</div>
</div>
</div>
{/* </div> */}
</Layout>
);
}
@@ -1,13 +1,14 @@
import React, { useState } from "react";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import { useNavigate } from "react-router-dom";
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()
const navigate = useNavigate();
let {pathname} = useLocation()
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
@@ -51,15 +52,15 @@ export default function MyActiveJobTable({ MyJobList, className }) {
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] rounded-full overflow-hidden flex justify-center items-center">
<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">
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.title}
</h1>
@@ -100,7 +101,9 @@ export default function MyActiveJobTable({ MyJobList, className }) {
<button
type="button"
onClick={() => {
navigate('/manage-active-job', {state:value});
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"
>
+233 -126
View File
@@ -1,145 +1,252 @@
import React, { useState } from "react";
import dataImage1 from "../../assets/images/data-table-user-1.png";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import dataImage3 from "../../assets/images/data-table-user-3.png";
import dataImage4 from "../../assets/images/data-table-user-4.png";
import SelectBox from "../Helpers/SelectBox";
import JobListPopout from "../jobPopout/JobListPopout";
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
import JobListPopout from "../jobPopout/JobListPopout";
import PaginatedList from "../Pagination/PaginatedList";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useSelector } from "react-redux";
import usersService from "../../services/UsersService";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
import EditJobPopOut from "../jobPopout/EditJobPopout";
export default function MyJobTable({MyJobList, className }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
const [myCountry, setCountries] = useState("");
const {
userDetails: { country },
} = useSelector((state) => state?.userDetails);
let [jobPopout,setJobPopout] = useState({show:false, data:{}}) // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
const userApi = useMemo(() => new usersService(), []);
let [deleteJobPopout,setDeleteJobPopout] = useState({show:false, data:{}}) // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
// Get Country Api
const getCountryList = useCallback(async () => {
const res = await userApi.getSignupCountryData();
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentJobList = MyJobList?.result_list?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e,setCurrentPage)
try {
if (res.status === 200) {
const {
data: { signup_country },
} = await res;
let checkCountry = signup_country
?.filter((item) => item[0] == country)
?.map((item, idx) => item[1])
.join("");
setCountries(checkCountry);
}
} catch (error) {
throw new Error(error);
}
}, [userApi, country]);
return (
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
<div className="header w-full flex justify-between items-center mb-5">
<div className="flex space-x-2 items-center">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
All Jobs
</h1>
</div>
<SelectBox
action={setCategory}
datas={filterCategories}
className="Update-table-dropdown"
contentBodyClasses="w-auto min-w-max"
/>
</div>
{MyJobList && MyJobList?.result_list &&
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
<tr className="text-base text-thin-light-gray border-b default-border-b dark:border-[#5356fb29] ottom ">
<td className="py-1">.</td>
<td className="py-1 text-right">.</td>
</tr>
useEffect(() => {
getCountryList();
}, [getCountryList]);
{selectedCategory === "All Categories" ? (
<>
{MyJobList && MyJobList?.result_list &&
MyJobList.result_list.length > 0 &&
currentJobList.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-9">
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
<div className="flex space-x-2 items-center job-items">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col">
<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>
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
</div>
</div>
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
<div className="min-w-[110px] max-w-[110px] bg-yellow-300 mx-2 rounded-md flex flex-nowrap space-x-2 justify-center items-center self-end">
<button type="button" className="p-2 w-[60px] h-11" onClick={()=>{setDeleteJobPopout({show:true, data:value})}}>[Delete]</button>
<span>|</span>
<button type="button" className="p-2 w-[40px] h-11">Edit</button>
</div>
</div>
let [deleteJobPopout, setDeleteJobPopout] = useState({
show: false,
data: {},
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
const [editJob, setEditJob] = useState({ show: false, data: {} });
</td>
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentJobList = MyJobList?.data?.result_list?.slice(
indexOfFirstItem,
indexOfLastItem
);
<td className="text-right py-9 px-2">
<button
type="button"
onClick={()=>{setJobPopout({show:true, data:value})}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button>
</td>
</tr>
))}
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
</>
) : selectedCategory === "Explore" ? (
<>
</>
) : (
<>
</>
)}
</tbody>
</table>
{/* PAGINATION BUTTON */}
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= MyJobList?.result_list?.length ? true : false} data={MyJobList?.result_list} start={indexOfFirstItem} stop={indexOfLastItem} />
{/* END OF PAGINATION BUTTON */}
</div>
}
{/* Job List Popout */}
{jobPopout.show &&
<JobListPopout details={jobPopout.data} onClose={()=>{setJobPopout({show:false, data:{}})}} situation={jobPopout.show} />
}
{/* End of Job List Popout */}
{/* Delete Job Popout */}
{deleteJobPopout.show &&
<DeleteJobPopout details={deleteJobPopout.data} onClose={()=>{setDeleteJobPopout({show:false, data:{}})}} situation={deleteJobPopout.show} />
}
{/* END of Delete Job Popout */}
return (
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
<div className="header w-full flex justify-between items-center mb-5">
<div className="flex space-x-2 items-center">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
All Jobs
</h1>
</div>
);
<SelectBox
action={setCategory}
datas={filterCategories}
className="Update-table-dropdown"
contentBodyClasses="w-auto min-w-max"
/>
</div>
{MyJobList.loading ? (
<LoadingSpinner size="16" color="sky-blue" />
) : (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
<tr className="text-base text-thin-light-gray border-b default-border-b dark:border-[#5356fb29] ottom ">
<td className="py-1">.</td>
<td className="py-1 text-right">.</td>
</tr>
{selectedCategory === "All Categories" ? (
<>
{MyJobList &&
MyJobList?.data?.result_list &&
MyJobList.data?.result_list.length > 0 &&
currentJobList.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-9">
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
<div className="flex space-x-2 items-center job-items 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>
</div>
</div>
<div className="min-w-[110px] max-w-[110px] bg-yellow-300 mx-2 rounded-md flex flex-nowrap space-x-2 justify-center items-center self-end">
<button
type="button"
className="p-2 w-[60px] h-11"
onClick={() => {
setDeleteJobPopout({
show: true,
data: value,
});
}}
>
[Delete]
</button>
<span>|</span>
<button
type="button"
className="p-2 w-[40px] h-11"
onClick={() => {
setEditJob({
show: true,
data: value,
});
}}
>
Edit
</button>
</div>
</div>
</td>
<td className="text-right py-9 px-2">
<button
type="button"
onClick={() => {
setJobPopout({ show: true, data: value });
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button>
</td>
</tr>
))}
</>
) : selectedCategory === "Explore" ? (
<></>
) : (
<></>
)}
</tbody>
</table>
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
MyJobList?.data?.result_list?.length
? true
: false
}
data={MyJobList?.data?.result_list}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
)}
{/* Job List Popout */}
{jobPopout.show && (
<JobListPopout
details={jobPopout.data}
onClose={() => {
setJobPopout({ show: false, data: {} });
}}
situation={jobPopout.show}
/>
)}
{/* End of Job List Popout */}
{/* Delete Job Popout */}
{deleteJobPopout.show && (
<DeleteJobPopout
details={deleteJobPopout.data}
onClose={() => {
setDeleteJobPopout({ show: false, data: {} });
}}
reloadJobList={reloadJobList}
situation={deleteJobPopout.show}
/>
)}
{/* END of Delete Job Popout */}
{editJob.show && (
<EditJobPopOut
details={editJob.data}
onClose={() => {
setEditJob({
show: false,
data: {},
});
}}
situation={editJob.show}
country={myCountry}
/>
)}
</div>
);
}
+3 -3
View File
@@ -18,7 +18,7 @@ export default function MyJobs(props) {
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold flex items-center space-x-1 text-dark-gray dark:text-white">
<h1 className="text-26 font-bold flex items-center space-x-1 text-dark-gray dark:text-white gap-2">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
@@ -27,7 +27,7 @@ export default function MyJobs(props) {
<Link
to="/add-job"
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
>
Add Job
</Link>
@@ -40,7 +40,7 @@ export default function MyJobs(props) {
></div>
</div>
</div>
<MyJobTable MyJobList={props.MyJobList} />
<MyJobTable MyJobList={props.MyJobList} reloadJobList={props.reloadJobList} />
</div>
</div>
</Layout>
@@ -1,112 +1,144 @@
import React, { useState } from "react";
import dataImage1 from "../../assets/images/data-table-user-1.png";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import dataImage3 from "../../assets/images/data-table-user-3.png";
import dataImage4 from "../../assets/images/data-table-user-4.png";
import SelectBox from "../Helpers/SelectBox";
import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
import PaginatedList from "../Pagination/PaginatedList";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
export default function MyPendingJobTable({MyJobList, className }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
export default function MyPendingJobTable({ MyJobList, className }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
let [jobPopout,setJobPopout] = useState({show:false, data:{}}) // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentActiveJobList = MyJobList?.result_list?.slice(
indexOfFirstItem,
indexOfLastItem
);
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentActiveJobList = MyJobList?.result_list?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e,setCurrentPage)
}
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
return (
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
{MyJobList && MyJobList?.result_list &&
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{/*<tr className="text-base text-thin-light-gray border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
{/* <td className="py-4">All Product</td>*/}
{/* <td className="py-4 text-right">.</td>*/}
{/*</tr>*/}
return (
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
{MyJobList && MyJobList?.result_list && (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{/*<tr className="text-base text-thin-light-gray border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
{/* <td className="py-4">All Product</td>*/}
{/* <td className="py-4 text-right">.</td>*/}
{/*</tr>*/}
{
<>
{MyJobList && 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">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col">
<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>
{
<>
{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>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
onClick={()=>{setJobPopout({show:true, data:value})}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
View
</button>
</td>
</tr>
))}
</>
}
</tbody>
</table>
{/* PAGINATION BUTTON */}
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= MyJobList?.result_list.length ? true : false} data={MyJobList?.result_list} start={indexOfFirstItem} stop={indexOfLastItem} />
{/* END OF PAGINATION BUTTON */}
</div>
<td className="text-right py-4 px-2">
<button
type="button"
onClick={() => {
setJobPopout({ show: true, data: value });
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
View
</button>
</td>
</tr>
))}
</>
}
</tbody>
</table>
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
MyJobList?.result_list.length
? true
: false
}
{/* Active Job Popout */}
{jobPopout.show &&
<PendingJobsPopout details={jobPopout.data} onClose={()=>{setJobPopout({show:false, data:{}})}} situation={jobPopout.show} />
}
{/* End of Active Job Popout */}
data={MyJobList?.result_list}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
);
)}
{/* Active Job Popout */}
{jobPopout.show && (
<PendingJobsPopout
details={jobPopout.data}
onClose={() => {
setJobPopout({ show: false, data: {} });
}}
situation={jobPopout.show}
/>
)}
{/* End of Active Job Popout */}
</div>
);
}
+45 -440
View File
@@ -1,48 +1,47 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import dataImage1 from "../../assets/images/data-table-user-1.png";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import dataImage3 from "../../assets/images/data-table-user-3.png";
import dataImage4 from "../../assets/images/data-table-user-4.png";
import SelectBox from "../Helpers/SelectBox";
import PaginatedList from "../Pagination/PaginatedList";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import {useNavigate, useLocation} from 'react-router-dom'
export default function MyJobTable({ className }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
let navigate = useNavigate()
let {pathname} = useLocation()
const [tasksData, setTasksData] = useState(null);
const [loader, setLoader] = useState(true);
let apiCall = useMemo(() => new usersService(), []);
const displayTasks = useCallback(async () => {
try {
const res = await apiCall.getMyActiveTaskList();
console.log('Ebube step', res)
let {
data: { result_list },
internal_return,
statusText,
} = await res;
data: { result_list },
internal_return,
statusText,
} = await res;
if (internal_return < 0 || statusText !== "OK") return;
setTasksData(result_list);
setLoader(false);
} catch (error) {
throw new Error(error);
}
}, [apiCall]);
useEffect(() => {
displayTasks()
}, [])
let data = ["1", "2", "3", "4", "5", "6"]; // to be replaced later by result from API CALL
displayTasks();
}, []);
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentTask = data.slice(indexOfFirstItem, indexOfLastItem);
const currentTask = tasksData?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
@@ -54,438 +53,29 @@ export default function MyJobTable({ className }) {
className || ""
}`}
>
{tasksData && (
{loader ? (
<div className="w-full h-[500px] flex items-center justify-center">
<LoadingSpinner size="16" color="sky-blue" />
</div>
) : (
<div className="relative w-full overflow-x-auto sm:rounded-lg">
{/* <table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
<tr className="text-base text-thin-light-gray whitespace-nowrap border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">
<td className="py-4">All Product</td>
<td className="py-4 text-center">Value</td>
<td className="py-4 text-center">USD</td>
<td className="py-4 text-center">24H%</td>
<td className="py-4 text-center">Bits</td>
<td className="py-4 text-center">Time</td>
<td className="py-4 text-right">Status</td>
</tr>
{selectedCategory === "All Categories"
? currentTask.map((item, 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">
<div className="w-[60px] 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">
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
Mullican Computer Joy
</h1>
<span className="text-sm text-thin-light-gray">
Owned by{" "}
<span className="text-purple">Xoeyam</span>
</span>
</div>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
fill="#627EEA"
/>
<path
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
fill="white"
/>
<path
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
fill="white"
/>
<path
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
fill="white"
fillOpacity="0.2"
/>
<path
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
fill="white"
fillOpacity="0.602"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
7473 ETH
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
fill="#59BE59"
/>
<path
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
fill="#FEFEFE"
/>
<path
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
fill="#59BE59"
/>
<path
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
fill="#59BE59"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
6392.99$
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<span className="text-base text-light-red whitespace-nowrap">
-24.75 (11.5%)
</span>
</td>
<td className="text-right py-4 px-2">
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
343
</span>
</td>
<td className="text-right py-4 px-2">
<span className="text-base text-thin-light-gray whitespace-nowrap">
2 Hours 1 min 30s
</span>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
className="text-sm text-white bg-purple px-2.5 py-1.5 rounded-full"
>
Active
</button>
</td>
</tr>
))
: selectedCategory === "Explore"
? currentTask.map((item, 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">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col">
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
Mullican Computer Joy
</h1>
<span className="text-sm text-thin-light-gray">
Owned by{" "}
<span className="text-purple">Xoeyam</span>
</span>
</div>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
fill="#627EEA"
/>
<path
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
fill="white"
/>
<path
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
fill="white"
/>
<path
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
fill="white"
fillOpacity="0.2"
/>
<path
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
fill="white"
fillOpacity="0.602"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
7473 ETH
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
fill="#59BE59"
/>
<path
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
fill="#FEFEFE"
/>
<path
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
fill="#59BE59"
/>
<path
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
fill="#59BE59"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
6392.99$
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<span className="text-base text-light-red whitespace-nowrap">
-24.75 (11.5%)
</span>
</td>
<td className="text-right py-4 px-2">
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
343
</span>
</td>
<td className="text-right py-4 px-2">
<span className="text-base text-thin-light-gray whitespace-nowrap">
2 Hours 1 min 30s
</span>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
className="text-sm text-white bg-purple px-2.5 py-1.5 rounded-full"
>
Active
</button>
</td>
</tr>
))
: currentTask.map((item, 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">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
src={dataImage3}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col">
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
Mullican Computer Joy
</h1>
<span className="text-sm text-thin-light-gray">
Owned by{" "}
<span className="text-purple">Xoeyam</span>
</span>
</div>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18Z"
fill="#627EEA"
/>
<path
d="M9.28125 2.25V7.23937L13.4983 9.12375L9.28125 2.25Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 2.25L5.0625 9.12375L9.28012 7.23937V2.25Z"
fill="white"
/>
<path
d="M9.28125 12.3582V15.7483L13.5011 9.91016L9.28125 12.3582Z"
fill="white"
fillOpacity="0.602"
/>
<path
d="M9.28012 15.7483V12.3576L5.0625 9.91016L9.28012 15.7483Z"
fill="white"
/>
<path
d="M9.28125 11.572L13.4983 9.12348L9.28125 7.24023V11.572Z"
fill="white"
fillOpacity="0.2"
/>
<path
d="M5.0625 9.12348L9.28012 11.572V7.24023L5.0625 9.12348Z"
fill="white"
fillOpacity="0.602"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
7473 ETH
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<div className="flex space-x-1 items-center justify-center">
<span>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.55225 0C7.8457 0 8.13914 0 8.43205 0C8.44829 0.026534 8.47537 0.0151623 8.49756 0.0162453C9.28966 0.0649812 10.0606 0.220936 10.8013 0.505229C12.7699 1.26172 14.2323 2.58354 15.183 4.46638C15.5999 5.29218 15.8506 6.16997 15.9561 7.08891C15.9691 7.201 15.9621 7.3158 16 7.42465C16 7.80858 16 8.19251 16 8.57698C15.9778 8.5916 15.9854 8.61543 15.9838 8.63546C15.9475 9.10387 15.8744 9.56686 15.7515 10.0206C15.1787 12.1342 13.9524 13.7603 12.0818 14.8942C11.1516 15.4579 10.1397 15.8002 9.06064 15.941C8.89497 15.9626 8.72875 15.98 8.56308 15.9995C8.17217 15.9995 7.78127 15.9995 7.39036 16C7.3752 15.9789 7.35138 15.9865 7.33135 15.9848C6.96752 15.9545 6.60639 15.9009 6.25068 15.8197C4.77639 15.4829 3.48998 14.793 2.4131 13.7311C0.998917 12.3372 0.204656 10.6461 0.0270709 8.66687C0.0205739 8.59431 0.033568 8.51904 0 8.44972C0 8.15081 0 7.85244 0 7.55352C0.0265295 7.53403 0.0151597 7.50479 0.016784 7.47988C0.0730915 6.64162 0.251218 5.83044 0.564158 5.05066C1.10179 3.71043 1.93774 2.59058 3.07634 1.70142C4.33839 0.715876 5.77098 0.159745 7.36762 0.0270755C7.4288 0.0216604 7.49432 0.0341151 7.55225 0ZM7.24635 9.86252C7.24635 10.2383 7.24526 10.6147 7.24743 10.9905C7.24797 11.0457 7.23389 11.0679 7.17596 11.0593C7.09691 11.0479 7.01678 11.0446 6.93774 11.0338C6.26746 10.9461 5.63563 10.7371 5.03952 10.4192C5.00379 10.4002 4.97834 10.3802 4.9621 10.4425C4.81375 11.0176 4.66324 11.5926 4.51164 12.1666C4.50027 12.2094 4.51272 12.2278 4.54954 12.2473C4.66486 12.3096 4.78235 12.3665 4.90309 12.4152C5.5961 12.6968 6.31998 12.8408 7.06497 12.8842C7.14131 12.8885 7.16134 12.9112 7.1608 12.9865C7.15701 13.4159 7.16026 13.8453 7.15809 14.2747C7.15755 14.3397 7.17488 14.3619 7.2431 14.3614C7.69085 14.3581 8.13914 14.3576 8.5869 14.3614C8.66432 14.3619 8.67731 14.3359 8.67731 14.2666C8.67461 13.8026 8.67677 13.3385 8.67461 12.8744C8.67407 12.8089 8.68544 12.7786 8.76015 12.765C9.09962 12.7049 9.4288 12.6058 9.74228 12.4607C10.3498 12.1802 10.8408 11.7703 11.1603 11.1724C11.4288 10.6699 11.51 10.1327 11.4618 9.56957C11.4158 9.03239 11.2366 8.55207 10.8787 8.14431C10.5506 7.77121 10.1402 7.51129 9.69843 7.29522C9.39145 7.14523 9.07363 7.02284 8.75041 6.91129C8.7098 6.89721 8.67407 6.88693 8.67407 6.82736C8.67623 6.14993 8.67569 5.4725 8.67461 4.79507C8.67461 4.75121 8.68489 4.73117 8.73308 4.73767C8.87547 4.75717 9.01895 4.77016 9.16134 4.79236C9.634 4.86493 10.0796 5.02467 10.5116 5.22395C10.5717 5.25157 10.5945 5.24886 10.6123 5.17684C10.7434 4.6467 10.8771 4.1171 11.0162 3.58913C11.0379 3.5079 11.0244 3.47541 10.948 3.44076C10.2799 3.13751 9.57282 3.01025 8.8457 2.97614C8.78018 2.97289 8.76123 2.95556 8.76178 2.88896C8.76503 2.50232 8.76232 2.11568 8.76448 1.72904C8.76503 1.66785 8.75041 1.64727 8.68489 1.64727C8.23173 1.64998 7.77802 1.64998 7.32485 1.64727C7.26151 1.64673 7.24418 1.66406 7.24418 1.72742C7.24689 2.1433 7.24256 2.55972 7.24797 2.9756C7.24905 3.06116 7.2209 3.08661 7.14239 3.10285C6.73579 3.18679 6.34651 3.32271 5.98646 3.53281C5.20628 3.98822 4.72117 4.64724 4.61938 5.5586C4.51597 6.48837 4.83812 7.2427 5.57661 7.81778C6.05739 8.19251 6.60639 8.43781 7.1738 8.64683C7.2274 8.66633 7.24743 8.68907 7.24689 8.7481C7.24472 9.12066 7.24635 9.49159 7.24635 9.86252Z"
fill="#59BE59"
/>
<path
d="M7.2452 9.86252C7.2452 9.49158 7.24358 9.12119 7.24683 8.75026C7.24737 8.69123 7.22734 8.66903 7.17374 8.64899C6.60687 8.43997 6.05787 8.19467 5.57655 7.81994C4.8386 7.24486 4.51591 6.49053 4.61933 5.56076C4.72057 4.6494 5.20568 3.99092 5.98641 3.53497C6.34645 3.32486 6.73519 3.18894 7.14233 3.10501C7.22084 3.08876 7.24899 3.06277 7.24791 2.97775C7.2425 2.56187 7.24683 2.14545 7.24412 1.72957C7.24358 1.66621 7.2609 1.64888 7.32479 1.64943C7.77796 1.65213 8.23167 1.65213 8.68483 1.64943C8.7498 1.64888 8.76442 1.66946 8.76442 1.73119C8.76171 2.11783 8.76496 2.50447 8.76171 2.89111C8.76117 2.95717 8.78012 2.97504 8.84563 2.97829C9.57276 3.01295 10.2793 3.13966 10.948 3.44291C11.0243 3.47757 11.0373 3.51006 11.0162 3.59128C10.877 4.11926 10.7433 4.64885 10.6123 5.17899C10.5944 5.25156 10.5717 5.25372 10.5116 5.2261C10.079 5.02683 9.63394 4.86708 9.16128 4.79452C9.01889 4.77286 8.87595 4.75932 8.73302 4.73983C8.68483 4.73333 8.67455 4.75337 8.67455 4.79723C8.67563 5.47466 8.67617 6.15209 8.674 6.82952C8.674 6.88908 8.70974 6.89937 8.75034 6.91345C9.07303 7.02446 9.39138 7.14684 9.69837 7.29738C10.1396 7.51344 10.5506 7.77283 10.8787 8.14647C11.2365 8.55369 11.4157 9.03455 11.4618 9.57173C11.51 10.1349 11.4287 10.6726 11.1602 11.1746C10.8408 11.7724 10.3497 12.1818 9.74222 12.4629C9.42874 12.608 9.09956 12.7071 8.76009 12.7672C8.68483 12.7802 8.674 12.811 8.67455 12.8766C8.67671 13.3406 8.67455 13.8047 8.67725 14.2688C8.67779 14.3381 8.66426 14.3646 8.58684 14.3636C8.13908 14.3598 7.69079 14.3608 7.24304 14.3636C7.17536 14.3641 7.15803 14.3424 7.15803 14.2769C7.1602 13.8475 7.15695 13.4181 7.16074 12.9887C7.16128 12.9128 7.14179 12.8906 7.06491 12.8863C6.31992 12.843 5.59658 12.699 4.90303 12.4174C4.78229 12.3681 4.66426 12.3112 4.54948 12.2495C4.51321 12.23 4.50075 12.2116 4.51158 12.1688C4.66318 11.5943 4.81369 11.0197 4.96204 10.4446C4.97829 10.3824 5.00373 10.4024 5.03947 10.4214C5.63557 10.7387 6.2674 10.9477 6.93768 11.036C7.01672 11.0463 7.09685 11.0501 7.1759 11.0614C7.23383 11.0695 7.24737 11.0479 7.24737 10.9927C7.24412 10.6147 7.2452 10.2383 7.2452 9.86252ZM8.68537 9.36325C8.67942 9.37245 8.67455 9.37678 8.67455 9.38112C8.674 9.83978 8.67401 10.2984 8.67292 10.7571C8.67292 10.8177 8.70216 10.7928 8.72598 10.7755C8.82452 10.7046 8.90736 10.619 8.96691 10.5123C9.17698 10.1333 9.05679 9.63725 8.68537 9.36325ZM7.23871 6.11147C7.23871 5.75354 7.23871 5.40589 7.23871 5.05174C6.92522 5.33982 6.92522 5.77249 7.23871 6.11147Z"
fill="#FEFEFE"
/>
<path
d="M8.68433 9.36328C9.05574 9.63729 9.17539 10.1333 8.96586 10.5118C8.90631 10.619 8.82347 10.7046 8.72493 10.775C8.70111 10.7918 8.67188 10.8172 8.67188 10.7566C8.67242 10.2979 8.67296 9.83927 8.6735 9.38061C8.67404 9.37682 8.67891 9.37249 8.68433 9.36328Z"
fill="#59BE59"
/>
<path
d="M7.23882 6.11149C6.92533 5.77305 6.92587 5.33984 7.23882 5.05176C7.23882 5.40591 7.23882 5.75355 7.23882 6.11149Z"
fill="#59BE59"
/>
</svg>
</span>
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
6392.99$
</span>
</div>
</td>
<td className="text-center py-4 px-2">
<span className="text-base text-light-red whitespace-nowrap">
-24.75 (11.5%)
</span>
</td>
<td className="text-right py-4 px-2">
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
343
</span>
</td>
<td className="text-right py-4 px-2">
<span className="text-base text-thin-light-gray whitespace-nowrap">
2 Hours 1 min 30s
</span>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
className="text-sm text-white bg-purple px-2.5 py-1.5 rounded-full"
>
Active
</button>
</td>
</tr>
))}
</tbody>
</table> */}
<div className="overflow-y-scroll h-auto w-full">
<div className="overflow-y-auto h-auto w-full">
{tasksData?.length > 0 ? (
tasksData?.map((task, idx) => (
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">
<div className="flex space-x-2 items-center">
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<div className="w-full 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">
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
{task?.title}
</h1>
@@ -494,19 +84,29 @@ export default function MyJobTable({ className }) {
</span>
<span className="text-sm text-thin-light-gray">
Price:
<span className="text-purple ml-1">{task?.price}</span>
<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-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-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-purple ml-1">
{task?.contract}
</span>
</span>
</div>
</div>
@@ -515,6 +115,11 @@ export default function MyJobTable({ className }) {
<div className="text-right 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
@@ -537,11 +142,11 @@ export default function MyJobTable({ className }) {
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
data.length
tasksData?.length
? true
: false
}
data={data}
data={tasksData}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
+1 -1
View File
@@ -3,7 +3,7 @@ import { createRoutesFromChildren } from 'react-router-dom';
const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
if(data.length){
if(data.length > process.env.REACT_APP_ITEM_PER_PAGE){
return (
<div className='p-3 flex justify-center items-center space-x-2 border-t-2'>
{/* Render pagination buttons */}
+2 -2
View File
@@ -505,9 +505,9 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</div>
<div className="heading border-b dark:border-[#5356fb29] border-light-purple px-7 py-2">
<h3 className="text-xl font-bold text-dark-gray dark:text-white">
Surname
Fullname
</h3>
<p className="text-sm text-gray-400 dark:text-white hover:text-sky-blue cursor-pointer">broklinslam_75@gamil.com</p>
<p className="text-base text-gray-400 dark:text-white hover:text-sky-blue cursor-pointer">{`${firstname} ${lastname}`}</p>
</div>
<div className="content">
<ul className="px-7">
+93 -24
View File
@@ -112,7 +112,7 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
title={name}
route={path}
bubble={bubble}
sidebar
sidebar = {sidebar}
/>
))}
{/*<li className="item group">*/}
@@ -220,34 +220,103 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
</ul>
</div>
</div>
{/*<div className="setting-item">*/}
{/* <div class="heading bg-pink dark:bg-dark-white rounded-2xl p-6 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">*/}
{/* <NavLink to="/acc-family">*/}
{/* <span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">*/}
{/* Family Account*/}
{/* </span>*/}
{/* </NavLink>*/}
{/* </div>*/}
{/*</div>*/}
<div className="setting-item">
<div className="heading mb-5 bg-dark-blue rounded-2xl p-2 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border">
<NavLink to="/acc-family">
<h1 className="title text-xl font-bold text-purple">
Family Corner
</h1>
</NavLink>
{/* <div className="setting-item">
<div class="heading bg-pink dark:bg-dark-white rounded-2xl p-6 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">
<NavLink to="/acc-family">
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">
Family Account
</span>
</NavLink>
</div>
</div> */}
{/* menu and settings item */}
<div className="menu-setting-items mb-11">
{/* menus item */}
<div className={`menu-item transition-all duration-300 ease-in-out ${
sidebar ? "mb-14" : ""
}`}>
{/* <div className="heading mb-5 bg-dark-blue rounded-2xl p-2 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border">
<NavLink to="/acc-family">
<h1 className="title text-xl font-bold text-purple">
Family Corner
</h1>
</NavLink>
</div> */}
<div className="items">
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-purple">Family</h1>
</div>
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
to="/acc-family"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="people-two" />
</span>
<span
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
Family Corner
</span>
</NavLink>
</li>
</ul>
</div>
</div>
</div>
{!userDetails.post_jobs ? (
<div className="setting-item">
<div className="top-platform bg-pink dark:bg-dark-white rounded-2xl p-16 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">
<NavLink to="/start-job">
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">
Enable Job Post
</span>
</NavLink>
<div className="menu-setting-items mb-11">
{/* menus item */}
<div className={`menu-item transition-all duration-300 ease-in-out bg-pink dark:bg-dark-white rounded-2xl p-3 ${
sidebar ? "mb-14" : "rounded-none p-0"
}`}>
{/* <div className="setting-item">
<div className="top-platform bg-pink dark:bg-dark-white rounded-2xl p-16 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border">
<NavLink to="/start-job">
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">
Enable Job Post
</span>
</NavLink>
</div>
</div> */}
<div className="items">
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-purple">Job Post</h1>
</div>
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
to="/start-job"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="people-two" />
</span>
<span
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
Enable Job Post
</span>
</NavLink>
</li>
</ul>
</div>
</div>
</div>
) : jobLists?.result_list?.length ? (
+8 -5
View File
@@ -3,8 +3,11 @@ import ModalCom from '../Helpers/ModalCom'
import { useNavigate } from 'react-router-dom'
import usersService from '../../services/UsersService'
import LoadingSpinner from '../Spinners/LoadingSpinner'
import { useDispatch } from 'react-redux'
import { tableReload } from '../../store/TableReloads'
function DeleteJobPopout({details, onClose, situation}) {
let dispatch = useDispatch()
const navigate = useNavigate()
const ApiCall = new usersService()
@@ -26,10 +29,10 @@ function DeleteJobPopout({details, onClose, situation}) {
}
setRequestStatus({laoding: false, status:true, message: 'Job deleted successfully'})
setTimeout(()=>{
navigate('/myjobs', {replace: true})
onClose()
window.location.reload()
}, 1000)
dispatch(tableReload({type:'JOBTABLE'}))
navigate('/myjobs', {replace: true})
onClose()
}, 1000)
}).catch(error => {
setRequestStatus({laoding: false, status:false, message: 'Opps! something went wrong, try again'})
}).finally(()=>{
@@ -97,7 +100,7 @@ function DeleteJobPopout({details, onClose, situation}) {
{details.title}
</p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
Price: {details.price}
Price: {details.price * 0.01}
</p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
Duration: {details.timeline_days} day(s)
+318
View File
@@ -0,0 +1,318 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import ModalCom from "../Helpers/ModalCom";
import { Form, Formik } from "formik";
import * as Yup from "yup";
import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService";
import { useNavigate } from "react-router-dom";
import { tableReload } from "../../store/TableReloads";
import { useDispatch } from "react-redux";
const EditJobPopOut = ({ details, onClose, situation, country }) => {
const dispatch = useDispatch()
let [requestStatus, setRequestStatus] = useState({
loading: false,
status: false,
message: "",
}); // Holds state when submit button is pressed
const validationSchema = Yup.object().shape({
country: Yup.string()
.min(1, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Country is required"),
price: Yup.number()
.typeError("you must specify a number")
.min(1, "Price must be greater than 0")
.required("Price is required"),
title: Yup.string()
.min(3, "Minimum 3 characters")
.max(100, "Maximum 25 characters")
.required("Title is required"),
description: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.required("Description is required"),
job_detail: Yup.string()
.min(3, "Minimum 3 characters")
.max(250, "Maximum 250 characters")
.required("Details is required"),
timeline_days: Yup.number()
.typeError("you must specify a number")
.min(1, "Price must be greater than 0")
.required("Price is required"),
});
let initialValues = {
// initial values for formik
country: country,
price: details?.price,
title: details?.title,
description: details?.description,
job_detail: details?.job_detail,
timeline_days: details?.timeline_days,
};
const jobApi = useMemo(() => new usersService(), []);
const navigate = useNavigate();
const handleEditJob = useCallback(
async (values) => {
setRequestStatus({ loading: true, message: "" });
let reqData = {
job_id: details.job_id,
job_uid: details.job_uid,
...values,
};
delete reqData?.country
try {
let res = await jobApi.jobManagerUpdateJob(reqData);
let { data } = await res;
if (data?.internal_return < 0) return;
setRequestStatus({ loading: false, message: null });
setTimeout(() => {
dispatch(tableReload({type:'JOBTABLE'}))
navigate("/myjobs", { replace: true });
onClose();
}, 1000);
} catch (error) {
setRequestStatus({ loading: false, message: error });
throw new Error(error);
}
},
[jobApi, navigate, onClose, details]
);
return (
<ModalCom action={onClose} situation={situation} className="edit-popup">
<div className="logout-modal-wrapper lg:w-[600px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="logout-modal-header w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b border-light-purple dark:border-[#5356fb29] ">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Edit Job
</h1>
<button
type="button"
className="text-[#374557] dark:text-red-500"
onClick={onClose}
>
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
fill=""
fillOpacity="0.6"
/>
<path
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
fill="#"
fillOpacity="0.6"
/>
</svg>
</button>
</div>
<div className="logout-modal-body w-full flex flex-col items-center px-10 py-8">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleEditJob}
>
{(props) => (
<Form className="w-full">
<div className="flex flex-col-reverse sm:flex-row">
<div className="fields w-full">
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
<InputCom
fieldClass="px-6 cursor-default"
label="Country"
labelClass="tracking-wide"
inputBg="bg-slate-100"
inputClass="input-curve lg border border-light-purple"
type="text"
name="country"
value={props.values.country}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
disable={true}
/>
{props.errors.country && props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)}
</div>
{/* Price */}
<div className="field w-full">
<InputCom
fieldClass="px-6 text-right"
label="Price"
labelClass="tracking-wide"
inputBg="bg-slate-100"
inputClass="input-curve lg border border-light-purple"
type="number"
name="price"
// placeholder="Please Enter Amount"
value={props.values.price * 0.01}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.price && props.touched.price && (
<p className="text-sm text-red-500">
{props.errors.price}
</p>
)}
</div>
</div>
{/* Title */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Title"
labelClass="tracking-wide"
inputBg="bg-slate-100"
inputClass=" input-curve lg border border-light-purple"
type="text"
name="title"
// placeholder="Enter Job Title"
value={props.values.title}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.title && props.touched.title && (
<p className="text-sm text-red-500">
{props.errors.title}
</p>
)}
</div>
{/* Description */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Description"
labelClass="tracking-wide"
inputBg="bg-slate-100"
inputClass=" input-curve lg border border-light-purple"
type="text"
name="description"
// placeholder="Enter a description"
value={props.values.description}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.description &&
props.touched.description && (
<p className="text-sm text-red-500">
{props.errors.description}
</p>
)}
</div>
{/* Details */}
<div className="field w-full mb-6">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block mb-3'
>
Job Delivery Details
</label>
<textarea
id="Job Delivery Details"
rows="5"
className={`input-field px-6 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] border border-[#dce4e9] rounded-[10px]`}
style={{ resize: "none" }}
name="job_detail"
value={props.values.job_detail}
onChange={props.handleChange}
onBlur={props.handleBlur}
/>
{props.errors.job_detail && props.touched.job_detail && (
<p className="text-sm text-red-500">
{props.errors.job_detail}
</p>
)}
</div>
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Timeline"
labelClass="tracking-wide"
inputBg="bg-slate-100"
inputClass=" input-curve lg border border-[#dce4e9]"
type="text"
name="timeline_days"
spanTag=" - Expected duration of this task"
// placeholder="Please Enter Detail Description of Job"
value={props.values.timeline_days}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.timeline_days &&
props.touched.timeline_days && (
<p className="text-sm text-red-500">
{props.errors.timeline_days}
</p>
)}
</div>
{/* inputs ends here */}
</div>
</div>
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
<div className="content-footer w-full">
{/* error or success display */}
{requestStatus.message != "" &&
(!requestStatus.status ? (
<div
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
) : (
requestStatus.status && (
<div
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
)
))}
{/* End of error or success display */}
<div className="w-full border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
<div className="flex items-center space-x-4 mr-2 mt-2">
{requestStatus.loading ? (
<LoadingSpinner size="6" color="sky-blue" />
) : (
<button
type="submit"
className="w-[120px] h-[40px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
// className='w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white'
>
Edit Job
</button>
)}
</div>
</div>
</div>
</Form>
)}
</Formik>
</div>
</div>
</ModalCom>
);
};
export default EditJobPopOut;
@@ -7,10 +7,10 @@ function PendingJobsPopout({details, onClose, situation}) {
return (
<ModalCom action={onClose} situation={situation}>
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
<div className="logout-modal-header w-full flex items-center justify-end 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">
Confirm
</h1> */}
<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">
Manage Pending Item
</h1>
<button
type="button"
className="text-[#374557] dark:text-red-500"
+8
View File
@@ -770,4 +770,12 @@ TODO: Responsive ===========================
border-bottom-right-radius: 50px;
background-color: #fff;
background: linear-gradient(134.38deg, #f539f8 0%, #c342f9 43.55%, #5356fb 104.51%);
}
.input-curve.lg{
border-radius: 35px !important;
}
.edit-popup{
top: 75px;
}
+37
View File
@@ -461,6 +461,43 @@ class usersService {
return this.postAuxEnd("/jobmanagercreatejob", postData);
}
jobManagerUpdateJob(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 13010,
...reqData
};
return this.postAuxEnd("/jobmanagerupdatejob", postData);
}
// FUNCTION TO GET ACTIVE JOB MESSAGE LIST
activeJobMesList(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
limit: 30,
action: 14011,
offset: 0,
...reqData
};
return this.postAuxEnd("/activejobmsglist", postData);
}
// FUNCTION TO SEND ACTIVE JOB TASK MESSAGE
sendTaskMessage(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 14010,
...reqData
};
return this.postAuxEnd("/sendtaskmessage", postData);
}
// END POINT TO DELETE A JOB
deleteJob(reqData) {
var postData = {
+29
View File
@@ -0,0 +1,29 @@
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
jobListTable: false,
pendingListTable: false
};
export const tableReloadSlice = createSlice({
name: "tableReload",
initialState,
reducers: {
tableReload: (state, action) => {
switch(action.payload.type){
case 'JOBTABLE':
state.jobListTable = !state.jobListTable;
return
case 'PENDINGTABLE' :
state.pendingListTable = !state.pendingListTable;
return
default:
return state
}
},
},
});
export const { tableReload } = tableReloadSlice.actions;
export default tableReloadSlice.reducer;
+3 -1
View File
@@ -3,11 +3,13 @@ import drawerReducer from "./drawer";
import userDetailReducer from "./UserDetails";
import jobReducer from "./jobLists";
import tableReloadReducer from "./TableReloads";
export default configureStore({
reducer: {
drawer: drawerReducer,
userDetails: userDetailReducer,
jobLists: jobReducer
jobLists: jobReducer,
tableReload: tableReloadReducer
},
});
+39 -2
View File
@@ -1,9 +1,46 @@
import React from 'react'
import React, {useState, useEffect} from 'react'
import ActiveJobs from '../components/MyActiveJobs/ActiveJobs'
import { useLocation, useNavigate } from 'react-router-dom'
import usersService from '../services/UsersService'
function ManageActiveJobs() {
const ApiCall = new usersService()
let navigate = useNavigate()
let {state} = useLocation()
let [details, setDetails] = useState({}) // to hold state values
let [activeJobMesList, setActiveJobMesList] = useState({loading: true, error: false, data: []})
let [activeJobMesListReload, setActiveJobMesListReload] = useState(false)// state to determine when ACTIVE JOB MESSAGE LIST RELOADS/RE-RENDERS
const getActiveJobMesList = () => { // FUNCTION TO GET ACTIVE JOB MESSAGE LIST
setActiveJobMesList({loading: true, error: false, data: []})
let contract = {contract: state.contract}
ApiCall.activeJobMesList(contract).then((res)=>{
if(res.status != 200 || res.data.internal_return < 0){
setActiveJobMesList({loading: false, error: false, data: []})
return
}
setActiveJobMesList({loading: false, error: false, data: res.data.result_list})
}).catch((error)=>{
setActiveJobMesList({loading: false, error: true, data: []})
})
}
useEffect(()=>{
if(!state){
navigate('/', {replace: true})
return
}
setDetails(state)
getActiveJobMesList()
},[activeJobMesListReload])
return (
<ActiveJobs />
<ActiveJobs details={state} activeJobMesList={activeJobMesList} reloadActiveJobList={setActiveJobMesListReload} />
)
}
+9 -3
View File
@@ -4,25 +4,31 @@ import React, { useContext,useState, useEffect } from "react";
// import UsersService from "../services/UsersService";
import usersService from "../services/UsersService";
import MyJobs from "../components/MyJobs";
import { useSelector } from "react-redux";
export default function MyJobsPage() {
const {jobListTable} = useSelector((state) => state.tableReload)
// const userApi = new usersService();
// const activeJobList = userApi.getMyJobList();
const [MyJobList, setMyJobList] = useState([]);
const [MyJobList, setMyJobList] = useState({loading: true, data:[]});
const api = new usersService();
const getMyJobList = async () => {
setMyJobList({loading: true, data:[]})
try {
const res = await api.getMyJobList();
setMyJobList(res.data);
setMyJobList({loading: false, data:res.data})
// setMyJobList(res.data);
} catch (error) {
setMyJobList({loading: false, data:[]})
console.log("Error getting mode");
}
};
useEffect(() => {
getMyJobList();
}, []);
}, [jobListTable]);
// debugger;
return (