102 lines
2.8 KiB
JavaScript
102 lines
2.8 KiB
JavaScript
import { useState, useEffect } from "react";
|
|
import { useEmployeesName } from "../../hooks/useEmployees";
|
|
import { useDebounce } from "../../utils/appUtils";
|
|
import { useController } from "react-hook-form";
|
|
import Avatar from "./Avatar";
|
|
|
|
const EmployeeSearchInput = ({
|
|
control,
|
|
name,
|
|
projectId,
|
|
placeholder,
|
|
forAll,
|
|
}) => {
|
|
const {
|
|
field: { onChange, value, ref },
|
|
fieldState: { error },
|
|
} = useController({ name, control });
|
|
|
|
const [search, setSearch] = useState("");
|
|
const [showDropdown, setShowDropdown] = useState(false);
|
|
const debouncedSearch = useDebounce(search, 500);
|
|
|
|
const { data: employees, isLoading } = useEmployeesName(
|
|
projectId,
|
|
debouncedSearch,
|
|
forAll
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (value && employees?.data) {
|
|
const found = employees.data.find((emp) => emp.id === value);
|
|
if (found && forAll) {
|
|
setSearch(found.firstName + " " + found.lastName);
|
|
}
|
|
}
|
|
}, [value, employees?.data]);
|
|
|
|
const handleSelect = (employee) => {
|
|
onChange(employee.id);
|
|
setSearch(employee.firstName + " " + employee.lastName);
|
|
setShowDropdown(false);
|
|
};
|
|
|
|
return (
|
|
<div className="position-relative">
|
|
<input
|
|
type="text"
|
|
ref={ref}
|
|
className={`form-control form-control-sm`}
|
|
placeholder={placeholder}
|
|
value={search}
|
|
onChange={(e) => {
|
|
setSearch(e.target.value);
|
|
setShowDropdown(true);
|
|
onChange("");
|
|
}}
|
|
onFocus={() => {
|
|
if (search) setShowDropdown(true);
|
|
}}
|
|
/>
|
|
|
|
{showDropdown && (employees?.data?.length > 0 || isLoading) && (
|
|
<ul
|
|
className="list-group position-absolute bg-white w-100 shadow z-3 rounded-none px-0"
|
|
style={{ maxHeight: 200, overflowY: "auto" }}
|
|
>
|
|
{isLoading ? (
|
|
<li className="list-group-item">
|
|
<a>Searching...</a>
|
|
</li>
|
|
) : (
|
|
employees?.data?.map((emp) => (
|
|
<li
|
|
key={emp.id}
|
|
className="list-group-item list-group-item-action py-1 px-1"
|
|
style={{ cursor: "pointer" }}
|
|
onClick={() => handleSelect(emp)}
|
|
>
|
|
<div className="d-flex align-items-center px-0">
|
|
<Avatar
|
|
size="xs"
|
|
classAvatar="m-0 me-2"
|
|
firstName={emp.firstName}
|
|
lastName={emp.lastName}
|
|
/>
|
|
<span className="text-muted">
|
|
{`${emp?.firstName} ${emp?.lastName}`.trim()}
|
|
</span>
|
|
</div>
|
|
</li>
|
|
))
|
|
)}
|
|
</ul>
|
|
)}
|
|
|
|
{error && <small className="danger-text">{error.message}</small>}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default EmployeeSearchInput;
|