Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: all circular imports fixed #1358

Merged
merged 9 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: conflict resolved
  • Loading branch information
stackedq committed Mar 31, 2022
commit 2617af70a525a801f979324601d7a2d0082bd971
1 change: 1 addition & 0 deletions src/assets/translations/messages-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
"transactionComplete": "Transaction Complete",
"transactionFailed": "Transaction Failed",
"validator": "Validator",
"stakedAmount": "Staked Amount",
"unstakeFrom": "Unstake From",
"gasFee": "Gas Fee",
"unbondInfoItWillTake": "While your tokens are staked you will not be able to transfer or spend them. It will take %{unbondingDays} days to unlock them after you unstake them.",
Expand Down
182 changes: 171 additions & 11 deletions src/components/Delegate/StakingOpportunities.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,174 @@
import { ArrowForwardIcon } from '@chakra-ui/icons'
import { Button, HStack, Stack } from '@chakra-ui/react'
import {
Box,
Button,
Flex,
HStack,
Skeleton,
SkeletonCircle,
Tag,
TagLabel
} from '@chakra-ui/react'
import { CAIP19 } from '@shapeshiftoss/caip'
import { AprTag } from 'plugins/cosmos/components/AprTag/AprTag'
import { StakingAction } from 'plugins/cosmos/components/modals/Staking/StakingCommon'
import { MouseEvent } from 'react'
import { useMemo } from 'react'
import { NavLink } from 'react-router-dom'
import { Column } from 'react-table'
import { Amount } from 'components/Amount/Amount'
import { AssetIcon } from 'components/AssetIcon'
import { Card } from 'components/Card/Card'
import { Text } from 'components/Text'
import { ReactTable } from 'components/ReactTable/ReactTable'
import { RawText, Text } from 'components/Text'
import { useModal } from 'hooks/useModal/useModal'
import { BigNumber, bnOrZero } from 'lib/bignumber/bignumber'
import { selectAssetByCAIP19 } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

import { StakingOpportunitiesRow } from './StakingOpportunitiesRow'
type StakingOpportunity = {
id: number
moniker: string
apr: BigNumber
cryptoAmount?: BigNumber
rewards: Rewards
}

type Rewards = {
fiatRate: BigNumber
stakedRewards?: BigNumber
}

type StakingOpportunitiesProps = {
assetId: CAIP19
opportunities: StakingOpportunity[]
}

type ValidatorNameProps = {
moniker: string
isStaking: boolean
}

export const ValidatorName = ({ moniker, isStaking }: ValidatorNameProps) => {
const isLoaded = true
const assetIcon = isStaking
? 'https://assets.coincap.io/assets/icons/eth@2x.png'
: 'https://assets.coingecko.com/coins/images/16724/small/osmo.png?1632763885'

export const StakingOpportunities = () => {
// TODO: wire up with real validator data
const validators = [{ id: 1, name: 'Cosmos Validator' }]
return (
<Box cursor='pointer'>
<Flex alignItems='center' maxWidth='180px' mr={'-20px'}>
<SkeletonCircle boxSize='8' isLoaded={isLoaded} mr={4}>
<AssetIcon src={assetIcon} boxSize='8' />
</SkeletonCircle>
<Skeleton isLoaded={isLoaded} cursor='pointer'>
{isStaking && (
<Tag colorScheme='blue'>
<TagLabel>{moniker}</TagLabel>
</Tag>
)}
{!isStaking && <RawText fontWeight='bold'>{`${moniker}`}</RawText>}
</Skeleton>
</Flex>
</Box>
)
}

export const StakingOpportunities = ({ assetId, opportunities }: StakingOpportunitiesProps) => {
const isLoaded = true
const isStaking = opportunities.some(x => x.cryptoAmount)
const assetSymbol = useAppSelector(state => selectAssetByCAIP19(state, assetId)).symbol

const { cosmosGetStarted, cosmosStaking } = useModal()

const handleGetStartedClick = (e: MouseEvent<HTMLButtonElement>) => {
cosmosGetStarted.open({ assetId: 'cosmos:cosmoshub-4/slip44:118' })
e.stopPropagation()
}

const handleStakedClick = () => {
cosmosStaking.open({ assetId: 'cosmos:cosmoshub-4/slip44:118', action: StakingAction.Overview })
}

const columns: Column<StakingOpportunity>[] = useMemo(
() => [
{
Header: <Text translation='defi.validator' />,
accessor: 'moniker',
display: { base: 'table-cell' },
Cell: ({ value }: { value: string }) => (
<ValidatorName moniker={value} isStaking={isStaking} />
),
disableSortBy: true
},
{
Header: <Text translation='defi.apr' />,
accessor: 'apr',
display: { base: 'table-cell' },
Cell: ({ value }: { value: string }) => (
<Skeleton isLoaded={isLoaded}>
<AprTag percentage={value} showAprSuffix />
</Skeleton>
),
disableSortBy: true
},
{
Header: <Text translation='defi.stakedAmount' />,
accessor: 'cryptoAmount',
isNumeric: true,
display: { base: 'table-cell' },
Cell: ({ value }: { value: BigNumber }) => {
return isStaking ? (
<Amount.Crypto
value={bnOrZero(value).toString()}
symbol={assetSymbol}
color='white'
fontWeight={'normal'}
/>
) : (
<Box minWidth={{ base: '0px', md: '200px' }} />
)
},
disableSortBy: true
},
{
Header: <Text translation='defi.rewards' />,
accessor: 'rewards',
display: { base: 'table-cell' },
Cell: ({ value }: { value: Rewards }) => {
return isStaking ? (
<HStack fontWeight={'normal'}>
<Amount.Crypto
value={bnOrZero(value.stakedRewards).toString()}
symbol={assetSymbol}
/>
<Amount.Fiat
value={bnOrZero(value.stakedRewards).times(value.fiatRate).toPrecision()}
color='green.500'
prefix='≈'
/>
</HStack>
) : (
<Button
onClick={handleGetStartedClick}
as='span'
colorScheme='blue'
variant='ghost-filled'
size='sm'
cursor='pointer'
>
<Text translation='common.getStarted' />
</Button>
)
},
disableSortBy: true
}
],
// React-tables requires the use of a useMemo
// but we do not want it to recompute the values onClick
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
)
return (
<Card>
<Card.Header flexDir='row' display='flex'>
Expand All @@ -24,11 +183,12 @@ export const StakingOpportunities = () => {
</HStack>
</Card.Header>
<Card.Body pt={0}>
<Stack spacing={2} mt={2} mx={-4}>
{validators.map(validator => (
<StakingOpportunitiesRow name={validator.name} key={validator.id} />
))}
</Stack>
<ReactTable
data={opportunities}
columns={columns}
displayHeaders={isStaking}
onRowClick={handleStakedClick}
/>
</Card.Body>
</Card>
)
Expand Down
73 changes: 0 additions & 73 deletions src/components/Delegate/StakingOpportunitiesRow.tsx

This file was deleted.

16 changes: 12 additions & 4 deletions src/components/ReactTable/ReactTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@ import { Column, TableState, useSortBy, useTable } from 'react-table'
type ReactTableProps = {
columns: Column<any>[]
data: object[]
displayHeaders?: boolean
onRowClick?: () => void
initialState?: Partial<TableState<object>>
}

export const ReactTable = ({ columns, data, initialState }: ReactTableProps) => {
export const ReactTable = ({
columns,
data,
displayHeaders = true,
onRowClick,
initialState
}: ReactTableProps) => {
const hoverColor = useColorModeValue('black', 'white')
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(
{
Expand All @@ -23,7 +31,7 @@ export const ReactTable = ({ columns, data, initialState }: ReactTableProps) =>
return rows.map(row => {
prepareRow(row)
return (
<Tr {...row.getRowProps()} tabIndex={row.index}>
<Tr {...row.getRowProps()} tabIndex={row.index} onClick={() => onRowClick && onRowClick()}>
{row.cells.map(cell => (
<Td {...cell.getCellProps()} display={cell.column.display}>
{cell.render('Cell')}
Expand All @@ -32,7 +40,7 @@ export const ReactTable = ({ columns, data, initialState }: ReactTableProps) =>
</Tr>
)
})
}, [prepareRow, rows])
}, [prepareRow, rows, onRowClick])

return (
<Table variant='clickable' {...getTableProps()}>
Expand All @@ -48,7 +56,7 @@ export const ReactTable = ({ columns, data, initialState }: ReactTableProps) =>
_hover={{ color: column.canSort ? hoverColor : 'gray.500' }}
>
<Flex justifyContent={column.justifyContent} alignItems={column.alignItems}>
{column.render('Header')}
{displayHeaders && column.render('Header')}
<Flex>
{column.isSorted ? (
column.isSortedDesc ? (
Expand Down
30 changes: 29 additions & 1 deletion src/plugins/cosmos/CosmosAssetAccountDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { AssetHeader } from 'components/AssetHeader/AssetHeader'
import { StakingOpportunities } from 'components/Delegate/StakingOpportunities'
import { Main } from 'components/Layout/Main'
import { AssetTransactionHistory } from 'components/TransactionHistory/AssetTransactionHistory'
import { bn } from 'lib/bignumber/bignumber'
import { AccountSpecifier } from 'state/slices/accountSpecifiersSlice/accountSpecifiersSlice'

import { AssetChart } from '../../components/AssetHeader/AssetChart'
Expand All @@ -22,6 +23,31 @@ type AssetDetailsProps = {

export const CosmosAssetAccountDetails = ({ assetId: caip19, accountId }: AssetDetailsProps) => {
const cosmosInvestorFlag = useAppSelector(state => selectFeatureFlag(state, 'CosmosInvestor'))

// TODO: wire up with real validator data
const stakingOpportunities = [
{ id: 1, moniker: 'Cosmos Validator', apr: bn(0.12), rewards: { fiatRate: bn(0.08) } },
{
id: 2,
moniker: 'Cosmos Validator',
apr: bn(0.13),
cryptoAmount: bn('1234'),
rewards: {
fiatRate: bn(0.08),
stakedRewards: bn('12')
}
},
{
id: 3,
moniker: 'Cosmos Validator',
apr: bn(0.14),
cryptoAmount: bn('789123'),
rewards: {
fiatRate: bn(0.08),
stakedRewards: bn('345')
}
}
]
return (
<Main titleComponent={<AssetHeader assetId={caip19} accountId={accountId} />}>
<Stack
Expand All @@ -34,7 +60,9 @@ export const CosmosAssetAccountDetails = ({ assetId: caip19, accountId }: AssetD
<AssetChart accountId={accountId} assetId={caip19} isLoaded={true} />
{accountId && <AccountAssets assetId={caip19} accountId={accountId} />}
<AssetAccounts assetId={caip19} accountId={accountId} />
{cosmosInvestorFlag && <StakingOpportunities />}
{cosmosInvestorFlag && (
<StakingOpportunities assetId={caip19} opportunities={stakingOpportunities} />
)}
<AssetTransactionHistory assetId={caip19} accountId={accountId} />
</Stack>
<Stack flex='1 1 0%' width='full' maxWidth={{ base: 'full', xl: 'sm' }} spacing={4}>
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.