Skip to content

Commit

Permalink
Add UI for portfolio overview chart and card
Browse files Browse the repository at this point in the history
  • Loading branch information
sophialittlejohn authored and JP Angelle committed Oct 31, 2023
1 parent 3ae0643 commit 1ccbf50
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 4 deletions.
99 changes: 99 additions & 0 deletions centrifuge-app/src/components/Portfolio/CardPortfolioValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { Box, Stack, Text, TextWithPlaceholder, Tooltip } from '@centrifuge/fabric'
import * as React from 'react'
import { useTheme } from 'styled-components'
import { config } from '../../config'
import { formatDate } from '../../utils/date'
import { Dec } from '../../utils/Decimal'
import { formatBalance } from '../../utils/formatting'
import { useListedPools } from '../../utils/useListedPools'
import { tooltipText } from './../Tooltips'
import { DataPoint, PortfolioValue } from './PortfolioValue'

export function CardPortfolioValue() {
const { colors } = useTheme()
const [hovered, setHovered] = React.useState<DataPoint | undefined>(undefined)
const [, listedTokens] = useListedPools()

const chartHeight = 130
const balanceProps = {
as: 'strong',
fontSize: [16, 18],
}
const headingProps = {
as: 'p',
variant: 'body3',
}

const totalValueLocked = React.useMemo(() => {
return (
listedTokens
?.map((tranche) => ({
valueLocked: tranche.totalIssuance
.toDecimal()
.mul(tranche.tokenPrice?.toDecimal() ?? Dec(0))
.toNumber(),
}))
.reduce((prev, curr) => prev.add(curr.valueLocked), Dec(0)) ?? Dec(0)
)
}, [listedTokens])

return (
<Box position="relative">
<Box
role="article"
borderRadius="card"
borderStyle="solid"
borderWidth={1}
borderColor="borderSecondary"
p={3}
pb={chartHeight * 0.6}
style={{
boxShadow: `0px 3px 2px -2px ${colors.borderPrimary}`,
}}
background={colors.backgroundPage}
>
<Stack gap={2} style={{ pointerEvents: 'none' }}>
<Text variant="heading2">Portfolio Overview</Text>
<Stack>
{hovered ? (
<>
<Text {...headingProps}>
Portfolio value on{' '}
<time dateTime={new Date(hovered.dateInMilliseconds).toISOString()}>
{formatDate(hovered.dateInMilliseconds)}
</time>
</Text>
<Text {...balanceProps}>
{formatBalance(Dec(hovered?.dateInMilliseconds || 0), config.baseCurrency)}
</Text>
</>
) : (
<>
<Tooltip body={tooltipText.currentPortfolioValue.body} style={{ pointerEvents: 'auto' }}>
<Text {...headingProps}>{tooltipText.currentPortfolioValue.label}</Text>
</Tooltip>
<TextWithPlaceholder {...balanceProps} isLoading={!totalValueLocked}>
{formatBalance(Dec(totalValueLocked || 0), config.baseCurrency)}
</TextWithPlaceholder>
</>
)}
</Stack>
</Stack>

<Box
as="figure"
position="absolute"
right={0}
bottom={0}
width="100%"
height="100%"
overflow="hidden"
borderBottomRightRadius="card"
borderBottomLeftRadius="card"
>
<PortfolioValue setHovered={setHovered} />
</Box>
</Box>
</Box>
)
}
110 changes: 110 additions & 0 deletions centrifuge-app/src/components/Portfolio/PortfolioValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import * as React from 'react'
import { Area, AreaChart, ResponsiveContainer, Tooltip } from 'recharts'

export type DataPoint = {
dateInMilliseconds: number
}

type TotalValueLockedProps = {
setHovered: (entry: DataPoint | undefined) => void
}

export function PortfolioValue({ setHovered }: TotalValueLockedProps) {
// const portfolioValue = usePortfolioValue()
const chartColor = '#FFC72B'

// const chartData = React.useMemo(
// () => {
// return []
// },
// [ portfolioValue ]
// )

return (
<ResponsiveContainer>
<AreaChart
data={[
{
portfolioValue: 123809,
dateInMilliseconds: Date.now(),
},
{
portfolioValue: 123809,
dateInMilliseconds: Date.now() - 86400000, // 1 day ago
},
{
portfolioValue: 123809,
dateInMilliseconds: Date.now() - 86400000 * 2, // 2 days ago
},
{
portfolioValue: 2023480,
dateInMilliseconds: Date.now() - 86400000 * 3, // 3 days ago
},
{
portfolioValue: 3023480,
dateInMilliseconds: Date.now() - 86400000 * 4, // 4 days ago
},
{
portfolioValue: 4023480,
dateInMilliseconds: Date.now() - 86400000 * 5, // 5 days ago
},
{
portfolioValue: 7023480,
dateInMilliseconds: Date.now() - 86400000 * 6, // 6 days ago
},
]}
margin={{ top: 0, left: 0, right: 0, bottom: 0 }}
onMouseMove={(val: any) => {
if (val?.activePayload && val?.activePayload.length > 0) {
setHovered(val.activePayload[0].payload)
}
}}
onMouseLeave={() => {
setHovered(undefined)
}}
>
<defs>
<linearGradient id="colorPoolValue" x1="0" y1="0" x2="0" y2="1">
<stop offset="10%" stopColor={chartColor} stopOpacity={0.9} />
<stop offset="90%" stopColor={chartColor} stopOpacity={0.1} />
</linearGradient>
</defs>
<Area
type="monotone"
dataKey="portfolioValue"
strokeWidth={1}
fillOpacity={1}
fill="url(#colorPoolValue)"
name="Current Value Locked"
stroke={chartColor}
activeDot={{ fill: chartColor }}
/>
<Tooltip content={<></>} />
</AreaChart>
</ResponsiveContainer>
)
}

// function getMergedData(combined: DataPoint[], current?: DataPoint) {
// const mergedMap = new Map()

// combined.forEach((entry) => {
// const { dateInMilliseconds, tvl } = entry

// if (mergedMap.has(dateInMilliseconds)) {
// mergedMap.set(dateInMilliseconds, mergedMap.get(dateInMilliseconds).add(tvl))
// } else {
// mergedMap.set(dateInMilliseconds, tvl)
// }
// })

// if (current) {
// mergedMap.set(current.dateInMilliseconds, current.tvl)
// }

// const merged = Array.from(mergedMap, ([dateInMilliseconds, tvl]) => ({ dateInMilliseconds, tvl }))
// .sort((a, b) => a.dateInMilliseconds - b.dateInMilliseconds)
// .map((entry) => ({ ...entry, tvl: entry.tvl.toNumber() }))

// return merged
// }
4 changes: 4 additions & 0 deletions centrifuge-app/src/components/Tooltips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ export const tooltipText = {
label: 'Notional value',
body: 'The notional value is the total value of the underlying asset.',
},
currentPortfolioValue: {
label: 'Current portfolio value',
body: 'Bla bla bla.',
},
}

export type TooltipsProps = {
Expand Down
7 changes: 3 additions & 4 deletions centrifuge-app/src/pages/Portfolio/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Card, Grid, Stack, Text } from '@centrifuge/fabric'
import { Grid, Stack, Text } from '@centrifuge/fabric'
import * as React from 'react'
import { useTheme } from 'styled-components'
import { LayoutBase } from '../../components/LayoutBase'
import { BasePadding } from '../../components/LayoutBase/BasePadding'
import { PoolList } from '../../components/PoolList'
import { AssetAllocation } from '../../components/Portfolio/AssetAllocation'
import { CardPortfolioValue } from '../../components/Portfolio/CardPortfolioValue'
import { InvestedTokens } from '../../components/Portfolio/InvestedTokens'
import { Rewards } from '../../components/Portfolio/Rewards'
import { Transactions } from '../../components/Portfolio/Transactions'
Expand Down Expand Up @@ -43,9 +44,7 @@ function Portfolio() {
</Stack>

<Grid gridTemplateColumns={['1.5fr 1fr']} gap={4}>
<Card as="article" p={1}>
<Text as="h2">Portfolio overview</Text>
</Card>
<CardPortfolioValue />

<Rewards />
</Grid>
Expand Down

0 comments on commit 1ccbf50

Please sign in to comment.