Skip to content

Commit

Permalink
Add table
Browse files Browse the repository at this point in the history
  • Loading branch information
kattylucy committed Feb 12, 2025
1 parent 3c735f1 commit 5a37f28
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 18 deletions.
129 changes: 127 additions & 2 deletions centrifuge-app/src/components/Dashboard/DashboardTable.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,130 @@
import { Pool } from '@centrifuge/centrifuge-js'
import { CurrencyBalance, Pool, Token } from '@centrifuge/centrifuge-js'
import { useCentrifuge } from '@centrifuge/centrifuge-react'
import { Box, Divider, Grid, Text } from '@centrifuge/fabric'
import Decimal from 'decimal.js-light'
import { useMemo } from 'react'
import { useTheme } from 'styled-components'
import { Dec } from '../../../src/utils/Decimal'
import { formatBalance } from '../../../src/utils/formatting'
import { DataTable, SortableTableHeader } from '../DataTable'
import { useGetPoolsMetadata } from './assets/utils'
import { calculateApyPerToken } from './utils'

export type Row = {
poolIcon: string
poolName: string
tranches: {
tranchetoken: string
apy: string
navPerToken: CurrencyBalance
valueLocked: Decimal
}[]
}

export function DashboardTable({ filteredPools }: { filteredPools: Pool[] }) {
return <div>DashboardTable</div>
const theme = useTheme()
const cent = useCentrifuge()
const pools = useGetPoolsMetadata(filteredPools || [])

const data = useMemo(() => {
return pools.map((pool) => {
return {
poolIcon: cent.metadata.parseMetadataUrl(pool.meta?.pool?.icon?.uri),
poolName: pool.meta?.pool?.name,
tranches: pool.tranches.map((token: Token) => ({
tranchetoken: token.currency.displayName,
apy: calculateApyPerToken(token, pool),
navPerToken: token.tokenPrice,
valueLocked: token?.tokenPrice ? token.totalIssuance.toDecimal().mul(token.tokenPrice.toDecimal()) : Dec(0),
})),
}
})
}, [pools])

Check warning on line 42 in centrifuge-app/src/components/Dashboard/DashboardTable.tsx

View workflow job for this annotation

GitHub Actions / build-app

React Hook useMemo has a missing dependency: 'cent.metadata'. Either include it or remove the dependency array

Check warning on line 42 in centrifuge-app/src/components/Dashboard/DashboardTable.tsx

View workflow job for this annotation

GitHub Actions / deploy-ff-prod / build-app

React Hook useMemo has a missing dependency: 'cent.metadata'. Either include it or remove the dependency array

const columns = useMemo(() => {
return [
{
header: 'Pool',
align: 'left',
cell: ({ poolName, poolIcon }: Row) => {
return (
<Box display="flex" alignItems="center">
{poolIcon && <Box as="img" src={poolIcon} alt="" height={24} width={24} borderRadius={4} mr={1} />}
<Text style={{ fontWeight: 500 }} variant="body3">
{poolName}
</Text>
</Box>
)
},
},
{
header: 'Tranche',
cell: ({ tranches }: Row) => {
return (
<Grid gap={2}>
{tranches.map((tranche, index) => (
<Box key={index}>
<Text variant="body3">{tranche.tranchetoken}</Text>
</Box>
))}
</Grid>
)
},
},
{
header: <SortableTableHeader label="APY" />,
sortKey: 'tranches.apy',
cell: ({ tranches }: Row) => {
return (
<Grid gap={2}>
{tranches.map((tranche, index) => (
<Box key={index}>
<Text variant="body3">{tranche.apy}</Text>
</Box>
))}
</Grid>
)
},
},
{
header: <SortableTableHeader label="NAV (USDC)" />,
sortKey: 'tranches.valueLocked',
cell: ({ tranches }: Row) => {
return (
<Grid gap={2}>
{tranches.map((tranche, index) => (
<Box key={index}>
<Text variant="body3">{tranche.valueLocked ? formatBalance(tranche.valueLocked) : '-'}</Text>
</Box>
))}
</Grid>
)
},
},
{
header: <SortableTableHeader label="NAV per share" />,
sortKey: 'tranches.navPerToken',
cell: ({ tranches }: Row) => {
return (
<Grid gap={2}>
{tranches.map((tranche, index) => (
<Box key={index}>
<Text variant="body3">{tranche.navPerToken ? formatBalance(tranche.navPerToken) : '-'}</Text>
</Box>
))}
</Grid>
)
},
},
]
}, [pools])

Check warning on line 120 in centrifuge-app/src/components/Dashboard/DashboardTable.tsx

View workflow job for this annotation

GitHub Actions / build-app

React Hook useMemo has an unnecessary dependency: 'pools'. Either exclude it or remove the dependency array

Check warning on line 120 in centrifuge-app/src/components/Dashboard/DashboardTable.tsx

View workflow job for this annotation

GitHub Actions / deploy-ff-prod / build-app

React Hook useMemo has an unnecessary dependency: 'pools'. Either exclude it or remove the dependency array

if (!pools.length) return <Text variant="heading4">No data available</Text>

return (
<Box>
<DataTable data={data || []} columns={columns} scrollable hideBorder hideHeader />
<Divider color={theme.colors.backgroundSecondary} />
</Box>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import { Box, Divider, Drawer, Select } from '@centrifuge/fabric'
import { BN } from 'bn.js'
import { Field, FieldProps, Form, FormikProvider, useFormik } from 'formik'
import { useMemo, useState } from 'react'
import { useState } from 'react'
import { Navigate } from 'react-router'
import { firstValueFrom, lastValueFrom, switchMap } from 'rxjs'
import { LoadBoundary } from '../../../../src/components/LoadBoundary'
Expand All @@ -32,7 +32,7 @@ import {
import { CreateAssetsForm } from './CreateAssetForm'
import { FooterActionButtons } from './FooterActionButtons'
import { UploadAssetTemplateForm } from './UploadAssetTemplateForm'
import { usePoolMetadataMap, valuesToNftProperties } from './utils'
import { useGetPoolsMetadata, valuesToNftProperties } from './utils'

export type PoolWithMetadata = Pool & { meta: PoolMetadata }

Expand Down Expand Up @@ -77,23 +77,11 @@ export function CreateAssetsDrawer({ open, setOpen, type, setType }: CreateAsset
const api = useCentrifugeApi()
const centrifuge = useCentrifuge()
const filteredPools = useFilterPoolsByUserRole(type === 'upload-template' ? ['PoolAdmin'] : ['Borrower', 'PoolAdmin'])
const metas = usePoolMetadataMap(filteredPools || [])
const poolsMetadata = useGetPoolsMetadata(filteredPools || [])
const [isUploadingTemplates, setIsUploadingTemplates] = useState(false)
const [redirect, setRedirect] = useState<string | null>(null)
const [isLoading, setIsLoading] = useState(false)

const poolsMetadata = useMemo(() => {
return (
filteredPools?.map((pool) => {
const meta = metas.get(pool.id)
return {
...pool,
meta,
}
}) || []
)
}, [filteredPools, metas])

const [pid, setPid] = useState<string>(poolsMetadata[0].id)
const [account] = useSuitableAccounts({ poolId: pid, poolRole: ['Borrower'], proxyType: ['Borrow'] })
const { assetOriginators } = usePoolAccess(pid)
Expand Down
13 changes: 13 additions & 0 deletions centrifuge-app/src/components/Dashboard/assets/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,19 @@ export function usePoolMetadataMap(pools: Pool[]) {
return poolMetadataMap
}

export function useGetPoolsMetadata(pools: Pool[]) {
const metas = usePoolMetadataMap(pools)
return (
pools?.map((pool) => {
const meta = metas.get(pool.id)
return {
...pool,
meta,
}
}) || []
)
}

export function valuesToNftProperties(values: CreateAssetFormValues['attributes'], template: LoanTemplate) {
return Object.fromEntries(
template.sections.flatMap((section) =>
Expand Down
26 changes: 25 additions & 1 deletion centrifuge-app/src/components/Dashboard/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { CurrencyBalance, Pool } from '@centrifuge/centrifuge-js'
import { CurrencyBalance, Perquintill, Pool, Token } from '@centrifuge/centrifuge-js'
import Decimal from 'decimal.js-light'
import { useMemo } from 'react'
import { daysBetween } from '../../../src/utils/date'
import { formatPercentage } from '../../../src/utils/formatting'
import { Dec } from '../../utils/Decimal'
import { useSubquery } from '../../utils/useSubquery'
import { CentrifugeTargetAPYs, DYF_POOL_ID, NS3_POOL_ID, centrifugeTargetAPYs } from '../PoolCard'

type FlattenedDataItem = {
netAssetValue: string
Expand Down Expand Up @@ -90,3 +93,24 @@ export function useNavGrowth(pools: Pool[], period: 'YTD' | '90d' | '180d') {

return { growth, isLoading }
}

const getTrancheText = (trancheToken: Token) => {
if (trancheToken.seniority === 0) return 'junior'
if (trancheToken.seniority === 1) return 'senior'
return 'mezzanine'
}

export const calculateApyPerToken = (trancheToken: Token, pool: Pool) => {
const daysSinceCreation = pool?.createdAt ? daysBetween(new Date(pool.createdAt), new Date()) : 0
const poolId = pool.id
if (getTrancheText(trancheToken) === 'senior')
return formatPercentage(trancheToken?.interestRatePerSec ? trancheToken?.interestRatePerSec.toAprPercent() : Dec(0))
if (trancheToken.seniority === 0) return '15%'
if (poolId === DYF_POOL_ID) return centrifugeTargetAPYs[poolId as CentrifugeTargetAPYs][0]
if (poolId === NS3_POOL_ID && trancheToken.seniority === 0)
return centrifugeTargetAPYs[poolId as CentrifugeTargetAPYs][0]
if (poolId === NS3_POOL_ID && trancheToken.seniority === 1)
return centrifugeTargetAPYs[poolId as CentrifugeTargetAPYs][1]
if (daysSinceCreation < 30) return 'N/A'
return trancheToken.yieldSinceInception ? formatPercentage(new Perquintill(trancheToken.yieldSinceInception)) : '-'
}
4 changes: 4 additions & 0 deletions centrifuge-app/src/components/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export type DataTableProps<T = any> = {
page?: number
hideHeader?: boolean
hideBorder?: boolean
rowProps?: React.HTMLAttributes<HTMLDivElement>
} & GroupedProps

export type OrderBy = 'asc' | 'desc'
Expand Down Expand Up @@ -103,6 +104,7 @@ export const DataTable = <T extends Record<string, any>>({
hideHeader,
scrollable = false,
hideBorder,
rowProps,
}: DataTableProps<T>) => {
const theme = useTheme()
const tableRef = React.useRef<HTMLDivElement>(null)
Expand Down Expand Up @@ -185,6 +187,7 @@ export const DataTable = <T extends Record<string, any>>({
key={keyField ? row[keyField] : i}
tabIndex={onRowClicked ? 0 : undefined}
hideBorder={hideBorder}
{...rowProps}
>
{columns.map((col, index) => (
<DataCol variant="body2" align={col?.align} key={index} isLabel={col.isLabel}>
Expand All @@ -203,6 +206,7 @@ export const DataTable = <T extends Record<string, any>>({
key={keyField ? row[keyField] : i}
tabIndex={onRowClicked ? 0 : undefined}
hideBorder={hideBorder}
{...rowProps}
>
{columns.map((col, index) => (
<DataCol
Expand Down

0 comments on commit 5a37f28

Please sign in to comment.