diff --git a/src/nft/components/details/detailsV2/DataPage.tsx b/src/nft/components/details/detailsV2/DataPage.tsx index 6cecf8cb0a..1f87ddd2ad 100644 --- a/src/nft/components/details/detailsV2/DataPage.tsx +++ b/src/nft/components/details/detailsV2/DataPage.tsx @@ -47,7 +47,7 @@ export const DataPage = ({ asset }: { asset: GenieAsset }) => { - {!!asset.traits?.length && } + {!!asset.traits?.length && } diff --git a/src/nft/components/details/detailsV2/DataPageTraits.test.tsx b/src/nft/components/details/detailsV2/DataPageTraits.test.tsx index f059398d90..079cfe0f6f 100644 --- a/src/nft/components/details/detailsV2/DataPageTraits.test.tsx +++ b/src/nft/components/details/detailsV2/DataPageTraits.test.tsx @@ -4,7 +4,7 @@ import { render } from 'test-utils/render' import { DataPageTraits } from './DataPageTraits' it('data page trait component does not load with asset with no traits', () => { - const { asFragment } = render() + const { asFragment } = render() expect(asFragment()).toMatchSnapshot() }) diff --git a/src/nft/components/details/detailsV2/DataPageTraits.tsx b/src/nft/components/details/detailsV2/DataPageTraits.tsx index 7e9d4c3268..50468c31ac 100644 --- a/src/nft/components/details/detailsV2/DataPageTraits.tsx +++ b/src/nft/components/details/detailsV2/DataPageTraits.tsx @@ -3,7 +3,7 @@ import Column from 'components/Column' import { ScrollBarStyles } from 'components/Common' import Row from 'components/Row' import { useSubscribeScrollState } from 'nft/hooks' -import { Trait } from 'nft/types' +import { GenieAsset } from 'nft/types' import { useMemo } from 'react' import styled from 'styled-components/macro' import { ThemedText } from 'theme' @@ -57,13 +57,15 @@ const Scrim = styled.div<{ isBottom?: boolean }>` display: flex; ` -const TraitsContent = ({ traits }: { traits?: Trait[] }) => { +const TraitsContent = ({ asset }: { asset: GenieAsset }) => { const { userCanScroll, scrollRef, scrollProgress, scrollHandler } = useSubscribeScrollState() // This is needed to prevent rerenders when handling scrolls const traitRows = useMemo(() => { - return traits?.map((trait) => ) - }, [traits]) + return asset.traits?.map((trait) => ( + + )) + }, [asset.address, asset.traits]) return ( @@ -96,7 +98,7 @@ enum TraitTabsKeys { Traits = 'traits', } -export const DataPageTraits = ({ traits }: { traits: Trait[] }) => { +export const DataPageTraits = ({ asset }: { asset: GenieAsset }) => { const TraitTabs: Map = useMemo( () => new Map([ @@ -105,12 +107,12 @@ export const DataPageTraits = ({ traits }: { traits: Trait[] }) => { { title: Traits, key: TraitTabsKeys.Traits, - content: , - count: traits?.length, + content: , + count: asset.traits?.length, }, ], ]), - [traits] + [asset] ) return } diff --git a/src/nft/components/details/detailsV2/RarityGraph.tsx b/src/nft/components/details/detailsV2/RarityGraph.tsx index 9a56fad8cd..4f9148e24d 100644 --- a/src/nft/components/details/detailsV2/RarityGraph.tsx +++ b/src/nft/components/details/detailsV2/RarityGraph.tsx @@ -1,3 +1,4 @@ +import { Trans } from '@lingui/macro' import Row from 'components/Row' import { Trait } from 'nft/types' import styled from 'styled-components/macro' @@ -13,6 +14,7 @@ const RarityBar = styled.div<{ $color?: string }>` interface RarityValue { threshold: number color: string + caption: React.ReactNode } enum RarityLevel { @@ -27,26 +29,31 @@ const RarityLevels: { [key in RarityLevel]: RarityValue } = { [RarityLevel.VeryCommon]: { threshold: 0.8, color: colors.gray500, + caption: Very common, }, [RarityLevel.Common]: { threshold: 0.6, color: colors.green300, + caption: Common, }, [RarityLevel.Rare]: { threshold: 0.4, color: colors.blueVibrant, + caption: Rare, }, [RarityLevel.VeryRare]: { threshold: 0.2, color: colors.purpleVibrant, + caption: Very rare, }, [RarityLevel.ExtremelyRare]: { threshold: 0, color: colors.magentaVibrant, + caption: Extremely rare, }, } -function getRarityLevel(rarity: number) { +export function getRarityLevel(rarity: number) { switch (true) { case rarity > RarityLevels[RarityLevel.VeryCommon].threshold: return RarityLevels[RarityLevel.VeryCommon] diff --git a/src/nft/components/details/detailsV2/TraitRow.tsx b/src/nft/components/details/detailsV2/TraitRow.tsx index 47e625728b..649d0f3d1f 100644 --- a/src/nft/components/details/detailsV2/TraitRow.tsx +++ b/src/nft/components/details/detailsV2/TraitRow.tsx @@ -2,21 +2,45 @@ import Column from 'components/Column' import Row from 'components/Row' import { Trait } from 'nft/types' import { formatEth } from 'nft/utils' +import qs from 'qs' +import { Link } from 'react-router-dom' import styled from 'styled-components/macro' import { ThemedText } from 'theme' -import { RarityGraph } from './RarityGraph' +import { getRarityLevel, RarityGraph } from './RarityGraph' -const SubheaderTiny = styled.div` +const TraitRowLink = styled(Link)` + text-decoration: none; +` + +const SubheaderTiny = styled.div<{ $color?: string }>` font-size: 10px; line-height: 16px; font-weight: 600; - color: ${({ theme }) => theme.textSecondary}; + color: ${({ theme, $color }) => ($color ? $color : theme.textSecondary)}; ` -const TraitValue = styled(Column)` +const SubheaderTinyHidden = styled(SubheaderTiny)` + opacity: 0; +` + +const TraitRowContainer = styled(Row)` + padding: 12px 18px 12px 0px; + border-radius: 12px; + cursor: pointer; + text-decoration: none; + &:hover { + background: ${({ theme }) => theme.hoverDefault}; + ${SubheaderTinyHidden} { + opacity: 1; + } + } +` + +const TraitColumnValue = styled(Column)<{ $flex?: number; $alignItems?: string }>` gap: 4px; - flex: 3; + flex: ${({ $flex }) => $flex ?? 3}; + align-items: ${({ $alignItems }) => $alignItems}; ` const TraitRowValue = styled(ThemedText.BodySmall)<{ $flex?: number; $justifyContent?: string }>` @@ -27,21 +51,31 @@ const TraitRowValue = styled(ThemedText.BodySmall)<{ $flex?: number; $justifyCon justify-content: ${({ $justifyContent }) => $justifyContent}; ` -export const TraitRow = ({ trait }: { trait: Trait }) => { - // TODO: Replace with actual rarity, count, and floor price when BE supports +export const TraitRow = ({ trait, collectionAddress }: { trait: Trait; collectionAddress: string }) => { + // TODO(NFT-1189): Replace with actual rarity, count, and floor price when BE supports // rarity eventually should be number of items with this trait / total number of items, smaller rarity means more rare const randomRarity = Math.random() + const rarityLevel = getRarityLevel(randomRarity) + const params = qs.stringify( + { traits: [`("${trait.trait_type}","${trait.trait_value}")`] }, + { + arrayFormat: 'comma', + } + ) return ( - - - {trait.trait_type} - {trait.trait_value} - - {formatEth(randomRarity * 1000)} ETH - {Math.round(randomRarity * 10000)} - - - - + + + + {trait.trait_type} + {trait.trait_value} + + {formatEth(randomRarity * 1000)} ETH + {Math.round(randomRarity * 10000)} + + {rarityLevel.caption} + + + + ) }