import { Button, Heading, Skeleton, Text } from '@moex-vibe/design-system'
import { Box } from '@mui/material'
import { Link } from '@tanstack/react-router'
import type { ReactNode } from 'react'
import {
type BrokerOperationImpact,
getBrokerOperationImpact,
getBrokerOperationTypeLabel,
} from '@/entities/broker-operation'
import { getBrokerInstrumentPath } from '@/entities/broker-position'
import type { BrokerOperation, BrokerOperationsPage } from '@/shared/api'
import { formatBrokerSignedMoney } from '@/shared/lib/formatters'
import { TableSkeleton } from '@/shared/ui/TableSkeleton'
const tableSx = {
width: '100%',
borderCollapse: 'collapse',
fontSize: 14,
} as const
const thSx = {
borderBottom: '1px solid',
borderColor: 'divider',
color: 'text.secondary',
fontWeight: 600,
p: 1,
textAlign: 'left',
} as const
const tdSx = {
borderBottom: '1px solid',
borderColor: 'divider',
p: 1,
verticalAlign: 'top',
textAlign: 'left',
} as const
const tdSxRight = {
...tdSx,
textAlign: 'right',
} as const
function formatDate(value: string | null) {
if (!value) return '-'
return new Date(value).toLocaleString('ru-RU')
}
function operationTone(impact: BrokerOperationImpact) {
if (impact === 'adds') return 'positive' as const
if (impact === 'reduces') return 'negative' as const
return 'primary' as const
}
function OperationInstrument({ operation }: { operation: BrokerOperation }) {
const ticker = operation.ticker || operation.description || '-'
const path = getBrokerInstrumentPath({
ticker: operation.ticker,
instrumentType: operation.instrumentType,
classCode: operation.classCode,
})
const name = operation.name || operation.description
if (!path && !name) return -
if (!path) return {name}
if (!ticker || ticker === '-') return {name}
return (
{ticker}
{name && name !== ticker && (
{name}
)}
)
}
export function BrokerOperationsTable({
title,
headerAction,
emptyMessage,
isLoading,
isFetching,
page,
pagination,
}: BrokerOperationsTableProps) {
const pageNumber = pagination?.pageNumber
const canGoBack = pagination?.canGoBack ?? false
const canGoForward = pagination?.canGoForward ?? false
const onPrevious = pagination?.onPrevious
const onNext = pagination?.onNext
const operations = page?.items ?? []
return (
{title}
{headerAction}
{pagination && (
{pageNumber}
)}
{isLoading ? (
Дата
Тип
Инструмент
Сумма
) : operations.length === 0 && !isFetching ? (
{emptyMessage}
) : (
Дата
Тип
Инструмент
Сумма
{operations.map((operation) => {
const impact = getBrokerOperationImpact(operation)
return (
{formatDate(operation.date)}
{getBrokerOperationTypeLabel(operation)}
{formatBrokerSignedMoney(operation.payment)}
)
})}
{isFetching && (
{pagination ? `Загрузка страницы ${pageNumber}…` : 'Обновление операций…'}
)}
)}
)
}
type BrokerOperationsTableProps = {
title: string
headerAction?: ReactNode
emptyMessage: string
isLoading: boolean
isFetching: boolean
page: BrokerOperationsPage | undefined
pagination?: {
pageNumber: number
canGoBack: boolean
canGoForward: boolean
onPrevious: () => void
onNext: () => void
}
}