Compare commits

..

No commits in common. "693cabf63daa82e4a067fa23f9f79f15c98b14ea" and "4afe43d1163bf9137b2de37ef970bf0b57ec1b62" have entirely different histories.

6 changed files with 109 additions and 155 deletions

View File

@ -12,19 +12,22 @@ import { useQueryClient } from "@tanstack/react-query";
import eventBus from "../../services/eventBus"; import eventBus from "../../services/eventBus";
import { useSelectedProject } from "../../slices/apiDataManager"; import { useSelectedProject } from "../../slices/apiDataManager";
const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizationId, includeInactive, date }) => { const Attendance = ({ getRole, handleModalData, searchTerm }) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const navigate = useNavigate(); const navigate = useNavigate();
const [todayDate, setTodayDate] = useState(new Date()); const [todayDate, setTodayDate] = useState(new Date());
const [ShowPending, setShowPending] = useState(false); const [ShowPending, setShowPending] = useState(false);
// const selectedProject = useSelector(
// (store) => store.localVariables.projectId
// );
const selectedProject = useSelectedProject(); const selectedProject = useSelectedProject();
const { const {
attendance, attendance,
loading: attLoading, loading: attLoading,
recall: attrecall, recall: attrecall,
isFetching isFetching
} = useAttendance(selectedProject, organizationId, includeInactive, date); } = useAttendance(selectedProject);
const filteredAttendance = ShowPending const filteredAttendance = ShowPending
? attendance?.filter( ? attendance?.filter(
(att) => att?.checkInTime !== null && att?.checkOutTime === null (att) => att?.checkInTime !== null && att?.checkOutTime === null
@ -64,6 +67,43 @@ const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizat
}); });
}, [group1, group2, searchTerm]); }, [group1, group2, searchTerm]);
// const finalFilteredData = useMemo(() => {
// const combinedData = [...group1, ...group2];
// let tempData = combinedData;
// // Search filter
// if (searchTerm) {
// const lowercasedSearchTerm = searchTerm.toLowerCase();
// tempData = tempData.filter((item) => {
// const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
// const role = item.jobRoleName?.toLowerCase() || "";
// return (
// fullName.includes(lowercasedSearchTerm) ||
// role.includes(lowercasedSearchTerm) // also search by role
// );
// });
// }
// // Organization filter
// if (filters?.selectedOrganization) {
// tempData = tempData.filter(
// (item) => item.organization?.name === filters.selectedOrganization
// );
// }
// // Services filter
// if (filters?.selectedServices?.length > 0) {
// tempData = tempData.filter((item) =>
// filters.selectedServices.includes(item.service?.name)
// );
// }
// return tempData;
// }, [group1, group2, searchTerm, filters]);
const { currentPage, totalPages, currentItems, paginate } = usePagination( const { currentPage, totalPages, currentItems, paginate } = usePagination(
finalFilteredData, finalFilteredData,
ITEMS_PER_PAGE ITEMS_PER_PAGE
@ -138,7 +178,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizat
<tr className="border-top-1"> <tr className="border-top-1">
<th colSpan={2}>Name</th> <th colSpan={2}>Name</th>
<th>Role</th> <th>Role</th>
<th>Organization</th> <th>Organization</th>
<th> <th>
<i className="bx bxs-down-arrow-alt text-success"></i> <i className="bx bxs-down-arrow-alt text-success"></i>
Check-In Check-In
@ -213,7 +253,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizat
{!attendance && ( {!attendance && (
<tr> <tr>
<td <td
colSpan={7} colSpan={7}
className="text-center text-secondary" className="text-center text-secondary"
style={{ height: "200px" }} style={{ height: "200px" }}
> >

View File

@ -33,7 +33,7 @@ const usePagination = (data, itemsPerPage) => {
}; };
}; };
const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => { const AttendanceLog = ({ handleModalData, searchTerm }) => {
// const selectedProject = useSelector( // const selectedProject = useSelector(
// (store) => store.localVariables.projectId // (store) => store.localVariables.projectId
// ); // );
@ -81,8 +81,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
} = useAttendancesLogs( } = useAttendancesLogs(
selectedProject, selectedProject,
dateRange.startDate, dateRange.startDate,
dateRange.endDate, dateRange.endDate
organizationId
); );
const filtering = (data) => { const filtering = (data) => {
const filteredData = showPending const filteredData = showPending

View File

@ -10,13 +10,13 @@ import eventBus from "../../services/eventBus";
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager"; import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
import { useQueryClient } from "@tanstack/react-query"; import { useQueryClient } from "@tanstack/react-query";
const Regularization = ({ handleRequest, searchTerm,projectId, organizationId, IncludeInActive }) => { const Regularization = ({ handleRequest, searchTerm }) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
// var selectedProject = useSelector((store) => store.localVariables.projectId); // var selectedProject = useSelector((store) => store.localVariables.projectId);
const selectedProject = useSelectedProject(); const selectedProject = useSelectedProject();
const [regularizesList, setregularizedList] = useState([]); const [regularizesList, setregularizedList] = useState([]);
const { regularizes, loading, error, refetch } = const { regularizes, loading, error, refetch } =
useRegularizationRequests(selectedProject, organizationId, IncludeInActive); useRegularizationRequests(selectedProject);
useEffect(() => { useEffect(() => {
setregularizedList(regularizes); setregularizedList(regularizes);

View File

@ -12,76 +12,46 @@ import { setDefaultDateRange } from "../slices/localVariablesSlice";
// ----------------------------Query----------------------------- // ----------------------------Query-----------------------------
// export const useAttendance = (projectId) => { export const useAttendance = (projectId) => {
// const dispatch = useDispatch() const dispatch = useDispatch()
// const {
// data: attendance = [],
// isLoading: loading,
// error,
// refetch: recall,
// isFetching
// } = useQuery({
// queryKey: ["attendance", projectId],
// queryFn: async () => {
// const response = await AttendanceRepository.getAttendance(projectId);
// return response.data;
// },
// enabled: !!projectId,
// onError: (error) => {
// showToast(error.message || "Error while fetching Attendance", "error");
// },
// });
// return {
// attendance,
// loading,
// error,
// recall,
// isFetching
// };
// };
export const useAttendance = (projectId, organizationId, includeInactive = false, date = null) => {
const dispatch = useDispatch();
const { const {
data: attendance = [], data: attendance = [],
isLoading: loading, isLoading: loading,
error, error,
refetch: recall, refetch: recall,
isFetching, isFetching
} = useQuery({ } = useQuery({
queryKey: ["attendance", projectId, organizationId, includeInactive, date], // include filters in cache key queryKey: ["attendance", projectId],
queryFn: async () => { queryFn: async () => {
const response = await AttendanceRepository.getAttendance( const response = await AttendanceRepository.getAttendance(projectId);
projectId,
organizationId,
includeInactive,
date
);
return response.data; return response.data;
}, },
enabled: !!projectId, // only run if projectId exists enabled: !!projectId,
onError: (error) => { onError: (error) => {
showToast(error.message || "Error while fetching Attendance", "error"); showToast(error.message || "Error while fetching Attendance", "error");
}, },
}); });
return { attendance, loading, error, recall, isFetching }; return {
attendance,
loading,
error,
recall,
isFetching
};
}; };
export const useAttendancesLogs = (projectId, fromDate, toDate,organizationId) => { export const useAttendancesLogs = (projectId, fromDate, toDate) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const enabled = !!projectId && !!fromDate && !!toDate; const enabled = !!projectId && !!fromDate && !!toDate;
const query = useQuery({ const query = useQuery({
queryKey: ['attendanceLogs', projectId, fromDate, toDate,organizationId], queryKey: ['attendanceLogs', projectId, fromDate, toDate],
queryFn: async () => { queryFn: async () => {
const res = await AttendanceRepository.getAttendanceFilteredByDate( const res = await AttendanceRepository.getAttendanceFilteredByDate(
projectId, projectId,
fromDate, fromDate,
toDate, toDate
organizationId
); );
return res.data; return res.data;
}, },
@ -142,58 +112,30 @@ export const useAttendanceByEmployee = (employeeId, fromDate, toDate) => {
}); });
}; };
// export const useRegularizationRequests = (projectId) => { export const useRegularizationRequests = (projectId) => {
// const {
// data: regularizes = [],
// isLoading: loading,
// error,
// refetch,
// } = useQuery({
// queryKey: ["regularizedList", projectId],
// queryFn: async () => {
// const response = await AttendanceRepository.getRegularizeList(projectId);
// return response.data;
// },
// enabled: !!projectId,
// onError: (error) => {
// showToast(error.message || "Error while fetching Regularization Requests", "error");
// },
// });
// return {
// regularizes,
// loading,
// error,
// refetch,
// };
// };
export const useRegularizationRequests = (projectId, organizationId, IncludeInActive = false) => {
const dispatch = useDispatch();
const { const {
data: regularizes = [], data: regularizes = [],
isLoading: loading, isLoading: loading,
error, error,
refetch: recall, refetch,
isFetching,
} = useQuery({ } = useQuery({
queryKey: ["regularizedList", projectId, organizationId, IncludeInActive], // include filters in cache key queryKey: ["regularizedList", projectId],
queryFn: async () => { queryFn: async () => {
const response = await AttendanceRepository.getRegularizeList( const response = await AttendanceRepository.getRegularizeList(projectId);
projectId,
organizationId,
IncludeInActive,
);
return response.data; return response.data;
}, },
enabled: !!projectId, // only run if projectId exists enabled: !!projectId,
onError: (error) => { onError: (error) => {
showToast(error.message || "Error while fetching regularizes", "error"); showToast(error.message || "Error while fetching Regularization Requests", "error");
}, },
}); });
return { regularizes, loading, error, recall, isFetching }; return {
regularizes,
loading,
error,
refetch,
};
}; };

View File

@ -16,7 +16,7 @@ import { setProjectId } from "../../slices/localVariablesSlice";
import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { REGULARIZE_ATTENDANCE } from "../../utils/constants"; import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
import eventBus from "../../services/eventBus"; import eventBus from "../../services/eventBus";
import { useProjectAssignedOrganizations, useProjectName } from "../../hooks/useProjects"; import { useProjectName } from "../../hooks/useProjects";
import GlobalModel from "../../components/common/GlobalModel"; import GlobalModel from "../../components/common/GlobalModel";
import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm"; import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm";
import AttendLogs from "../../components/Activities/AttendLogs"; import AttendLogs from "../../components/Activities/AttendLogs";
@ -43,9 +43,6 @@ const AttendancePage = () => {
selectedServices: [], selectedServices: [],
}); });
const { data: organizations = [], isLoading: orgLoading } =
useProjectAssignedOrganizations(selectedProject);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
markTime: "", markTime: "",
description: "", description: "",
@ -171,30 +168,37 @@ const AttendancePage = () => {
</ul> </ul>
</div> </div>
{/* Single search input that moves */}
{/* <div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto d-flex gap-2 align-items-center">
<input
type="text"
className="form-control form-control-sm"
placeholder="Search Employee..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{ minWidth: "200px" }}
/>
</div> */}
{/* Search + Organization filter */} {/* Search + Organization filter */}
<div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto d-flex gap-2 align-items-center"> <div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto d-flex gap-2 align-items-center">
{/* Organization Dropdown */} {/* Organization Dropdown */}
{organizations?.length > 1 && ( <select
<select className="form-select form-select-sm"
className="form-select form-select-sm" style={{ minWidth: "180px" }}
style={{ minWidth: "180px" }} value={appliedFilters.selectedOrganization}
value={appliedFilters.selectedOrganization} onChange={(e) =>
onChange={(e) => setAppliedFilters((prev) => ({
setAppliedFilters((prev) => ({ ...prev,
...prev, selectedOrganization: e.target.value,
selectedOrganization: e.target.value, }))
})) }
} >
disabled={orgLoading} <option value="">All Organizations</option>
> <option value="Org A">Org A</option>
<option value="">All Organizations</option> <option value="Org B">Org B</option>
{organizations?.map((org) => ( <option value="Org C">Org C</option>
<option key={org.id} value={org.id}> </select>
{org.name}
</option>
))}
</select>
)}
{/* Search Input */} {/* Search Input */}
<input <input
@ -219,7 +223,6 @@ const AttendancePage = () => {
handleModalData={handleModalData} handleModalData={handleModalData}
getRole={getRole} getRole={getRole}
searchTerm={searchTerm} searchTerm={searchTerm}
organizationId={appliedFilters.selectedOrganization}
/> />
</div> </div>
)} )}
@ -228,7 +231,6 @@ const AttendancePage = () => {
<AttendanceLog <AttendanceLog
handleModalData={handleModalData} handleModalData={handleModalData}
searchTerm={searchTerm} searchTerm={searchTerm}
organizationId={appliedFilters.selectedOrganization}
/> />
</div> </div>
)} )}
@ -236,7 +238,6 @@ const AttendancePage = () => {
<div className="tab-pane fade show active py-0"> <div className="tab-pane fade show active py-0">
<Regularization <Regularization
searchTerm={searchTerm} searchTerm={searchTerm}
organizationId={appliedFilters.selectedOrganization}
/> />
</div> </div>
)} )}

View File

@ -2,22 +2,8 @@ import { api } from "../utils/axiosClient";
const AttendanceRepository = { const AttendanceRepository = {
markAttendance: (data) => api.post("/api/attendance/record", data), markAttendance: (data) => api.post("/api/attendance/record", data),
getAttendance: (id) => api.get(`api/attendance/project/team?projectId=${id}`),
getAttendance: (projectId, organizationId, includeInactive,date) => { getAttendanceFilteredByDate: (projectId, fromDate, toDate) => {
let url = `/api/attendance/project/team?projectId=${projectId}`;
const params = [];
if (organizationId) params.push(`organizationId=${organizationId}`);
if (includeInactive) params.push(`includeInactive=${includeInactive}`);
if (date) params.push(`date=${date}`);
if (params.length > 0) {
url += `&${params.join("&")}`; }
return api.get(url);
},
getAttendanceFilteredByDate: (projectId, fromDate, toDate,organizationId) => {
let url = `api/Attendance/project/log?projectId=${projectId}`; let url = `api/Attendance/project/log?projectId=${projectId}`;
if (fromDate) { if (fromDate) {
url += `&dateFrom=${fromDate}`; url += `&dateFrom=${fromDate}`;
@ -26,26 +12,12 @@ const AttendanceRepository = {
if (toDate) { if (toDate) {
url += `&dateTo=${toDate}`; url += `&dateTo=${toDate}`;
} }
if (organizationId) {
url += `&organizationId=${organizationId}`;
}
return api.get(url); return api.get(url);
}, },
getAttendanceLogs: (id) => api.get(`api/attendance/log/attendance/${id}`), getAttendanceLogs: (id) => api.get(`api/attendance/log/attendance/${id}`),
getRegularizeList: (id) =>
getRegularizeList: (projectId, organizationId, IncludeInActive) => { api.get(`api/attendance/regularize?projectId=${id}`),
let url = `/api/attendance/regularize?projectId=${projectId}`;
const params = [];
if (organizationId) params.push(`organizationId=${organizationId}`);
if (IncludeInActive) params.push(`IncludeInActive=${IncludeInActive}`);
if (params.length > 0) {
url += `&${params.join("&")}`; }
return api.get(url);
},
getAttendanceByEmployee: (employeeId, fromDate, toDate) => { getAttendanceByEmployee: (employeeId, fromDate, toDate) => {
let url = `api/Attendance/log/employee/${employeeId}?`; let url = `api/Attendance/log/employee/${employeeId}?`;