import { useMemo, useState } from "react"; import { Controller, type Control, type FieldError } from "react-hook-form"; import { Autocomplete, TextField } from "@mui/material"; import type { AccountListItem } from "@/domain/accounts/types/account"; import { useAccountsList } from "@/domain/accounts/use-cases/use-accounts-list"; import type { LocationFormValues } from "@/domain/locations/schemas/location-schema"; import { useDebounce } from "@/hooks/use-debounce"; type ClientOption = Pick; interface ClientSelectProps { control: Control; error?: FieldError; /** Stored client, shown even when it is not in the first page of search results. */ initialClient?: ClientOption; } /** Searchable client (account) picker bound to `accountId`. */ export function ClientSelect({ control, error, initialClient }: ClientSelectProps) { const [search, setSearch] = useState(""); const debouncedSearch = useDebounce(search, 300); const { data, isLoading } = useAccountsList({ search: debouncedSearch, page: 1, pageSize: 50 }); const options = useMemo(() => { const items: ClientOption[] = data?.items ?? []; const hasInitial = initialClient !== undefined && items.some((item) => String(item.id) === String(initialClient.id)); return initialClient === undefined || hasInitial ? items : [initialClient, ...items]; }, [data?.items, initialClient]); return ( ( options={options} loading={isLoading} getOptionLabel={(option) => option.name || String(option.id)} isOptionEqualToValue={(option, value) => String(option.id) === String(value.id)} value={options.find((option) => String(option.id) === field.value) ?? null} onChange={(_event, option) => field.onChange(option ? String(option.id) : "")} onBlur={field.onBlur} onInputChange={(_event, value, reason) => { if (reason === "input") { setSearch(value); } }} renderInput={(params) => ( )} /> )} /> ); }