mirror of
https://github.com/luxfi/market.git
synced 2026-09-24 00:25:57 +00:00
Add crypto currency components
This commit is contained in:
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { BigNumberish } from 'ethers'
|
||||
import { formatBN } from 'utils/numbers'
|
||||
import { FC } from 'react'
|
||||
import Flex from './primitives/Flex'
|
||||
import Text from './primitives/Text'
|
||||
|
||||
type Props = {
|
||||
amount: BigNumberish | null | undefined
|
||||
maximumFractionDigits?: number
|
||||
css?: Parameters<typeof Text>['0']['css']
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
const FormatCurrency: FC<Props> = ({
|
||||
amount,
|
||||
maximumFractionDigits = 4,
|
||||
css,
|
||||
children,
|
||||
}) => {
|
||||
const value = formatBN(amount, maximumFractionDigits)
|
||||
|
||||
return (
|
||||
<Flex align="center" css={{ gap: '$1' }}>
|
||||
{value !== '-' ? children : null}
|
||||
<Text style="subtitle2" css={css}>
|
||||
{value}
|
||||
</Text>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormatCurrency
|
||||
@@ -1,27 +0,0 @@
|
||||
import FormatCurrency from 'components/FormatCurrency'
|
||||
import { FC, ComponentProps } from 'react'
|
||||
|
||||
type FormatEthProps = {
|
||||
logoWidth?: number
|
||||
}
|
||||
|
||||
type Props = ComponentProps<typeof FormatCurrency> & FormatEthProps
|
||||
|
||||
const FormatEth: FC<Props> = ({
|
||||
amount,
|
||||
maximumFractionDigits,
|
||||
logoWidth = 8,
|
||||
css,
|
||||
}) => {
|
||||
return (
|
||||
<FormatCurrency
|
||||
css={css}
|
||||
amount={amount}
|
||||
maximumFractionDigits={maximumFractionDigits}
|
||||
>
|
||||
<img src="/eth.svg" alt="ETH logo" style={{ width: `${logoWidth}px` }} />
|
||||
</FormatCurrency>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormatEth
|
||||
@@ -1,31 +0,0 @@
|
||||
import FormatCurrency from 'components/FormatCurrency'
|
||||
import { FC, ComponentProps } from 'react'
|
||||
|
||||
type FormatWEthProps = {
|
||||
logoWidth?: number
|
||||
}
|
||||
|
||||
type Props = ComponentProps<typeof FormatCurrency> & FormatWEthProps
|
||||
|
||||
const FormatWEth: FC<Props> = ({
|
||||
amount,
|
||||
maximumFractionDigits,
|
||||
logoWidth = 8,
|
||||
css,
|
||||
}) => {
|
||||
return (
|
||||
<FormatCurrency
|
||||
css={css}
|
||||
amount={amount}
|
||||
maximumFractionDigits={maximumFractionDigits}
|
||||
>
|
||||
<img
|
||||
src="/weth.svg"
|
||||
alt="WETH logo"
|
||||
style={{ width: `${logoWidth}px` }}
|
||||
/>
|
||||
</FormatCurrency>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormatWEth
|
||||
@@ -1,8 +1,5 @@
|
||||
import { useCollections } from '@reservoir0x/reservoir-kit-ui'
|
||||
import Box from '../primitives/Box'
|
||||
import Flex from '../primitives/Flex'
|
||||
import Text from '../primitives/Text'
|
||||
import FormatEth from '../FormatEth'
|
||||
import { Text, Box, Flex, FormatCryptoCurrency } from '../primitives'
|
||||
import { formatNumber } from '../../utils/numbers'
|
||||
import Link from 'next/link'
|
||||
|
||||
@@ -29,7 +26,11 @@ const CollectionRow = ({ rank, collection }: CollectionRowProps) => {
|
||||
<Text css={{ mr: '$1', color: '$gray11' }} as="p" style="body2">
|
||||
Floor
|
||||
</Text>
|
||||
<FormatEth amount={collection?.floorAsk?.price?.amount?.native} />
|
||||
<FormatCryptoCurrency
|
||||
amount={collection?.floorAsk?.price?.amount?.decimal}
|
||||
address={collection?.floorAsk?.price?.currency?.contract}
|
||||
decimals={collection?.floorAsk?.price?.currency?.decimals}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
@@ -37,9 +38,8 @@ const CollectionRow = ({ rank, collection }: CollectionRowProps) => {
|
||||
<Text css={{ mb: 4, color: '$green10' }} style="body2" as="p">
|
||||
{formatNumber(collection?.volumeChange['7day'])}%
|
||||
</Text>
|
||||
|
||||
<FormatEth
|
||||
amount={collection?.volume['7day']}
|
||||
<FormatCryptoCurrency
|
||||
amount={collection.volume['7day']}
|
||||
maximumFractionDigits={1}
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import React, { FC } from 'react'
|
||||
import { useChainCurrency } from '../../hooks'
|
||||
import { constants } from 'ethers'
|
||||
import { styled } from '../../stitches.config'
|
||||
import { StyledComponent } from '@stitches/react/types/styled-component'
|
||||
import Box from './Box'
|
||||
import wrappedContracts from '../../utils/wrappedContracts'
|
||||
import { useReservoirClient } from '@reservoir0x/reservoir-kit-ui'
|
||||
|
||||
type Props = {
|
||||
address: string
|
||||
} & Parameters<StyledComponent>['0']
|
||||
|
||||
const StyledImg = styled('img', {})
|
||||
|
||||
const CryptoCurrencyIcon: FC<Props> = ({
|
||||
address = constants.AddressZero,
|
||||
css,
|
||||
}) => {
|
||||
const client = useReservoirClient()
|
||||
const chainCurrency = useChainCurrency()
|
||||
|
||||
if (chainCurrency.symbol === 'ETH') {
|
||||
if (constants.AddressZero === address) {
|
||||
return (
|
||||
<Box css={{ display: 'flex', ...css }}>
|
||||
<img src="/eth.svg" alt="ETH Logo" />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
const wrappedContractAddress = wrappedContracts[chainCurrency.chainId]
|
||||
if (
|
||||
wrappedContractAddress &&
|
||||
wrappedContractAddress.toLowerCase() == address.toLowerCase()
|
||||
) {
|
||||
return (
|
||||
<Box css={{ display: 'flex', ...css }}>
|
||||
<img src="/weth.svg" alt="WETH Logo" />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledImg
|
||||
src={`${client?.apiBase}/redirect/currency/${address}/icon/v1`}
|
||||
css={css}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default CryptoCurrencyIcon
|
||||
@@ -0,0 +1,36 @@
|
||||
import { BigNumberish } from 'ethers'
|
||||
import { formatBN } from '../../utils/numbers'
|
||||
import React, { FC } from 'react'
|
||||
import { Flex, Text } from './index'
|
||||
|
||||
type Props = {
|
||||
amount: BigNumberish | null | undefined
|
||||
maximumFractionDigits?: number
|
||||
decimals?: number
|
||||
css?: Parameters<typeof Text>['0']['css']
|
||||
textStyle?: Parameters<typeof Text>['0']['style']
|
||||
textColor?: Parameters<typeof Text>['0']['color']
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
const FormatCrypto: FC<Props> = ({
|
||||
amount,
|
||||
maximumFractionDigits = 4,
|
||||
decimals = 18,
|
||||
css,
|
||||
textStyle = 'subtitle2',
|
||||
textColor = 'base',
|
||||
children,
|
||||
}) => {
|
||||
const value = formatBN(amount, maximumFractionDigits, decimals)
|
||||
return (
|
||||
<Flex align="center" css={{ gap: '$1' }}>
|
||||
{value !== '-' ? children : null}
|
||||
<Text style={textStyle} color={textColor} css={css} as="p">
|
||||
{value}
|
||||
</Text>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormatCrypto
|
||||
@@ -0,0 +1,37 @@
|
||||
import FormatCrypto from './FormatCrypto'
|
||||
import React, { FC, ComponentProps } from 'react'
|
||||
import { constants } from 'ethers'
|
||||
import CryptoCurrencyIcon from './CryptoCurrencyIcon'
|
||||
|
||||
type FormatCryptoCurrencyProps = {
|
||||
logoWidth?: number
|
||||
address?: string
|
||||
}
|
||||
|
||||
type Props = ComponentProps<typeof FormatCrypto> & FormatCryptoCurrencyProps
|
||||
|
||||
const FormatCryptoCurrency: FC<Props> = ({
|
||||
amount,
|
||||
address = constants.AddressZero,
|
||||
maximumFractionDigits,
|
||||
logoWidth = 8,
|
||||
textStyle,
|
||||
css,
|
||||
textColor,
|
||||
decimals,
|
||||
}) => {
|
||||
return (
|
||||
<FormatCrypto
|
||||
css={css}
|
||||
textColor={textColor}
|
||||
textStyle={textStyle}
|
||||
amount={amount}
|
||||
maximumFractionDigits={maximumFractionDigits}
|
||||
decimals={decimals}
|
||||
>
|
||||
<CryptoCurrencyIcon css={{ height: logoWidth }} address={address} />
|
||||
</FormatCrypto>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormatCryptoCurrency
|
||||
@@ -0,0 +1,41 @@
|
||||
import React, { ComponentPropsWithoutRef, FC, useEffect, useState } from 'react'
|
||||
import { Text } from './index'
|
||||
|
||||
type Props = {
|
||||
amount: string | number | null | undefined
|
||||
currency?: Intl.NumberFormatOptions['currency']
|
||||
maximumFractionDigits?: number
|
||||
}
|
||||
|
||||
const FormatCurrency: FC<ComponentPropsWithoutRef<typeof Text> & Props> = ({
|
||||
amount,
|
||||
maximumFractionDigits = 2,
|
||||
currency = 'USD',
|
||||
...props
|
||||
}) => {
|
||||
const [formattedValue, setFormattedValue] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
if (amount) {
|
||||
const formatted = new Intl.NumberFormat(undefined, {
|
||||
style: 'currency',
|
||||
currency: currency,
|
||||
}).format(+amount)
|
||||
setFormattedValue(formatted)
|
||||
} else {
|
||||
setFormattedValue('')
|
||||
}
|
||||
}, [amount, maximumFractionDigits])
|
||||
|
||||
return (
|
||||
<Text
|
||||
{...props}
|
||||
style={props.style || 'subtitle2'}
|
||||
color={props.color || 'base'}
|
||||
>
|
||||
{formattedValue}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormatCurrency
|
||||
@@ -6,3 +6,6 @@ export { default as Value } from './Value'
|
||||
export { default as Button } from './Button'
|
||||
export { default as Tooltip } from './Tooltip'
|
||||
export { default as Switch } from './Switch'
|
||||
export { default as FormatCrypto } from './FormatCrypto'
|
||||
export { default as FormatCryptoCurrency } from './FormatCryptoCurrency'
|
||||
export { default as FormatCurrency } from './FormatCurrency'
|
||||
|
||||
@@ -2,3 +2,4 @@ export { default as useMounted } from './useMounted'
|
||||
export { default as useTimeSince } from './useTimeSince'
|
||||
export { default as useUserActivity } from './useUserActivity'
|
||||
export { default as useUserCollections } from './useUserCollections'
|
||||
export { default as useChainCurrency } from './useChainCurrency'
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { constants } from 'ethers'
|
||||
import { chainId, useNetwork } from 'wagmi'
|
||||
|
||||
export default function () {
|
||||
const { chain: activeChain, chains } = useNetwork()
|
||||
|
||||
let chain = chains.find((chain) => activeChain?.id === chain.id)
|
||||
|
||||
if (!chain && chains.length > 0) {
|
||||
chain = chains[0]
|
||||
} else {
|
||||
chain = activeChain
|
||||
}
|
||||
|
||||
const ETHChains: number[] = [chainId.mainnet, chainId.goerli]
|
||||
|
||||
if (!chain || !chain.nativeCurrency || ETHChains.includes(chain.id)) {
|
||||
return {
|
||||
name: 'Ethereum',
|
||||
symbol: 'ETH',
|
||||
decimals: 18,
|
||||
address: constants.AddressZero,
|
||||
chainId: chain?.id || chainId.mainnet,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
...chain.nativeCurrency,
|
||||
address: constants.AddressZero,
|
||||
chainId: chain.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
import { NextPage } from 'next'
|
||||
import { Text, Switch, Flex, Box } from '../../components/primitives'
|
||||
import {
|
||||
Text,
|
||||
Switch,
|
||||
Flex,
|
||||
Box,
|
||||
FormatCryptoCurrency,
|
||||
} from '../../components/primitives'
|
||||
import {
|
||||
useCollections,
|
||||
useTokens,
|
||||
@@ -8,8 +14,6 @@ import {
|
||||
import { formatNumber } from 'utils/numbers'
|
||||
import Layout from 'components/Layout'
|
||||
import { useRouter } from 'next/router'
|
||||
import FormatEth from 'components/FormatEth'
|
||||
import FormatWEth from 'components/FormatWEth'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import {
|
||||
faCertificate,
|
||||
@@ -21,7 +25,6 @@ import {
|
||||
faChevronUp,
|
||||
faChevronDown,
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
import { faTwitter, faDiscord } from '@fortawesome/free-brands-svg-icons'
|
||||
import { useState } from 'react'
|
||||
import { truncateAddress } from 'utils/truncate'
|
||||
@@ -151,10 +154,11 @@ const TokenCard = ({ token }) => (
|
||||
|
||||
<Flex align="center" css={{ gap: '$2' }}>
|
||||
<Box css={{ flex: 1 }}>
|
||||
<FormatEth
|
||||
<FormatCryptoCurrency
|
||||
logoWidth={11}
|
||||
css={{ fontSize: 16, fontWeight: 600, color: 'white' }}
|
||||
amount={token.market?.floorAsk?.price?.amount.native}
|
||||
amount={token.market?.floorAsk?.price?.amount?.decimal}
|
||||
address={token.market?.floorAsk?.price?.currency?.contract}
|
||||
/>
|
||||
</Box>
|
||||
<img
|
||||
@@ -240,18 +244,22 @@ const IndexPage: NextPage = () => {
|
||||
}}
|
||||
>
|
||||
<StatBox label="Floor">
|
||||
<FormatEth
|
||||
amount={collection?.floorAsk?.price?.amount?.native}
|
||||
<FormatCryptoCurrency
|
||||
amount={collection?.floorAsk?.price?.amount?.decimal}
|
||||
address={collection?.floorAsk?.price?.currency.contract}
|
||||
decimals={collection?.floorAsk?.price?.currency.decimals}
|
||||
logoWidth={10}
|
||||
css={{ fontSize: 16 }}
|
||||
textStyle={'body1'}
|
||||
/>
|
||||
</StatBox>
|
||||
|
||||
<StatBox label="Top Bid">
|
||||
<FormatWEth
|
||||
amount={collection?.topBid?.price?.amount?.native}
|
||||
<FormatCryptoCurrency
|
||||
amount={collection?.topBid?.price?.amount?.decimal}
|
||||
address={collection?.topBid?.price?.currency.contract}
|
||||
decimals={collection?.topBid?.price?.currency.decimals}
|
||||
logoWidth={10}
|
||||
css={{ fontSize: 16 }}
|
||||
textStyle={'body1'}
|
||||
/>
|
||||
</StatBox>
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
<svg width="15" height="25" viewBox="0 0 15 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="auto" height="100%" viewBox="0 0 15 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.49721 0L0 12.4432L7.49721 9.03511V0Z" fill="#3E63DD"/>
|
||||
<path d="M7.49721 9.03516L0 12.4433L7.49721 16.8768V9.03516Z" fill="#2F4EB2"/>
|
||||
<path d="M14.9959 12.4432L7.49731 0V9.03511L14.9959 12.4432Z" fill="#2F4EB2"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 572 B |
+1
-1
@@ -1,4 +1,4 @@
|
||||
<svg width="15" height="25" viewBox="0 0 15 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="auto" height="100%" viewBox="0 0 15 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.49721 0L0 12.4432L7.49721 9.03511V0Z" fill="#AE1955"/>
|
||||
<path d="M7.49721 9.03506L0 12.4432L7.49721 16.8767V9.03506Z" fill="#801D45"/>
|
||||
<path d="M14.9959 12.4433L7.49731 0V9.03511L14.9959 12.4433Z" fill="#801D45"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 587 B After Width: | Height: | Size: 591 B |
@@ -0,0 +1,7 @@
|
||||
const wrappedContracts: Record<number, string> = {
|
||||
1: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
||||
5: '0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6',
|
||||
137: '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270',
|
||||
}
|
||||
|
||||
export default wrappedContracts
|
||||
Reference in New Issue
Block a user