diff --git a/src/components/Accordion.tsx b/src/components/Accordion.tsx index cdfa04b9..9c625041 100644 --- a/src/components/Accordion.tsx +++ b/src/components/Accordion.tsx @@ -38,9 +38,7 @@ export default function Accordion(props: Props) { -
- {item.content} -
+
{item.content}
))} diff --git a/src/components/Account/AccountBalancesTable.tsx b/src/components/Account/AccountBalancesTable.tsx new file mode 100644 index 00000000..cbdda335 --- /dev/null +++ b/src/components/Account/AccountBalancesTable.tsx @@ -0,0 +1,219 @@ +'use client' + +import { + ColumnDef, + flexRender, + getCoreRowModel, + getSortedRowModel, + SortingState, + useReactTable, +} from '@tanstack/react-table' +import classNames from 'classnames' +import React from 'react' + +import DisplayCurrency from 'components/DisplayCurrency' +import { FormattedNumber } from 'components/FormattedNumber' +import { SortAsc, SortDesc, SortNone } from 'components/Icons' +import Text from 'components/Text' +import { ASSETS } from 'constants/assets' +import useStore from 'store' +import { convertToDisplayAmount, demagnify } from 'utils/formatters' + +interface Props { + data: Account +} + +export const AcccountBalancesTable = (props: Props) => { + const displayCurrency = useStore((s) => s.displayCurrency) + const prices = useStore((s) => s.prices) + const [sorting, setSorting] = React.useState([]) + + const balanceData = React.useMemo(() => { + const accountDeposits = props.data?.deposits ?? [] + const accountLends = props.data?.lends ?? [] + + const deposits = accountDeposits.map((deposit) => { + const asset = ASSETS.find((asset) => asset.denom === deposit.denom) ?? ASSETS[0] + const apy = 0 + return { + type: 'deposit', + symbol: asset.symbol, + denom: deposit.denom, + amount: deposit.amount, + size: demagnify(deposit.amount, asset), + value: convertToDisplayAmount( + { amount: deposit.amount, denom: deposit.denom }, + displayCurrency, + prices, + ), + apy, + } + }) + const lends = accountLends.map((lending) => { + const asset = ASSETS.find((asset) => asset.denom === lending.denom) ?? ASSETS[0] + const apy = 0 + return { + type: 'lending', + symbol: asset.symbol, + denom: lending.denom, + amount: lending.amount, + size: demagnify(lending.amount, asset), + value: convertToDisplayAmount( + { amount: lending.amount, denom: lending.denom }, + displayCurrency, + prices, + ), + apy, + } + }) + + return [...deposits, ...lends] + }, [displayCurrency, prices, props.data?.deposits, props.data?.lends]) + + const columns = React.useMemo[]>( + () => [ + { + header: 'Asset', + accessorKey: 'symbol', + id: 'symbol', + cell: ({ row }) => { + return ( + + {row.original.symbol} + {row.original.type === 'lending' && (Lent)} + + ) + }, + }, + { + header: 'Value', + accessorKey: 'value', + id: 'value', + cell: ({ row }) => { + return ( + + ) + }, + }, + { + id: 'size', + accessorKey: 'size', + header: 'Size', + cell: ({ row }) => { + return ( + asset.denom === row.original.denom) ?? ASSETS[0], + )} + options={{ maxDecimals: 4 }} + /> + ) + }, + }, + { + id: 'apy', + accessorKey: 'apy', + header: 'APY', + cell: ({ row }) => { + return ( + + ) + }, + }, + ], + [], + ) + + const table = useReactTable({ + data: balanceData, + columns, + state: { + sorting, + }, + onSortingChange: setSorting, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + debugTable: true, + }) + + return ( + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header, index) => { + return ( + + ) + })} + + ))} + + + {table.getRowModel().rows.map((row) => { + return ( + + {row.getVisibleCells().map((cell) => { + const borderClass = + cell.row.original.type === 'deposit' ? 'border-profit' : 'border-loss' + return ( + + ) + })} + + ) + })} + +
+
+ + {header.column.getCanSort() + ? { + asc: , + desc: , + false: , + }[header.column.getIsSorted() as string] ?? null + : null} + + + {flexRender(header.column.columnDef.header, header.getContext())} + +
+
+ {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+ ) +} diff --git a/src/components/Account/AccountComposition.tsx b/src/components/Account/AccountComposition.tsx index 17ddfe3b..124e2c0a 100644 --- a/src/components/Account/AccountComposition.tsx +++ b/src/components/Account/AccountComposition.tsx @@ -44,7 +44,7 @@ export default function AccountComposition(props: Props) { const borrowRateChange = props.change ? calculateAccountPnL(props.change, prices) : BN(0) return ( -
+
+
, open: true, }, - { title: 'Balances', content:

My content

}, + { title: 'Balances', content: }, ]} />
diff --git a/src/components/DisplayCurrency.tsx b/src/components/DisplayCurrency.tsx index c56cb3e3..2eef0fe0 100644 --- a/src/components/DisplayCurrency.tsx +++ b/src/components/DisplayCurrency.tsx @@ -2,8 +2,7 @@ import { Coin } from '@cosmjs/stargate' import { FormattedNumber } from 'components/FormattedNumber' import useStore from 'store' -import { getMarketAssets } from 'utils/assets' -import { BN } from 'utils/helpers' +import { convertToDisplayAmount } from 'utils/formatters' interface Props { coin: Coin @@ -15,24 +14,10 @@ export default function DisplayCurrency(props: Props) { const displayCurrency = useStore((s) => s.displayCurrency) const prices = useStore((s) => s.prices) - function convertToDisplayAmount(coin: Coin) { - const price = prices.find((price) => price.denom === coin.denom) - const asset = getMarketAssets().find((asset) => asset.denom === coin.denom) - const displayPrice = prices.find((price) => price.denom === displayCurrency.denom) - - if (!price || !asset || !displayPrice) return '0' - - return BN(coin.amount) - .shiftedBy(-1 * asset.decimals) - .times(price.amount) - .div(displayPrice.amount) - .toNumber() - } - return ( { - if (!selectedAccount) - setSelectedAccount(currentAccount) + if (!selectedAccount) setSelectedAccount(currentAccount) }, [selectedAccount, currentAccount]) useEffect(() => { diff --git a/src/components/Portfolio/AccountOverview.tsx b/src/components/Portfolio/AccountOverview.tsx index 338d2a00..09525f31 100644 --- a/src/components/Portfolio/AccountOverview.tsx +++ b/src/components/Portfolio/AccountOverview.tsx @@ -1,6 +1,7 @@ import classNames from 'classnames' import { Suspense } from 'react' +import { AcccountBalancesTable } from 'components/Account/AccountBalancesTable' import AccountComposition from 'components/Account/AccountComposition' import Card from 'components/Card' import Loading from 'components/Loading' @@ -30,13 +31,10 @@ async function Content(props: PageProps) { className={classNames('grid w-full grid-cols-1 gap-4', 'md:grid-cols-2', 'lg:grid-cols-3')} > {account.map((account: Account, index: number) => ( - + + Balances + ))}
@@ -50,13 +48,12 @@ function Fallback() { className={classNames('grid w-full grid-cols-1 gap-4', 'md:grid-cols-2', 'lg:grid-cols-3')} > {Array.from({ length: cardCount }, (_, i) => ( - - + +
+ +
+ Balances +
))}
diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx index 7027a616..b6268f29 100644 --- a/src/components/Select/Select.tsx +++ b/src/components/Select/Select.tsx @@ -46,7 +46,7 @@ export default function Select(props: Props) { (option) => option?.value === props.defaultValue || option?.denom === props.defaultValue, ), ) - }, [value, props.defaultValue, props.options]) + }, [value, props.defaultValue, props.options, selected]) return (
price.denom === coin.denom) + const asset = getMarketAssets().find((asset) => asset.denom === coin.denom) + const displayPrice = prices.find((price) => price.denom === displayCurrency.denom) + + if (!price || !asset || !displayPrice) return '0' + + return BN(coin.amount) + .shiftedBy(-1 * asset.decimals) + .times(price.amount) + .div(displayPrice.amount) + .toNumber() +}