import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import Autocomplete from "@mui/material/Autocomplete"; import TextField from "@mui/material/TextField"; import CircularProgress from "@mui/material/CircularProgress"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; import useDebounce from "../../hooks/useDebounce"; import { warehouseItemListOptions, type WarehouseItem, } from "../../lib/queries/warehouse"; interface ItemPickerProps { value: number | null; onChange: (itemId: number) => void; itemName?: string; } /** Minimal option shape used to display a selected value that isn't in the * current search results (edit/prefill via `itemName`). */ type ItemOption = Pick & Partial; export default function ItemPicker({ value, onChange, itemName, }: ItemPickerProps) { const [inputValue, setInputValue] = useState(itemName ?? ""); // Debounce the search so the list query doesn't fire on every keystroke. const debouncedSearch = useDebounce(inputValue, 300); const { data, isFetching } = useQuery( warehouseItemListOptions({ search: debouncedSearch, perPage: 20 }), ); const options: ItemOption[] = data?.data ?? []; // Show the selected value even when it isn't in the current search results // (e.g. prefilled via `itemName`) by synthesizing a fallback option. const selectedOption: ItemOption | null = value == null ? null : (options.find((o) => o.id === value) ?? { id: value, name: itemName ?? "", }); return ( value={selectedOption} inputValue={inputValue} onInputChange={(_, newInput) => setInputValue(newInput)} onChange={(_, opt) => { if (opt) onChange(opt.id); }} options={options} loading={isFetching} filterOptions={(x) => x} getOptionLabel={(o) => o.name} isOptionEqualToValue={(o, v) => o.id === v.id} noOptionsText="Žádné položky" renderOption={(props, option) => { const { key, ...rest } = props; return ( {option.name} {(option.item_number || option.available_quantity !== undefined) && ( {option.item_number} {option.item_number && option.available_quantity !== undefined ? " · " : ""} {option.available_quantity !== undefined ? `${option.available_quantity} ${option.unit ?? ""}` : ""} )} ); }} renderInput={(params) => ( {isFetching ? ( ) : null} {params.InputProps.endAdornment} ), }, }} /> )} /> ); }