import { ColumnDef, flexRender, getCoreRowModel, getSortedRowModel, Row, SortingState, useReactTable, } from '@tanstack/react-table' import classNames from 'classnames' import React from 'react' import ActionButton from 'components/Button/ActionButton' import DisplayCurrency from 'components/DisplayCurrency' import VaultExpanded from 'components/Earn/Farm/VaultExpanded' import VaultLogo from 'components/Earn/Farm/VaultLogo' import { VaultRow } from 'components/Earn/Farm/VaultRow' import { FormattedNumber } from 'components/FormattedNumber' import { ChevronDown, SortAsc, SortDesc, SortNone } from 'components/Icons' import Loading from 'components/Loading' import Text from 'components/Text' import TitleAndSubCell from 'components/TitleAndSubCell' import { ORACLE_DENOM } from 'constants/oracle' import { VAULT_DEPOSIT_BUFFER } from 'constants/vaults' import useStore from 'store' import { BNCoin } from 'types/classes/BNCoin' import { VaultStatus } from 'types/enums/vault' import { getAssetByDenom } from 'utils/assets' import { formatPercent, produceCountdown } from 'utils/formatters' type Props = { data: Vault[] | DepositedVault[] isLoading?: boolean } export const VaultTable = (props: Props) => { const [sorting, setSorting] = React.useState([{ id: 'name', desc: true }]) const columns = React.useMemo[]>(() => { return [ { header: 'Vault', accessorKey: 'name', cell: ({ row }) => { const vault = row.original as DepositedVault const timeframe = vault.lockup.timeframe[0] const unlockDuration = !!timeframe ? ` - (${vault.lockup.duration}${timeframe})` : '' const status = vault.status let remainingTime = 0 if (status === VaultStatus.UNLOCKING && vault.unlocksAt) { remainingTime = vault.unlocksAt - Date.now() } return (
{status === VaultStatus.UNLOCKING && ( Unlocking {produceCountdown(remainingTime)} )} {status === VaultStatus.UNLOCKED && ( Unlocked )}
) }, }, ...((props.data[0] as DepositedVault)?.values ? [ { header: 'Pos. Value', cell: ({ row }: { row: Row }) => { const vault = row.original as DepositedVault const positionValue = vault.values.primary.plus(vault.values.secondary) const coin = BNCoin.fromDenomAndBigNumber(ORACLE_DENOM, positionValue) return }, }, ] : []), { accessorKey: 'apy', header: 'APY', cell: ({ row }) => { const vault = row.original as DepositedVault if (vault.apy === null) return return ( ) }, }, { accessorKey: 'tvl', header: 'TVL', cell: ({ row }) => { const vault = row.original as DepositedVault if (props.isLoading) return const coin = new BNCoin({ denom: vault.cap.denom, amount: vault.cap.used.toString(), }) return }, }, { accessorKey: 'cap', header: 'Depo. Cap', cell: ({ row }) => { const vault = row.original as DepositedVault if (props.isLoading) return const percent = vault.cap.used .dividedBy(vault.cap.max.multipliedBy(VAULT_DEPOSIT_BUFFER)) .multipliedBy(100) .integerValue() const decimals = getAssetByDenom(vault.cap.denom)?.decimals ?? 6 return ( } sub={ } /> ) }, }, { accessorKey: 'ltv.max', header: 'Max LTV', cell: ({ row }) => { if (props.isLoading) return return {formatPercent(row.original.ltv.max)} }, }, { accessorKey: 'ltv.liq', header: 'Liq. LTV', cell: ({ row }) => { if (props.isLoading) return return {formatPercent(row.original.ltv.liq)} }, }, { accessorKey: 'details', enableSorting: false, header: (data) => { const tableData = data.table.options.data as DepositedVault[] if (tableData.length && tableData[0].status) return 'Details' return 'Deposit' }, cell: ({ row }) => { const vault = row.original as DepositedVault function enterVaultHandler() { useStore.setState({ vaultModal: { vault, selectedBorrowDenoms: [vault.denoms.secondary], isCreate: true, }, }) } if (props.isLoading) return return (
{vault.status ? (
) : ( )}
) }, }, ] }, [props.data, props.isLoading]) const table = useReactTable({ data: props.data, columns: columns, state: { sorting, }, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), }) return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { if (row.getIsExpanded()) { return ( ) } return ( ) })}
{header.column.getCanSort() ? { asc: , desc: , false: , }[header.column.getIsSorted() as string] ?? null : null} {flexRender(header.column.columnDef.header, header.getContext())}
) }