Replaced normal hooks to react-query Hook - Employee
This commit is contained in:
parent
1b5fa173f0
commit
fa32913e34
55
package-lock.json
generated
55
package-lock.json
generated
@ -11,6 +11,8 @@
|
||||
"@hookform/resolvers": "^3.10.0",
|
||||
"@microsoft/signalr": "^8.0.7",
|
||||
"@reduxjs/toolkit": "^2.5.0",
|
||||
"@tanstack/react-query": "^5.81.2",
|
||||
"@tanstack/react-query-devtools": "^5.81.2",
|
||||
"@types/web": "^0.0.216",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"apexcharts": "^4.5.0",
|
||||
@ -1423,6 +1425,59 @@
|
||||
"@swc/counter": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/query-core": {
|
||||
"version": "5.81.2",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.81.2.tgz",
|
||||
"integrity": "sha512-QLYkPdrudoMATDFa3MiLEwRhNnAlzHWDf0LKaXUqJd0/+QxN8uTPi7bahRlxoAyH0UbLMBdeDbYzWALj7THOtw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/query-devtools": {
|
||||
"version": "5.81.2",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.81.2.tgz",
|
||||
"integrity": "sha512-jCeJcDCwKfoyyBXjXe9+Lo8aTkavygHHsUHAlxQKKaDeyT0qyQNLKl7+UyqYH2dDF6UN/14873IPBHchcsU+Zg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-query": {
|
||||
"version": "5.81.2",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.81.2.tgz",
|
||||
"integrity": "sha512-pe8kFlTrL2zFLlcAj2kZk9UaYYHDk9/1hg9EBaoO3cxDhOZf1FRGJeziSXKrVZyxIfs7b3aoOj/bw7Lie0mDUg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/query-core": "5.81.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-query-devtools": {
|
||||
"version": "5.81.2",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.81.2.tgz",
|
||||
"integrity": "sha512-TX0OQ4cbgX6z2uN8c9x0QUNbyePGyUGdcgrGnV6TYEJc7KPT8PqeASuzoA5NGw1CiMGvyFAkIGA2KipvhM9d1g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/query-devtools": "5.81.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tanstack/react-query": "^5.81.2",
|
||||
"react": "^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
|
@ -14,6 +14,8 @@
|
||||
"@hookform/resolvers": "^3.10.0",
|
||||
"@microsoft/signalr": "^8.0.7",
|
||||
"@reduxjs/toolkit": "^2.5.0",
|
||||
"@tanstack/react-query": "^5.81.2",
|
||||
"@tanstack/react-query-devtools": "^5.81.2",
|
||||
"@types/web": "^0.0.216",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"apexcharts": "^4.5.0",
|
||||
|
22
src/App.tsx
22
src/App.tsx
@ -1,21 +1,33 @@
|
||||
import { DireProvider } from "./Context/DireContext";
|
||||
import AppRoutes from "./router/AppRoutes";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
staleTime: 5 * 60 * 1000, // 5 min: data considered fresh
|
||||
refetchOnWindowFocus: false, // refresh on tab switch
|
||||
refetchOnReconnect: true, // re-fetch if network was lost
|
||||
retry: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<div className="app">
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<DireProvider>
|
||||
<AppRoutes />
|
||||
</DireProvider>
|
||||
|
||||
<ToastContainer>
|
||||
|
||||
</ToastContainer>
|
||||
|
||||
<ToastContainer />
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App
|
||||
export default App;
|
||||
|
@ -19,7 +19,7 @@ import { useProfile } from "../../hooks/useProfile";
|
||||
const ManageBucket = () => {
|
||||
const { profile } = useProfile();
|
||||
const [bucketList, setBucketList] = useState([]);
|
||||
const { employeesList } = useAllEmployees(false);
|
||||
const {employeesList} = useAllEmployees( false );
|
||||
const [selectedEmployee, setSelectEmployee] = useState([]);
|
||||
const { buckets, loading, refetch } = useBuckets();
|
||||
const [action_bucket, setAction_bucket] = useState(false);
|
||||
|
@ -9,20 +9,21 @@ import { useDispatch } from "react-redux";
|
||||
import { changeMaster } from "../../slices/localVariablesSlice";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import { formatDate } from "../../utils/dateUtils";
|
||||
import { useEmployeeProfile } from "../../hooks/useEmployees";
|
||||
import { useEmployeeProfile, useUpdateEmployee } from "../../hooks/useEmployees";
|
||||
import {
|
||||
cacheData,
|
||||
clearCacheKey,
|
||||
getCachedData,
|
||||
} from "../../slices/apiDataManager";
|
||||
import { clearApiCacheKey } from "../../slices/apiCacheSlice";
|
||||
import {useMutation} from "@tanstack/react-query";
|
||||
|
||||
const mobileNumberRegex = /^[0-9]\d{9}$/;
|
||||
|
||||
const ManageEmployee = ({ employeeId, onClosed }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { mutate: updateEmployee, isLoading } = useUpdateEmployee();
|
||||
|
||||
// const { employeeId } = useParams();
|
||||
const {
|
||||
employee,
|
||||
error,
|
||||
@ -163,39 +164,53 @@ const ManageEmployee = ({ employeeId, onClosed }) => {
|
||||
|
||||
const AadharNumberValue = watch("aadharNumber") || "";
|
||||
|
||||
// const onSubmit = (data) => {
|
||||
// setLoading(true);
|
||||
// if (data.email == "") {
|
||||
// data.email = null;
|
||||
// }
|
||||
// EmployeeRepository.manageEmployee(data)
|
||||
// .then((response) => {
|
||||
// cacheData("employeeProfileInfo", data);
|
||||
// showToast(
|
||||
// `Employee details ${
|
||||
// data.id == null ? "created" : "updated"
|
||||
// } successfully.`,
|
||||
// "success"
|
||||
// );
|
||||
// clearCacheKey("employeeListByProject");
|
||||
// clearCacheKey("allEmployeeList");
|
||||
// clearCacheKey("allInactiveEmployeeList");
|
||||
// clearCacheKey("employeeProfile");
|
||||
|
||||
// setLoading(false);
|
||||
// reset();
|
||||
// // navigation("/employees");
|
||||
// onClosed();
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// const message =
|
||||
// error?.response?.data?.message ||
|
||||
// error?.message ||
|
||||
// "Error occured during api calling";
|
||||
// showToast(message, "error");
|
||||
// setLoading(false);
|
||||
// });
|
||||
// };
|
||||
|
||||
const onSubmit = (data) => {
|
||||
setLoading(true);
|
||||
if (data.email == "") {
|
||||
if (data.email === "") {
|
||||
data.email = null;
|
||||
}
|
||||
EmployeeRepository.manageEmployee(data)
|
||||
.then((response) => {
|
||||
cacheData("employeeProfileInfo", data);
|
||||
showToast(
|
||||
`Employee details ${
|
||||
data.id == null ? "created" : "updated"
|
||||
} successfully.`,
|
||||
"success"
|
||||
);
|
||||
clearCacheKey("employeeListByProject");
|
||||
clearCacheKey("allEmployeeList");
|
||||
clearCacheKey("allInactiveEmployeeList");
|
||||
clearCacheKey("employeeProfile");
|
||||
|
||||
setLoading(false);
|
||||
updateEmployee(data, {
|
||||
onSuccess: () => {
|
||||
reset();
|
||||
// navigation("/employees");
|
||||
onClosed();
|
||||
})
|
||||
.catch((error) => {
|
||||
const message =
|
||||
error?.response?.data?.message ||
|
||||
error?.message ||
|
||||
"Error occured during api calling";
|
||||
showToast(message, "error");
|
||||
setLoading(false);
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && !error && employee) {
|
||||
@ -233,12 +248,6 @@ const ManageEmployee = ({ employeeId, onClosed }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
{/* <div className="c">
|
||||
{!currentEmployee && empLoading && employeeId && (
|
||||
<p>Loading Employee Data...</p>
|
||||
)} */}
|
||||
|
||||
<form onSubmit={handleSubmit( onSubmit )} className="p-sm-0 p-2">
|
||||
<div className="text-center"><p className="fs-6 fw-semibold"> {employee ? "Update Employee" : "Create Employee"}</p></div>
|
||||
<div className="row mb-3">
|
||||
|
@ -1,12 +1,13 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import useMaster from "../../hooks/masterHook/useMaster";
|
||||
import React, { useEffect, useRef, useState, useMemo } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { RolesRepository } from "../../repositories/MastersRepository";
|
||||
import { useEmployeeRoles } from "../../hooks/useEmployees";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
import { useEmployeeRoles, useUpdateEmployeeRoles } from "../../hooks/useEmployees";
|
||||
import useMaster from "../../hooks/masterHook/useMaster";
|
||||
import { changeMaster } from "../../slices/localVariablesSlice";
|
||||
import { RolesRepository } from "../../repositories/MastersRepository";
|
||||
import showToast from "../../services/toastService";
|
||||
|
||||
const formSchema = z.object({
|
||||
@ -15,44 +16,17 @@ const formSchema = z.object({
|
||||
|
||||
const ManageRole = ( {employeeId, onClosed} ) =>
|
||||
{
|
||||
const dispatch = useDispatch();
|
||||
const formStateRef = useRef({});
|
||||
|
||||
const disptach = useDispatch();
|
||||
useEffect(()=>{
|
||||
disptach(changeMaster("Application Role"));
|
||||
},[disptach])
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { employeeRoles, loading } = useEmployeeRoles(employeeId);
|
||||
const { data, loading: roleLoading } = useMaster();
|
||||
|
||||
const buildDefaultRoles = () => {
|
||||
const defaults = {};
|
||||
data.forEach((role) => {
|
||||
const isRoleEnabled = employeeRoles?.some(
|
||||
(empRole) => empRole.roleId === role.id
|
||||
);
|
||||
defaults[role.id] = isRoleEnabled;
|
||||
});
|
||||
|
||||
return defaults;
|
||||
};
|
||||
|
||||
const [initialRoles, setInitialRoles] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
if (employeeRoles && data) {
|
||||
if (employeeRoles.length > 0) {
|
||||
const updatedRoles = buildDefaultRoles();
|
||||
setInitialRoles(updatedRoles);
|
||||
} else {
|
||||
setInitialRoles({});
|
||||
}
|
||||
} else {
|
||||
setInitialRoles({});
|
||||
}
|
||||
}, [employeeRoles, data]);
|
||||
|
||||
dispatch(changeMaster("Application Role"));
|
||||
}, [dispatch]);
|
||||
|
||||
|
||||
const { employeeRoles = [], loading: empLoading } = useEmployeeRoles(employeeId);
|
||||
const { data: roles = [], loading: roleLoading } = useMaster();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
@ -60,83 +34,53 @@ useEffect(()=>{
|
||||
reset,
|
||||
} = useForm({
|
||||
resolver: zodResolver(formSchema),
|
||||
|
||||
defaultValues: { selectedRole: {} },
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!data) return;
|
||||
|
||||
const updatedRoles = {};
|
||||
data.forEach((role) => {
|
||||
const isRoleEnabled = employeeRoles?.some(
|
||||
const {
|
||||
updateRoles,
|
||||
isPending : isLoading,
|
||||
isError,
|
||||
error,
|
||||
} = useUpdateEmployeeRoles({
|
||||
onClose: onClosed,
|
||||
resetForm: reset,
|
||||
});
|
||||
// Prepare default form values based on roles and current assignments
|
||||
const selectedRoleDefaults = useMemo(() => {
|
||||
const defaults = {};
|
||||
roles.forEach((role) => {
|
||||
const enabled = employeeRoles.some(
|
||||
(empRole) => empRole.roleId === role.id && empRole.isEnabled
|
||||
);
|
||||
updatedRoles[role.id] = isRoleEnabled || false;
|
||||
defaults[role.id] = enabled;
|
||||
});
|
||||
return defaults;
|
||||
}, [roles, employeeRoles]);
|
||||
|
||||
setInitialRoles(updatedRoles);
|
||||
// Avoid infinite loop by comparing previous form values
|
||||
useEffect(() => {
|
||||
const prev = JSON.stringify(formStateRef.current);
|
||||
const next = JSON.stringify(selectedRoleDefaults);
|
||||
|
||||
reset({
|
||||
selectedRole: updatedRoles,
|
||||
});
|
||||
}, [employeeRoles, data, reset]);
|
||||
if (prev !== next) {
|
||||
formStateRef.current = selectedRoleDefaults;
|
||||
reset({ selectedRole: selectedRoleDefaults });
|
||||
}
|
||||
}, [selectedRoleDefaults, reset]);
|
||||
|
||||
// const onSubmit = (formdata) => {
|
||||
const onSubmit = async (formData) => {
|
||||
// setIsLoading(true);
|
||||
// const result = [];
|
||||
|
||||
// const selectedRoles = formdata.selectedRole;
|
||||
const updates = [];
|
||||
const selected = formData.selectedRole;
|
||||
|
||||
// for (const [roleId, isChecked] of Object.entries(selectedRoles)) {
|
||||
// const existingRole = employeeRoles?.find((role) => role.roleId === roleId);
|
||||
// const wasChecked = !!existingRole?.isEnabled;
|
||||
for (const [roleId, isChecked] of Object.entries(selected)) {
|
||||
const existing = employeeRoles.find((r) => r.roleId === roleId);
|
||||
const wasChecked = !!existing?.isEnabled;
|
||||
|
||||
// // Only push if the checked status has changed
|
||||
// if (isChecked !== wasChecked) {
|
||||
// result.push({
|
||||
// id: existingRole?.id || "00000000-0000-0000-0000-000000000000",
|
||||
// employeeId,
|
||||
// roleId,
|
||||
// isEnabled: isChecked,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (result.length === 0) {
|
||||
// showToast("No changes made", "info");
|
||||
// setIsLoading(false);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// console.log(result);
|
||||
|
||||
// RolesRepository.createEmployeeRoles(result)
|
||||
// .then(() => {
|
||||
// showToast("Roles updated successfully", "success");
|
||||
// setIsLoading(false);
|
||||
// reset();
|
||||
// onClosed();
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.error(err);
|
||||
// showToast(err.message, "error");
|
||||
// setIsLoading(false);
|
||||
// });
|
||||
// };
|
||||
|
||||
const onSubmit = (formdata) => {
|
||||
setIsLoading(true);
|
||||
const result = [];
|
||||
const selectedRoles = formdata.selectedRole;
|
||||
|
||||
for (const [roleId, isChecked] of Object.entries(selectedRoles)) {
|
||||
const existingRole = employeeRoles?.find((role) => role.roleId === roleId);
|
||||
const wasChecked = !!existingRole?.isEnabled;
|
||||
|
||||
// Only push if the checked status has changed
|
||||
if (isChecked !== wasChecked) {
|
||||
result.push({
|
||||
id: existingRole?.id || "00000000-0000-0000-0000-000000000000",
|
||||
updates.push({
|
||||
id: existing?.id || "00000000-0000-0000-0000-000000000000",
|
||||
employeeId,
|
||||
roleId,
|
||||
isEnabled: isChecked,
|
||||
@ -144,83 +88,69 @@ useEffect(()=>{
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length === 0) {
|
||||
if (updates.length === 0) {
|
||||
showToast("No changes made", "info");
|
||||
setIsLoading(false);
|
||||
// setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
|
||||
RolesRepository.createEmployeeRoles(result)
|
||||
.then(() => {
|
||||
showToast("Roles updated successfully", "success");
|
||||
setIsLoading(false);
|
||||
reset();
|
||||
onClosed();
|
||||
})
|
||||
.catch((error) => {
|
||||
const message = error?.response?.data?.message || error?.message || "Error occured during api calling"
|
||||
showToast(message, "error");
|
||||
setIsLoading(false);
|
||||
});
|
||||
// try {
|
||||
// await RolesRepository.createEmployeeRoles(updates);
|
||||
// showToast("Roles updated successfully", "success");
|
||||
// reset();
|
||||
// onClosed();
|
||||
// } catch (err) {
|
||||
// const message =
|
||||
// err?.response?.data?.message || err?.message || "Error occurred while updating roles";
|
||||
// showToast(message, "error");
|
||||
// } finally {
|
||||
// setIsLoading(false);
|
||||
// }
|
||||
updateRoles(updates);
|
||||
};
|
||||
|
||||
const isLoadingData = roleLoading || empLoading;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`modal fade `}
|
||||
id="managerole-modal"
|
||||
tabIndex="-1"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div className="modal-dialog modal-simple modal-md d-flex align-items-center justify-content-center">
|
||||
<div className="modal-content ">
|
||||
<div className="modal-body">
|
||||
<button
|
||||
type="button"
|
||||
className="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="text-start my-0">
|
||||
<div className="text-start mb-3">
|
||||
<p className="lead">Select Roles</p>
|
||||
</div>
|
||||
|
||||
{isLoadingData ? (
|
||||
<p>Loading...</p>
|
||||
) : (
|
||||
<div
|
||||
className="d-flex flex-wrap justify-content-between align-items-center pb-5 "
|
||||
style={{ maxHeight: "70vh", overflowY: "scroll" }}
|
||||
className="d-flex flex-wrap justify-content-between pb-4"
|
||||
style={{ maxHeight: "70vh", overflowY: "auto" }}
|
||||
>
|
||||
{roleLoading && <p>Loading...</p>}
|
||||
{loading && <p>Loading...</p>}
|
||||
{data &&
|
||||
data.map((item) => (
|
||||
<div className="col-md-6 col-lg-4 mb-4" key={item.id}>
|
||||
{roles.map((role) => (
|
||||
<div className="col-md-6 col-lg-4 mb-3" key={role.id}>
|
||||
<div className="form-check ms-2 text-start">
|
||||
<input
|
||||
className="form-check-input"
|
||||
type="checkbox"
|
||||
id={item.id}
|
||||
{...register(`selectedRole.${item.id}`)}
|
||||
|
||||
id={role.id}
|
||||
{...register(`selectedRole.${role.id}`)}
|
||||
/>
|
||||
<label
|
||||
className="form-check-label text-bold"
|
||||
htmlFor={item.id}
|
||||
>
|
||||
<small>{item.role || "--"}</small>
|
||||
<label className="form-check-label" htmlFor={role.id}>
|
||||
<small>{role.role || "--"}</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{errors.selected && (
|
||||
<div className="text-center">{errors.selected.message}</div>
|
||||
)}
|
||||
|
||||
<div className="col-12 text-center">
|
||||
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||
{isLoading ? "Please Wait" : "Submit"}
|
||||
{errors.selectedRole && (
|
||||
<div className="text-danger text-center">
|
||||
{errors.selectedRole.message}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="text-center mt-3">
|
||||
<button type="submit" className="btn btn-sm btn-primary me-3" disabled={isLoading}>
|
||||
{isLoading ? "Please Wait..." : "Submit"}
|
||||
</button>
|
||||
<button
|
||||
type="reset"
|
||||
@ -232,10 +162,6 @@ useEffect(()=>{
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@ import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||
import { MANAGE_PROJECT } from "../../utils/constants";
|
||||
|
||||
const Header = () => {
|
||||
const { profile } = useProfile();
|
||||
const {profile} = useProfile();
|
||||
const location = useLocation();
|
||||
const dispatch = useDispatch(changeMaster("Job Role"));
|
||||
const { data, loading } = useMaster();
|
||||
|
@ -3,236 +3,518 @@ import { cacheData, getCachedData } from "../slices/apiDataManager";
|
||||
import { RolesRepository } from "../repositories/MastersRepository";
|
||||
import EmployeeRepository from "../repositories/EmployeeRepository";
|
||||
import ProjectRepository from "../repositories/ProjectRepository";
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import showToast from "../services/toastService";
|
||||
import {useSelector} from "react-redux";
|
||||
import {store} from "../store/store";
|
||||
|
||||
export const useAllEmployees = (showInactive) => {
|
||||
const [employeesList, setEmployeeList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState();
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
let EmployeeList_cached = getCachedData("AllEmployees");
|
||||
if (!EmployeeList_cached) {
|
||||
setLoading(true);
|
||||
const response = await EmployeeRepository.getAllEmployeeList(showInactive);
|
||||
cacheData("AllEmployees", response.data);
|
||||
setEmployeeList(response.data);
|
||||
setLoading(false);
|
||||
} else {
|
||||
setEmployeeList(EmployeeList_cached);
|
||||
setLoading(false);
|
||||
}
|
||||
} catch (error) {
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
}
|
||||
// export const useAllEmployees = (showInactive) => {
|
||||
// const [employeesList, setEmployeeList] = useState([]);
|
||||
// const [loading, setLoading] = useState(false);
|
||||
// const [error, setError] = useState();
|
||||
|
||||
// const fetchData = async () => {
|
||||
// try {
|
||||
// let EmployeeList_cached = getCachedData("AllEmployees");
|
||||
// if (!EmployeeList_cached) {
|
||||
// setLoading(true);
|
||||
// const response = await EmployeeRepository.getAllEmployeeList(showInactive);
|
||||
// cacheData("AllEmployees", response.data);
|
||||
// setEmployeeList(response.data);
|
||||
// setLoading(false);
|
||||
// } else {
|
||||
// setEmployeeList(EmployeeList_cached);
|
||||
// setLoading(false);
|
||||
// }
|
||||
// } catch (error) {
|
||||
// setError("Failed to fetch data.");
|
||||
// setLoading(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// useEffect(() => {
|
||||
// fetchData();
|
||||
// }, []);
|
||||
// return { employeesList, loading, error };
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// export const useEmployees = (selectedProject) => {
|
||||
// const [employees, setEmployeeList] = useState([]);
|
||||
// const [loading, setLoading] = useState(true);
|
||||
// const [projects, setProjects] = useState([]);
|
||||
|
||||
// const fetchData = async (projectid) => {
|
||||
// try {
|
||||
// let EmployeeByProject_Cache = getCachedData("employeeListByProject");
|
||||
// if (
|
||||
// !EmployeeByProject_Cache ||
|
||||
// !EmployeeByProject_Cache.projectId === projectid
|
||||
// ) {
|
||||
// EmployeeRepository.getEmployeeListByproject(projectid)
|
||||
// .then((response) => {
|
||||
// setEmployeeList(response);
|
||||
// cacheData("employeeListByProject", {
|
||||
// data: response,
|
||||
// projectId: projectid,
|
||||
// });
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// setError("Failed to fetch data.");
|
||||
// });
|
||||
// } else {
|
||||
// setEmployeeList(EmployeeByProject_Cache.data);
|
||||
// }
|
||||
// setLoading(false);
|
||||
// } catch (err) {
|
||||
// setError("Failed to fetch data.");
|
||||
// setLoading(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// useEffect(() => {
|
||||
// if (selectedProject) {
|
||||
// fetchData(selectedProject);
|
||||
// }
|
||||
// }, [selectedProject]);
|
||||
|
||||
// return { employees, loading, projects, reCallAllEmployee };
|
||||
// };
|
||||
|
||||
// export const useEmployeeRoles = (employeeId) => {
|
||||
// const [loading, setLoading] = useState(true);
|
||||
// const [error, setError] = useState();
|
||||
// const [employeeRoles, setEmployeeRoles] = useState([]);
|
||||
// const fetchData = async (employeeid) => {
|
||||
// try {
|
||||
// let response = await RolesRepository.getEmployeeRoles(employeeid);
|
||||
// setEmployeeRoles(response.data);
|
||||
// cacheData("employeelist", response.data);
|
||||
// } catch (err) {
|
||||
// setError("Failed to fetch data.");
|
||||
// setEmployeeRoles([]);
|
||||
// } finally {
|
||||
// setLoading(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// useEffect(() => {
|
||||
// if (employeeId) {
|
||||
// fetchData(employeeId);
|
||||
// }
|
||||
// }, [employeeId]);
|
||||
|
||||
// return { employeeRoles, loading, error };
|
||||
// };
|
||||
|
||||
// export const useEmployeesByProject = (projectId) => {
|
||||
// const [loading, setLoading] = useState(false);
|
||||
// const [error, setError] = useState();
|
||||
// const [employees, setEmployees] = useState([]);
|
||||
|
||||
// const fetchData = async () => {
|
||||
// const Employees_cache = getCachedData("employeeListByProject");
|
||||
// if (!Employees_cache || Employees_cache.projectId !== projectId) {
|
||||
// setEmployees(true);
|
||||
// ProjectRepository.getEmployeesByProject(projectId)
|
||||
// .then((response) => {
|
||||
// setEmployees(response.data);
|
||||
// cacheData("employeeListByProject", {
|
||||
// data: response.data,
|
||||
// projectId,
|
||||
// });
|
||||
// setLoading(false);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// setError("Failed to fetch data.");
|
||||
// setLoading(false);
|
||||
// });
|
||||
// } else {
|
||||
// setEmployees(Employees_cache.data);
|
||||
// setLoading(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// useEffect(() => {
|
||||
// fetchData(projectId);
|
||||
// }, [projectId]);
|
||||
|
||||
// return { employees, loading, error, recallProjectEmplloyee: fetchData };
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// export const useEmployeesAllOrByProjectId = (projectId, showInactive) => {
|
||||
// const [employees, setEmployees] = useState([]);
|
||||
// const [loading, setLoading] = useState(false);
|
||||
// const [error, setError] = useState(null);
|
||||
|
||||
// const fetchData = async (showInactive) => {
|
||||
// if ( projectId )
|
||||
// {
|
||||
// const Employees_cache = getCachedData("employeeListByProject");
|
||||
// if (!Employees_cache || Employees_cache.projectId !== projectId) {
|
||||
// setLoading(true);
|
||||
// setError(null);
|
||||
// try {
|
||||
// const response = await ProjectRepository.getEmployeesByProject(
|
||||
// projectId
|
||||
// );
|
||||
// setEmployees(response.data);
|
||||
// cacheData("employeeListByProject", {
|
||||
// data: response.data,
|
||||
// projectId,
|
||||
// });
|
||||
// setLoading(false);
|
||||
// } catch (err) {
|
||||
// setError("Failed to fetch data.");
|
||||
// setLoading(false);
|
||||
// }
|
||||
// } else {
|
||||
// setEmployees(Employees_cache.data);
|
||||
// setLoading(false);
|
||||
// }
|
||||
// } else
|
||||
// {
|
||||
// const cacheKey = showInactive
|
||||
// ? "allInactiveEmployeeList"
|
||||
// : "allEmployeeList";
|
||||
|
||||
// try {
|
||||
// const response = await EmployeeRepository.getAllEmployeeList(
|
||||
// showInactive
|
||||
// );
|
||||
// setEmployees(response.data);
|
||||
// cacheData(cacheKey, { data: response.data });
|
||||
// setLoading(false);
|
||||
// } catch (err) {
|
||||
// setError("Failed to fetch data.");
|
||||
// setLoading(false);
|
||||
// }
|
||||
|
||||
// }
|
||||
// };
|
||||
|
||||
// useEffect(() => {
|
||||
// fetchData(showInactive); // Fetch data when the component mounts or projectId changes
|
||||
// }, [projectId]); // Re-fetch when projectId changes
|
||||
|
||||
// return {
|
||||
// employees,
|
||||
// loading,
|
||||
// error,
|
||||
// recallEmployeeData: fetchData,
|
||||
// };
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
// export const useEmployeeProfile = (employeeId) => {
|
||||
// const [loading, setLoading] = useState(true);
|
||||
// const [error, setError] = useState();
|
||||
// const [employee, setEmployees] = useState(null);
|
||||
|
||||
// const fetchData = async () => {
|
||||
// if (!employeeId) {
|
||||
// // Reset the state if no employeeId (e.g., opening for 'add' mode)
|
||||
// setEmployees(null);
|
||||
// setLoading(false);
|
||||
// return;
|
||||
// }
|
||||
// const Employee_cache = getCachedData("employeeProfile");
|
||||
// if (!Employee_cache || Employee_cache.employeeId !== employeeId) {
|
||||
// EmployeeRepository.getEmployeeProfile(employeeId)
|
||||
// .then((response) => {
|
||||
// setEmployees(response.data);
|
||||
// cacheData("employeeProfile", { data: response.data, employeeId });
|
||||
// setLoading(false);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// setError("Failed to fetch data.");
|
||||
// setLoading(false);
|
||||
// });
|
||||
// } else {
|
||||
// setEmployees(Employee_cache.data);
|
||||
// setLoading(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// useEffect(() => {
|
||||
// fetchData();
|
||||
// }, [employeeId]);
|
||||
|
||||
// return { employee, loading, error };
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Query ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export const useAllEmployees = ( showInactive ) =>
|
||||
{
|
||||
const {
|
||||
data = [],
|
||||
isLoading,
|
||||
error,
|
||||
refetch, // optional if you want recall functionality
|
||||
} = useQuery({
|
||||
queryKey: ['allEmployee', showInactive],
|
||||
queryFn: async () => {
|
||||
const res = await EmployeeRepository.getAllEmployeeList(showInactive);
|
||||
return res.data;
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
employeesList: data,
|
||||
loading: isLoading,
|
||||
error,
|
||||
recallEmployeeData: refetch,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
return { employeesList, loading, error };
|
||||
};
|
||||
|
||||
export const useEmployees = (selectedProject) => {
|
||||
const [employees, setEmployeeList] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [projects, setProjects] = useState([]);
|
||||
// ManageBucket.jsx
|
||||
export const useEmployees = ( selectedProject ) =>
|
||||
{
|
||||
|
||||
const fetchData = async (projectid) => {
|
||||
try {
|
||||
let EmployeeByProject_Cache = getCachedData("employeeListByProject");
|
||||
if (
|
||||
!EmployeeByProject_Cache ||
|
||||
!EmployeeByProject_Cache.projectId === projectid
|
||||
) {
|
||||
EmployeeRepository.getEmployeeListByproject(projectid)
|
||||
.then((response) => {
|
||||
setEmployeeList(response);
|
||||
cacheData("employeeListByProject", {
|
||||
data: response,
|
||||
projectId: projectid,
|
||||
const {
|
||||
data = [],
|
||||
isLoading,
|
||||
error,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ["employeeListByProject", selectedProject],
|
||||
queryFn: async () => {
|
||||
const res = await EmployeeRepository.getEmployeeListByproject(selectedProject);
|
||||
return res.data || res;
|
||||
},
|
||||
enabled: !!selectedProject,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
setError("Failed to fetch data.");
|
||||
});
|
||||
} else {
|
||||
setEmployeeList(EmployeeByProject_Cache.data);
|
||||
}
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
return {
|
||||
employees: data,
|
||||
loading: isLoading,
|
||||
projects: [], // if needed, pass this separately or manage from another hook
|
||||
reCallAllEmployee: refetch,
|
||||
error,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedProject) {
|
||||
fetchData(selectedProject);
|
||||
}
|
||||
}, [selectedProject]);
|
||||
|
||||
return { employees, loading, projects, reCallAllEmployee };
|
||||
};
|
||||
|
||||
// ManageRole.jsx
|
||||
export const useEmployeeRoles = (employeeId) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState();
|
||||
const [employeeRoles, setEmployeeRoles] = useState([]);
|
||||
const fetchData = async (employeeid) => {
|
||||
try {
|
||||
let response = await RolesRepository.getEmployeeRoles(employeeid);
|
||||
setEmployeeRoles(response.data);
|
||||
cacheData("employeelist", response.data);
|
||||
} catch (err) {
|
||||
setError("Failed to fetch data.");
|
||||
setEmployeeRoles([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
const {
|
||||
data = [],
|
||||
isLoading: loading,
|
||||
error,
|
||||
} = useQuery({
|
||||
queryKey: ['employeeRoles', employeeId],
|
||||
queryFn: async () => {
|
||||
const res = await RolesRepository.getEmployeeRoles(employeeId);
|
||||
return res.data;
|
||||
},
|
||||
enabled: !!employeeId,
|
||||
});
|
||||
|
||||
return {
|
||||
employeeRoles: data,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (employeeId) {
|
||||
fetchData(employeeId);
|
||||
}
|
||||
}, [employeeId]);
|
||||
|
||||
return { employeeRoles, loading, error };
|
||||
};
|
||||
|
||||
// EmployeeProfile.jsx
|
||||
export const useEmployeesByProject = (projectId) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState();
|
||||
const [employees, setEmployees] = useState([]);
|
||||
const {
|
||||
data = [],
|
||||
isLoading: loading,
|
||||
error,
|
||||
refetch: recallProjectEmplloyee,
|
||||
} = useQuery({
|
||||
queryKey: ['projectEmployees', projectId],
|
||||
queryFn: async () => {
|
||||
const res = await ProjectRepository.getEmployeesByProject(projectId);
|
||||
return res.data;
|
||||
},
|
||||
enabled: !!projectId,
|
||||
});
|
||||
|
||||
const fetchData = async () => {
|
||||
const Employees_cache = getCachedData("employeeListByProject");
|
||||
if (!Employees_cache || Employees_cache.projectId !== projectId) {
|
||||
setEmployees(true);
|
||||
ProjectRepository.getEmployeesByProject(projectId)
|
||||
.then((response) => {
|
||||
setEmployees(response.data);
|
||||
cacheData("employeeListByProject", {
|
||||
data: response.data,
|
||||
projectId,
|
||||
});
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
});
|
||||
} else {
|
||||
setEmployees(Employees_cache.data);
|
||||
setLoading(false);
|
||||
}
|
||||
return {
|
||||
employees: data,
|
||||
loading,
|
||||
error,
|
||||
recallProjectEmplloyee,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData(projectId);
|
||||
}, [projectId]);
|
||||
|
||||
return { employees, loading, error, recallProjectEmplloyee: fetchData };
|
||||
};
|
||||
|
||||
// EmployeeList.jsx
|
||||
export const useEmployeesAllOrByProjectId = (projectId, showInactive) => {
|
||||
const [employees, setEmployees] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const isAllEmployees = !projectId && projectId !== undefined;
|
||||
|
||||
const fetchData = async (showInactive) => {
|
||||
if ( projectId )
|
||||
{
|
||||
const Employees_cache = getCachedData("employeeListByProject");
|
||||
if (!Employees_cache || Employees_cache.projectId !== projectId) {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await ProjectRepository.getEmployeesByProject(
|
||||
projectId
|
||||
);
|
||||
setEmployees(response.data);
|
||||
cacheData("employeeListByProject", {
|
||||
data: response.data,
|
||||
projectId,
|
||||
});
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
}
|
||||
const queryKey = isAllEmployees
|
||||
? ['allEmployees', showInactive]
|
||||
: ['projectEmployees', projectId];
|
||||
|
||||
const queryFn = async () => {
|
||||
if (isAllEmployees) {
|
||||
const res = await EmployeeRepository.getAllEmployeeList(showInactive);
|
||||
return res.data;
|
||||
} else {
|
||||
setEmployees(Employees_cache.data);
|
||||
setLoading(false);
|
||||
}
|
||||
} else
|
||||
{
|
||||
const cacheKey = showInactive
|
||||
? "allInactiveEmployeeList"
|
||||
: "allEmployeeList";
|
||||
|
||||
try {
|
||||
const response = await EmployeeRepository.getAllEmployeeList(
|
||||
showInactive
|
||||
);
|
||||
setEmployees(response.data);
|
||||
cacheData(cacheKey, { data: response.data });
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const res = await ProjectRepository.getEmployeesByProject(projectId);
|
||||
return res.data;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData(showInactive); // Fetch data when the component mounts or projectId changes
|
||||
}, [projectId]); // Re-fetch when projectId changes
|
||||
const {
|
||||
data: employees = [],
|
||||
isLoading,
|
||||
error,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: isAllEmployees || !!projectId,
|
||||
});
|
||||
|
||||
return {
|
||||
employees,
|
||||
loading: isLoading,
|
||||
error,
|
||||
recallEmployeeData: refetch,
|
||||
};
|
||||
};
|
||||
|
||||
// ManageEmployee.jsx
|
||||
export const useEmployeeProfile = (employeeId) => {
|
||||
const isEnabled = !!employeeId;
|
||||
|
||||
const {
|
||||
data = null,
|
||||
isLoading: loading,
|
||||
error,
|
||||
} = useQuery({
|
||||
queryKey: ['employeeProfile', employeeId],
|
||||
queryFn: async () => {
|
||||
if (!employeeId) return null;
|
||||
const res = await EmployeeRepository.getEmployeeProfile(employeeId);
|
||||
return res.data;
|
||||
},
|
||||
enabled: isEnabled,
|
||||
});
|
||||
|
||||
return {
|
||||
employee: data,
|
||||
loading,
|
||||
error,
|
||||
recallEmployeeData: fetchData,
|
||||
};
|
||||
};
|
||||
|
||||
export const useEmployeeProfile = (employeeId) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState();
|
||||
const [employee, setEmployees] = useState(null);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!employeeId) {
|
||||
// Reset the state if no employeeId (e.g., opening for 'add' mode)
|
||||
setEmployees(null);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
const Employee_cache = getCachedData("employeeProfile");
|
||||
if (!Employee_cache || Employee_cache.employeeId !== employeeId) {
|
||||
EmployeeRepository.getEmployeeProfile(employeeId)
|
||||
.then((response) => {
|
||||
setEmployees(response.data);
|
||||
cacheData("employeeProfile", { data: response.data, employeeId });
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
// Mutation------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
export const useUpdateEmployee = () =>
|
||||
{
|
||||
const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (employeeData) => EmployeeRepository.manageEmployee(employeeData),
|
||||
onSuccess: (_, variables) => {
|
||||
const id = variables.id || variables.employeeId;
|
||||
|
||||
// Cache invalidation
|
||||
queryClient.invalidateQueries( ['allEmployee',false]);
|
||||
queryClient.invalidateQueries(['employeeProfile', id]);
|
||||
queryClient.invalidateQueries( {queryKey: [ 'projectEmployees' ]} );
|
||||
|
||||
queryClient.invalidateQueries( [ 'employeeListByProject' ,selectedProject] );
|
||||
showToast( `Employee ${ id ? 'updated' : 'created' } successfully`, 'success' );
|
||||
},
|
||||
onError: (error) => {
|
||||
const msg = error?.response?.data?.message || error.message || 'Something went wrong';
|
||||
showToast(msg, 'error');
|
||||
},
|
||||
});
|
||||
} else {
|
||||
setEmployees(Employee_cache.data);
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, [employeeId]);
|
||||
|
||||
return { employee, loading, error };
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const useSuspendEmployee = ({ setIsDeleteModalOpen, setemployeeLodaing }) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (id) => {
|
||||
setemployeeLodaing(true);
|
||||
return EmployeeRepository.deleteEmployee(id);
|
||||
},
|
||||
|
||||
onSuccess: () => {
|
||||
showToast("Employee deleted successfully.", "success");
|
||||
|
||||
queryClient.invalidateQueries( ['allEmployee',false]);
|
||||
queryClient.invalidateQueries( {queryKey: [ 'projectEmployees' ]} );
|
||||
queryClient.invalidateQueries( [ 'employeeListByProject' ,selectedProject] );
|
||||
|
||||
setIsDeleteModalOpen(false);
|
||||
},
|
||||
|
||||
onError: (error) => {
|
||||
const message =
|
||||
error.response?.data?.message ||
|
||||
error.message ||
|
||||
"An unexpected error occurred";
|
||||
showToast(message, "error");
|
||||
setIsDeleteModalOpen(false);
|
||||
},
|
||||
|
||||
onSettled: () => {
|
||||
setemployeeLodaing(false);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Manage Role
|
||||
|
||||
|
||||
export const useUpdateEmployeeRoles = ({ onClose, resetForm, onSuccessCallback } = {}) => {
|
||||
const queryClient = useQueryClient();
|
||||
const mutation = useMutation({
|
||||
mutationFn: (updates) => RolesRepository.createEmployeeRoles(updates),
|
||||
onSuccess: () => {
|
||||
showToast("Roles updated successfully", "success");
|
||||
|
||||
resetForm?.();
|
||||
onClose?.();
|
||||
onSuccessCallback?.();
|
||||
|
||||
queryClient.invalidateQueries( {queryKey: [ "employeeRoles" ]} );
|
||||
queryClient.invalidateQueries( {queryKey: [ "profile" ]} );
|
||||
},
|
||||
onError: (err) => {
|
||||
const message =
|
||||
err?.response?.data?.message || err?.message || "Error occurred while updating roles";
|
||||
showToast(message, "error");
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
updateRoles: mutation.mutate,
|
||||
isPending: mutation.isPending,
|
||||
isError: mutation.isError,
|
||||
error: mutation.error,
|
||||
};
|
||||
};
|
||||
|
@ -3,60 +3,99 @@ import AuthRepository from "../repositories/AuthRepository";
|
||||
import {cacheData, cacheProfileData, getCachedData, getCachedProfileData} from "../slices/apiDataManager";
|
||||
import {useSelector} from "react-redux";
|
||||
import eventBus from "../services/eventBus";
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
let hasFetched = false;
|
||||
let hasReceived = false;
|
||||
|
||||
// export const useProfile = () => {
|
||||
// const loggedUser = useSelector( ( store ) => store.globalVariables.loginUser );
|
||||
// const [profile, setProfile] = useState(null);
|
||||
// const [loading, setLoading] = useState(false);
|
||||
// const [error, setError] = useState("");
|
||||
|
||||
// const fetchData = async () => {
|
||||
// try {
|
||||
// setLoading(true);
|
||||
// let response = await AuthRepository.profile();
|
||||
// setProfile(response.data);
|
||||
// cacheProfileData(response.data);
|
||||
// } catch (error) {
|
||||
// setError("Failed to fetch data.");
|
||||
// } finally {
|
||||
// setLoading(false);
|
||||
// }
|
||||
// };
|
||||
|
||||
// const validation = () => {
|
||||
// if (!hasFetched) {
|
||||
// hasFetched = true;
|
||||
// if (!loggedUser) {
|
||||
// fetchData();
|
||||
// } else {
|
||||
// setProfile(loggedUser);
|
||||
// }
|
||||
// }
|
||||
|
||||
// setProfile(loggedUser);
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// validation();
|
||||
// }, [loggedUser]);
|
||||
|
||||
// const handler = useCallback(
|
||||
// (data) => {
|
||||
// if(!getCachedData("hasReceived")){
|
||||
// cacheData("hasReceived", true);
|
||||
// hasFetched = false;
|
||||
// validation();
|
||||
// }
|
||||
// },[]
|
||||
// );
|
||||
|
||||
// useEffect(() => {
|
||||
// eventBus.on("assign_project_one", handler);
|
||||
// return () => eventBus.off("assign_project_one", handler);
|
||||
// }, [handler]);
|
||||
|
||||
// return { profile, loading, error };
|
||||
// };
|
||||
|
||||
export const useProfile = () => {
|
||||
const loggedUser = useSelector( ( store ) => store.globalVariables.loginUser );
|
||||
const [profile, setProfile] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
let response = await AuthRepository.profile();
|
||||
setProfile(response.data);
|
||||
const {
|
||||
data: profile,
|
||||
error,
|
||||
isLoading,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ["profile"],
|
||||
queryFn: async () => {
|
||||
const response = await AuthRepository.profile();
|
||||
cacheProfileData(response.data);
|
||||
} catch (error) {
|
||||
setError("Failed to fetch data.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
return response.data;
|
||||
},
|
||||
initialData: loggedUser || undefined,
|
||||
enabled: true,
|
||||
staleTime: 10 * 60 * 1000,
|
||||
});
|
||||
|
||||
const validation = () => {
|
||||
if (!hasFetched) {
|
||||
hasFetched = true;
|
||||
if (!loggedUser) {
|
||||
fetchData();
|
||||
} else {
|
||||
setProfile(loggedUser);
|
||||
}
|
||||
}
|
||||
|
||||
setProfile(loggedUser);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
validation();
|
||||
}, [loggedUser]);
|
||||
|
||||
const handler = useCallback(
|
||||
(data) => {
|
||||
if(!getCachedData("hasReceived")){
|
||||
cacheData("hasReceived", true);
|
||||
hasFetched = false;
|
||||
validation();
|
||||
}
|
||||
},[]
|
||||
);
|
||||
const handler = useCallback(() => {
|
||||
queryClient.invalidateQueries({ queryKey: ["profile"] });
|
||||
}, [queryClient]);
|
||||
|
||||
useEffect(() => {
|
||||
eventBus.on("assign_project_one", handler);
|
||||
return () => eventBus.off("assign_project_one", handler);
|
||||
}, [handler]);
|
||||
|
||||
return { profile, loading, error };
|
||||
return {
|
||||
profile,
|
||||
loading: isLoading,
|
||||
error,
|
||||
refetch,
|
||||
};
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ import { Link, NavLink, useNavigate } from "react-router-dom";
|
||||
import Avatar from "../../components/common/Avatar";
|
||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||
import ManageEmp from "../../components/Employee/ManageRole";
|
||||
import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
|
||||
import { useEmployeesAllOrByProjectId, useSuspendEmployee } from "../../hooks/useEmployees";
|
||||
import { useProjects } from "../../hooks/useProjects";
|
||||
import { useProfile } from "../../hooks/useProfile";
|
||||
import { hasUserPermission } from "../../utils/authUtils";
|
||||
@ -26,6 +26,7 @@ import { useSelector } from "react-redux";
|
||||
import eventBus from "../../services/eventBus";
|
||||
import { newlineChars } from "pdf-lib";
|
||||
import GlobalModel from "../../components/common/GlobalModel";
|
||||
import usePagination from "../../hooks/usePagination";
|
||||
|
||||
const EmployeeList = () => {
|
||||
const selectedProjectId = useSelector((store) => store.localVariables.projectId);
|
||||
@ -40,9 +41,10 @@ const EmployeeList = () => {
|
||||
const [projectsList, setProjectsList] = useState(projects || []);
|
||||
|
||||
const [employeeList, setEmployeeList] = useState([]);
|
||||
const [modelConfig, setModelConfig] = useState();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemsPerPage] = useState(ITEMS_PER_PAGE);
|
||||
const [ modelConfig, setModelConfig ] = useState();
|
||||
const [EmpForManageRole,setEmpForManageRole] = useState(null)
|
||||
// const [currentPage, setCurrentPage] = useState(1);
|
||||
// const [itemsPerPage] = useState(ITEMS_PER_PAGE);
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||
const [isEmployeeModalOpen, setIsEmployeeModalOpen] = useState(false);
|
||||
const [searchText, setSearchText] = useState("");
|
||||
@ -51,7 +53,16 @@ const EmployeeList = () => {
|
||||
const [selectedEmployeeId, setSelecedEmployeeId] = useState(null);
|
||||
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
const [selectedEmpFordelete, setSelectedEmpFordelete] = useState(null);
|
||||
const [employeeLodaing, setemployeeLodaing] = useState(false);
|
||||
const [ employeeLodaing, setemployeeLodaing ] = useState( false );
|
||||
const {
|
||||
mutate: suspendEmployee,
|
||||
isPending: empLodaing
|
||||
} = useSuspendEmployee({
|
||||
setIsDeleteModalOpen,
|
||||
setemployeeLodaing
|
||||
} );
|
||||
|
||||
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -65,49 +76,26 @@ const EmployeeList = () => {
|
||||
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
||||
const email = item.email ? item.email.toLowerCase() : "";
|
||||
const phoneNumber = item.phoneNumber ? item.phoneNumber.toLowerCase() : "";
|
||||
const jobRole = item.jobRole ? item.jobRole.toLowerCase() : ""; // Get jobRole and convert to lowercase
|
||||
const jobRole = item.jobRole ? item.jobRole.toLowerCase() : "";
|
||||
|
||||
return (
|
||||
fullName.includes(value) ||
|
||||
email.includes(value) ||
|
||||
phoneNumber.includes(value) ||
|
||||
jobRole.includes(value) // Include jobRole in the search
|
||||
jobRole.includes(value)
|
||||
);
|
||||
});
|
||||
|
||||
setFilteredData(results);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentPage(1);
|
||||
|
||||
if (!loading && Array.isArray(employees)) {
|
||||
// Sort by full name (firstName + lastName)
|
||||
const sorted = [...employees].sort((a, b) => {
|
||||
const nameA = `${a.firstName || ""}${a.middleName || ""}${b.lastName || ""
|
||||
}`.toLowerCase();
|
||||
const nameB = `${b.firstName || ""}${b.middleName || ""}${b.lastName || ""
|
||||
}`.toLowerCase();
|
||||
return nameA?.localeCompare(nameB);
|
||||
});
|
||||
|
||||
setEmployeeList(sorted);
|
||||
setFilteredData(sorted);
|
||||
}
|
||||
}, [loading, employees, selectedProject, showAllEmployees]); // Add showAllEmployees to dependencies
|
||||
|
||||
const displayData = searchText ? filteredData : employeeList;
|
||||
const indexOfLastItem = currentPage * itemsPerPage;
|
||||
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
|
||||
const currentItems = Array.isArray(displayData)
|
||||
? displayData.slice(indexOfFirstItem, indexOfLastItem)
|
||||
: [];
|
||||
|
||||
const paginate = (pageNumber) => setCurrentPage(pageNumber);
|
||||
const totalPages = Array.isArray(displayData)
|
||||
? Math.ceil(displayData.length / itemsPerPage)
|
||||
: 0;
|
||||
|
||||
const { currentPage, totalPages, currentItems, paginate,setCurrentPage } = usePagination(
|
||||
displayData,
|
||||
ITEMS_PER_PAGE
|
||||
);
|
||||
const openModal = () => {
|
||||
setIsCreateModalOpen(true);
|
||||
};
|
||||
@ -127,32 +115,50 @@ const EmployeeList = () => {
|
||||
recallEmployeeData(showInactive);
|
||||
};
|
||||
const handleShow = () => setShowModal(true);
|
||||
const handleClose = () => setShowModal(false);
|
||||
const handleClose = () => setShowModal( false );
|
||||
|
||||
const suspendEmployee = (id) => {
|
||||
setemployeeLodaing(true);
|
||||
EmployeeRepository.deleteEmployee(id)
|
||||
.then((response) => {
|
||||
showToast("Employee deleted successfully.", "success");
|
||||
clearCacheKey("employeeListByProject");
|
||||
clearCacheKey("allEmployeeList");
|
||||
clearCacheKey("allInactiveEmployeeList");
|
||||
clearCacheKey("employeeProfile");
|
||||
setEmployeeList([]);
|
||||
recallEmployeeData(showInactive);
|
||||
setemployeeLodaing(false);
|
||||
setIsDeleteModalOpen(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
const message =
|
||||
error.response?.data?.message ||
|
||||
error.message ||
|
||||
"An unexpected error occurred";
|
||||
showToast(message, "error");
|
||||
setemployeeLodaing(false);
|
||||
setIsDeleteModalOpen(false);
|
||||
useEffect(() => {
|
||||
setCurrentPage(1)
|
||||
|
||||
if (!loading && Array.isArray(employees)) {
|
||||
// Sort by full name (firstName + lastName)
|
||||
const sorted = [...employees].sort((a, b) => {
|
||||
const nameA = `${a.firstName || ""}${a.middleName || ""}${b.lastName || ""
|
||||
}`.toLowerCase();
|
||||
const nameB = `${b.firstName || ""}${b.middleName || ""}${b.lastName || ""
|
||||
}`.toLowerCase();
|
||||
return nameA?.localeCompare(nameB);
|
||||
});
|
||||
};
|
||||
|
||||
setEmployeeList(sorted);
|
||||
setFilteredData(sorted);
|
||||
}
|
||||
}, [loading, employees, selectedProject, showAllEmployees]);
|
||||
|
||||
// const suspendEmployee = (id) => {
|
||||
// setemployeeLodaing(true);
|
||||
// EmployeeRepository.deleteEmployee(id)
|
||||
// .then((response) => {
|
||||
// showToast("Employee deleted successfully.", "success");
|
||||
// clearCacheKey("employeeListByProject");
|
||||
// clearCacheKey("allEmployeeList");
|
||||
// clearCacheKey("allInactiveEmployeeList");
|
||||
// clearCacheKey("employeeProfile");
|
||||
// setEmployeeList([]);
|
||||
// recallEmployeeData(showInactive);
|
||||
// setemployeeLodaing(false);
|
||||
// setIsDeleteModalOpen(false);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// const message =
|
||||
// error.response?.data?.message ||
|
||||
// error.message ||
|
||||
// "An unexpected error occurred";
|
||||
// showToast(message, "error");
|
||||
// setemployeeLodaing(false);
|
||||
// setIsDeleteModalOpen(false);
|
||||
// });
|
||||
// };
|
||||
|
||||
const handleConfigData = (config) => {
|
||||
setModelConfig(config);
|
||||
@ -241,28 +247,11 @@ const handleAllEmployeesToggle = (e) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{isCreateModalOpen && (
|
||||
<ManageEmp employeeId={modelConfig} onClosed={closeModal} />
|
||||
{EmpForManageRole && (
|
||||
<GlobalModel isOpen={EmpForManageRole} closeModal={() => setEmpForManageRole( null )}>
|
||||
<ManageEmp employeeId={EmpForManageRole} onClosed={()=>setEmpForManageRole(null)} />
|
||||
</GlobalModel>
|
||||
)}
|
||||
{/* {showModal && (<div
|
||||
className={`modal fade ${showModal ? "show" : ""} `}
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
style={{ display: showModal ? "block" : "none" }}
|
||||
aria-hidden={!showModal}
|
||||
>
|
||||
<div className="modal-dialog modal-xl modal-dialog-centered ">
|
||||
<div
|
||||
className="modal-content overflow-y-auto overflow-x-hidden"
|
||||
style={{ maxHeight: "90vh" }}
|
||||
>
|
||||
<ManageEmployee
|
||||
employeeId={selectedEmployeeId}
|
||||
onClosed={closeModal}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div> )} */}
|
||||
|
||||
{showModal && (
|
||||
<GlobalModel isOpen={showModal} size="lg" closeModal={()=>setShowModal(false)}>
|
||||
@ -650,7 +639,7 @@ const handleAllEmployeesToggle = (e) => {
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#managerole-modal"
|
||||
onClick={() =>
|
||||
handleConfigData(item.id)
|
||||
setEmpForManageRole(item.id)
|
||||
}
|
||||
>
|
||||
<i className="bx bx-cog bx-sm"></i>{" "}
|
||||
@ -670,7 +659,7 @@ const handleAllEmployeesToggle = (e) => {
|
||||
<div style={{ width: "1%" }}></div>
|
||||
|
||||
{/* Pagination */}
|
||||
{!loading && displayData.length > itemsPerPage && (
|
||||
{!loading && displayData.length > ITEMS_PER_PAGE && (
|
||||
<nav aria-label="Page">
|
||||
<ul className="pagination pagination-sm justify-content-end py-1">
|
||||
<li
|
||||
|
Loading…
x
Reference in New Issue
Block a user