update attendnace and expense

This commit is contained in:
pramod.mahajan 2025-09-30 19:31:24 +05:30
parent 4ea1e06a9c
commit 4e48478fbc
10 changed files with 90 additions and 90 deletions

View File

@ -33,7 +33,7 @@ const createSchema = (modeldata) => {
const checkOut = new Date(checkIn); const checkOut = new Date(checkIn);
checkOut.setHours(hour, minute, 0, 0); checkOut.setHours(hour, minute, 0, 0);
return checkOut > checkIn; return checkOut >= checkIn;
} }
return true; return true;
}, { }, {
@ -83,7 +83,7 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
Id: modeldata?.id || null, Id: modeldata?.id || null,
comment: data.description, comment: data.description,
employeeID: modeldata.employeeId, employeeID: modeldata.employeeId,
projectId: projectId, // projectId: projectId,
date: new Date().toISOString(), date: new Date().toISOString(),
markTime: data.markTime, markTime: data.markTime,
latitude: coords.latitude.toString(), latitude: coords.latitude.toString(),

View File

@ -2,7 +2,7 @@ import React, { useState, useMemo } from "react";
import ApexChart from "../Charts/Circle"; import ApexChart from "../Charts/Circle";
import { useProjects } from "../../hooks/useProjects"; import { useProjects } from "../../hooks/useProjects";
import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data"; import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data";
import { useSelectedProject } from "../../hooks/useSelectedProject"; // your custom hook import { useSelectedProject } from "../../hooks/useSelectedProject";
const Attendance = () => { const Attendance = () => {
const { projects } = useProjects(); const { projects } = useProjects();

View File

@ -0,0 +1,50 @@
const ActiveFilters = ({ filters, optionsLookup = {}, onRemove }) => {
const entries = Object.entries(filters || {});
return (
<div className="d-flex flex-wrap gap-2">
{entries.map(([key, value]) => {
if (!value || (Array.isArray(value) && value.length === 0)) return null;
if (Array.isArray(value)) {
return value.map((v) => {
const label = optionsLookup[key]?.[v] || v;
return (
<span
key={`${key}-${v}`}
className="badge bg-label-primary cursor-pointer"
onClick={() => onRemove(key, v)}
>
{label} <i className="bx bx-x ms-1"></i>
</span>
);
});
}
if (typeof value === "boolean") {
return (
<span
key={key}
className="badge bg-label-success cursor-pointer"
onClick={() => onRemove(key)}
>
{key}: {value ? "Yes" : "No"} <i className="bx bx-x ms-1"></i>
</span>
);
}
return (
<span className="badge bg-primary">
{data?.startDate && data?.endDate
? `${formatUTCToLocalTime(
data.startDate
)} - ${formatUTCToLocalTime(data.endDate)}`
: "No dates"}
</span>
);
})}
</div>
);
};
export default ActiveFilters;

View File

@ -61,33 +61,33 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
let key; let key;
switch (field) { switch (field) {
case "transactionDate": case "transactionDate":
key = item.transactionDate?.split("T")[0]; key = item?.transactionDate?.split("T")[0];
break; break;
case "status": case "status":
key = item.status?.displayName || "Unknown"; key = item?.status?.displayName || "Unknown";
break; break;
case "submittedBy": case "submittedBy":
key = `${item.createdBy?.firstName ?? ""} ${ key = `${item?.createdBy?.firstName ?? ""} ${
item.createdBy?.lastName ?? "" item.createdBy?.lastName ?? ""
}`.trim(); }`.trim();
break; break;
case "project": case "project":
key = item.project?.name || "Unknown Project"; key = item?.project?.name || "Unknown Project";
break; break;
case "paymentMode": case "paymentMode":
key = item.paymentMode?.name || "Unknown Mode"; key = item?.paymentMode?.name || "Unknown Mode";
break; break;
case "expensesType": case "expensesType":
key = item.expensesType?.name || "Unknown Type"; key = item?.expensesType?.name || "Unknown Type";
break; break;
case "createdAt": case "createdAt":
key = item.createdAt?.split("T")[0] || "Unknown Type"; key = item?.createdAt?.split("T")[0] || "Unknown Type";
break; break;
default: default:
key = "Others"; key = "Others";
} }
if (!acc[key]) acc[key] = []; if (!acc[key]) acc[key] = [];
acc[key].push(item); acc[key]?.push(item);
return acc; return acc;
}, {}); }, {});
}; };
@ -163,23 +163,23 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
]; ];
if (isInitialLoading) return <ExpenseTableSkeleton />; if (isInitialLoading) return <ExpenseTableSkeleton />;
if (isError) return <div>{error.message}</div>; if (isError) return <div>{error?.message}</div>;
const grouped = groupBy const grouped = groupBy
? groupByField(data?.data ?? [], groupBy) ? groupByField(data?.data ?? [], groupBy)
: { All: data?.data ?? [] }; : { All: data?.data ?? [] };
const IsGroupedByDate = ["transactionDate", "createdAt"].includes(groupBy); const IsGroupedByDate = ["transactionDate", "createdAt"]?.includes(groupBy);
const canEditExpense = (expense) => { const canEditExpense = (expense) => {
return ( return (
(expense.status.id === EXPENSE_DRAFT || (expense?.status?.id === EXPENSE_DRAFT ||
EXPENSE_REJECTEDBY.includes(expense.status.id)) && EXPENSE_REJECTEDBY.includes(expense?.status?.id)) &&
expense.createdBy?.id === SelfId expense?.createdBy?.id === SelfId
); );
}; };
const canDetetExpense = (expense) => { const canDetetExpense = (expense) => {
return ( return (
expense.status.id === EXPENSE_DRAFT && expense.createdBy.id === SelfId expense?.status?.id === EXPENSE_DRAFT && expense?.createdBy?.id === SelfId
); );
}; };
@ -198,7 +198,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
/> />
)} )}
<div className="card px-0 px-sm-4"> <div className="card page-min-h px-sm-4">
<div <div
className="card-datatable table-responsive " className="card-datatable table-responsive "
id="horizontal-example" id="horizontal-example"
@ -292,8 +292,10 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
)) ))
) : ( ) : (
<tr> <tr>
<td colSpan={8} className="text-center py-4"> <td colSpan={8} className="text-center border-0 ">
No Expense Found <div className="py-8">
<p>No Expense Found</p>
</div>
</td> </td>
</tr> </tr>
)} )}

View File

@ -296,13 +296,13 @@ const Header = () => {
<li> <li>
<div className="dropdown-divider"></div> <div className="dropdown-divider"></div>
</li> </li>
<li onClick={() => onOpen()}> {/* <li onClick={() => onOpen()}>
{" "} {" "}
<a className="dropdown-item cusor-pointer"> <a className="dropdown-item cusor-pointer">
<i className="bx bx-transfer-alt me-2"></i> <i className="bx bx-transfer-alt me-2"></i>
<span className="align-middle">Switch Workspace</span> <span className="align-middle">Switch Workspace</span>
</a> </a>
</li> </li> */}
<li onClick={handleProfilePage}> <li onClick={handleProfilePage}>
<a <a
aria-label="go to profile" aria-label="go to profile"

View File

@ -37,7 +37,6 @@ const ServiceGroups = ({ service }) => {
<div className="w-100 my-2"> <div className="w-100 my-2">
<p className="fs-5 fw-semibold">Manage Service</p>
<div className="accordion" id="accordionExample"> <div className="accordion" id="accordionExample">
<div className="accordion-item active shadow-none"> <div className="accordion-item active shadow-none">
{/* Service Header */} {/* Service Header */}

View File

@ -12,38 +12,9 @@ import { setDefaultDateRange } from "../slices/localVariablesSlice";
// ----------------------------Query----------------------------- // ----------------------------Query-----------------------------
// export const useAttendance = (projectId) => {
// 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) => { export const useAttendance = (projectId, organizationId, includeInactive = false, date = null) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
// queryKey: ["attendance", projectId, organizationId, includeInactive, date],
const { const {
data: attendance = [], data: attendance = [],
isLoading: loading, isLoading: loading,
@ -51,7 +22,7 @@ export const useAttendance = (projectId, organizationId, includeInactive = false
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,
@ -61,7 +32,7 @@ export const useAttendance = (projectId, organizationId, includeInactive = false
); );
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");
}, },
@ -142,31 +113,6 @@ export const useAttendanceByEmployee = (employeeId, fromDate, toDate) => {
}); });
}; };
// 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) => { export const useRegularizationRequests = (projectId, organizationId, IncludeInActive = false) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -218,10 +164,11 @@ export const useMarkAttendance = () => {
emp.employeeId === data.employeeId ? { ...emp, ...data } : emp emp.employeeId === data.employeeId ? { ...emp, ...data } : emp
); );
}); });
// queryClient.invalidateQueries({queryKey:["attendance"]})
}else if(variables.forWhichTab == 2){ }else if(variables.forWhichTab == 2){
// queryClient.invalidateQueries({ queryClient.invalidateQueries({
// queryKey: ["attendanceLogs"], queryKey: ["attendanceLogs"],
// }); });
queryClient.setQueryData(["attendanceLogs",selectedProject,selectedDateRange.startDate,selectedDateRange.endDate], (oldData) => { queryClient.setQueryData(["attendanceLogs",selectedProject,selectedDateRange.startDate,selectedDateRange.endDate], (oldData) => {
if (!oldData) return oldData; if (!oldData) return oldData;
return oldData.map((record) => return oldData.map((record) =>

View File

@ -174,7 +174,7 @@ const AttendancePage = () => {
{/* 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 */}
<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}
@ -192,7 +192,7 @@ const AttendancePage = () => {
{org.name} {org.name}
</option> </option>
))} ))}
</select> </select> */}
{/* Search Input */} {/* Search Input */}
<input <input

View File

@ -289,7 +289,7 @@ const EmployeeList = () => {
{ViewTeamMember ? ( {ViewTeamMember ? (
// <div className="row"> // <div className="row">
<div className="card p-1"> <div className="card page-min-h p-1">
<div className="card-datatable table-responsive pt-5 mx-5 py-10"> <div className="card-datatable table-responsive pt-5 mx-5 py-10">
<div <div
id="DataTables_Table_0_wrapper" id="DataTables_Table_0_wrapper"
@ -537,9 +537,11 @@ const EmployeeList = () => {
<tr> <tr>
<td <td
colSpan={8} colSpan={8}
style={{ paddingTop: "20px", textAlign: "center" }} className="border-0"
> >
No Data Found <div className="py-1">
No Employeee Found
</div>
</td> </td>
</tr> </tr>
) : null} ) : null}

View File

@ -181,7 +181,7 @@ const ProjectPage = () => {
</div> </div>
<div> <div>
{HasManageProject && ( <button {/* {HasManageProject && ( <button
className="btn btn-sm btn-primary" className="btn btn-sm btn-primary"
type="button" type="button"
onClick={() => onClick={() =>
@ -192,7 +192,7 @@ const ProjectPage = () => {
<span className="d-none d-md-inline-block"> <span className="d-none d-md-inline-block">
Add New Project Add New Project
</span> </span>
</button>)} </button>)} */}
</div> </div>
</div> </div>
</div> </div>