104 lines
4.2 KiB
JavaScript
104 lines
4.2 KiB
JavaScript
import { Autocomplete, CircularProgress, TextField } from "@mui/material";
|
||
import { useEffect, useState } from "react";
|
||
import useRequest from "@/lib/hooks/useRequest";
|
||
import { debounce } from "@mui/material/utils";
|
||
import { GET_CAR_LIST_SEARCH } from "@/core/utils/routes";
|
||
|
||
const CarCode = ({ carCode, setCarCode, inputValueDefault = "", error, multiple = false }) => {
|
||
const [inputValue, setInputValue] = useState(inputValueDefault);
|
||
const [options, setOptions] = useState([]);
|
||
const [loading, setLoading] = useState(false);
|
||
const requestServer = useRequest();
|
||
|
||
useEffect(() => {
|
||
const fetchCarCodes = (inputValue, controller) => {
|
||
const debouncer = debounce((query) => {
|
||
if (!query || query?.length < 3) {
|
||
setOptions([]);
|
||
return;
|
||
}
|
||
setLoading(true);
|
||
requestServer(`${GET_CAR_LIST_SEARCH}?machine_code=${query}`, "get", {
|
||
requestOptions: { signal: controller.signal },
|
||
})
|
||
.then((response) => {
|
||
const combinedArray = carCode ? [...carCode, ...response.data.data] : [...response.data.data];
|
||
const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values());
|
||
setOptions(uniqueArray || []);
|
||
})
|
||
.catch(() => {
|
||
setOptions([]);
|
||
})
|
||
.finally(() => {
|
||
setLoading(false);
|
||
});
|
||
}, 500);
|
||
debouncer(inputValue);
|
||
};
|
||
|
||
const controller = new AbortController();
|
||
fetchCarCodes(inputValue, controller);
|
||
return () => controller.abort();
|
||
}, [inputValue]);
|
||
|
||
return (
|
||
<Autocomplete
|
||
multiple={multiple}
|
||
value={carCode}
|
||
size="small"
|
||
onChange={(event, newValue) => {
|
||
setCarCode(multiple ? newValue || [] : newValue || null);
|
||
}}
|
||
inputValue={inputValue}
|
||
onInputChange={(event, newInputValue) => {
|
||
setInputValue(newInputValue || "");
|
||
}}
|
||
options={options}
|
||
getOptionLabel={(option) => {
|
||
if (typeof option === "string") return option;
|
||
const { machine_code, car_name, plak_number } = option;
|
||
let label = `${machine_code || ""}`;
|
||
if (car_name) {
|
||
label += ` | ${car_name}`;
|
||
}
|
||
if (plak_number) {
|
||
label += ` | ${plak_number}`;
|
||
}
|
||
return label;
|
||
}}
|
||
isOptionEqualToValue={(option, value) => {
|
||
if (!value) return false;
|
||
if (value === "") return option.machine_code === "";
|
||
return option.machine_code === (value?.machine_code || value);
|
||
}}
|
||
loading={loading}
|
||
loadingText="درحال جستجوی کد خودرو"
|
||
noOptionsText={inputValue?.length < 3 ? "حداقل سه رقم از کد خودرو را وارد کنید" : "کد خودرویی یافت نشد"}
|
||
fullWidth
|
||
renderInput={(params) => (
|
||
<TextField
|
||
{...params}
|
||
label={multiple ? "خودرو ها" : "خودرو"}
|
||
fullWidth
|
||
placeholder={multiple ? "کد خودرو ها را وارد کنید" : "کد خودرو را وارد کنید"}
|
||
error={!!error}
|
||
helperText={error?.message}
|
||
InputLabelProps={{
|
||
shrink: true,
|
||
}}
|
||
InputProps={{
|
||
...params.InputProps,
|
||
endAdornment: (
|
||
<>
|
||
{loading ? <CircularProgress size="25px" color="inherit" /> : null}
|
||
{params.InputProps.endAdornment}
|
||
</>
|
||
),
|
||
}}
|
||
/>
|
||
)}
|
||
/>
|
||
);
|
||
};
|
||
export default CarCode;
|