diff --git a/centrifuge-app/src/components/LoanList.tsx b/centrifuge-app/src/components/LoanList.tsx index 711103b6d4..cb204e25b6 100644 --- a/centrifuge-app/src/components/LoanList.tsx +++ b/centrifuge-app/src/components/LoanList.tsx @@ -29,8 +29,8 @@ import { useMetadata } from '../utils/useMetadata' import { useCentNFT } from '../utils/useNFTs' import { usePool, usePoolMetadata } from '../utils/usePools' import { Column, DataTable, SortableTableHeader } from './DataTable' -import { LoadBoundary } from './LoadBoundary' import { prefetchRoute } from './Root' +import { Spinner } from './Spinner' type Row = (Loan | TinlakeLoan) & { idSortKey: number @@ -47,9 +47,10 @@ type Row = (Loan | TinlakeLoan) & { type Props = { loans: Loan[] | TinlakeLoan[] snapshots: AssetSnapshot[] + isLoading: boolean } -export function LoanList({ loans, snapshots }: Props) { +export function LoanList({ loans, snapshots, isLoading }: Props) { const { pid: poolId } = useParams<{ pid: string }>() if (!poolId) throw new Error('Pool not found') @@ -266,6 +267,8 @@ export function LoanList({ loans, snapshots }: Props) { const csvUrl = React.useMemo(() => csvData && getCSVDownloadUrl(csvData as any), [csvData]) + if (isLoading) return + return ( <> @@ -275,7 +278,7 @@ export function LoanList({ loans, snapshots }: Props) { - Show repaid assets + Show closed assets } onChange={(e) => setShowRepaid(!showRepaid)} @@ -304,18 +307,16 @@ export function LoanList({ loans, snapshots }: Props) { - - - !row?.marketValue?.isZero())} - columns={columns} - onRowClicked={(row) => `${basePath}/${poolId}/assets/${row.id}`} - pageSize={20} - page={pagination.page} - defaultSortKey="maturityDate" - /> - - + + !row?.marketValue?.isZero())} + columns={columns} + onRowClicked={(row) => `${basePath}/${poolId}/assets/${row.id}`} + pageSize={20} + page={pagination.page} + defaultSortKey="maturityDate" + /> + {pagination.pageCount > 1 && ( diff --git a/centrifuge-app/src/components/PoolCard/PoolListView.tsx b/centrifuge-app/src/components/PoolCard/PoolListView.tsx new file mode 100644 index 0000000000..c94ecc7ed8 --- /dev/null +++ b/centrifuge-app/src/components/PoolCard/PoolListView.tsx @@ -0,0 +1,43 @@ +import { Box, Grid, Text } from '@centrifuge/fabric' +import { useTheme } from 'styled-components' +import { PoolCardProps } from '.' +import { formatBalance, formatPercentage } from '../../../src/utils/formatting' +import { PoolStatus } from './PoolStatus' + +export const PoolListView = ({ + poolId, + assetClass, + valueLocked, + iconUri, + tranches, + name, + currencySymbol, + status, + createdAt, + ...pool +}: PoolCardProps) => { + const theme = useTheme() + const calculateApy = () => { + const APR = tranches?.find((tranche) => tranche.interestRatePerSec)?.interestRatePerSec + if (APR) return formatPercentage(APR.toAprPercent(), true, {}, 1) + else return '-' + } + return ( + + + {name} + {assetClass} + {formatBalance(valueLocked || 0, currencySymbol)} + {calculateApy()} + + + ) +} diff --git a/centrifuge-app/src/components/PoolList.tsx b/centrifuge-app/src/components/PoolList.tsx index 5becd2238a..ea08acccf9 100644 --- a/centrifuge-app/src/components/PoolList.tsx +++ b/centrifuge-app/src/components/PoolList.tsx @@ -9,6 +9,7 @@ import { TinlakePool } from '../utils/tinlake/useTinlakePools' import { useListedPools } from '../utils/useListedPools' import { useMetadataMulti } from '../utils/useMetadata' import { PoolCard, PoolCardProps } from './PoolCard' +import { PoolListView } from './PoolCard/PoolListView' import { PoolStatusKey } from './PoolCard/PoolStatus' import { filterPools } from './PoolFilter/utils' @@ -118,10 +119,10 @@ export function PoolList() { function ArchivedPools({ pools }: { pools: PoolCardProps[] }) { return ( - + {pools.map((pool) => ( - + ))} diff --git a/centrifuge-app/src/config.ts b/centrifuge-app/src/config.ts index e4e0f0d1e9..03d72cb7df 100644 --- a/centrifuge-app/src/config.ts +++ b/centrifuge-app/src/config.ts @@ -104,7 +104,7 @@ export const ethConfig = { chainId: 1, poolRegistryAddress: '0xcA11bde05977b3631167028862bE2a173976CA11', tinlakeUrl: 'https://tinlake.centrifuge.io', - poolsHash: 'QmaMA1VYSKuuYhBcQCyf5Ek4VoiiEG6oLGp3iGbsQPGpkS', // TODO: add registry to config and fetch poolHash + poolsHash: 'QmXJZjBMvW8Qgqt82zAbAKYSBV5u91JsC8uHfF2eR2uAZA', // TODO: add registry to config and fetch poolHash blockExplorerUrl: 'https://etherscan.io', network: ethNetwork, multicallContractAddress: '0xcA11bde05977b3631167028862bE2a173976CA11', // Same for all networks diff --git a/centrifuge-app/src/pages/Pool/Assets/index.tsx b/centrifuge-app/src/pages/Pool/Assets/index.tsx index b9ebfc843e..ffc089c64a 100644 --- a/centrifuge-app/src/pages/Pool/Assets/index.tsx +++ b/centrifuge-app/src/pages/Pool/Assets/index.tsx @@ -132,7 +132,7 @@ export function PoolDetailAssets() { - + ) diff --git a/centrifuge-app/src/pages/Pools.tsx b/centrifuge-app/src/pages/Pools.tsx index 0b734ca111..1d938c1c65 100644 --- a/centrifuge-app/src/pages/Pools.tsx +++ b/centrifuge-app/src/pages/Pools.tsx @@ -1,12 +1,12 @@ -import { formatBalance } from '@centrifuge/centrifuge-react' import { Box, Stack, Text } from '@centrifuge/fabric' import * as React from 'react' +import { Dec } from '../../src/utils/Decimal' +import { formatBalance } from '../../src/utils/formatting' import { useListedPools } from '../../src/utils/useListedPools' import { LayoutSection } from '../components/LayoutBase/LayoutSection' import { PoolList } from '../components/PoolList' import { prefetchRoute } from '../components/Root' import { config } from '../config' -import { Dec } from '../utils/Decimal' export default function PoolsPage() { const [, listedTokens] = useListedPools() diff --git a/centrifuge-app/src/utils/useListedPools.ts b/centrifuge-app/src/utils/useListedPools.ts index 48f69decc9..a215e76441 100644 --- a/centrifuge-app/src/utils/useListedPools.ts +++ b/centrifuge-app/src/utils/useListedPools.ts @@ -8,6 +8,7 @@ import { useMetadataMulti } from '../utils/useMetadata' import { usePermissions } from '../utils/usePermissions' import { usePools } from '../utils/usePools' import { Dec } from './Decimal' +import { formatBalanceAbbreviated } from './formatting' import { getPoolTVL } from './getPoolTVL' import { useTinlakePools } from './tinlake/useTinlakePools' import { useSubquery } from './useSubquery' @@ -17,6 +18,13 @@ type FlattenedDataItem = { decimals: number } +type Pool = { + sumBorrowedAmount: CurrencyBalance + currency: { + decimals: number + } +} + const sign = (n: BN) => (n.isZero() ? 0 : n.isNeg() ? -1 : 1) export function useListedPools() { @@ -129,3 +137,27 @@ export function useYearOverYearGrowth() { return { totalYoyGrowth, isLoading } } + +export function useTotalAssetsFinanced() { + const { data, isLoading } = useSubquery( + `query { + pools { + nodes { + sumBorrowedAmount + currency { + decimals + } + } + } + }` + ) + + const pools = data?.pools?.nodes + + const sumBorrowedAmount = pools?.reduce((accumulator: Decimal, pool: Pool) => { + const total = new CurrencyBalance(pool.sumBorrowedAmount || 0, pool.currency.decimals) + return accumulator.add(total.toDecimal()) + }, Dec(0)) + + return { sumBorrowedAmount: formatBalanceAbbreviated(sumBorrowedAmount || 0), isLoading } +}