import { useDebouncedValue } from "@mantine/hooks"; import { useSearchParams } from "react-router"; import { MIN_BOND_SEARCH_LENGTH, useBondSearch } from "@/entities/bond"; import { useScreenSync } from "@/features/tbank-connection"; import { apiErrorCode } from "@/shared/api"; import { instrumentLogoUrl } from "@/shared/lib"; const SEARCH_DEBOUNCE_MS = 300; type BondsPageVm = ReturnType; function useBondsPageVm() { const [parameters, setParameters] = useSearchParams(); const query = parameters.get("q") ?? ""; const [debounced] = useDebouncedValue(query.trim(), SEARCH_DEBOUNCE_MS); const result = useBondSearch(debounced); const sync = useScreenSync({ query: debounced, screen: "bonds" }, [result]); const canSearch = query.trim().length >= MIN_BOND_SEARCH_LENGTH; const isWaiting = query.trim() !== debounced; return { canSearch, code: apiErrorCode(result.error), error: result.isError || sync.sourceError || sync.transportError, items: result.data?.map(bond => ({ ...bond, logoSrc: instrumentLogoUrl(bond.logoName), to: `/bonds/${encodeURIComponent(bond.slug ?? bond.instrumentUid)}`, })) ?? [], loading: canSearch && (isWaiting || (!result.data && !result.isError && result.meta?.sync.state !== "failed")), partial: result.meta?.availability === "partial", query, ready: debounced.length >= MIN_BOND_SEARCH_LENGTH && !isWaiting && Boolean(result.data), refreshing: sync.refreshing, retry: () => { void sync.retry(); }, setQuery: (q: string) => setParameters(q ? { q } : {}, { replace: true }), }; } export { type BondsPageVm, useBondsPageVm };