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

View File

@ -2,7 +2,7 @@ import React, { useState, useMemo } from "react";
import ApexChart from "../Charts/Circle";
import { useProjects } from "../../hooks/useProjects";
import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data";
import { useSelectedProject } from "../../hooks/useSelectedProject"; // your custom hook
import { useSelectedProject } from "../../hooks/useSelectedProject";
const Attendance = () => {
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;
switch (field) {
case "transactionDate":
key = item.transactionDate?.split("T")[0];
key = item?.transactionDate?.split("T")[0];
break;
case "status":
key = item.status?.displayName || "Unknown";
key = item?.status?.displayName || "Unknown";
break;
case "submittedBy":
key = `${item.createdBy?.firstName ?? ""} ${
key = `${item?.createdBy?.firstName ?? ""} ${
item.createdBy?.lastName ?? ""
}`.trim();
break;
case "project":
key = item.project?.name || "Unknown Project";
key = item?.project?.name || "Unknown Project";
break;
case "paymentMode":
key = item.paymentMode?.name || "Unknown Mode";
key = item?.paymentMode?.name || "Unknown Mode";
break;
case "expensesType":
key = item.expensesType?.name || "Unknown Type";
key = item?.expensesType?.name || "Unknown Type";
break;
case "createdAt":
key = item.createdAt?.split("T")[0] || "Unknown Type";
key = item?.createdAt?.split("T")[0] || "Unknown Type";
break;
default:
key = "Others";
}
if (!acc[key]) acc[key] = [];
acc[key].push(item);
acc[key]?.push(item);
return acc;
}, {});
};
@ -163,23 +163,23 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
];
if (isInitialLoading) return <ExpenseTableSkeleton />;
if (isError) return <div>{error.message}</div>;
if (isError) return <div>{error?.message}</div>;
const grouped = groupBy
? groupByField(data?.data ?? [], groupBy)
: { All: data?.data ?? [] };
const IsGroupedByDate = ["transactionDate", "createdAt"].includes(groupBy);
const IsGroupedByDate = ["transactionDate", "createdAt"]?.includes(groupBy);
const canEditExpense = (expense) => {
return (
(expense.status.id === EXPENSE_DRAFT ||
EXPENSE_REJECTEDBY.includes(expense.status.id)) &&
expense.createdBy?.id === SelfId
(expense?.status?.id === EXPENSE_DRAFT ||
EXPENSE_REJECTEDBY.includes(expense?.status?.id)) &&
expense?.createdBy?.id === SelfId
);
};
const canDetetExpense = (expense) => {
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
className="card-datatable table-responsive "
id="horizontal-example"
@ -292,8 +292,10 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
))
) : (
<tr>
<td colSpan={8} className="text-center py-4">
No Expense Found
<td colSpan={8} className="text-center border-0 ">
<div className="py-8">
<p>No Expense Found</p>
</div>
</td>
</tr>
)}

View File

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

View File

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

View File

@ -12,38 +12,9 @@ import { setDefaultDateRange } from "../slices/localVariablesSlice";
// ----------------------------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) => {
const dispatch = useDispatch();
// queryKey: ["attendance", projectId, organizationId, includeInactive, date],
const {
data: attendance = [],
isLoading: loading,
@ -51,7 +22,7 @@ export const useAttendance = (projectId, organizationId, includeInactive = false
refetch: recall,
isFetching,
} = useQuery({
queryKey: ["attendance", projectId, organizationId, includeInactive, date], // include filters in cache key
queryKey: ["attendance", projectId ],
queryFn: async () => {
const response = await AttendanceRepository.getAttendance(
projectId,
@ -61,7 +32,7 @@ export const useAttendance = (projectId, organizationId, includeInactive = false
);
return response.data;
},
enabled: !!projectId, // only run if projectId exists
enabled: !!projectId,
onError: (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) => {
const dispatch = useDispatch();
@ -218,10 +164,11 @@ export const useMarkAttendance = () => {
emp.employeeId === data.employeeId ? { ...emp, ...data } : emp
);
});
// queryClient.invalidateQueries({queryKey:["attendance"]})
}else if(variables.forWhichTab == 2){
// queryClient.invalidateQueries({
// queryKey: ["attendanceLogs"],
// });
queryClient.invalidateQueries({
queryKey: ["attendanceLogs"],
});
queryClient.setQueryData(["attendanceLogs",selectedProject,selectedDateRange.startDate,selectedDateRange.endDate], (oldData) => {
if (!oldData) return oldData;
return oldData.map((record) =>

View File

@ -174,7 +174,7 @@ const AttendancePage = () => {
{/* 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">
{/* Organization Dropdown */}
<select
{/* <select
className="form-select form-select-sm"
style={{ minWidth: "180px" }}
value={appliedFilters.selectedOrganization}
@ -192,7 +192,7 @@ const AttendancePage = () => {
{org.name}
</option>
))}
</select>
</select> */}
{/* Search Input */}
<input

View File

@ -289,7 +289,7 @@ const EmployeeList = () => {
{ViewTeamMember ? (
// <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
id="DataTables_Table_0_wrapper"
@ -537,9 +537,11 @@ const EmployeeList = () => {
<tr>
<td
colSpan={8}
style={{ paddingTop: "20px", textAlign: "center" }}
className="border-0"
>
No Data Found
<div className="py-1">
No Employeee Found
</div>
</td>
</tr>
) : null}

View File

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