Jobs Manager Side task done

This commit was merged in pull request #551.
This commit is contained in:
2024-01-24 01:11:49 +01:00
parent ec88f304ab
commit 0e4b1af1ce
9 changed files with 577 additions and 448 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ export default function DeleteGroup({action, situation, details}) {
</div> </div>
<div className="mb-6"> <div className="mb-6">
<p className="text-xl text-center tracking-wide text-dark-gray dark:text-white"> <p className="text-xl text-center tracking-wide text-dark-gray dark:text-white">
Are you sure, you want to delete <br /> <span>'{details?.group_name}'</span> Are you sure, you want to delete <br /> <span>'{details?.group_name}'</span> group?
</p> </p>
</div> </div>
<div className="flex space-x-2.5"> <div className="flex space-x-2.5">
+3 -3
View File
@@ -23,7 +23,7 @@ export default function DeleteMember({action, situation, details}) {
<div className="logout-modal-wrapper lg:w-[500px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl"> <div className="logout-modal-wrapper lg:w-[500px] 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] "> <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"> <h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Delete Member Remove Member
</h1> </h1>
<button <button
type="button" type="button"
@@ -73,7 +73,7 @@ export default function DeleteMember({action, situation, details}) {
</div> </div>
<div className="mb-6"> <div className="mb-6">
<p className="text-xl text-center tracking-wide text-dark-gray dark:text-white"> <p className="text-xl text-center tracking-wide text-dark-gray dark:text-white">
Are you sure, you want to delete <br /> <span>'{details?.firstname} {details.lastname}'</span> Are you sure, you want to remove <br /> <span>'{details?.firstname} {details.lastname}'</span>
</p> </p>
</div> </div>
<div className="flex space-x-2.5"> <div className="flex space-x-2.5">
@@ -92,7 +92,7 @@ export default function DeleteMember({action, situation, details}) {
type="button" type="button"
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full" className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
> >
Confirm Delete Remove
</button> </button>
)} )}
</div> </div>
+67 -35
View File
@@ -1,72 +1,104 @@
import React, { useState } from 'react' import React, { useState } from "react";
import InputCom from '../../components/Helpers/Inputs/InputCom/index' import AddGroup from "./AddGroup";
import DeleteGroup from './DeleteGroup' import DeleteGroup from "./DeleteGroup";
import AddGroup from './AddGroup' import { localImgLoad } from "../../lib";
export default function GroupList({groupList, selectedGroup, changeSelectedGroup, setUpdateList}) {
export default function GroupList({
groupList,
selectedGroup,
changeSelectedGroup,
setUpdateList,
}) {
const [deletePopout, setDeletePopout] = useState({ const [deletePopout, setDeletePopout] = useState({
status: false, status: false,
data: {} data: {},
}) });
const [addGroupPopout, setAddGroupPopout] = useState(false) const [addGroupPopout, setAddGroupPopout] = useState(false);
const handleAddGroup = () => { const handleAddGroup = () => {
setAddGroupPopout(true) setAddGroupPopout(true);
} };
const handleDeleteGroup = (item) => { const handleDeleteGroup = (item) => {
setDeletePopout({ setDeletePopout({
status: true, status: true,
data: {...item} data: { ...item },
}) });
} };
return ( return (
<> <>
<div className='p-5 w-full lg:w-[400px] min-h-[300px] bg-sky-100 dark:bg-dark-gray rounded-2xl'> <div className="p-5 w-full lg:w-[400px] min-h-[300px] bg-sky-100 dark:bg-dark-gray rounded-2xl">
{/* <h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>Jobs Groups</h1> */} {/* <h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>Jobs Groups</h1> */}
<div className='flex justify-end items-center'> <div className="flex justify-end items-center">
<button onClick={handleAddGroup} className='py-2 px-4 flex justify-center items-center bg-sky-blue hover:bg-sky-600 text-base rounded-full text-white font-bold'>Add Group</button> <button
onClick={handleAddGroup}
className="py-2 px-4 flex justify-center items-center bg-sky-blue hover:bg-sky-600 text-base rounded-full text-white font-bold"
>
Add Group
</button>
</div> </div>
{groupList && groupList.length < 1 ? {groupList && groupList.length < 1 ? (
<h1 className='my-5 text-lg tracking-wide text-slate-900 dark:text-slate-100'>No Group Found!</h1> <h1 className="my-5 text-lg tracking-wide text-slate-900 dark:text-slate-100">
: No Group Found!
<div className='my-4 max-h-[400px] overflow-y-auto'> </h1>
<div className='flex flex-col'> ) : (
{groupList.map(item=> ( <div className="my-4 max-h-[400px] overflow-y-auto">
<div key={item.group_uid} className='p-2 flex gap-2 items-center justify-between w-full'> <div className="flex flex-col">
<div className='flex gap-2 items-center'> {groupList.map((item) => (
<input type='radio' name='grouplist' value={item.group_id} checked={selectedGroup?.id == item?.group_id} onChange={changeSelectedGroup} className='w-[20px] h-[20px] outline-none' /> <div
<p className='text-sm lg:text-base text-slate-900 dark:text-slate-100'>{item.group_name}</p> key={item.group_uid}
className="p-2 flex gap-2 items-center justify-between w-full"
>
<div className="flex gap-2 items-center">
<input
type="radio"
name="grouplist"
value={item.group_id}
checked={selectedGroup?.id == item?.group_id}
onChange={changeSelectedGroup}
className="w-[20px] h-[20px] outline-none"
/>
<p className="text-sm lg:text-base text-slate-900 dark:text-slate-100">
{item.group_name}
</p>
</div> </div>
<button onClick={()=>{handleDeleteGroup(item)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5 flex justify-center items-center'>X</button> <button
onClick={() => {
handleDeleteGroup(item);
}}
className="flex relative items-center justify-center border-0 w-6 h-6"
>
<img
src={localImgLoad("images/icons/remove_grp.svg")}
alt="remove-icon"
/>
</button>
</div> </div>
))} ))}
</div> </div>
</div> </div>
} )}
</div> </div>
{deletePopout.status && {deletePopout.status && (
<DeleteGroup <DeleteGroup
action={() => setDeletePopout({ status: false, data: {} })} action={() => setDeletePopout({ status: false, data: {} })}
situation={deletePopout.status} situation={deletePopout.status}
details={deletePopout.data} details={deletePopout.data}
/> />
} )}
{addGroupPopout && {addGroupPopout && (
<AddGroup <AddGroup
action={() => setAddGroupPopout(false)} action={() => setAddGroupPopout(false)}
situation={addGroupPopout} situation={addGroupPopout}
setUpdateList={setUpdateList} setUpdateList={setUpdateList}
/> />
} )}
</> </>
) );
} }
+41 -21
View File
@@ -1,16 +1,20 @@
import React, { useState } from 'react' import React, { useState } from "react";
import { handlePagingFunc } from '../Pagination/HandlePagination'; import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from '../Pagination/PaginatedList'; import PaginatedList from "../Pagination/PaginatedList";
import DeleteMember from './DeleteMember'; import DeleteMember from "./DeleteMember";
import { localImgLoad } from "../../lib";
export default function GroupMemberTable({ selectedList }) { export default function GroupMemberTable({ selectedList }) {
// Handle Pagination // Handle Pagination
const [currentPage, setCurrentPage] = useState(0); const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage); const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE); const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentSelectedList = selectedList?.slice(indexOfFirstItem, indexOfLastItem); const currentSelectedList = selectedList?.slice(
indexOfFirstItem,
indexOfLastItem
);
const handlePagination = (e) => { const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage); handlePagingFunc(e, setCurrentPage);
@@ -18,43 +22,59 @@ export default function GroupMemberTable({selectedList}) {
const [deletePopout, setDeletePopout] = useState({ const [deletePopout, setDeletePopout] = useState({
status: false, status: false,
data: {} data: {},
}) });
const handleDeleteMember = (item) => { const handleDeleteMember = (item) => {
setDeletePopout({ setDeletePopout({
status: true, status: true,
data: {...item} data: { ...item },
}) });
} };
return ( return (
<div className={`w-full p-8 bg-white dark:bg-dark-gray overflow-hidden rounded-2xl section-shadow`}> <div
className={`w-full p-8 bg-white dark:bg-dark-gray overflow-hidden rounded-2xl section-shadow`}
>
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[400px]"> <div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[400px]">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400"> <table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody> <tbody>
<> <>
{selectedList && selectedList?.length > 0 ? ( {selectedList && selectedList?.length > 0 ? (
currentSelectedList.map((value, index) => ( currentSelectedList.map((value, index) => (
<tr key={value.uid} className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"> <tr
key={value.uid}
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
>
{/* <td className="p-1">{value?.firstname}</td> {/* <td className="p-1">{value?.firstname}</td>
<td className="p-1">{value?.lastname}</td> <td className="p-1">{value?.lastname}</td>
<td className="p-1">{value?.email}</td> <td className="p-1">{value?.email}</td>
<td className="p-1 text-right"> <td className="p-1 text-right">
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button> <button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button>
</td> */} </td> */}
<td className='py-2'> <td className="py-2">
<div className="flex flex-col"> <div className="flex flex-col">
<h1 className="font-bold text-xl text-dark-gray dark:text-white"> <h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.firstname && value.firstname} {value.lastname && value.lastname} {value.firstname && value.firstname}{" "}
{value.lastname && value.lastname}
</h1> </h1>
<span className="text-sm text-thin-light-gray"> <span className="text-sm text-thin-light-gray">
{value.email && value.email} {value.email && value.email}
</span> </span>
</div> </div>
</td> </td>
<td className='py-2 text-right'> <td className="py-2 text-right">
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button> <button
onClick={() => {
handleDeleteMember(value);
}}
className="flex relative items-center justify-center border-0 w-8 h-8"
>
<img
src={localImgLoad("images/icons/remove_grp.svg")}
alt="remove-icon"
/>
</button>
</td> </td>
</tr> </tr>
)) ))
@@ -85,14 +105,14 @@ export default function GroupMemberTable({selectedList}) {
</div> </div>
{/* DELETE MEMBER POPOUT */} {/* DELETE MEMBER POPOUT */}
{deletePopout.status && {deletePopout.status && (
<DeleteMember <DeleteMember
action={() => setDeletePopout({ status: false, data: {} })} action={() => setDeletePopout({ status: false, data: {} })}
situation={deletePopout.status} situation={deletePopout.status}
details={deletePopout.data} details={deletePopout.data}
/> />
} )}
{/* END OF DELETE MEMBER POPOUT */} {/* END OF DELETE MEMBER POPOUT */}
</div> </div>
); );
}; }
+86 -46
View File
@@ -1,79 +1,119 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from "react";
import Layout from '../Partials/Layout' import Layout from "../Partials/Layout";
import GroupList from './GroupList' import GroupList from "./GroupList";
import MemberList from './MemberList' import MemberList from "./MemberList";
import LoadingSpinner from '../Spinners/LoadingSpinner' import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from '../../services/UsersService' import usersService from "../../services/UsersService";
export default function JobGroups() { export default function JobGroups() {
const userApi = new usersService(); const userApi = new usersService();
const [updateList, setUpdateList] = useState(false) const [updateList, setUpdateList] = useState(false);
const [groupList, setGroupList] = useState({ const [groupList, setGroupList] = useState({
loading: true, loading: true,
groups: [], groups: [],
members: [] members: [],
}) });
const [selectedGroup, setSelectedGroup] = useState({id:'', name:'', data: []}) const [selectedGroup, setSelectedGroup] = useState({
id: "",
name: "",
data: [],
});
const changeSelectedGroup = (e) => { const changeSelectedGroup = (e) => {
let groupID = e.target.value let groupID = e.target.value;
const activeMembers = groupList?.members?.filter(item => item.group_id == groupID) const activeMembers = groupList?.members?.filter(
const activeGroup = groupList?.groups?.filter(item => item.group_id == groupID) (item) => item.group_id == groupID
setSelectedGroup({id: groupID, name:activeGroup[0]?.group_name, data:activeMembers}) );
} const activeGroup = groupList?.groups?.filter(
(item) => item.group_id == groupID
);
setSelectedGroup({
id: groupID,
name: activeGroup[0]?.group_name,
data: activeMembers,
});
};
useEffect(() => { useEffect(() => {
setGroupList({loading: true, groups: [], members: []}) setGroupList({ loading: true, groups: [], members: [] });
userApi.jobGroupList({}).then(res => { userApi
const {status, data} = res .jobGroupList({})
.then((res) => {
const { status, data } = res;
if (status != 200 || data?.internal_return < 0) { if (status != 200 || data?.internal_return < 0) {
setGroupList({loading: false, groups: [], members: []}) setGroupList({ loading: false, groups: [], members: [] });
return return;
} }
if (data.result_list.length < 0) { if (data.result_list.length < 0) {
setGroupList({loading: false, groups: [], members: []}) setGroupList({ loading: false, groups: [], members: [] });
return return;
} }
setGroupList({loading: false, groups: data.result_list, members: data.result_list_member}) setGroupList({
if(selectedGroup.id == ''){ loading: false,
let activeGroupId = data.result_list[0].group_id groups: data.result_list,
let activeGroup = data.result_list[0].group_name members: data.result_list_member,
let activeMembers = data.result_list_member?.filter(item => item.group_id == activeGroupId) });
setSelectedGroup({id: activeGroupId, name:activeGroup, data:activeMembers}) if (selectedGroup.id == "") {
let activeGroupId = data.result_list[0].group_id;
let activeGroup = data.result_list[0].group_name;
let activeMembers = data.result_list_member?.filter(
(item) => item.group_id == activeGroupId
);
setSelectedGroup({
id: activeGroupId,
name: activeGroup,
data: activeMembers,
});
} else { } else {
let activeMembers = data.result_list_member?.filter(item => item.group_id == selectedGroup?.id) let activeMembers = data.result_list_member?.filter(
setSelectedGroup({id: selectedGroup?.id, name:selectedGroup?.name, data:activeMembers}) (item) => item.group_id == selectedGroup?.id
);
setSelectedGroup({
id: selectedGroup?.id,
name: selectedGroup?.name,
data: activeMembers,
});
} }
}).catch(error => {
setGroupList({loading: false, groups: [], members: []})
console.log(error)
}) })
},[updateList]) .catch((error) => {
setGroupList({ loading: false, groups: [], members: [] });
console.log(error);
});
}, [updateList]);
return ( return (
<Layout> <Layout>
<div> <div>
<h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>Jobs Groups</h1> <h1 className="mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100">
Jobs Groups
</h1>
</div> </div>
<div className='p-5 w-full min-h-[400px] flex flex-col lg:flex-row gap-3 lg:gap-6 rounded-lg shadow-md bg-white dark:bg-dark-white'> <div className="p-5 w-full min-h-[400px] flex flex-col lg:flex-row gap-3 lg:gap-6 rounded-lg shadow-md bg-white dark:bg-dark-white">
{groupList.loading ? {groupList.loading ? (
<div className='w-full h-[400px] flex justify-center items-center'> <div className="w-full h-[400px] flex justify-center items-center">
<LoadingSpinner size='16' /> <LoadingSpinner size="16" />
</div> </div>
: ) : (
<> <>
<GroupList groupList={groupList?.groups} selectedGroup={selectedGroup} changeSelectedGroup={changeSelectedGroup} setUpdateList={setUpdateList} /> <GroupList
<MemberList groupList={groupList?.groups} selectedGroup={selectedGroup} setUpdateList={setUpdateList} /> groupList={groupList?.groups}
selectedGroup={selectedGroup}
changeSelectedGroup={changeSelectedGroup}
setUpdateList={setUpdateList}
/>
<MemberList
groupList={groupList?.groups}
selectedGroup={selectedGroup}
setUpdateList={setUpdateList}
/>
</> </>
} )}
</div> </div>
</Layout> </Layout>
) );
} }
+1 -1
View File
@@ -6,8 +6,8 @@ import GroupMemberTable from "./GroupMemberTable";
import EmailValidator from "../../lib/EmailValidator"; import EmailValidator from "../../lib/EmailValidator";
import usersService from "../../services/UsersService";
import { apiConst } from "../../lib/apiConst"; import { apiConst } from "../../lib/apiConst";
import usersService from "../../services/UsersService";
export default function MemberList({ export default function MemberList({
groupList, groupList,
@@ -1,12 +1,10 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import localImgLoad from "../../lib/localImgLoad";
import { PriceFormatter } from "../Helpers/PriceFormatter"; import { PriceFormatter } from "../Helpers/PriceFormatter";
import { handlePagingFunc } from "../Pagination/HandlePagination"; import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList"; import PaginatedList from "../Pagination/PaginatedList";
export default function MyActiveJobTable({ MyJobList, className }) { export default function MyActiveJobTable({ MyJobList, className }) {
const navigate = useNavigate(); const navigate = useNavigate();
let { pathname } = useLocation(); let { pathname } = useLocation();
@@ -45,7 +43,11 @@ export default function MyActiveJobTable({ MyJobList, className }) {
value?.currency_code, value?.currency_code,
value?.currency value?.currency
); );
let image = `${MyJobList.session_image_server}${localStorage.getItem('session_token')}/job/${value.job_uid}` let image = `${
MyJobList.session_image_server
}${localStorage.getItem("session_token")}/job/${
value.job_uid
}`;
return ( return (
<tr <tr
key={index} key={index}
@@ -112,7 +114,7 @@ export default function MyActiveJobTable({ MyJobList, className }) {
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
> >
{value.owner_status == "OWNER" {value.owner_status == "OWNER"
? "Manage" ? "Review"
: "Send Updates"} : "Send Updates"}
</button> </button>
</div> </div>
@@ -6,9 +6,7 @@ import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
import { PriceFormatter } from "../Helpers/PriceFormatter"; import { PriceFormatter } from "../Helpers/PriceFormatter";
import localImgLoad from "../../lib/localImgLoad"; import localImgLoad from "../../lib/localImgLoad";
export default function MyPendingJobTable({ MyJobList, className }) { export default function MyPendingJobTable({ MyJobList, className }) {
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 [currentPage, setCurrentPage] = useState(0);
@@ -46,7 +44,11 @@ export default function MyPendingJobTable({ MyJobList, className }) {
value?.currency_code, value?.currency_code,
value?.currency value?.currency
); );
let image = `${MyJobList.session_image_server}${localStorage.getItem('session_token')}/job/${value.job_uid}` let image = `${
MyJobList.session_image_server
}${localStorage.getItem("session_token")}/job/${
value.job_uid
}`;
return ( return (
<tr <tr
key={index} key={index}
@@ -107,7 +109,9 @@ export default function MyPendingJobTable({ MyJobList, className }) {
}} }}
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
> >
{value.owner_status == 'OWNER' ? 'Manage' : 'Send Updates'} {value.owner_status == "OWNER"
? "Manage"
: "View"}
</button> </button>
</td> </td>
</tr> </tr>
+92 -61
View File
@@ -1,13 +1,13 @@
import { Field, Form, Formik } from "formik"; import { Field, Form, Formik } from "formik";
import React, { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useDispatch } from "react-redux";
import * as Yup from "yup"; import * as Yup from "yup";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import { tableReload } from "../../store/TableReloads";
import InputCom from "../Helpers/Inputs/InputCom/index"; import InputCom from "../Helpers/Inputs/InputCom/index";
import ModalCom from "../Helpers/ModalCom"; import ModalCom from "../Helpers/ModalCom";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import Detail from "./popoutcomponent/Detail"; import Detail from "./popoutcomponent/Detail";
import { tableReload } from "../../store/TableReloads";
import { useDispatch } from "react-redux";
const validationSchema = Yup.object().shape({ const validationSchema = Yup.object().shape({
family: Yup.string().required("This is required "), family: Yup.string().required("This is required "),
@@ -23,13 +23,15 @@ const validationSchema = Yup.object().shape({
}); });
function JobListPopout({ details, onClose, situation }) { function JobListPopout({ details, onClose, situation }) {
const [selectedTab, setSelectedTab] = useState("public");
const tabs = ["public", "individual", "group"];
const [selectedTab, setSelectedTab] = useState('public') const dispatch = useDispatch();
const tabs = ['public', 'individual', 'group']
const dispatch = useDispatch() const [requestStatus, setRequestStatus] = useState({
message: "",
const [requestStatus, setRequestStatus] = useState({message:'', status:false}) status: false,
});
const [familyList, setFamilyList] = useState([]); const [familyList, setFamilyList] = useState([]);
let [loader, setLoader] = useState({ let [loader, setLoader] = useState({
@@ -147,7 +149,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
// for group input // for group input
reqData = { reqData = {
...jobReq, ...jobReq,
email: '', email: "",
group_id: values?.group, group_id: values?.group,
assign_mode: 110044, assign_mode: 110044,
duration: details?.timeline_days, duration: details?.timeline_days,
@@ -162,49 +164,60 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
const res = await apiCall.assignJobTask(reqData); const res = await apiCall.assignJobTask(reqData);
let { status, data } = await res; let { status, data } = await res;
if (status != 200 || data.internal_return < 0) { if (status != 200 || data.internal_return < 0) {
setRequestStatus({message:'Unable to complete', status:false}) setRequestStatus({ message: "Unable to complete", status: false });
return setTimeout(() => { return setTimeout(() => {
setLoader({ jobFields: false }); setLoader({ jobFields: false });
setRequestStatus({message:'', status:false}) setRequestStatus({ message: "", status: false });
},3000) }, 3000);
} }
dispatch(tableReload({ type: "JOBTABLE" })); dispatch(tableReload({ type: "JOBTABLE" }));
setRequestStatus({message:'Successful', status:true}) setRequestStatus({ message: "Successful", status: true });
setTimeout(() => { setTimeout(() => {
setLoader({ jobFields: false }); setLoader({ jobFields: false });
onClose(); onClose();
throw new Response(data); throw new Response(data);
},3000) }, 3000);
} catch (error) { } catch (error) {
setRequestStatus({message:'Unable to complete', status:false}) setRequestStatus({ message: "Unable to complete", status: false });
setTimeout(() => { setTimeout(() => {
setRequestStatus({message:'', status:false}) setRequestStatus({ message: "", status: false });
setLoader({ jobFields: false }); setLoader({ jobFields: false });
throw new Error(error); throw new Error(error);
},3000) }, 3000);
} }
}; };
const [groupList, setGroupList] = useState({loading: true, groups: [], members: []}) const [groupList, setGroupList] = useState({
loading: true,
groups: [],
members: [],
});
// FUNCTION TO POPULATE USER GROUP LIST // FUNCTION TO POPULATE USER GROUP LIST
useEffect(() => { useEffect(() => {
// setGroupList({loading: true, groups: [], members: []}) // setGroupList({loading: true, groups: [], members: []})
apiCall.jobGroupList({}).then(res => { apiCall
const {status, data} = res .jobGroupList({})
.then((res) => {
const { status, data } = res;
if (status != 200 || data?.internal_return < 0) { if (status != 200 || data?.internal_return < 0) {
setGroupList({loading: false, groups: [], members: []}) setGroupList({ loading: false, groups: [], members: [] });
return return;
} }
if (data.result_list.length < 0) { if (data.result_list.length < 0) {
setGroupList({loading: false, groups: [], members: []}) setGroupList({ loading: false, groups: [], members: [] });
return return;
} }
setGroupList({loading: false, groups: data.result_list, members: data.result_list_member}) setGroupList({
}).catch(error => { loading: false,
setGroupList({loading: false, groups: [], members: []}) groups: data.result_list,
members: data.result_list_member,
});
}) })
},[]) .catch((error) => {
setGroupList({ loading: false, groups: [], members: [] });
});
}, []);
// console.log("Job List P >> ", details) // console.log("Job List P >> ", details)
return ( return (
@@ -241,7 +254,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
</button> </button>
</div> </div>
<div className="md:grid grid-cols-2 bg-white dark:bg-dark-white rounded-lg shadow-lg"> <div className="md:grid grid-cols-2 bg-white dark:bg-dark-white rounded-lg shadow-lg">
<div className="p-4 pb-3 w-full md:border-r-2"> <div className="px-4 pb-3 w-full md:border-r-2">
{/* <p className='text-lg font-semibold text-slate-900 tracking-wide'>{details.title}</p> */} {/* <p className='text-lg font-semibold text-slate-900 tracking-wide'>{details.title}</p> */}
{/* INPUT SECTION */} {/* INPUT SECTION */}
@@ -283,25 +296,37 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
</div> </div>
{/* ACTION SECTION */} {/* ACTION SECTION */}
<div className="p-4 w-ful flex flex-col justify-between"> <div className="px-4 pb-3 w-ful flex flex-col justify-between">
<h1 className="text-lg mt-3 font-medium tracking-wide text-black dark:text-white">Send this Task to:</h1> <h1 className="text-lg mt-3 font-medium tracking-wide text-black dark:text-white">
Send this Task to:
</h1>
<div className="flex flex-col grow"> <div className="flex flex-col grow">
<div className="grid grid-cols-3 mt-4"> <div className="grid grid-cols-3 mt-4">
{tabs.map(item => ( {tabs.map((item) => (
<button <button
// className={`px-4 py-1 rounded-t-2xl ${selectedTab == item ? 'btn-gradient border-[2px] text-white' : 'bg-white text-[#000] border-t-[2px]'}`} // className={`px-4 py-1 rounded-t-2xl ${selectedTab == item ? 'btn-gradient border-[2px] text-white' : 'bg-white text-[#000] border-t-[2px]'}`}
className={`px-4 py-1 rounded-t-2xl border-t-[2px] transition-all duration-200 flex flex-col justify-center items-center ${selectedTab == item ? 'bg-red-50 dark:bg-[#D85A5A] text-slate-600 font-extrabold' : 'bg-white text-[#000]'}`} className={`px-4 py-1 rounded-t-2xl border-t-[2px] transition-all duration-200 flex flex-col justify-center items-center ${
selectedTab == item
? "bg-red-50 dark:bg-[#D85A5A] text-slate-600 font-extrabold"
: "bg-white text-[#000]"
}`}
value={item} value={item}
name={item} name={item}
onClick={() => setSelectedTab(item)} onClick={() => setSelectedTab(item)}
> >
<div className={`mb-[1px] h-6 w-6 border-4 rounded-full transition-all duration-200 ${selectedTab == item ? 'border-white bg-emerald-500' : 'border-red-50 dark:border-[#D85A5A] bg-white'}`}></div> <div
className={`mb-[1px] h-6 w-6 border-4 rounded-full transition-all duration-200 ${
selectedTab == item
? "border-white bg-emerald-500"
: "border-red-50 dark:border-[#D85A5A] bg-white"
}`}
></div>
{item[0].toUpperCase() + item.slice(1)} {item[0].toUpperCase() + item.slice(1)}
</button> </button>
))} ))}
</div> </div>
<div className="grow flex flex-col bg-red-50 dark:bg-[#D85A5A] rounded-b-2xl"> <div className="grow flex flex-col bg-red-50 dark:bg-[#D85A5A] rounded-b-2xl">
{selectedTab == 'family' && {selectedTab == "family" && (
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema.fields.family} validationSchema={validationSchema.fields.family}
@@ -321,7 +346,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
optionText="Select Family" optionText="Select Family"
loader={loader?.jobFields?.family} loader={loader?.jobFields?.family}
errorHandler={errorHandler} errorHandler={errorHandler}
parentClass='w-full flex flex-col gap-4' parentClass="w-full flex flex-col gap-4"
/> />
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide"> <p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
{" "} {" "}
@@ -333,9 +358,9 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
); );
}} }}
</Formik> </Formik>
} )}
{selectedTab == 'public' && {selectedTab == "public" && (
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema.fields.public} validationSchema={validationSchema.fields.public}
@@ -355,7 +380,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
optionText="Select Duration" optionText="Select Duration"
loader={loader?.jobFields?.public} loader={loader?.jobFields?.public}
errorHandler={errorHandler} errorHandler={errorHandler}
parentClass='w-full flex flex-col gap-4' parentClass="w-full flex flex-col gap-4"
/> />
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide"> <p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
{" "} {" "}
@@ -367,9 +392,9 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
); );
}} }}
</Formik> </Formik>
} )}
{selectedTab == 'individual' && {selectedTab == "individual" && (
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema.fields.individual} validationSchema={validationSchema.fields.individual}
@@ -389,7 +414,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
btnText="Send Offer to Individual" btnText="Send Offer to Individual"
loader={loader?.jobFields?.individual} loader={loader?.jobFields?.individual}
errorHandler={errorHandler} errorHandler={errorHandler}
parentClass='w-full flex flex-col gap-4' parentClass="w-full flex flex-col gap-4"
/> />
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide"> <p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
{" "} {" "}
@@ -401,10 +426,10 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
); );
}} }}
</Formik> </Formik>
} )}
{/* { process.env.REACT_APP_SHOW_OFFER_GROUP_JOB != 0 && } */} {/* { process.env.REACT_APP_SHOW_OFFER_GROUP_JOB != 0 && } */}
{selectedTab == 'group' && {selectedTab == "group" && (
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema.fields.group} validationSchema={validationSchema.fields.group}
@@ -424,7 +449,7 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
loader={loader?.jobFields?.group} loader={loader?.jobFields?.group}
errorHandler={errorHandler} errorHandler={errorHandler}
data={groupList} data={groupList}
parentClass='w-full flex flex-col gap-4' parentClass="w-full flex flex-col gap-4"
/> />
<p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide"> <p className="h-4 text-[13px] font-light italic text-red-600 tracking-wide">
{" "} {" "}
@@ -436,13 +461,20 @@ const [requestStatus, setRequestStatus] = useState({message:'', status:false})
); );
}} }}
</Formik> </Formik>
} )}
<p
className={`text-center w-full text-lg ${
requestStatus.status ? "text-emerald-600" : "text-red-600"
}`}
>
{requestStatus.message && requestStatus.message}
</p>
</div> </div>
</div> </div>
{/*
{requestStatus.message && {requestStatus.message &&
<p className={`mt-4 w-full text-lg ${requestStatus.status ? 'text-emerald-600' : 'text-red-600'}`}>{requestStatus.message}</p> <p className={`mt-4 w-full text-lg ${requestStatus.status ? 'text-emerald-600' : 'text-red-600'}`}>{requestStatus.message}</p>
} } */}
</div> </div>
{/* END OF ACTION SECTION */} {/* END OF ACTION SECTION */}
</div> </div>
@@ -480,7 +512,7 @@ const JobFieldInput = ({
> >
{label && ( {label && (
<label <label
className="input-label border-2 w-full border-sky-700 py-4 px-2 text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block tracking-wide" className="input-label border-2 w-full border-sky-700 rounded py-4 px-2 text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block tracking-wide"
htmlFor={inputName} htmlFor={inputName}
> >
{label} {label}
@@ -497,13 +529,14 @@ const JobFieldInput = ({
value={value} value={value}
> >
{/* <option value="">{optionText}</option> */} {/* <option value="">{optionText}</option> */}
{(inputName == 'family' || inputName == 'public') && {(inputName == "family" || inputName == "public") &&
Array.isArray(data) && Array.isArray(data) && (
<> <>
<option value="">{optionText}</option> <option value="">{optionText}</option>
{data?.map((item, idx) => ( {data?.map((item, idx) => (
<React.Fragment key={idx}> <React.Fragment key={idx}>
{inputName === "family" && item?.last_login !== "" && ( {inputName === "family" &&
item?.last_login !== "" && (
<option value={item?.family_uid} key={idx}> <option value={item?.family_uid} key={idx}>
{`${item?.firstname} ${item?.lastname}`} {`${item?.firstname} ${item?.lastname}`}
</option> </option>
@@ -521,14 +554,12 @@ const JobFieldInput = ({
</React.Fragment> </React.Fragment>
))} ))}
</> </>
} )}
{(inputName == 'group') && {inputName == "group" && (
<> <>
{data.loading ? {data.loading ? (
<option value={''}> <option value={""}>Loading...</option>
Loading... ) : data?.groups?.length > 0 ? (
</option>
: data?.groups?.length > 0 ?
<> <>
<option value="">{optionText}</option> <option value="">{optionText}</option>
{data?.groups?.map((item, index) => ( {data?.groups?.map((item, index) => (
@@ -537,11 +568,11 @@ const JobFieldInput = ({
</option> </option>
))} ))}
</> </>
: ) : (
<option value="">No Group Found</option> <option value="">No Group Found</option>
} )}
</> </>
} )}
</Field> </Field>
</div> </div>
</div> </div>