Skip to content

Commit

Permalink
feat(app): download history data buttons (#414)
Browse files Browse the repository at this point in the history
  • Loading branch information
kingsleydon authored May 9, 2024
1 parent e840084 commit 06f5acf
Show file tree
Hide file tree
Showing 27 changed files with 429 additions and 191 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
"fortawesome",
"karura",
"khala",
"lefthook",
"moonbase",
"moonriver",
"movr",
"orml",
"parachain",
"phala",
"polkadot",
"preinstall",
"readystate",
"roboto",
"staker",
Expand Down
15 changes: 15 additions & 0 deletions apps/app/components/BasePool/DetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {useAtom} from 'jotai'
import {type FC, useCallback, useMemo, useState} from 'react'
import DelegationChart from '../Delegation/Chart'
import Withdraw from '../Delegation/Withdraw'
import DownloadHistory from '../DownloadHistory'
import Empty from '../Empty'
import PromiseButton from '../PromiseButton'
import SectionHeader from '../SectionHeader'
Expand Down Expand Up @@ -292,6 +293,12 @@ const DetailPage: FC<{basePool: BasePoolCommonFragment}> = ({basePool}) => {
</TabPanel>
))}
</TabContext>
<DownloadHistory
kind="pool"
id={basePool.pid}
sx={{alignSelf: 'flex-end'}}
color={color}
/>
</Stack>
</Paper>
</Stack>
Expand Down Expand Up @@ -364,6 +371,14 @@ const DetailPage: FC<{basePool: BasePoolCommonFragment}> = ({basePool}) => {
<DelegationChart delegation={delegation} />
)}
</Box>
{delegation != null && (
<DownloadHistory
sx={{alignSelf: 'flex-end'}}
kind="delegation"
id={delegation.id}
color={color}
/>
)}
<DelegateInput basePool={basePool} sx={{mt: 1}} />
</Stack>
</Stack>
Expand Down
81 changes: 25 additions & 56 deletions apps/app/components/Delegation/HorizonCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import VaultIcon from '@/assets/vault_detailed.svg'
import Property from '@/components/Property'
import useDelegationOneDayProfit from '@/hooks/useDelegationOneDayProfit'
import useGetApr from '@/hooks/useGetApr'
import usePolkadotApi from '@/hooks/usePolkadotApi'
import useSignAndSend from '@/hooks/useSignAndSend'
import {aprToApy} from '@/lib/apr'
import getPoolPath from '@/lib/getPoolPath'
import type {DelegationCommonFragment} from '@/lib/subsquidQuery'
Expand All @@ -13,8 +11,6 @@ import {chainAtom} from '@/store/common'
import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'
import {
Box,
Button,
Chip,
Link,
Paper,
Skeleton,
Expand All @@ -27,56 +23,23 @@ import {toCurrency, toPercentage} from '@phala/lib'
import {useAtom} from 'jotai'
import type {FC} from 'react'
import Identity from '../BasePool/Identity'
import PromiseButton from '../PromiseButton'
import WrapDecimal from '../WrapDecimal'
import type {OnAction} from './List'
import DelegationMenu from './Menu'

const HorizonCard: FC<{
delegation: DelegationCommonFragment
onAction: OnAction
isOwner?: boolean
}> = ({delegation, onAction, isOwner = false}) => {
const profit = useDelegationOneDayProfit(delegation.id)
const api = usePolkadotApi()
const signAndSend = useSignAndSend()
const {value, basePool, withdrawingValue} = delegation
const isVault = basePool.kind === 'Vault'
const [chain] = useAtom(chainAtom)
const theme = useTheme()
const getApr = useGetApr()
const apr = getApr(basePool.aprMultiplier)
const hasWithdrawal = withdrawingValue !== '0'
const poolHasWithdrawal = delegation.basePool.withdrawingShares !== '0'
const reclaim = async (): Promise<void> => {
if (api == null) return
await signAndSend(
isVault
? api.tx.phalaVault.checkAndMaybeForceWithdraw(basePool.id)
: api.tx.phalaStakePoolv2.checkAndMaybeForceWithdraw(basePool.id),
)
}

const actions = isOwner && (
<Stack direction="row" alignItems="center">
<Button
size="small"
variant="text"
onClick={() => {
onAction(delegation, 'withdraw')
}}
>
Withdraw
</Button>
<PromiseButton
size="small"
variant="text"
onClick={reclaim}
disabled={!poolHasWithdrawal}
>
Reclaim
</PromiseButton>
</Stack>
)

return (
<Paper
Expand All @@ -96,7 +59,7 @@ const HorizonCard: FC<{
<VaultIcon color={colors.vault[400]} />
)}
</Box>
<Stack flex="1 0" width={120}>
<Stack flex="1 0" width={130}>
<Link
lineHeight={1.3}
onClick={(e) => {
Expand All @@ -114,14 +77,19 @@ const HorizonCard: FC<{
<Identity {...basePool.owner} />
</Stack>
</Stack>
<Stack direction="row" spacing={{xs: 1, md: 2}} alignItems="center">
<Stack
direction="row"
spacing={{xs: 1, md: 2}}
alignItems="center"
flex={1}
>
<Property
label="Value"
sx={{width: 130}}
wikiEntry="nftValue"
>{`${toCurrency(value)} PHA`}</Property>
{profit != null && (
<Property label="1d" sx={{width: 100}} wikiEntry="oneDayRewards">
<Property label="1d" sx={{width: 110}} wikiEntry="oneDayRewards">
<Stack
direction="row"
alignItems="center"
Expand All @@ -143,7 +111,7 @@ const HorizonCard: FC<{
)}
<Property
label={`Est. ${isVault ? 'APY' : 'APR'}`}
sx={{width: 80}}
sx={{width: 90}}
wikiEntry="estApr"
>
{apr != null ? (
Expand All @@ -164,24 +132,25 @@ const HorizonCard: FC<{
>{`${toCurrency(delegation.basePool.freeValue)} PHA`}</Property>
{hasWithdrawal && (
<Property
label="Withdrawing"
label={
<Box
component="span"
sx={(theme) => ({color: theme.palette.warning.dark})}
>
Withdrawing
</Box>
}
sx={{width: 120}}
wikiEntry="withdrawing"
>{`${toCurrency(withdrawingValue)} PHA`}</Property>
)}
</Stack>

<Stack flex="1" alignItems="flex-end" justifyContent="space-between">
<Stack direction="row" height="24px">
{hasWithdrawal && (
<Chip
label="Withdrawing"
size="small"
sx={{color: theme.palette.warning.dark}}
/>
)}
</Stack>
{actions}
{isOwner && (
<DelegationMenu
delegation={delegation}
onAction={onAction}
sx={{ml: 'auto!important'}}
/>
)}
</Stack>
</Stack>
</Paper>
Expand Down
87 changes: 87 additions & 0 deletions apps/app/components/Delegation/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import usePolkadotApi from '@/hooks/usePolkadotApi'
import useSignAndSend from '@/hooks/useSignAndSend'
import type {DelegationCommonFragment} from '@/lib/subsquidQuery'
import {chainAtom} from '@/store/common'
import MoreVert from '@mui/icons-material/MoreVert'
import {
IconButton,
Menu,
MenuItem,
type SxProps,
type Theme,
} from '@mui/material'
import {useAtom} from 'jotai'
import {type FC, useRef, useState} from 'react'
import type {OnAction} from './List'

const DelegationMenu: FC<{
onAction?: OnAction
delegation: DelegationCommonFragment
sx?: SxProps<Theme>
}> = ({delegation, onAction, sx}) => {
const api = usePolkadotApi()
const signAndSend = useSignAndSend()
const {basePool} = delegation
const [chain] = useAtom(chainAtom)
const [menuOpen, setMenuOpen] = useState(false)
const moreRef = useRef(null)
const poolHasWithdrawal = delegation.basePool.withdrawingShares !== '0'
const isVault = basePool.kind === 'Vault'
const reclaim = async (): Promise<void> => {
if (api == null) return
await signAndSend(
isVault
? api.tx.phalaVault.checkAndMaybeForceWithdraw(basePool.id)
: api.tx.phalaStakePoolv2.checkAndMaybeForceWithdraw(basePool.id),
)
}

return (
<>
<IconButton
ref={moreRef}
onClick={() => {
setMenuOpen(true)
}}
sx={sx}
>
<MoreVert />
</IconButton>
<Menu
open={menuOpen}
anchorEl={moreRef.current}
onClose={() => {
setMenuOpen(false)
}}
>
<MenuItem
onClick={() => {
onAction?.(delegation, 'withdraw')
setMenuOpen(false)
}}
>
Withdraw
</MenuItem>
<MenuItem
disabled={!poolHasWithdrawal}
onClick={() => {
void reclaim()
setMenuOpen(false)
}}
>
Reclaim
</MenuItem>
<MenuItem
onClick={() => {
location.href = `/api/${chain}/snapshots/delegation/${delegation.id}`
setMenuOpen(false)
}}
>
Download history data
</MenuItem>
</Menu>
</>
)
}

export default DelegationMenu
Loading

0 comments on commit 06f5acf

Please sign in to comment.