Adding Search box in Expense Paid by dropdown.

This commit is contained in:
Kartik Sharma 2025-10-08 11:29:51 +05:30
parent bd3645aae6
commit bc933f4c64
4 changed files with 35 additions and 41 deletions

View File

@ -330,6 +330,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
control={control} control={control}
name="paidById" name="paidById"
projectId={null} projectId={null}
forAll={expenseToEdit ? true :false}
/> />
</div> </div>
</div> </div>

View File

@ -1,11 +1,16 @@
import { useState, useEffect, useRef } from "react"; import { useState, useEffect } from "react";
import { useEmployeesName } from "../../hooks/useEmployees"; import { useEmployeesName } from "../../hooks/useEmployees";
import { useDebounce } from "../../utils/appUtils"; import { useDebounce } from "../../utils/appUtils";
import { useController } from "react-hook-form"; import { useController } from "react-hook-form";
import Avatar from "./Avatar"; import Avatar from "./Avatar";
const EmployeeSearchInput = ({
const EmployeeSearchInput = ({ control, name, projectId, placeholder }) => { control,
name,
projectId,
placeholder,
forAll,
}) => {
const { const {
field: { onChange, value, ref }, field: { onChange, value, ref },
fieldState: { error }, fieldState: { error },
@ -15,32 +20,20 @@ const EmployeeSearchInput = ({ control, name, projectId, placeholder }) => {
const [showDropdown, setShowDropdown] = useState(false); const [showDropdown, setShowDropdown] = useState(false);
const debouncedSearch = useDebounce(search, 500); const debouncedSearch = useDebounce(search, 500);
const wrapperRef = useRef(null); const { data: employees, isLoading } = useEmployeesName(
projectId,
const { debouncedSearch,
data: employees, forAll
isLoading, );
} = useEmployeesName(projectId, debouncedSearch);
useEffect(() => { useEffect(() => {
if (value && !search) { if (value && employees?.data) {
const found = employees?.data?.find((emp) => emp.id === value); const found = employees.data.find((emp) => emp.id === value);
if (found) setSearch(found.firstName + " " + found.lastName); if (found && forAll) {
} setSearch(found.firstName + " " + found.lastName);
}, [value, employees]);
useEffect(() => {
const handleClickOutside = (e) => {
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
setShowDropdown(false);
} }
}; }
document.addEventListener("mousedown", handleClickOutside); }, [value, employees?.data]);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
const handleSelect = (employee) => { const handleSelect = (employee) => {
onChange(employee.id); onChange(employee.id);
@ -49,11 +42,11 @@ const EmployeeSearchInput = ({ control, name, projectId, placeholder }) => {
}; };
return ( return (
<div className="position-relative" ref={wrapperRef}> <div className="position-relative">
<input <input
type="text" type="text"
ref={ref} ref={ref}
className="form-control form-control-sm" className={`form-control form-control-sm`}
placeholder={placeholder} placeholder={placeholder}
value={search} value={search}
onChange={(e) => { onChange={(e) => {
@ -68,7 +61,7 @@ const EmployeeSearchInput = ({ control, name, projectId, placeholder }) => {
{showDropdown && (employees?.data?.length > 0 || isLoading) && ( {showDropdown && (employees?.data?.length > 0 || isLoading) && (
<ul <ul
className="list-group position-absolute bg-white w-100 shadow z-3 px-0" className="list-group position-absolute bg-white w-100 shadow z-3 rounded-none px-0"
style={{ maxHeight: 200, overflowY: "auto" }} style={{ maxHeight: 200, overflowY: "auto" }}
> >
{isLoading ? ( {isLoading ? (
@ -106,4 +99,3 @@ const EmployeeSearchInput = ({ control, name, projectId, placeholder }) => {
}; };
export default EmployeeSearchInput; export default EmployeeSearchInput;

View File

@ -184,11 +184,11 @@ export const useEmployeeProfile = (employeeId) => {
}; };
}; };
export const useEmployeesName = (projectId, search) => { export const useEmployeesName = (projectId, search,forAll) => {
return useQuery({ return useQuery({
queryKey: ["employees", projectId, search], queryKey: ["employees", projectId, search,forAll],
queryFn: async () => queryFn: async () =>
await EmployeeRepository.getEmployeeName(projectId, search), await EmployeeRepository.getEmployeeName(projectId, search,forAll),
staleTime: 5 * 60 * 1000, // Optional: cache for 5 minutes staleTime: 5 * 60 * 1000, // Optional: cache for 5 minutes
}); });

View File

@ -10,16 +10,17 @@ const EmployeeRepository = {
updateEmployee: (id, data) => api.put(`/users/${id}`, data), updateEmployee: (id, data) => api.put(`/users/${id}`, data),
// deleteEmployee: ( id ) => api.delete( `/users/${ id }` ), // deleteEmployee: ( id ) => api.delete( `/users/${ id }` ),
getEmployeeProfile: (id) => api.get(`/api/employee/profile/get/${id}`), getEmployeeProfile: (id) => api.get(`/api/employee/profile/get/${id}`),
deleteEmployee: (id,active) => api.delete(`/api/employee/${id}?active=${active}`), deleteEmployee: (id, active) => api.delete(`/api/employee/${id}?active=${active}`),
getEmployeeName: (projectId, search) => { getEmployeeName: (projectId, search, allEmployee) => {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (projectId) params.append("projectId", projectId); if (projectId) params.append("projectId", projectId);
if (search) params.append("searchString", search); if (search) params.append("searchString", search);
if (allEmployee) params.append("sendAll", allEmployee)
const query = params.toString(); const query = params.toString();
return api.get(`/api/Employee/basic${query ? `?${query}` : ""}`); return api.get(`/api/Employee/basic${query ? `?${query}` : ""}`);
} }
}; };