Files
frontend/src/pages/stock/ui/StockPage/StockPage.vm.ts
T
ksv741 5b30bb802a feat: add quiet reading with rare confirmations
Part of the quiet-user-feedback change; docs and specs land in their own repositories.
2026-10-06 07:01:58 +03:00

102 lines
2.7 KiB
TypeScript

import { useParams } from "react-router";
import { useBrokerageOperationHistory } from "@/entities/broker-operation";
import {
useStock,
useStockCandles,
useStockCompany,
useStockDividends,
useStockPosition,
useStockQuote,
} from "@/entities/stock";
import {
section,
toInstrumentEventRows,
useInstrumentParameters,
} from "@/features/instrument-details";
import { useScreenSync } from "@/features/tbank-connection";
import { apiErrorCode } from "@/shared/api";
import { compareDateDesc, instrumentLogoUrl } from "@/shared/lib";
type StockPageVm = ReturnType<typeof useStockPageVm>;
function useStockPageVm() {
const { stockId = "" } = useParams();
const stock = useStock(stockId);
const uid = stock.data?.instrumentUid ?? "";
const { categories, filter, period, search, setFilter, setPeriod }
= useInstrumentParameters("dividends");
const quote = useStockQuote(uid);
const candles = useStockCandles(uid, period);
const position = useStockPosition(uid);
const company = useStockCompany(uid);
const dividends = useStockDividends(uid);
const history = useBrokerageOperationHistory(uid ? "all" : undefined, {
categories,
instrumentUid: uid,
limit: 20,
});
const { operations } = history;
useScreenSync(
{
accountId: "all",
candlePeriod: period,
categories,
instrumentUid: uid,
limit: 20,
screen: "stock",
},
[stock, quote, candles, position, company, dividends, operations],
);
return {
candles: candles.data,
candlesState: section(candles),
canonicalTo:
stock.data?.slug && stock.data.slug !== stockId
? `/stocks/${encodeURIComponent(stock.data.slug)}${search}`
: null,
code: apiErrorCode(stock.error),
company: company.data,
companyState: section(company),
dividends: dividends.data,
dividendsState: section(dividends),
eventRows: toInstrumentEventRows(operations.data?.items, stock.data),
filter,
hasPrevious: history.hasPrevious,
logoSrc: instrumentLogoUrl(stock.data?.logoName),
onNext: history.onNext,
onPrevious: history.onPrevious,
operations: operations.data,
operationsState: section(operations),
pastDividends:
dividends.data?.dividends
.filter(event => event.timing !== "upcoming")
.toSorted((a, b) =>
compareDateDesc(a.paymentDate, b.paymentDate),
) ?? [],
period,
position: position.data,
positionState: section(position),
quote: quote.data,
quoteState: section(quote),
setFilter,
setPeriod,
stock: stock.data,
stockState: section(stock),
upcoming:
dividends.data?.dividends
.filter(event => event.timing === "upcoming")
.toSorted((a, b) =>
compareDateDesc(b.paymentDate, a.paymentDate),
) ?? [],
};
}
export { type StockPageVm, useStockPageVm };