diff --git a/src/components/JobGroups/AddGroup.jsx b/src/components/JobGroups/AddGroup.jsx
new file mode 100644
index 0000000..8f8a62b
--- /dev/null
+++ b/src/components/JobGroups/AddGroup.jsx
@@ -0,0 +1,157 @@
+import React, { useState } from 'react'
+
+import ModalCom from '../Helpers/ModalCom'
+import LoadingSpinner from '../Spinners/LoadingSpinner'
+import InputCom from '../Helpers/Inputs/InputCom/index'
+
+import usersService from '../../services/UsersService'
+
+export default function AddGroup({action, situation , setUpdateList}) {
+
+ const api = new usersService()
+
+ const [name, setName] = useState('')
+
+ const handleChange = ({target:{name, value}}) =>{
+ setName(value)
+ }
+
+ let [requestStatus, setRequestStatus] = useState({
+ loading: false,
+ status: false,
+ message: "",
+ }); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
+
+ const addGroup = () => {
+ setRequestStatus({loading:true, status:false, message:''})
+ if(name == ''){
+ setRequestStatus({loading:false, status:false, message:'Please enter a group name'})
+ return setTimeout(()=>{
+ setRequestStatus({loading:false, status:false, message:''})
+ },3000)
+ }
+ if(name.length < 6){
+ setRequestStatus({loading:false, status:false, message:'Group name must be up to six characters'})
+ return setTimeout(()=>{
+ setRequestStatus({loading:false, status:false, message:''})
+ },3000)
+ }
+ api.jobGroupAdd({group_name:name, action:13025}).then(response => {
+ let {status, data} = response
+ if(status != 200 || data.internal_return < 0){
+ setRequestStatus({loading:false, status:false, message:'Unable to add Group'})
+ return
+ }
+ setRequestStatus({loading:false, status:true, message:'Group Added'})
+ setTimeout(()=>{
+ setRequestStatus({loading:false, status:false, message:''})
+ // close modal
+ action()
+ // reload group page
+ setUpdateList(prev => !prev)
+ },3000)
+ }).catch(error => {
+ setRequestStatus({loading:false, status:false, message:'Unable to add Group, try again later'})
+ }).finally(()=>{
+ setTimeout(()=>{
+ setRequestStatus({loading:false, status:false, message:''})
+ },3000)
+ })
+ }
+
+ return (
+
+
+
+
+ Add Group
+
+
+
+
+
+
+
+ {requestStatus.loading ? (
+
+ ) : (
+
+ )}
+
+
+ {/* ERROR DISPLAY AND SUBMIT BUTTON */}
+ {requestStatus.message != "" &&
+ (!requestStatus.status ? (
+
+ {requestStatus.message}
+
+ ) : (
+ requestStatus.status && (
+
+ {requestStatus.message}
+
+ )
+ ))}
+ {/* End of error or success display */}
+
+
+
+ )
+}
diff --git a/src/components/JobGroups/DeleteGroup.jsx b/src/components/JobGroups/DeleteGroup.jsx
new file mode 100644
index 0000000..6c646d3
--- /dev/null
+++ b/src/components/JobGroups/DeleteGroup.jsx
@@ -0,0 +1,122 @@
+import React, { useState } from 'react'
+
+import ModalCom from '../Helpers/ModalCom'
+import LoadingSpinner from '../Spinners/LoadingSpinner'
+
+export default function DeleteGroup({action, situation, details}) {
+
+ let [requestStatus, setRequestStatus] = useState({
+ laoding: false,
+ status: false,
+ message: "",
+ }); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
+
+ const deleteGroup = () => {
+
+ }
+
+ return (
+
+
+
+
+ Delete Group
+
+
+
+
+
+
+
+ Are you sure, you want to delete
'{details?.group_name}'
+
+
+
+
+ {requestStatus.laoding ? (
+
+ ) : (
+
+ )}
+
+
+ {/* ERROR DISPLAY AND SUBMIT BUTTON */}
+ {requestStatus.message != "" &&
+ (!requestStatus.status ? (
+
+ {requestStatus.message}
+
+ ) : (
+ requestStatus.status && (
+
+ {requestStatus.message}
+
+ )
+ ))}
+ {/* End of error or success display */}
+
+
+
+ )
+}
diff --git a/src/components/JobGroups/DeleteMember.jsx b/src/components/JobGroups/DeleteMember.jsx
new file mode 100644
index 0000000..e899cff
--- /dev/null
+++ b/src/components/JobGroups/DeleteMember.jsx
@@ -0,0 +1,122 @@
+import React, { useState } from 'react'
+
+import ModalCom from '../Helpers/ModalCom'
+import LoadingSpinner from '../Spinners/LoadingSpinner'
+
+export default function DeleteMember({action, situation, details}) {
+
+ let [requestStatus, setRequestStatus] = useState({
+ laoding: false,
+ status: false,
+ message: "",
+ }); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
+
+ const deleteMember = () => {
+
+ }
+
+ return (
+
+
+
+
+ Delete Member
+
+
+
+
+
+
+
+ Are you sure, you want to delete
'{details?.firstname} {details.lastname}'
+
+
+
+
+ {requestStatus.laoding ? (
+
+ ) : (
+
+ )}
+
+
+ {/* ERROR DISPLAY AND SUBMIT BUTTON */}
+ {requestStatus.message != "" &&
+ (!requestStatus.status ? (
+
+ {requestStatus.message}
+
+ ) : (
+ requestStatus.status && (
+
+ {requestStatus.message}
+
+ )
+ ))}
+ {/* End of error or success display */}
+
+
+
+ )
+}
diff --git a/src/components/JobGroups/GroupList.jsx b/src/components/JobGroups/GroupList.jsx
new file mode 100644
index 0000000..c5ba8db
--- /dev/null
+++ b/src/components/JobGroups/GroupList.jsx
@@ -0,0 +1,72 @@
+import React, { useState } from 'react'
+
+import InputCom from '../../components/Helpers/Inputs/InputCom/index'
+import DeleteGroup from './DeleteGroup'
+import AddGroup from './AddGroup'
+
+export default function GroupList({groupList, selectedGroup, changeSelectedGroup, setUpdateList}) {
+
+ const [deletePopout, setDeletePopout] = useState({
+ status: false,
+ data: {}
+ })
+
+ const [addGroupPopout, setAddGroupPopout] = useState(false)
+
+ const handleAddGroup = () => {
+ setAddGroupPopout(true)
+ }
+
+ const handleDeleteGroup = (item) => {
+ setDeletePopout({
+ status: true,
+ data: {...item}
+ })
+ }
+
+
+ return (
+ <>
+
+ {/*
Jobs Groups
*/}
+
+
+
+
+ {groupList && groupList.length < 1 ?
+
No Group Found!
+ :
+
+
+ {groupList.map(item=> (
+
+
+
+
+ ))}
+
+
+ }
+
+
+ {deletePopout.status &&
+ setDeletePopout({status:false, data:{}})}
+ situation={deletePopout.status}
+ details={deletePopout.data}
+ />
+ }
+
+ {addGroupPopout &&
+ setAddGroupPopout(false)}
+ situation={addGroupPopout}
+ setUpdateList={setUpdateList}
+ />
+ }
+ >
+ )
+}
diff --git a/src/components/JobGroups/GroupMemberTable.jsx b/src/components/JobGroups/GroupMemberTable.jsx
new file mode 100644
index 0000000..2bfe99b
--- /dev/null
+++ b/src/components/JobGroups/GroupMemberTable.jsx
@@ -0,0 +1,103 @@
+import React, { useState } from 'react'
+import { handlePagingFunc } from '../Pagination/HandlePagination';
+import PaginatedList from '../Pagination/PaginatedList';
+import DeleteMember from './DeleteMember';
+
+export default function GroupMemberTable({selectedList}) {
+
+ // Handle Pagination
+ const [currentPage, setCurrentPage] = useState(0);
+ const indexOfFirstItem = Number(currentPage);
+ const indexOfLastItem =Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
+
+ const currentSelectedList = selectedList?.slice(indexOfFirstItem, indexOfLastItem);
+
+
+ const handlePagination = (e) => {
+ handlePagingFunc(e, setCurrentPage);
+ };
+
+ const [deletePopout, setDeletePopout] = useState({
+ status: false,
+ data: {}
+ })
+
+ const handleDeleteMember = (item) => {
+ setDeletePopout({
+ status: true,
+ data: {...item}
+ })
+ }
+
+ return (
+
+
+
+
+ <>
+
+ | First Name |
+ Last Name |
+ Email |
+ |
+
+
+ |
+
+ {selectedList && selectedList?.length > 0 ? (
+ currentSelectedList?.length ? (
+ currentSelectedList.map((value, index) => (
+
+ | {value?.firstname} |
+ {value?.lastname} |
+ {value?.email} |
+
+
+ |
+
+ ))
+ ) : (
+
+ |
+ No Members Found
+ |
+
+ )
+ ) : (
+
+ | No Members Found |
+
+ )}
+ >
+
+
+
+ {/* PAGINATION BUTTON */}
+
=
+ currentSelectedList?.length
+ ? true
+ : false
+ }
+ data={currentSelectedList}
+ start={indexOfFirstItem}
+ stop={indexOfLastItem}
+ />
+ {/* END OF PAGINATION BUTTON */}
+
+
+ {/* DELETE MEMBER POPOUT */}
+ {deletePopout.status &&
+
setDeletePopout({status:false, data:{}})}
+ situation={deletePopout.status}
+ details={deletePopout.data}
+ />
+ }
+ {/* END OF DELETE MEMBER POPOUT */}
+
+ );
+ };
diff --git a/src/components/JobGroups/JobGroups.jsx b/src/components/JobGroups/JobGroups.jsx
index 87d96c9..1a47054 100644
--- a/src/components/JobGroups/JobGroups.jsx
+++ b/src/components/JobGroups/JobGroups.jsx
@@ -1,10 +1,74 @@
-import React from 'react'
+import React, { useEffect, useState } from 'react'
import Layout from '../Partials/Layout'
+import GroupList from './GroupList'
+import MemberList from './MemberList'
+import LoadingSpinner from '../Spinners/LoadingSpinner'
+
+import usersService from '../../services/UsersService'
+
export default function JobGroups() {
+
+ const userApi = new usersService();
+
+ const [updateList, setUpdateList] = useState(false)
+
+
+ const [groupList, setGroupList] = useState({
+ loading:true,
+ groups: [],
+ members: []
+ })
+
+ const [selectedGroup, setSelectedGroup] = useState({id:'', data: []})
+
+ const changeSelectedGroup = (e) => {
+ let groupID = e.target.value
+ const activeMembers = groupList?.members?.filter(item => item.group_id == groupID)
+ const activeGroup = groupList?.groups?.filter(item => item.group_id == groupID)
+ setSelectedGroup({id: groupID, name:activeGroup[0]?.group_name, data:activeMembers})
+ }
+
+ useEffect(()=>{
+ setGroupList({loading: true, groups: [], members: []})
+ userApi.jobGroupList({}).then(res => {
+ const {status, data} = res
+ if(status != 200 || data?.internal_return < 0){
+ setGroupList({loading: false, groups: [], members: []})
+ return
+ }
+ if(data.result_list.length < 0){
+ setGroupList({loading: false, groups: [], members: []})
+ return
+ }
+ setGroupList({loading: false, groups: data.result_list, members: data.result_list_member})
+ 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})
+ }).catch(error => {
+ setGroupList({loading: false, groups: [], members: []})
+ console.log(error)
+ })
+ },[updateList])
+
return (
- JobGroups
+
+
Jobs Groups
+
+
+ {groupList.loading ?
+
+
+
+ :
+ <>
+
+
+ >
+ }
+
)
}
diff --git a/src/components/JobGroups/MemberList.jsx b/src/components/JobGroups/MemberList.jsx
new file mode 100644
index 0000000..dcef796
--- /dev/null
+++ b/src/components/JobGroups/MemberList.jsx
@@ -0,0 +1,224 @@
+import React, { useState } from 'react'
+
+import InputCom from '../../components/Helpers/Inputs/InputCom/index'
+import LoadingSpinner from '../Spinners/LoadingSpinner'
+import GroupMemberTable from './GroupMemberTable'
+
+import EmailValidator from '../../lib/EmailValidator'
+
+import usersService from '../../services/UsersService'
+
+export default function MemberList({groupList, selectedGroup, setUpdateList}) {
+
+ const api = new usersService()
+
+ const [fields, setFields] = useState({
+ firstname: '',
+ lastname: '',
+ email: ''
+ })
+
+ const handleFieldsChange = ({target:{name, value}}) => {
+ setFields(prev => ({...prev, [name]:value}))
+ let error = requestState?.errors?.indexOf(name) //// checks if the input field was in error array and removes it when the input changes
+ if(error >= 0){
+ let oldErrorArr = requestState.errors
+ let newErrorArr = oldErrorArr.splice(error, 1)
+ setRequestState(prev => ({...prev, errors:oldErrorArr}))
+ }
+ }
+
+ const [requestState, setRequestState] = useState({
+ loading: false,
+ status: false,
+ message: '',
+ data: [],
+ errors: []
+ })
+
+ const addMember = () => {
+ let errors = Object.keys(fields).filter((item) => { // CHECKS FOR EMPTY STRINGS
+ if(typeof item == 'string' && fields[item] === ''){
+ return item
+ }
+ })
+
+ if(errors.length){
+ setRequestState({
+ loading: false,
+ status: false,
+ message: '',
+ data: [],
+ errors: [...errors]
+ })
+ return
+ }
+
+ //checks if email is a valid email address
+ let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
+ if (!EmailValidator(fields.email)) {
+ setRequestState({
+ loading: false,
+ status: false,
+ message: 'Email is invalid',
+ data: [],
+ errors: []
+ })
+ return setTimeout(()=>{
+ setRequestState({
+ loading: false,
+ status: false,
+ message: '',
+ data: [],
+ errors: []
+ })
+ },3000)
+ }
+
+ setRequestState({
+ loading: true,
+ status: false,
+ message: '',
+ data: [],
+ errors: []
+ })
+ const requestData = {
+ firstname:fields.firstname,lastname:fields.lastname, email:fields.email, group_id: selectedGroup?.id, action:13015
+ }
+
+ api.groupMemberAdd(requestData).then(response => {
+ let {status, data} = response
+ if(status != 200 || data?.internal_return < 0){
+ setRequestState({
+ loading: false,
+ status: false,
+ message: 'Unable to add member',
+ data: [],
+ errors: []
+ })
+ return
+ }
+ setRequestState({
+ loading: false,
+ status: true,
+ message: 'Member added',
+ data: [],
+ errors: []
+ })
+
+ setTimeout(()=>{
+ // trigger group page reload
+ setUpdateList(prev => !prev)
+ setRequestState({
+ loading: false,
+ status: false,
+ message: '',
+ data: [],
+ errors: []
+ })
+ }, 3000)
+
+ }).catch(error=>{
+ setRequestState({
+ loading: false,
+ status: false,
+ message: 'Something went wrong, try again',
+ data: [],
+ errors: []
+ })
+ }).finally(()=>{
+ setTimeout(()=>{
+ setRequestState({
+ loading: false,
+ status: false,
+ message: '',
+ data: [],
+ errors: []
+ })
+ setFields({
+ firstname: '',
+ lastname: '',
+ email: ''
+ })
+ }, 3000)
+ })
+ }
+
+ return (
+ <>
+
+ {groupList && groupList.length < 1 ?
+ <>
+
No Group selected
+ >
+ :
+ <>
+
{selectedGroup?.name}
+
+
+
+
+
+ {/* */}
+
+
+
+ {/* */}
+
+
+
+ {/* */}
+
+
+ {requestState.loading ?
+
+ :
+
+ }
+
+ {!requestState.loading && requestState.message &&
+
{requestState.message}
+ }
+
+
+
+ {selectedGroup?.data?.length < 1 ?
+
No Member Found, Please Add
+ :
+
+ }
+
+
+ >
+ }
+
+ >
+ )
+}
diff --git a/src/components/Partials/Layout.jsx b/src/components/Partials/Layout.jsx
index f7963b2..6bd8c47 100644
--- a/src/components/Partials/Layout.jsx
+++ b/src/components/Partials/Layout.jsx
@@ -79,7 +79,7 @@ export default function Layout({ children }) {
{children && children}
-
+
diff --git a/src/components/Partials/RightSideBar.jsx b/src/components/Partials/RightSideBar.jsx
index 5a73988..179bbe6 100644
--- a/src/components/Partials/RightSideBar.jsx
+++ b/src/components/Partials/RightSideBar.jsx
@@ -3,7 +3,7 @@ import { useSelector } from "react-redux";
import { NavLink } from "react-router-dom";
//import SideStatistics from "./SideStatistics";
-export default function RightSideBar() {
+export default function RightSideBar({myJobList}) {
const filterDatas = ["Last 15 days", "Last Month", "Last 6 month"];
const [filterDataSet, setFilterDataSet] = useState([10, 30, 20, 40]);
const dataSetHandler = (value) => {
@@ -156,6 +156,7 @@ export default function RightSideBar() {
{/*JOB LINKS*/}
+ {myJobList?.data?.result_list?.length > 0 &&
{/* heading */}
@@ -190,7 +191,7 @@ export default function RightSideBar() {
{/* name */}
- Active Task
+ Active Task
{/* action */}
@@ -227,7 +228,7 @@ export default function RightSideBar() {
{/* name */}
- Review Pending
+ Review Pending
@@ -265,13 +266,13 @@ export default function RightSideBar() {
{/* name */}
{/* Line */}
-
+
{/* image */}
@@ -314,6 +315,7 @@ export default function RightSideBar() {
)}
+ }
>
);
diff --git a/src/services/UsersService.js b/src/services/UsersService.js
index 159b0e9..70a5087 100644
--- a/src/services/UsersService.js
+++ b/src/services/UsersService.js
@@ -1145,6 +1145,41 @@ class usersService {
return this.postAuxEnd("/familytransfer", postData);
}
+
+ // FUNCTION GET JOB GROUP LIST
+ jobGroupList(reqData) {
+ var postData = {
+ uid: localStorage.getItem("uid"),
+ member_id: localStorage.getItem("member_id"),
+ sessionid: localStorage.getItem("session_token"),
+ action: 13045,
+ ...reqData,
+ };
+ return this.postAuxEnd("/jobgrouplist", postData);
+ }
+
+ // FUNCTION TO ADD JOB GROUP
+ jobGroupAdd(reqData) {
+ var postData = {
+ uid: localStorage.getItem("uid"),
+ member_id: localStorage.getItem("member_id"),
+ sessionid: localStorage.getItem("session_token"),
+ ...reqData,
+ };
+ return this.postAuxEnd("/jobgroupadd", postData);
+ }
+
+ // FUNCTION TO ADD JOB GROUP MEMBER
+ groupMemberAdd(reqData) {
+ var postData = {
+ uid: localStorage.getItem("uid"),
+ member_id: localStorage.getItem("member_id"),
+ sessionid: localStorage.getItem("session_token"),
+ ...reqData,
+ };
+ return this.postAuxEnd("/groupmemberadd", postData);
+ }
+
/*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)