Skip to content

Commit

Permalink
Add metadata tab to NFT details page
Browse files Browse the repository at this point in the history
  • Loading branch information
buberdds committed Nov 23, 2023
1 parent d67f70c commit 192bdb6
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 13 deletions.
1 change: 1 addition & 0 deletions .changelog/1036.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add NFT feature
23 changes: 13 additions & 10 deletions src/app/components/CodeDisplay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { FC, ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import Box from '@mui/material/Box'
import Typography from '@mui/material/Typography'
import { styled } from '@mui/material/styles'
import { ScrollableDataDisplay } from '../../components/ScrollableDataDisplay'
import { CopyToClipboard } from '../../components/CopyToClipboard'
import { useScreenSize } from '../../hooks/useScreensize'
import { base64ToHex } from '../../utils/helpers'

export const CodeDisplay: FC<{
const CodeDisplay: FC<{
code: ReactNode
copyToClipboardValue: string
label: string
Expand Down Expand Up @@ -59,12 +60,14 @@ export const RawDataDisplay: FC<{
)
}

export const JsonCodeDisplay: FC<{ data: Record<string, any>; label: string }> = ({ data, label }) => {
return (
<CodeDisplay
code={<pre>{JSON.stringify(data, null, 2)}</pre>}
copyToClipboardValue={JSON.stringify(data)}
label={label}
/>
)
}
const StyledPre = styled('pre')({
margin: 0,
})

export const JsonCodeDisplay: FC<{ data: Record<string, any>; label: string }> = ({ data, label }) => (
<CodeDisplay
code={<StyledPre>{JSON.stringify(data, null, 2)}</StyledPre>}
copyToClipboardValue={JSON.stringify(data)}
label={label}
/>
)
37 changes: 37 additions & 0 deletions src/app/pages/NFTInstanceDashboardPage/NftMetadataCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Card from '@mui/material/Card'
import CardContent from '@mui/material/CardContent'
import { Runtime, useGetRuntimeEvmTokensAddressNftsId } from '../../../oasis-nexus/api'
import { LinkableDiv } from '../../components/PageLayout/LinkableDiv'
import { CardEmptyState } from './../AccountDetailsPage/CardEmptyState'
import { NftDashboardContext } from '../NFTInstanceDashboardPage'
import { JsonCodeDisplay } from '../../components/CodeDisplay'

export const nftMetadataId = 'metadata'

export const NftMetadataCard: FC<NftDashboardContext> = ({ scope, address, instanceId }) => {
const { t } = useTranslation()
const { data, isFetched } = useGetRuntimeEvmTokensAddressNftsId(
scope.network,
scope.layer as Runtime,
address,
instanceId,
)
const metadata = data?.data?.metadata

return (
<Card>
{isFetched && !metadata && <CardEmptyState label={t('nft.noMetadata')} />}
<>
{metadata && (
<CardContent>
<LinkableDiv id={nftMetadataId}>
<JsonCodeDisplay data={metadata} label={t('nft.metadata')} />
</LinkableDiv>
</CardContent>
)}
</>
</Card>
)
}
22 changes: 20 additions & 2 deletions src/app/pages/NFTInstanceDashboardPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
import { FC } from 'react'
import { useParams } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import { useHref, useParams, useOutletContext } from 'react-router-dom'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { PageLayout } from '../../components/PageLayout'
import { InstanceTitleCard } from './InstanceTitleCard'
import { InstanceDetailsCard } from './InstanceDetailsCard'
import { InstanceImageCard } from './InstanceImageCard'
import { Layer, Runtime, useGetRuntimeEvmTokensAddressNftsId } from '../../../oasis-nexus/api'
import { AppErrors } from '../../../types/errors'
import { RouterTabs } from 'app/components/RouterTabs'
import { SearchScope } from '../../../types/searchScope'

export type NftDashboardContext = {
scope: SearchScope
address: string
instanceId: string
}

export const useNftDetailsProps = () => useOutletContext<NftDashboardContext>()

export const NFTInstanceDashboardPage: FC = () => {
const { t } = useTranslation()
const scope = useRequiredScopeParam()
const { address, instanceId } = useParams()
if (scope.layer === Layer.consensus) {
Expand All @@ -27,7 +39,12 @@ export const NFTInstanceDashboardPage: FC = () => {
instanceId,
)
const nft = data?.data

const metadataLink = useHref('')
const context: NftDashboardContext = {
scope,
address,
instanceId,
}
return (
<PageLayout>
<InstanceTitleCard isFetched={isFetched} isLoading={isLoading} nft={nft} scope={scope} />
Expand All @@ -39,6 +56,7 @@ export const NFTInstanceDashboardPage: FC = () => {
scope={scope}
contractAddress={address!}
/>
<RouterTabs tabs={[{ label: t('nft.metadata'), to: metadataLink }]} context={context} />
</PageLayout>
)
}
2 changes: 2 additions & 0 deletions src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@
"collection": "Collection",
"instance": "(NFT Instance)",
"instanceId": "Token ID",
"metadata": "Metadata",
"noMetadata": "There is no metadata on record for this NFT.",
"noPreview": "No preview available",
"openInFull": "Open in full",
"owner": "Owner",
Expand Down
10 changes: 9 additions & 1 deletion src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import { TokenDashboardPage, useTokenDashboardProps } from './app/pages/TokenDas
import { AccountTokenTransfersCard } from './app/pages/AccountDetailsPage/AccountTokenTransfersCard'
import { TokenTransfersCard } from './app/pages/TokenDashboardPage/TokenTransfersCard'
import { TokenHoldersCard } from './app/pages/TokenDashboardPage/TokenHoldersCard'
import { NFTInstanceDashboardPage } from './app/pages/NFTInstanceDashboardPage'
import { NFTInstanceDashboardPage, useNftDetailsProps } from './app/pages/NFTInstanceDashboardPage'
import { NftMetadataCard } from './app/pages/NFTInstanceDashboardPage/NftMetadataCard'

const NetworkSpecificPart = () => (
<ThemeByNetwork network={useRequiredScopeParam().network}>
Expand Down Expand Up @@ -120,6 +121,13 @@ export const routes: RouteObject[] = [
{
path: 'token/:address/instance/:instanceId',
element: <NFTInstanceDashboardPage />,
loader: addressParamLoader,
children: [
{
path: '',
Component: () => <NftMetadataCard {...useNftDetailsProps()} />,
},
],
},
{
path: `token/:address`,
Expand Down

0 comments on commit 192bdb6

Please sign in to comment.