update attendnace and expense
This commit is contained in:
parent
4ea1e06a9c
commit
4e48478fbc
@ -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(),
|
||||
|
@ -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();
|
||||
|
50
src/components/Expenses/ActiveFilters.jsx
Normal file
50
src/components/Expenses/ActiveFilters.jsx
Normal 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;
|
@ -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>
|
||||
)}
|
||||
|
@ -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"
|
||||
|
@ -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 */}
|
||||
|
@ -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) =>
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user