From 815fcdc95d428f7a9da0d5b6b4ad1b8e981c3603 Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Thu, 25 Sep 2025 00:55:28 +0900 Subject: [PATCH 01/18] create nft collection page --- pages/nft-collection/[id].js | 546 +++++++++++++++++++++++++++++++++++ pages/nft-volumes/index.js | 15 +- 2 files changed, 560 insertions(+), 1 deletion(-) create mode 100644 pages/nft-collection/[id].js diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js new file mode 100644 index 000000000..f4f80b27a --- /dev/null +++ b/pages/nft-collection/[id].js @@ -0,0 +1,546 @@ +import { useTranslation } from 'next-i18next' +import { useState, useEffect } from 'react' +import axios from 'axios' +import { serverSideTranslations } from 'next-i18next/serverSideTranslations' +import Link from 'next/link' + +import { usernameOrAddress, AddressWithIconFilled, shortHash, addressUsernameOrServiceLink } from '../../utils/format' +import { getIsSsrMobile } from '../../utils/mobile' +import { nftUrl, nftName } from '../../utils/nft' +import { axiosServer, passHeaders } from '../../utils/axios' + +import SEO from '../../components/SEO' +import { nftClass } from '../../styles/pages/nft.module.scss' +import Tiles from '../../components/Tiles' + +export async function getServerSideProps(context) { + const { locale, query, req } = context + let pageMeta = null + const { id } = query + const collectionId = id ? (Array.isArray(id) ? id[0] : id) : '' + + if (collectionId) { + try { + // Try collection-specific endpoint first, fallback to NFT endpoint + let res = await axiosServer({ + method: 'get', + url: 'v2/nft-collection/' + collectionId + '?uri=true&metadata=true', + headers: passHeaders(req) + }).catch(async () => { + // Fallback to individual NFT endpoint if collection endpoint doesn't exist + return await axiosServer({ + method: 'get', + url: 'v2/nft/' + collectionId + '?uri=true&metadata=true', + headers: passHeaders(req) + }) + }) + pageMeta = res?.data + } catch (error) { + console.error(error) + } + } + + return { + props: { + id: collectionId, + pageMeta: pageMeta || {}, + isSsrMobile: getIsSsrMobile(context), + ...(await serverSideTranslations(locale, ['common', 'nft'])) + } + } +} + +export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMobile }) { + const { t } = useTranslation() + const [data, setData] = useState(pageMeta) + const [loading, setLoading] = useState(false) + const [errorMessage, setErrorMessage] = useState('') + const [mounted, setMounted] = useState(false) + const [nftList, setNftList] = useState([]) + const [nftListLoading, setNftListLoading] = useState(false) + const {statistics} = data.collection + const [activityData, setActivityData] = useState({ + sales: [], + listings: [], + mints: [] + }) + const [activityLoading, setActivityLoading] = useState(false) + const [isMobile, setIsMobile] = useState(isSsrMobile) + + useEffect(() => { + setMounted(true) + // Client-side viewport fallback for mobile detection + const updateIsMobile = () => { + try { + const width = window.innerWidth || document.documentElement.clientWidth + setIsMobile(isSsrMobile || width <= 768) + } catch (_) {} + } + updateIsMobile() + window.addEventListener('resize', updateIsMobile) + return () => window.removeEventListener('resize', updateIsMobile) + }, []) + + useEffect(() => { + if (!selectedCurrency || !id) return + checkApi() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [id, selectedCurrency]) + + useEffect(() => { + if (!mounted) return + if (!id) return + fetchCollectionNfts() + fetchActivityData() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [mounted, id]) + + const checkApi = async () => { + if (!id) return + + setLoading(true) + // Try collection-specific endpoint first, fallback to NFT endpoint + let response = await axiosServer({ + method: 'get', + url: 'v2/nft-collection/' + id + '?floorPrice=true&statistics=true&assets=true' + }).catch((error) => { + setErrorMessage(t('error.' + error.message)) + return null + }) + + setLoading(false) + const newdata = response?.data + + if (newdata) { + setData(newdata) + } else { + setErrorMessage('Error') + } + } + + const fetchCollectionNfts = async () => { + setNftListLoading(true) + const url = `/v2/nfts?collection=${encodeURIComponent(id)}&limit=14&order=mintedNew&hasMedia=true` + const res = await axios(url).catch(() => null) + setNftListLoading(false) + const list = res?.data?.nfts || [] + setNftList(list) + } + + const fetchActivityData = async () => { + setActivityLoading(true) + + try { + // Fetch recent sales + const salesRes = await axios(`/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3`).catch(() => null) + + // Fetch recent listings (NFTs on sale) + const listingsRes = await axios(`/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3`).catch(() => null) + + // Fetch recent mints + const mintsRes = await axios(`/v2/nfts?collection=${encodeURIComponent(id)}&limit=3&order=mintedNew`).catch(() => null) + setActivityData({ + sales: salesRes?.data?.sales || [], + listings: listingsRes?.data?.nfts || [], + mints: mintsRes?.data?.nfts || [] + }) + } catch (error) { + console.error('Error fetching activity data:', error) + setActivityData({ sales: [], listings: [], mints: [] }) + } finally { + setActivityLoading(false) + } + } + + const collectionName = (data) => { + return data?.collection?.name || '' + } + + const collectionDescription = (data) => { + return data?.collection?.description || '' + } + + const imageUrl = data?.collection?.assets?.image || data?.collection?.image + + const renderActivityTable = (kind) => { + let title = '' + let headers = [] + let items = [] + if (kind === 'sales') { + title = 'Recent Sales' + headers = ['NFT', 'Seller', 'Amount', 'Date'] + items = activityData.sales || [] + } else if (kind === 'listings') { + title = 'Recent Listings' + headers = ['NFT', 'Owner', 'Date'] + items = activityData.listings || [] + } else if (kind === 'mints') { + title = 'Recent Mints' + headers = ['NFT', 'Owner', 'Date'] + items = activityData.mints || [] + } + + // Mobile: render blocks instead of table + if (isMobile) { + return ( +
+
{title}
+ {items.length > 0 ? ( + items.map((item, i) => ( +
+
+ NFT: + {nftUrl(item?.nftoken || item, 'thumbnail') ? ( + {nftName(item?.nftoken + ) : ( + '' + )} +
+ {nftName(item?.nftoken || item)} + {shortHash(item.nftokenID, 6)} +
+
+
+ {kind === 'sales' && ( + <> +
+ Seller: + {item.seller ? : ''} +
+
+ Amount: + {item.amount ? item.amount : ''} +
+
+ Date: + {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : ''} +
+ + )} + {kind === 'listings' && ( + <> +
+ Owner: + {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} +
+
+ Date: + {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} +
+ + )} + {kind === 'mints' && ( + <> +
+ Owner: + {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} +
+
+ Date: + {new Date(item.issuedAt * 1000).toLocaleDateString()} +
+ + )} +
+
+ )) + ) : ( +
{t('general.nodata') || 'No data'}
+ )} +
+ ) + } + + // Desktop: render table + return ( + + + + + + + + + {headers.map((h, i) => ( + + ))} + + {items.length > 0 ? ( + items.map((item, i) => ( + + + {kind === 'sales' && ( + <> + + + + + )} + {kind === 'listings' && ( + <> + + + + )} + {kind === 'mints' && ( + <> + + + + )} + + )) + ) : ( + + + + )} + +
{title}
{h}
+
+ {nftUrl(item?.nftoken || item, 'thumbnail') ? ( + {nftName(item?.nftoken + ) : ( + '' + )} + + {nftName(item?.nftoken || item)} + {shortHash(item.nftokenID, 6)} + +
+
{item.seller ? : '—'}{item.amount ? item.amount : 'N/A'}{item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : 'N/A'}{item.owner && }{new Date(item.ownerChangedAt * 1000).toLocaleDateString()}{item.owner && }{new Date(item.issuedAt * 1000).toLocaleDateString()}
{t('general.nodata') || 'No data'}
+ ) + } + + return ( +
+ +
+ {id ? ( + <> + {loading ? ( +
+ +
+ {t('general.loading')} +
+ ) : ( + <> + {errorMessage ? ( +
{errorMessage}
+ ) : ( + <> + {data && ( + <> +
+
+ {imageUrl ? ( + {collectionName(data)} + ) : ( +
+ No Image Available +
+ )} +
+
+ +
+
+

{collectionName(data)}

+ {collectionDescription(data) && ( +

{collectionDescription(data)}

+ )} +
+ + {mounted && data?.collection?.issuerDetails && ( + + + + + + + + + + + + {data?.collection?.issuerDetails?.username && ( + + + + + )} + {data?.collection?.issuerDetails?.service && ( + + + + + )} + {data?.collection?.taxon ? ( + + + + + ) : null} + {data?.collection?.createdAt && ( + + + + + )} + {data?.collection?.updatedAt && ( + + + + + )} + +
Issuer Information
Address + +
Username{data.collection.issuerDetails.username}
Service{data.collection.issuerDetails.service}
Taxon{data.collection.taxon}
Created At{new Date(data.collection.createdAt * 1000).toLocaleString()}
Updated At{new Date(data.collection.updatedAt * 1000).toLocaleString()}
+ )} + + {mounted && statistics && ( + + + + + + + + {statistics?.nfts && ( + + + + + )} + {statistics?.owners && ( + + + + + )} + {statistics?.all?.tradedNfts && ( + + + + + )} + {statistics?.all?.buyers && ( + + + + + )} + {statistics?.month?.tradedNfts && ( + + + + + )} + {statistics?.week?.tradedNfts && ( + + + + + )} + +
Collection Statistics
Total Supply{statistics.nfts}
Unique Owners{statistics.owners}
Total Traded NFTs{statistics.all.tradedNfts}
Total Buyers{statistics.all.buyers}
Monthly Traded NFTs{statistics.month.tradedNfts}
Weekly Traded NFTs{statistics.week.tradedNfts}
+ )} + + {mounted && ( +
+
+

NFTs in this Collection

+ {data?.collection?.issuer !== undefined && (data?.collection?.taxon || data?.collection?.taxon === 0) ? ( + + View all + + ) : ( + '' + )} +
+ + {nftListLoading && ( +
+ +
+ )} + + {!nftListLoading && nftList.length === 0 && ( +
No NFTs found
+ )} + + {!nftListLoading && nftList.length > 0 && ( +
+ +
+ )} +
+ )} + + {mounted && ( +
+ {activityLoading && ( +
+ +
+ )} + + {!activityLoading && ( +
+ {renderActivityTable('sales')} + {renderActivityTable('listings')} + {renderActivityTable('mints')} +
+ )} +
+ )} +
+ + )} + + )} + + )} + + ) : ( + <> +

NFT Collection

+

{t('desc', { ns: 'nft' })}

+ + )} +
+
+ ) +} diff --git a/pages/nft-volumes/index.js b/pages/nft-volumes/index.js index 7b381f109..b0c437926 100644 --- a/pages/nft-volumes/index.js +++ b/pages/nft-volumes/index.js @@ -648,6 +648,19 @@ export default function NftVolumes({ return {text || } } + const nftCollectionLink = (data, options = {}) => { + if (!data) return '' + const { text } = options + + // Create collection ID from issuer:taxon format + if (data.collectionDetails?.issuer) { + const collectionId = data.collectionDetails.issuer + ':' + data.collectionDetails.taxon + return {text || } + } + + return '' + } + const nftDistributionLink = (data) => { if (!data) return '' let params = '?issuer=' @@ -917,7 +930,7 @@ export default function NftVolumes({ ) } - let nameLink = nftExplorerLink(data, { + let nameLink = nftCollectionLink(data, { text: name || collectionNameText(data) }) From a20e3e149df7321cc6ce2dfec4e2d45e308342e2 Mon Sep 17 00:00:00 2001 From: Viacheslav Bakshaev Date: Thu, 25 Sep 2025 15:58:54 +0200 Subject: [PATCH 02/18] prettify --- pages/nft-collection/[id].js | 101 +++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index f4f80b27a..a9914225e 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -18,7 +18,7 @@ export async function getServerSideProps(context) { let pageMeta = null const { id } = query const collectionId = id ? (Array.isArray(id) ? id[0] : id) : '' - + if (collectionId) { try { // Try collection-specific endpoint first, fallback to NFT endpoint @@ -58,7 +58,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob const [mounted, setMounted] = useState(false) const [nftList, setNftList] = useState([]) const [nftListLoading, setNftListLoading] = useState(false) - const {statistics} = data.collection + const { statistics } = data.collection const [activityData, setActivityData] = useState({ sales: [], listings: [], @@ -107,10 +107,10 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob setErrorMessage(t('error.' + error.message)) return null }) - + setLoading(false) const newdata = response?.data - + if (newdata) { setData(newdata) } else { @@ -129,16 +129,22 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob const fetchActivityData = async () => { setActivityLoading(true) - + try { // Fetch recent sales - const salesRes = await axios(`/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3`).catch(() => null) - + const salesRes = await axios(`/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3`).catch( + () => null + ) + // Fetch recent listings (NFTs on sale) - const listingsRes = await axios(`/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3`).catch(() => null) - + const listingsRes = await axios( + `/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3` + ).catch(() => null) + // Fetch recent mints - const mintsRes = await axios(`/v2/nfts?collection=${encodeURIComponent(id)}&limit=3&order=mintedNew`).catch(() => null) + const mintsRes = await axios(`/v2/nfts?collection=${encodeURIComponent(id)}&limit=3&order=mintedNew`).catch( + () => null + ) setActivityData({ sales: salesRes?.data?.sales || [], listings: listingsRes?.data?.nfts || [], @@ -184,12 +190,22 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob if (isMobile) { return (
-
{title}
+
+ {title} +
{items.length > 0 ? ( items.map((item, i) => (
NFT: @@ -212,7 +228,11 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob <>
Seller: - {item.seller ? : ''} + {item.seller ? ( + + ) : ( + '' + )}
Amount: @@ -252,7 +272,9 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
)) ) : ( -
{t('general.nodata') || 'No data'}
+
+ {t('general.nodata') || 'No data'} +
)}
) @@ -269,7 +291,9 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob {headers.map((h, i) => ( - {h} + + {h} + ))} {items.length > 0 ? ( @@ -286,7 +310,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob ) : ( '' )} - + {nftName(item?.nftoken || item)} {shortHash(item.nftokenID, 6)} @@ -294,20 +318,30 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob {kind === 'sales' && ( <> - {item.seller ? : '—'} + + {item.seller ? ( + + ) : ( + '—' + )} + {item.amount ? item.amount : 'N/A'} {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : 'N/A'} )} {kind === 'listings' && ( <> - {item.owner && } + + {item.owner && } + {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} )} {kind === 'mints' && ( <> - {item.owner && } + + {item.owner && } + {new Date(item.issuedAt * 1000).toLocaleDateString()} )} @@ -315,7 +349,9 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob )) ) : ( - {t('general.nodata') || 'No data'} + + {t('general.nodata') || 'No data'} + )} @@ -331,7 +367,9 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob description={ collectionDescription(data) || t('desc', { ns: 'nft' }) + - (data?.collection?.issuer ? ' - ' + t('table.issuer') + ': ' + usernameOrAddress(data?.collection, 'issuer') : '') + (data?.collection?.issuer + ? ' - ' + t('table.issuer') + ': ' + usernameOrAddress(data?.collection, 'issuer') + : '') } image={{ file: imageUrl }} /> @@ -355,15 +393,13 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
{imageUrl ? ( - {collectionName(data)} ) : ( -
- No Image Available -
+
No Image Available
)}
@@ -476,13 +512,12 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob

NFTs in this Collection

- {data?.collection?.issuer !== undefined && (data?.collection?.taxon || data?.collection?.taxon === 0) ? ( + {data?.collection?.issuer !== undefined && + (data?.collection?.taxon || data?.collection?.taxon === 0) ? ( View all From a900d2aee91f4915fa77a2d67d0e44cc823e0fc5 Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Fri, 26 Sep 2025 00:48:39 +0900 Subject: [PATCH 03/18] fix sologenic nft collections --- pages/nft-collection/[id].js | 16 ++++++++++++---- pages/nft-volumes/index.js | 10 +++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index f4f80b27a..bb0e49ca3 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -58,7 +58,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob const [mounted, setMounted] = useState(false) const [nftList, setNftList] = useState([]) const [nftListLoading, setNftListLoading] = useState(false) - const {statistics} = data.collection + const statistics = data?.collection?.statistics const [activityData, setActivityData] = useState({ sales: [], listings: [], @@ -462,12 +462,12 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob {statistics.month.tradedNfts} )} - {statistics?.week?.tradedNfts && ( + {statistics?.week?.tradedNfts ? ( Weekly Traded NFTs {statistics.week.tradedNfts} - )} + ) : null} )} @@ -487,7 +487,15 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob View all ) : ( - '' + + View all + )}
diff --git a/pages/nft-volumes/index.js b/pages/nft-volumes/index.js index b0c437926..312a82ee4 100644 --- a/pages/nft-volumes/index.js +++ b/pages/nft-volumes/index.js @@ -652,9 +652,13 @@ export default function NftVolumes({ if (!data) return '' const { text } = options - // Create collection ID from issuer:taxon format - if (data.collectionDetails?.issuer) { - const collectionId = data.collectionDetails.issuer + ':' + data.collectionDetails.taxon + if (data.collectionDetails?.issuer || data.collectionDetails?.name) { + let collectionId + if(data.collectionDetails.issuer) { + collectionId = data.collectionDetails.issuer + ':' + data.collectionDetails.taxon + } else { + collectionId = data.collection + } return {text || } } From 19f637a57b595383cf56f80063e503e82e2a8309 Mon Sep 17 00:00:00 2001 From: Viacheslav Bakshaev Date: Sun, 28 Sep 2025 08:59:51 +0200 Subject: [PATCH 04/18] js fixes --- pages/nft-collection/[id].js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 33f677771..b2fe7e56d 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -79,6 +79,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob updateIsMobile() window.addEventListener('resize', updateIsMobile) return () => window.removeEventListener('resize', updateIsMobile) + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { @@ -512,25 +513,23 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob

NFTs in this Collection

- {data?.collection?.issuer !== undefined && + {data?.collection?.issuer && (data?.collection?.taxon || data?.collection?.taxon === 0) ? ( View all ) : ( - - View all - + )}&includeWithoutMediaData=true`} + > + View all + + ) )}
From 43af331881f64f0e0f3ab6698d02ed0e0d7d6087 Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Fri, 10 Oct 2025 20:02:39 +0900 Subject: [PATCH 05/18] change nft tables and tiles --- pages/_app.js | 3 +- pages/nft-collection/[id].js | 138 +++++++++++++++++++++++++---------- 2 files changed, 100 insertions(+), 41 deletions(-) diff --git a/pages/_app.js b/pages/_app.js index d0ee3a9df..f98c74e58 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -100,7 +100,8 @@ const MyApp = ({ Component, pageProps }) => { '/distribution', '/admin/watchlist', '/tokens', - '/nft/[[...id]]' + '/nft/[[...id]]', + '/nft-collection/[id]' ] const skipOnFirstRender = ['/', '/account', '/account/[id]', '/account/[id]/transactions', '/amms', '/tokens'] diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index b2fe7e56d..1b43f627e 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -4,14 +4,13 @@ import axios from 'axios' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import Link from 'next/link' -import { usernameOrAddress, AddressWithIconFilled, shortHash, addressUsernameOrServiceLink } from '../../utils/format' +import { usernameOrAddress, AddressWithIconFilled, shortHash, addressUsernameOrServiceLink, amountFormat, convertedAmount, nativeCurrencyToFiat } from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' import { nftUrl, nftName } from '../../utils/nft' import { axiosServer, passHeaders } from '../../utils/axios' import SEO from '../../components/SEO' import { nftClass } from '../../styles/pages/nft.module.scss' -import Tiles from '../../components/Tiles' export async function getServerSideProps(context) { const { locale, query, req } = context @@ -50,7 +49,7 @@ export async function getServerSideProps(context) { } } -export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMobile }) { +export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMobile, fiatRate }) { const { t } = useTranslation() const [data, setData] = useState(pageMeta) const [loading, setLoading] = useState(false) @@ -121,7 +120,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob const fetchCollectionNfts = async () => { setNftListLoading(true) - const url = `/v2/nfts?collection=${encodeURIComponent(id)}&limit=14&order=mintedNew&hasMedia=true` + const url = `/v2/nfts?collection=${encodeURIComponent(id)}&limit=16&order=mintedNew&hasMedia=true` const res = await axios(url).catch(() => null) setNftListLoading(false) const list = res?.data?.nfts || [] @@ -133,13 +132,13 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob try { // Fetch recent sales - const salesRes = await axios(`/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3`).catch( + const salesRes = await axios(`/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}`).catch( () => null ) // Fetch recent listings (NFTs on sale) const listingsRes = await axios( - `/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3` + `/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` ).catch(() => null) // Fetch recent mints @@ -160,7 +159,10 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob } const collectionName = (data) => { - return data?.collection?.name || '' + return data?.collection?.name || + <> + {addressUsernameOrServiceLink(data?.collection, 'issuer', { short: isMobile })} ({data?.collection?.taxon}) + } const collectionDescription = (data) => { @@ -175,11 +177,11 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob let items = [] if (kind === 'sales') { title = 'Recent Sales' - headers = ['NFT', 'Seller', 'Amount', 'Date'] + headers = ['NFT', 'Seller', 'Buyer', 'Price', 'Date'] items = activityData.sales || [] } else if (kind === 'listings') { title = 'Recent Listings' - headers = ['NFT', 'Owner', 'Date'] + headers = ['NFT', 'Owner', 'Price', 'Date'] items = activityData.listings || [] } else if (kind === 'mints') { title = 'Recent Mints' @@ -235,9 +237,18 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob '' )}
+
+ Buyer: + {item.buyer ? ( + + ) : ( + '' + )} +
- Amount: - {item.amount ? item.amount : ''} + Price: + {amountFormat(item.amount)} + ≈ {convertedAmount(item, selectedCurrency, { short: true })}
Date: @@ -251,6 +262,11 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob Owner: {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })}
+
+ Price: + {amountFormat(item?.sellOffers?.[0]?.amount)} + {nativeCurrencyToFiat({amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate})} +
Date: {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} @@ -283,7 +299,14 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob // Desktop: render table return ( - +
@@ -326,7 +349,17 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob '—' )} - + + )} @@ -335,6 +368,10 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob + )} @@ -364,7 +401,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
-

{collectionName(data)}

+

{collectionName(data)}

{collectionDescription(data) && (

{collectionDescription(data)}

)} @@ -510,29 +547,39 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob )} {mounted && ( -
-
-

NFTs in this Collection

- {data?.collection?.issuer && - (data?.collection?.taxon || data?.collection?.taxon === 0) ? ( - - View all - - ) : ( - data.collection?.collection && ( - - View all - - ) - )} -
- +
{title}{item.amount ? item.amount : 'N/A'} + {item.buyer ? ( + + ) : ( + '—' + )} + + {amountFormat(item.amount)} + ≈ {convertedAmount(item, selectedCurrency, { short: true })} + {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : 'N/A'} {item.owner && } + {amountFormat(item?.sellOffers?.[0]?.amount)} + {nativeCurrencyToFiat({amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate})} + {new Date(item.ownerChangedAt * 1000).toLocaleDateString()}
+ + + + + + {nftListLoading && (
@@ -545,10 +592,21 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob {!nftListLoading && nftList.length > 0 && (
- + { + nftList.map((nft, i) => ( + + {nftName(nft)} + + )) + }
)} -
+ +
+ NFTs in this Collection + {data?.collection?.issuer && + (data?.collection?.taxon || data?.collection?.taxon === 0) ? ( + <> + {' '} + [ + View all + ] + + ) : ( + data.collection?.collection && ( + <> + {' '} + [ + View all + ] + + ) + )} +
)} {mounted && ( From c79cc558c58a56360352c2cacbac03e7131f7213 Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Fri, 10 Oct 2025 21:45:33 +0900 Subject: [PATCH 06/18] solve conflict --- pages/_app.js | 5 +---- pages/nft-collection/[id].js | 15 +++------------ 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/pages/_app.js b/pages/_app.js index 610a1d49f..5e4f5c108 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -101,10 +101,8 @@ const MyApp = ({ Component, pageProps }) => { '/admin/watchlist', '/nft/[[...id]]', '/tokens', -<<<<<<< HEAD '/nft/[[...id]]', - '/nft-collection/[id]' -======= + '/nft-collection/[id]', '/token/[[...id]]' ] const skipOnFirstRender = [ @@ -115,7 +113,6 @@ const MyApp = ({ Component, pageProps }) => { '/amms', '/tokens', '/token/[[...id]]' ->>>>>>> upstream ] // Skip fetch on first render for pages that get on the server side diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 1b43f627e..0eadb2bc7 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -177,7 +177,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob let items = [] if (kind === 'sales') { title = 'Recent Sales' - headers = ['NFT', 'Seller', 'Buyer', 'Price', 'Date'] + headers = ['NFT', 'Seller / Buyer', 'Price', 'Date'] items = activityData.sales || [] } else if (kind === 'listings') { title = 'Recent Listings' @@ -299,14 +299,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob // Desktop: render table return ( - +
@@ -342,14 +335,12 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob {kind === 'sales' && ( <> - - - {headers.map((h, i) => ( + {items.length > 0 && headers.map((h, i) => ( @@ -379,7 +375,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob ) : ( )} @@ -403,7 +399,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob image={{ file: imageUrl }} />
- {id ? ( + {id && !data?.error ? ( <> {loading ? (
@@ -452,37 +448,37 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
- {data?.collection?.issuerDetails?.username && ( + {issuerDetails?.username && ( - + )} {data?.collection?.issuerDetails?.service && ( - + )} - {data?.collection?.taxon ? ( + {collection?.taxon ? ( - + ) : null} - {data?.collection?.createdAt && ( + {collection?.createdAt && ( - + )} - {data?.collection?.updatedAt && ( + {collection?.updatedAt && ( - + )} @@ -543,24 +539,22 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob - {nftListLoading && ( -
- -
- )} + + + {!nftListLoading && nftList.length > 0 && ( +
+ { + nftList.map((nft, i) => ( + + {nftName(nft)} + + )) + } +
+ )} + + +
{title} + {item.seller ? ( ) : ( '—' )} - {item.buyer ? ( ) : ( From b0d4e19fd3651179998acdf1055292a8c14e6f2a Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Tue, 14 Oct 2025 00:42:06 +0900 Subject: [PATCH 07/18] remove assets --- pages/nft-collection/[id].js | 312 +++++++++++++++++------------------ 1 file changed, 155 insertions(+), 157 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 0eadb2bc7..31519ff3d 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -6,7 +6,7 @@ import Link from 'next/link' import { usernameOrAddress, AddressWithIconFilled, shortHash, addressUsernameOrServiceLink, amountFormat, convertedAmount, nativeCurrencyToFiat } from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' -import { nftUrl, nftName } from '../../utils/nft' +import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' import { axiosServer, passHeaders } from '../../utils/axios' import SEO from '../../components/SEO' @@ -23,17 +23,10 @@ export async function getServerSideProps(context) { // Try collection-specific endpoint first, fallback to NFT endpoint let res = await axiosServer({ method: 'get', - url: 'v2/nft-collection/' + collectionId + '?uri=true&metadata=true', + url: 'v2/nft-collection/' + collectionId, headers: passHeaders(req) - }).catch(async () => { - // Fallback to individual NFT endpoint if collection endpoint doesn't exist - return await axiosServer({ - method: 'get', - url: 'v2/nft/' + collectionId + '?uri=true&metadata=true', - headers: passHeaders(req) - }) }) - pageMeta = res?.data + pageMeta = res?.data?.collection || res?.data } catch (error) { console.error(error) } @@ -58,6 +51,8 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob const [nftList, setNftList] = useState([]) const [nftListLoading, setNftListLoading] = useState(false) const statistics = data?.collection?.statistics + const issuerDetails = data?.collection?.issuerDetails + const collection = data?.collection const [activityData, setActivityData] = useState({ sales: [], listings: [], @@ -114,7 +109,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob if (newdata) { setData(newdata) } else { - setErrorMessage('Error') + setErrorMessage('No data found') } } @@ -169,7 +164,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob return data?.collection?.description || '' } - const imageUrl = data?.collection?.assets?.image || data?.collection?.image + const imageUrl = ipfsUrl(data?.collection?.image) const renderActivityTable = (kind) => { let title = '' @@ -193,106 +188,107 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob if (isMobile) { return (
-
- {title} -
- {items.length > 0 ? ( - items.map((item, i) => ( -
-
- NFT: - {nftUrl(item?.nftoken || item, 'thumbnail') ? ( - {nftName(item?.nftoken - ) : ( - '' - )} -
- {nftName(item?.nftoken || item)} - {shortHash(item.nftokenID, 6)} -
-
-
- {kind === 'sales' && ( - <> -
- Seller: - {item.seller ? ( - - ) : ( - '' - )} -
-
- Buyer: - {item.buyer ? ( - - ) : ( - '' - )} -
-
- Price: - {amountFormat(item.amount)} - ≈ {convertedAmount(item, selectedCurrency, { short: true })} -
-
- Date: - {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : ''} -
- - )} - {kind === 'listings' && ( - <> -
- Owner: - {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} -
-
- Price: - {amountFormat(item?.sellOffers?.[0]?.amount)} - {nativeCurrencyToFiat({amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate})} -
-
- Date: - {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} -
- - )} - {kind === 'mints' && ( - <> -
- Owner: - {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} -
-
- Date: - {new Date(item.issuedAt * 1000).toLocaleDateString()} -
- - )} -
-
- )) - ) : ( -
- {t('general.nodata') || 'No data'} -
- )} + + + + + + + + { + items.length > 0 ? items.map((item, i) => { + return ( + + + + ) + }) : ( + + + + ) + } + +
{title}
+
+ NFT: + {nftUrl(item?.nftoken || item, 'thumbnail') ? ( + {nftName(item?.nftoken + ) : ( + '' + )} +
+ {nftName(item?.nftoken || item)} + {shortHash(item.nftokenID, 6)} +
+
+
+ {kind === 'sales' && ( + <> +
+ Seller: + {item.seller ? ( + + ) : ( + '' + )} +
+
+ Buyer: + {item.buyer ? ( + + ) : ( + '' + )} +
+
+ Price: + {amountFormat(item.amount)} + ≈ {convertedAmount(item, selectedCurrency, { short: true })} +
+
+ Date: + {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : ''} +
+ + )} + {kind === 'listings' && ( + <> +
+ Owner: + {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} +
+
+ Price: + {amountFormat(item?.sellOffers?.[0]?.amount)} + {nativeCurrencyToFiat({amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate})} +
+
+ Date: + {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} +
+ + )} + {kind === 'mints' && ( + <> +
+ Owner: + {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} +
+
+ Date: + {new Date(item.issuedAt * 1000).toLocaleDateString()} +
+ + )} +
+
+ {'No data'} +
) } @@ -307,7 +303,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
{h}
- {t('general.nodata') || 'No data'} + {'No data'}
Address - +
Username{data.collection.issuerDetails.username}{issuerDetails.username}
Service{data.collection.issuerDetails.service}{issuerDetails.service}
Taxon{data.collection.taxon}{collection?.taxon}
Created At{new Date(data.collection.createdAt * 1000).toLocaleString()}{new Date(collection?.createdAt * 1000).toLocaleString()}
Updated At{new Date(data.collection.updatedAt * 1000).toLocaleString()}{new Date(collection?.updatedAt * 1000).toLocaleString()}
NFTs in this Collection - {data?.collection?.issuer && - (data?.collection?.taxon || data?.collection?.taxon === 0) ? ( + {collection?.issuer && + (collection?.taxon || collection?.taxon === 0) ? ( <> {' '} [ View all ] ) : ( - data.collection?.collection && ( + collection?.collection && ( <> {' '} [ View all ] @@ -571,32 +565,36 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
+ {nftListLoading && ( +
+ +
+ )} - {!nftListLoading && nftList.length === 0 && ( -
No NFTs found
- )} + {!nftListLoading && nftList.length === 0 && ( +
No NFTs found
+ )} - {!nftListLoading && nftList.length > 0 && ( -
- { - nftList.map((nft, i) => ( - - {nftName(nft)} - - )) - } -
- )} -
)} @@ -628,7 +626,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob ) : ( <>

NFT Collection

-

{t('desc', { ns: 'nft' })}

+

{data?.error || t('desc', { ns: 'nft' })}

)}
From 62bd3f360b6d24a0d1babe2c617a780a610052d4 Mon Sep 17 00:00:00 2001 From: Viacheslav Bakshaev Date: Wed, 15 Oct 2025 11:11:54 +0200 Subject: [PATCH 08/18] remove &assets=true on the backend api request + prettify --- pages/nft-collection/[id].js | 137 ++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 57 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 31519ff3d..50ba32cb3 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -4,7 +4,15 @@ import axios from 'axios' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import Link from 'next/link' -import { usernameOrAddress, AddressWithIconFilled, shortHash, addressUsernameOrServiceLink, amountFormat, convertedAmount, nativeCurrencyToFiat } from '../../utils/format' +import { + usernameOrAddress, + AddressWithIconFilled, + shortHash, + addressUsernameOrServiceLink, + amountFormat, + convertedAmount, + nativeCurrencyToFiat +} from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' import { axiosServer, passHeaders } from '../../utils/axios' @@ -97,7 +105,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob // Try collection-specific endpoint first, fallback to NFT endpoint let response = await axiosServer({ method: 'get', - url: 'v2/nft-collection/' + id + '?floorPrice=true&statistics=true&assets=true' + url: 'v2/nft-collection/' + id + '?floorPrice=true&statistics=true' }).catch((error) => { setErrorMessage(t('error.' + error.message)) return null @@ -127,13 +135,15 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob try { // Fetch recent sales - const salesRes = await axios(`/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}`).catch( - () => null - ) + const salesRes = await axios( + `/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}` + ).catch(() => null) // Fetch recent listings (NFTs on sale) const listingsRes = await axios( - `/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` + `/v2/nfts?collection=${encodeURIComponent( + id + )}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` ).catch(() => null) // Fetch recent mints @@ -154,10 +164,13 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob } const collectionName = (data) => { - return data?.collection?.name || - <> - {addressUsernameOrServiceLink(data?.collection, 'issuer', { short: isMobile })} ({data?.collection?.taxon}) - + return ( + data?.collection?.name || ( + <> + {addressUsernameOrServiceLink(data?.collection, 'issuer', { short: isMobile })} ({data?.collection?.taxon}) + + ) + ) } const collectionDescription = (data) => { @@ -195,8 +208,8 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob - { - items.length > 0 ? items.map((item, i) => { + {items.length > 0 ? ( + items.map((item, i) => { return ( @@ -237,8 +250,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
Price: - {amountFormat(item.amount)} - ≈ {convertedAmount(item, selectedCurrency, { short: true })} + {amountFormat(item.amount)}≈ {convertedAmount(item, selectedCurrency, { short: true })}
Date: @@ -254,8 +266,12 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob
Price: - {amountFormat(item?.sellOffers?.[0]?.amount)} - {nativeCurrencyToFiat({amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate})} + {amountFormat(item?.sellOffers?.[0]?.amount)} + {nativeCurrencyToFiat({ + amount: item?.sellOffers?.[0]?.amount, + selectedCurrency, + fiatRate + })}
Date: @@ -279,14 +295,14 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob ) - }) : ( - - - {'No data'} - - - ) - } + }) + ) : ( + + + {'No data'} + + + )}
@@ -303,11 +319,12 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob - {items.length > 0 && headers.map((h, i) => ( - - {h} - - ))} + {items.length > 0 && + headers.map((h, i) => ( + + {h} + + ))} {items.length > 0 ? ( items.map((item, i) => ( @@ -331,21 +348,16 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob {kind === 'sales' && ( <> - + {item.seller ? ( ) : ( '—' )} - {item.buyer ? ( - - ) : ( - '—' - )} + {item.buyer ? : '—'} - {amountFormat(item.amount)} - ≈ {convertedAmount(item, selectedCurrency, { short: true })} + {amountFormat(item.amount)}≈ {convertedAmount(item, selectedCurrency, { short: true })} {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : 'N/A'} @@ -357,7 +369,7 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob {amountFormat(item?.sellOffers?.[0]?.amount)} - {nativeCurrencyToFiat({amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate})} + {nativeCurrencyToFiat({ amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate })} {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} @@ -539,25 +551,30 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob NFTs in this Collection - {collection?.issuer && - (collection?.taxon || collection?.taxon === 0) ? ( + {collection?.issuer && (collection?.taxon || collection?.taxon === 0) ? ( <> {' '} - [ View all - ] + + ] ) : ( collection?.collection && ( <> {' '} - [ View all - ] + + ] ) )} @@ -574,22 +591,28 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob )} {!nftListLoading && nftList.length === 0 && ( -
No NFTs found
+
+ No NFTs found +
)} {!nftListLoading && nftList.length > 0 && (
- { - nftList.map((nft, i) => ( - - {nftName(nft)} - - )) - } + {nftList.map((nft, i) => ( + + {nftName(nft)} + + ))}
)} From 4c5ac39ac772082589197c96a7fe163f51ba68f5 Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Fri, 17 Oct 2025 17:17:41 +0900 Subject: [PATCH 09/18] move the calls on the server side --- pages/nft-collection/[id].js | 125 ++++++++++++----------------------- 1 file changed, 43 insertions(+), 82 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 50ba32cb3..901ccf417 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -15,49 +15,55 @@ import { } from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' -import { axiosServer, passHeaders } from '../../utils/axios' +import { axiosServer } from '../../utils/axios' import SEO from '../../components/SEO' import { nftClass } from '../../styles/pages/nft.module.scss' export async function getServerSideProps(context) { - const { locale, query, req } = context - let pageMeta = null + const { locale, query } = context const { id } = query const collectionId = id ? (Array.isArray(id) ? id[0] : id) : '' - if (collectionId) { - try { - // Try collection-specific endpoint first, fallback to NFT endpoint - let res = await axiosServer({ - method: 'get', - url: 'v2/nft-collection/' + collectionId, - headers: passHeaders(req) - }) - pageMeta = res?.data?.collection || res?.data - } catch (error) { - console.error(error) - } - } + let loading = true + let errorMessage = '' + let newdata = null + + // Try collection-specific endpoint first, fallback to NFT endpoint + let response = await axiosServer({ + method: 'get', + url: 'v2/nft-collection/' + collectionId + '?floorPrice=true&statistics=true' + }).catch((error) => { + errorMessage = 'error.' + error.message + }) + + loading = false + newdata = response?.data + if (!newdata) errorMessage = 'No data found' + + let nftListLoading = true + const url = `/v2/nfts?collection=${encodeURIComponent(id)}&limit=16&order=mintedNew&hasMedia=true` + const res = await axios(url).catch(() => null) + nftListLoading = false + const nftList = res?.data?.nfts || [] return { props: { id: collectionId, - pageMeta: pageMeta || {}, + data: newdata, + nftList: nftList, isSsrMobile: getIsSsrMobile(context), + loading: loading, + nftListLoading: nftListLoading, + errorMessage: errorMessage, ...(await serverSideTranslations(locale, ['common', 'nft'])) } } } -export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMobile, fiatRate }) { +export default function NftCollection({ id, nftList, nftListLoading, selectedCurrency, isSsrMobile, fiatRate, loading, errorMessage, data }) { const { t } = useTranslation() - const [data, setData] = useState(pageMeta) - const [loading, setLoading] = useState(false) - const [errorMessage, setErrorMessage] = useState('') const [mounted, setMounted] = useState(false) - const [nftList, setNftList] = useState([]) - const [nftListLoading, setNftListLoading] = useState(false) const statistics = data?.collection?.statistics const issuerDetails = data?.collection?.issuerDetails const collection = data?.collection @@ -85,71 +91,26 @@ export default function NftCollection({ pageMeta, id, selectedCurrency, isSsrMob }, []) useEffect(() => { - if (!selectedCurrency || !id) return - checkApi() - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [id, selectedCurrency]) - - useEffect(() => { - if (!mounted) return - if (!id) return - fetchCollectionNfts() fetchActivityData() - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [mounted, id]) - - const checkApi = async () => { - if (!id) return - - setLoading(true) - // Try collection-specific endpoint first, fallback to NFT endpoint - let response = await axiosServer({ - method: 'get', - url: 'v2/nft-collection/' + id + '?floorPrice=true&statistics=true' - }).catch((error) => { - setErrorMessage(t('error.' + error.message)) - return null - }) - - setLoading(false) - const newdata = response?.data - - if (newdata) { - setData(newdata) - } else { - setErrorMessage('No data found') - } - } - - const fetchCollectionNfts = async () => { - setNftListLoading(true) - const url = `/v2/nfts?collection=${encodeURIComponent(id)}&limit=16&order=mintedNew&hasMedia=true` - const res = await axios(url).catch(() => null) - setNftListLoading(false) - const list = res?.data?.nfts || [] - setNftList(list) - } + }, [selectedCurrency]) const fetchActivityData = async () => { setActivityLoading(true) try { - // Fetch recent sales - const salesRes = await axios( - `/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}` - ).catch(() => null) - - // Fetch recent listings (NFTs on sale) - const listingsRes = await axios( - `/v2/nfts?collection=${encodeURIComponent( - id - )}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` - ).catch(() => null) - - // Fetch recent mints - const mintsRes = await axios(`/v2/nfts?collection=${encodeURIComponent(id)}&limit=3&order=mintedNew`).catch( - () => null - ) + const [salesRes, listingsRes, mintsRes] = await Promise.all([ + axios( + `/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}` + ).catch(() => null), + + axios( + `/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` + ).catch(() => null), + + axios( + `/v2/nfts?collection=${encodeURIComponent(id)}&limit=3&order=mintedNew` + ).catch(() => null) + ]) setActivityData({ sales: salesRes?.data?.sales || [], listings: listingsRes?.data?.nfts || [], From 4a325769bcd861d245df13a3d6560b55ffd28b0a Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Mon, 20 Oct 2025 16:15:06 +0900 Subject: [PATCH 10/18] fix comments and nfts preview look --- pages/_app.js | 1 - pages/nft-collection/[id].js | 124 +++++++++++++++-------------------- 2 files changed, 54 insertions(+), 71 deletions(-) diff --git a/pages/_app.js b/pages/_app.js index 5e4f5c108..eaeb0b025 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -101,7 +101,6 @@ const MyApp = ({ Component, pageProps }) => { '/admin/watchlist', '/nft/[[...id]]', '/tokens', - '/nft/[[...id]]', '/nft-collection/[id]', '/token/[[...id]]' ] diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 901ccf417..ed2a80462 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -15,54 +15,46 @@ import { } from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' -import { axiosServer } from '../../utils/axios' import SEO from '../../components/SEO' import { nftClass } from '../../styles/pages/nft.module.scss' +import { useWidth } from '../../utils' export async function getServerSideProps(context) { const { locale, query } = context const { id } = query const collectionId = id ? (Array.isArray(id) ? id[0] : id) : '' - let loading = true let errorMessage = '' - let newdata = null - // Try collection-specific endpoint first, fallback to NFT endpoint - let response = await axiosServer({ - method: 'get', - url: 'v2/nft-collection/' + collectionId + '?floorPrice=true&statistics=true' - }).catch((error) => { - errorMessage = 'error.' + error.message - }) - - loading = false - newdata = response?.data - if (!newdata) errorMessage = 'No data found' + const [dataRes, nftRes] = await Promise.all([ + axios( + `/v2/nft-collection/${encodeURIComponent(collectionId)}?floorPrice=true&statistics=true` + ).catch((error) => { + errorMessage = 'error.' + error.message + }), + axios( + `/v2/nfts?collection=${encodeURIComponent(collectionId)}&limit=16&order=mintedNew&hasMedia=true` + ).catch(() => null) + ]) - let nftListLoading = true - const url = `/v2/nfts?collection=${encodeURIComponent(id)}&limit=16&order=mintedNew&hasMedia=true` - const res = await axios(url).catch(() => null) - nftListLoading = false - const nftList = res?.data?.nfts || [] + if (!dataRes?.data) errorMessage = 'No data found' return { props: { id: collectionId, - data: newdata, - nftList: nftList, + data: dataRes?.data, + nftList: nftRes?.data?.nfts || [], isSsrMobile: getIsSsrMobile(context), - loading: loading, - nftListLoading: nftListLoading, errorMessage: errorMessage, ...(await serverSideTranslations(locale, ['common', 'nft'])) } } } -export default function NftCollection({ id, nftList, nftListLoading, selectedCurrency, isSsrMobile, fiatRate, loading, errorMessage, data }) { +export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobile, fiatRate, errorMessage, data }) { const { t } = useTranslation() + const width = useWidth() const [mounted, setMounted] = useState(false) const statistics = data?.collection?.statistics const issuerDetails = data?.collection?.issuerDetails @@ -80,7 +72,6 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur // Client-side viewport fallback for mobile detection const updateIsMobile = () => { try { - const width = window.innerWidth || document.documentElement.clientWidth setIsMobile(isSsrMobile || width <= 768) } catch (_) {} } @@ -88,7 +79,7 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur window.addEventListener('resize', updateIsMobile) return () => window.removeEventListener('resize', updateIsMobile) // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [width]) useEffect(() => { fetchActivityData() @@ -98,23 +89,19 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur setActivityLoading(true) try { - const [salesRes, listingsRes, mintsRes] = await Promise.all([ + const [salesRes, listingsRes] = await Promise.all([ axios( `/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}` ).catch(() => null), axios( `/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` - ).catch(() => null), - - axios( - `/v2/nfts?collection=${encodeURIComponent(id)}&limit=3&order=mintedNew` ).catch(() => null) ]) setActivityData({ sales: salesRes?.data?.sales || [], listings: listingsRes?.data?.nfts || [], - mints: mintsRes?.data?.nfts || [] + mints: nftList.slice(0, 3) }) } catch (error) { console.error('Error fetching activity data:', error) @@ -134,9 +121,7 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur ) } - const collectionDescription = (data) => { - return data?.collection?.description || '' - } + const collectionDescription = data?.collection?.description const imageUrl = ipfsUrl(data?.collection?.image) @@ -363,7 +348,7 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur page="NFT Collection" title={'NFT Collection'} description={ - collectionDescription(data) || + collectionDescription || t('desc', { ns: 'nft' }) + (data?.collection?.issuer ? ' - ' + t('table.issuer') + ': ' + usernameOrAddress(data?.collection, 'issuer') @@ -374,7 +359,7 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur
{id && !data?.error ? ( <> - {loading ? ( + {(!data && !errorMessage) ? (

@@ -405,8 +390,8 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur

{collectionName(data)}

- {collectionDescription(data) && ( -

{collectionDescription(data)}

+ {collectionDescription && ( +

{collectionDescription}

)}
@@ -545,37 +530,36 @@ export default function NftCollection({ id, nftList, nftListLoading, selectedCur - {nftListLoading && ( -
- -
- )} - - {!nftListLoading && nftList.length === 0 && ( -
- No NFTs found -
- )} - - {!nftListLoading && nftList.length > 0 && ( -
- {nftList.map((nft, i) => ( - - {nftName(nft)} - - ))} -
- )} +
+ {nftList.length === 0 && ( + + No NFTs found + + )} + {nftList?.map((nft, i) => ( + + {nftName(nft)} + + ))} +
From 5108bfbd637a63cbd7a3cdc1df92593548761593 Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Mon, 20 Oct 2025 16:20:23 +0900 Subject: [PATCH 11/18] fix nfts preview look --- pages/nft-collection/[id].js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index ed2a80462..e48911503 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -554,7 +554,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi height: '64px', objectFit: 'cover', borderRadius: '4px', - margin: '2px' + margin: '1px' }} /> From 69f2eecfeac1b00af78baebda6d8e2602d83c0d4 Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Tue, 21 Oct 2025 00:03:00 +0900 Subject: [PATCH 12/18] update axiosServer and resize UI --- pages/nft-collection/[id].js | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index e48911503..2f7d6af39 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -19,24 +19,33 @@ import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' import SEO from '../../components/SEO' import { nftClass } from '../../styles/pages/nft.module.scss' import { useWidth } from '../../utils' +import { axiosServer, passHeaders } from '../../utils/axios' export async function getServerSideProps(context) { - const { locale, query } = context + const { locale, query, req } = context const { id } = query const collectionId = id ? (Array.isArray(id) ? id[0] : id) : '' + let dataRes = [] + let nftRes = [] let errorMessage = '' - const [dataRes, nftRes] = await Promise.all([ - axios( - `/v2/nft-collection/${encodeURIComponent(collectionId)}?floorPrice=true&statistics=true` - ).catch((error) => { - errorMessage = 'error.' + error.message - }), - axios( - `/v2/nfts?collection=${encodeURIComponent(collectionId)}&limit=16&order=mintedNew&hasMedia=true` - ).catch(() => null) - ]) + try { + [dataRes, nftRes] = await Promise.all([ + axiosServer({ + method: 'get', + url: `/v2/nft-collection/${encodeURIComponent(collectionId)}?floorPrice=true&statistics=true`, + headers: passHeaders(req) + }), + axiosServer({ + method: 'get', + url: `/v2/nfts?collection=${encodeURIComponent(collectionId)}&limit=16&order=mintedNew&hasMedia=true`, + headers: passHeaders(req) + }) + ]) + } catch(error) { + errorMessage = "error." + error.message + } if (!dataRes?.data) errorMessage = 'No data found' @@ -76,8 +85,6 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi } catch (_) {} } updateIsMobile() - window.addEventListener('resize', updateIsMobile) - return () => window.removeEventListener('resize', updateIsMobile) // eslint-disable-next-line react-hooks/exhaustive-deps }, [width]) From 7f4cee91243f723279527a34b9298d218d5acb1d Mon Sep 17 00:00:00 2001 From: pandablue0809 Date: Tue, 21 Oct 2025 22:57:31 +0900 Subject: [PATCH 13/18] reuse time function --- pages/nft-collection/[id].js | 57 +++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 2f7d6af39..adce68f9b 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -11,7 +11,8 @@ import { addressUsernameOrServiceLink, amountFormat, convertedAmount, - nativeCurrencyToFiat + nativeCurrencyToFiat, + fullDateAndTime } from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' @@ -51,12 +52,12 @@ export async function getServerSideProps(context) { return { props: { - id: collectionId, - data: dataRes?.data, + id: collectionId || null, + data: dataRes?.data || null, nftList: nftRes?.data?.nfts || [], isSsrMobile: getIsSsrMobile(context), - errorMessage: errorMessage, - ...(await serverSideTranslations(locale, ['common', 'nft'])) + errorMessage: errorMessage || null, + ...(await serverSideTranslations(locale, ['common'])) } } } @@ -65,9 +66,9 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi const { t } = useTranslation() const width = useWidth() const [mounted, setMounted] = useState(false) - const statistics = data?.collection?.statistics - const issuerDetails = data?.collection?.issuerDetails const collection = data?.collection + const statistics = collection?.statistics + const issuerDetails = collection?.issuerDetails const [activityData, setActivityData] = useState({ sales: [], listings: [], @@ -127,10 +128,10 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi ) ) } +`` + const collectionDescription = collection?.description - const collectionDescription = data?.collection?.description - - const imageUrl = ipfsUrl(data?.collection?.image) + const imageUrl = ipfsUrl(collection?.image) const renderActivityTable = (kind) => { let title = '' @@ -207,7 +208,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi
Date: - {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : ''} + {item.acceptedAt ? fullDateAndTime(item.acceptedAt) : ''}
)} @@ -228,7 +229,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi
Date: - {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} + {fullDateAndTime(item.ownerChangedAt)}
)} @@ -240,7 +241,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi
Date: - {new Date(item.issuedAt * 1000).toLocaleDateString()} + {fullDateAndTime(item.issuedAt)}
)} @@ -312,7 +313,9 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {amountFormat(item.amount)}≈ {convertedAmount(item, selectedCurrency, { short: true })} - {item.acceptedAt ? new Date(item.acceptedAt * 1000).toLocaleDateString() : 'N/A'} + + {item.acceptedAt ? fullDateAndTime(item.acceptedAt) : 'N/A'} + )} {kind === 'listings' && ( @@ -324,7 +327,9 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {amountFormat(item?.sellOffers?.[0]?.amount)} {nativeCurrencyToFiat({ amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate })} - {new Date(item.ownerChangedAt * 1000).toLocaleDateString()} + + {fullDateAndTime(item.ownerChangedAt)} + )} {kind === 'mints' && ( @@ -332,7 +337,9 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {item.owner && } - {new Date(item.issuedAt * 1000).toLocaleDateString()} + + {fullDateAndTime(item.issuedAt)} + )} @@ -357,8 +364,8 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi description={ collectionDescription || t('desc', { ns: 'nft' }) + - (data?.collection?.issuer - ? ' - ' + t('table.issuer') + ': ' + usernameOrAddress(data?.collection, 'issuer') + (collection?.issuer + ? ' - ' + t('table.issuer') + ': ' + usernameOrAddress(collection, 'issuer') : '') } image={{ file: imageUrl }} @@ -402,7 +409,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi )}
- {mounted && data?.collection?.issuerDetails && ( + {mounted && collection?.issuer && ( @@ -413,7 +420,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {issuerDetails?.username && ( @@ -422,7 +429,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi )} - {data?.collection?.issuerDetails?.service && ( + {collection?.issuerDetails?.service && ( @@ -437,13 +444,17 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {collection?.createdAt && ( - + )} {collection?.updatedAt && ( - + )} From 8412e8f7ba7c18a0f70c24a3dbcd4d266c32435f Mon Sep 17 00:00:00 2001 From: Viacheslav Bakshaev Date: Thu, 23 Oct 2025 11:55:30 +0300 Subject: [PATCH 14/18] UI updates --- pages/nft-collection/[id].js | 90 +++++++++++++----------------------- 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index adce68f9b..6332559be 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -32,7 +32,7 @@ export async function getServerSideProps(context) { let errorMessage = '' try { - [dataRes, nftRes] = await Promise.all([ + ;[dataRes, nftRes] = await Promise.all([ axiosServer({ method: 'get', url: `/v2/nft-collection/${encodeURIComponent(collectionId)}?floorPrice=true&statistics=true`, @@ -44,8 +44,8 @@ export async function getServerSideProps(context) { headers: passHeaders(req) }) ]) - } catch(error) { - errorMessage = "error." + error.message + } catch (error) { + errorMessage = 'error.' + error.message } if (!dataRes?.data) errorMessage = 'No data found' @@ -68,7 +68,6 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi const [mounted, setMounted] = useState(false) const collection = data?.collection const statistics = collection?.statistics - const issuerDetails = collection?.issuerDetails const [activityData, setActivityData] = useState({ sales: [], listings: [], @@ -99,11 +98,15 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi try { const [salesRes, listingsRes] = await Promise.all([ axios( - `/v2/nft-sales?collection=${encodeURIComponent(id)}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}` + `/v2/nft-sales?collection=${encodeURIComponent( + id + )}&list=lastSold&limit=3&convertCurrencies=${selectedCurrency}` ).catch(() => null), - + axios( - `/v2/nfts?collection=${encodeURIComponent(id)}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` + `/v2/nfts?collection=${encodeURIComponent( + id + )}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` ).catch(() => null) ]) setActivityData({ @@ -128,8 +131,6 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi ) ) } -`` - const collectionDescription = collection?.description const imageUrl = ipfsUrl(collection?.image) @@ -313,9 +314,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi - + )} {kind === 'listings' && ( @@ -327,9 +326,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {amountFormat(item?.sellOffers?.[0]?.amount)} {nativeCurrencyToFiat({ amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate })} - + )} {kind === 'mints' && ( @@ -337,9 +334,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi - + )} @@ -362,18 +357,16 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi page="NFT Collection" title={'NFT Collection'} description={ - collectionDescription || + collection?.description || t('desc', { ns: 'nft' }) + - (collection?.issuer - ? ' - ' + t('table.issuer') + ': ' + usernameOrAddress(collection, 'issuer') - : '') + (collection?.issuer ? ' - ' + t('table.issuer') + ': ' + usernameOrAddress(collection, 'issuer') : '') } image={{ file: imageUrl }} />
{id && !data?.error ? ( <> - {(!data && !errorMessage) ? ( + {!data && !errorMessage ? (

@@ -402,59 +395,46 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi
-
-

{collectionName(data)}

- {collectionDescription && ( -

{collectionDescription}

- )} -
- {mounted && collection?.issuer && (
Address - +
{issuerDetails.username}
Service {issuerDetails.service}
Created At{new Date(collection?.createdAt * 1000).toLocaleString()} + {fullDateAndTime(collection.createdAt)} +
Updated At{new Date(collection?.updatedAt * 1000).toLocaleString()} + {fullDateAndTime(collection.updatedAt)} +
{amountFormat(item.amount)}≈ {convertedAmount(item, selectedCurrency, { short: true })} - {item.acceptedAt ? fullDateAndTime(item.acceptedAt) : 'N/A'} - {item.acceptedAt ? fullDateAndTime(item.acceptedAt) : 'N/A'} - {fullDateAndTime(item.ownerChangedAt)} - {fullDateAndTime(item.ownerChangedAt)} {item.owner && } - {fullDateAndTime(item.issuedAt)} - {fullDateAndTime(item.issuedAt)}
- + - - + + - {issuerDetails?.username && ( - - - - - )} - {collection?.issuerDetails?.service && ( + {collection?.description && ( - - + + )} - {collection?.taxon ? ( + {collection?.taxon !== undefined && ( - ) : null} + )} + + + + {collection?.createdAt && ( - + )} {collection?.updatedAt && ( - + )} @@ -557,11 +537,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi alignItems: 'start' }} > - {nftList.length === 0 && ( - - No NFTs found - - )} + {nftList.length === 0 && No NFTs found} {nftList?.map((nft, i) => ( Date: Thu, 23 Oct 2025 14:42:06 +0300 Subject: [PATCH 15/18] updates --- pages/nft-collection/[id].js | 2091 +++++++++++++++++++++++++++++++++- 1 file changed, 2037 insertions(+), 54 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 6332559be..85be749d6 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -1,4 +1,4 @@ -import { useTranslation } from 'next-i18next' +import { i18n, useTranslation } from 'next-i18next' import { useState, useEffect } from 'react' import axios from 'axios' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' @@ -12,7 +12,8 @@ import { amountFormat, convertedAmount, nativeCurrencyToFiat, - fullDateAndTime + fullDateAndTime, + timeFromNow } from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' @@ -30,7 +31,6 @@ export async function getServerSideProps(context) { let nftRes = [] let errorMessage = '' - try { ;[dataRes, nftRes] = await Promise.all([ axiosServer({ @@ -48,7 +48,8 @@ export async function getServerSideProps(context) { errorMessage = 'error.' + error.message } - if (!dataRes?.data) errorMessage = 'No data found' + //TEST!!! + //if (!dataRes?.data) errorMessage = 'No data found' return { props: { @@ -63,6 +64,1305 @@ export async function getServerSideProps(context) { } export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobile, fiatRate, errorMessage, data }) { + data = { + type: 'xls20', + floorPrice: true, + statistics: true, + collection: { + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + name: 'sraebyzzuF', + family: null, + description: null, + image: 'bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#383.png', + createdAt: 1759327260, + updatedAt: 1761155150, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + issuerDetails: { + address: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + username: null, + service: 'Fuzzybear' + }, + taxon: 0, + floorPrices: [ + { + open: { + amount: '8288000000' + }, + private: { + amount: '215000000', + destination: 'rpx9JThQ2y37FaGeeJP7PXDUVEXY3PHZSC', + destinationDetails: { + username: 'xrpcafe', + service: 'xrp.cafe' + } + } + } + ], + statistics: { + owners: 383, + nfts: 1220, + all: { + buyers: 158, + tradedNfts: 380 + }, + day: { + buyers: 9, + tradedNfts: 9 + }, + week: { + buyers: 69, + tradedNfts: 161 + }, + month: { + buyers: 158, + tradedNfts: 380 + }, + year: { + buyers: 157, + tradedNfts: 377 + } + } + } + } + nftList = [ + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC94961979D05E9EC02', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216386, + owner: 'rwyNi4qUd7PXMM61zhcxAWvTKQj9kXADWe', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233736392E6A736F6E', + nftSerial: 99216386, + issuedAt: 1761155150, + ownerChangedAt: 1761155211, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23769.json', + metadata: { + name: 'raebyzzuF #769', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#769.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'yerG LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'eulB' + }, + { + trait_type: 'sehtolC', + value: 'ieL' + }, + { + trait_type: 'htuoM', + value: 'nioC' + }, + { + trait_type: 'raewdaeH', + value: 'rethgiferiF' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#769.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC9327BC69C05E9EC01', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216385, + owner: 'rwyNi4qUd7PXMM61zhcxAWvTKQj9kXADWe', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233139332E6A736F6E', + nftSerial: 99216385, + issuedAt: 1761155111, + ownerChangedAt: 1761155200, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23193.json', + metadata: { + name: 'raebyzzuF #193', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#193.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'wolleY LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'ksaM', + value: 'ksaM dloG' + }, + { + trait_type: 'seyE', + value: 'eulB' + }, + { + trait_type: 'sehtolC', + value: 'eceiP-eerhT' + }, + { + trait_type: 'htuoM', + value: 'prahS' + }, + { + trait_type: 'raewdaeH', + value: 'ekureP' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#193.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC91B95F59B05E9EC00', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216384, + owner: 'rBMv1oKS4KiJF7BoiAMX1AU9Jo7Jj4MphQ', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233938312E6A736F6E', + nftSerial: 99216384, + issuedAt: 1759746280, + ownerChangedAt: 1760926961, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23981.json', + metadata: { + name: 'raebyzzuF #981', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#981.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'yerG LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'elconoM' + }, + { + trait_type: 'sehtolC', + value: 'tiuS ecaR' + }, + { + trait_type: 'htuoM', + value: 'nioC' + }, + { + trait_type: 'raewdaeH', + value: 'nayiaS' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#981.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC904B0249A05E9EBFF', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216383, + owner: 'rGrnqJovoTZ3mgNP7jAJhPJjUm2YWhDqqo', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233932372E6A736F6E', + nftSerial: 99216383, + issuedAt: 1759690561, + ownerChangedAt: 1759690620, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23927.json', + metadata: { + name: 'raebyzzuF #927', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#927.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'egnarO LPRX' + }, + { + trait_type: 'ruF', + value: 'yenoH' + }, + { + trait_type: 'ksaM', + value: 'ksaM dloG' + }, + { + trait_type: 'seyE', + value: 'seyE eriF' + }, + { + trait_type: 'sehtolC', + value: 'ommA' + }, + { + trait_type: 'htuoM', + value: 'ragiC' + }, + { + trait_type: 'raewdaeH', + value: 'reitalocohC' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#927.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC9EDCA539905E9EBFE', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216382, + owner: 'rfTASBA5vSNaKn5myMz7qiN3ixQ46DsAzq', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233735342E6A736F6E', + nftSerial: 99216382, + issuedAt: 1759655081, + ownerChangedAt: 1759655171, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23754.json', + metadata: { + name: 'raebyzzuF #754', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#754.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'neerG LPRX' + }, + { + trait_type: 'ruF', + value: 'yenoH' + }, + { + trait_type: 'seyE', + value: 'eulB' + }, + { + trait_type: 'sehtolC', + value: 'lennalF' + }, + { + trait_type: 'htuoM', + value: 'nioC' + }, + { + trait_type: 'raewdaeH', + value: 'nogarD' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#754.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC9D6E4829805E9EBFD', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216381, + owner: 'rfTASBA5vSNaKn5myMz7qiN3ixQ46DsAzq', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233636322E6A736F6E', + nftSerial: 99216381, + issuedAt: 1759655081, + ownerChangedAt: 1759655232, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23662.json', + metadata: { + name: 'raebyzzuF #662', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#662.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'wolleY LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'srotaivA' + }, + { + trait_type: 'sehtolC', + value: 'laitnediserP' + }, + { + trait_type: 'htuoM', + value: 'prahS' + }, + { + trait_type: 'raewdaeH', + value: 'feihC' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#662.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC9BFFEB19705E9EBFC', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216380, + owner: 'rfTASBA5vSNaKn5myMz7qiN3ixQ46DsAzq', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233930392E6A736F6E', + nftSerial: 99216380, + issuedAt: 1759655081, + ownerChangedAt: 1759655191, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23909.json', + metadata: { + name: 'raebyzzuF #909', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#909.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'atnegaM LPRX' + }, + { + trait_type: 'ruF', + value: 'TMD' + }, + { + trait_type: 'seyE', + value: 'gninthgiL' + }, + { + trait_type: 'sehtolC', + value: 'ommA' + }, + { + trait_type: 'htuoM', + value: 'lamroN' + }, + { + trait_type: 'raewdaeH', + value: 'taH repaP' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#909.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC9A918E09605E9EBFB', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216379, + owner: 'rwnUartEhN32NegquKcDAMf8bauA3UsHrY', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A75462023313136372E6A736F6E', + nftSerial: 99216379, + issuedAt: 1759595091, + ownerChangedAt: 1759595130, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%231167.json', + metadata: { + name: 'raebyzzuF #1167', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#1167.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'atnegaM LPRX' + }, + { + trait_type: 'ruF', + value: 'kcalB' + }, + { + trait_type: 'ksaM', + value: 'ksaM dloG' + }, + { + trait_type: 'seyE', + value: 'elconoM' + }, + { + trait_type: 'sehtolC', + value: 'lennalF' + }, + { + trait_type: 'htuoM', + value: 'yfooG' + }, + { + trait_type: 'raewdaeH', + value: 'reitalocohC' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#1167.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC992330F9505E9EBFA', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216378, + owner: 'raiJs637z3ojvsehKRUyXuBxJgFVKoEogE', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233335322E6A736F6E', + nftSerial: 99216378, + issuedAt: 1759590921, + ownerChangedAt: 1759590951, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23352.json', + metadata: { + name: 'raebyzzuF #352', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#352.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'wolleY LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'seyE yppaH' + }, + { + trait_type: 'sehtolC', + value: 'ommA' + }, + { + trait_type: 'htuoM', + value: 'ragiC' + }, + { + trait_type: 'raewdaeH', + value: 'paC talF' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#352.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC97B4D3E9405E9EBF9', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216377, + owner: 'rGrnqJovoTZ3mgNP7jAJhPJjUm2YWhDqqo', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233538352E6A736F6E', + nftSerial: 99216377, + issuedAt: 1759578411, + ownerChangedAt: 1759578440, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23585.json', + metadata: { + name: 'raebyzzuF #585', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#585.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'yerG LPRX' + }, + { + trait_type: 'ruF', + value: 'raloP' + }, + { + trait_type: 'ksaM', + value: 'ksaM dloG' + }, + { + trait_type: 'seyE', + value: 'eulB' + }, + { + trait_type: 'sehtolC', + value: 'yrediorbmE' + }, + { + trait_type: 'htuoM', + value: 'prahS' + }, + { + trait_type: 'raewdaeH', + value: 'AGAM kraD' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#585.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC964676D9305E9EBF8', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216376, + owner: 'rKqqb5QZXVAL3VqXJL6obfRGeHou1DtyBV', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233930312E6A736F6E', + nftSerial: 99216376, + issuedAt: 1759514490, + ownerChangedAt: 1759514490, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23901.json', + metadata: { + name: 'raebyzzuF #901', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#901.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'atnegaM LPRX' + }, + { + trait_type: 'ruF', + value: 'kcalB' + }, + { + trait_type: 'seyE', + value: 'eulB' + }, + { + trait_type: 'sehtolC', + value: 'ngiS' + }, + { + trait_type: 'htuoM', + value: 'eugnoT' + }, + { + trait_type: 'raewdaeH', + value: 'temleH nI kcoL' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#901.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC94D819C9205E9EBF7', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216375, + owner: 'rGrnqJovoTZ3mgNP7jAJhPJjUm2YWhDqqo', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233238392E6A736F6E', + nftSerial: 99216375, + issuedAt: 1759508510, + ownerChangedAt: 1759508561, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23289.json', + metadata: { + name: 'raebyzzuF #289', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#289.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'wolleY LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'eulB' + }, + { + trait_type: 'sehtolC', + value: 'nI kcoL' + }, + { + trait_type: 'htuoM', + value: 'nioC' + }, + { + trait_type: 'raewdaeH', + value: 'nwolbdniM' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#289.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC9369BCB9105E9EBF6', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216374, + owner: 'rKRDnGGz9GttgSNRe6iMsQHFe3KQyqwFZP', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233435392E6A736F6E', + nftSerial: 99216374, + issuedAt: 1759466841, + ownerChangedAt: 1759466862, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23459.json', + metadata: { + name: 'raebyzzuF #459', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#459.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'neerG LPRX' + }, + { + trait_type: 'ruF', + value: 'raloP' + }, + { + trait_type: 'seyE', + value: 'eulB' + }, + { + trait_type: 'sehtolC', + value: 'eceiP-eerhT' + }, + { + trait_type: 'htuoM', + value: 'yfooG' + }, + { + trait_type: 'raewdaeH', + value: 'lacitcaT' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#459.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC91FB5FA9005E9EBF5', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216373, + owner: 'rsEvQmfNYxQZE6csWtYo1YesgKBRWPwZHn', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233532372E6A736F6E', + nftSerial: 99216373, + issuedAt: 1759466741, + ownerChangedAt: 1760301320, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23527.json', + metadata: { + name: 'raebyzzuF #527', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#527.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'dedoC' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'oeN' + }, + { + trait_type: 'sehtolC', + value: 'nI kcoL' + }, + { + trait_type: 'htuoM', + value: 'eugnoT' + }, + { + trait_type: 'raewdaeH', + value: 'paC lortaP' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#527.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC908D0298F05E9EBF4', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216372, + owner: 'rUmB9q64vyf4jKBDNEzk11M4MbunWo9xDV', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233835342E6A736F6E', + nftSerial: 99216372, + issuedAt: 1759460480, + ownerChangedAt: 1759460592, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23854.json', + metadata: { + name: 'raebyzzuF #854', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#854.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'elpruP-deR LPRX' + }, + { + trait_type: 'ruF', + value: 'toirtaP' + }, + { + trait_type: 'seyE', + value: 'sessalgeyE' + }, + { + trait_type: 'sehtolC', + value: 'rediaR' + }, + { + trait_type: 'htuoM', + value: 'draeB' + }, + { + trait_type: 'raewdaeH', + value: 'galF' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#854.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC9F1EA588E05E9EBF3', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216371, + owner: 'r9vcymgCTNX91gxx33ULFrmYBTBrVKuRsk', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A75462023313133342E6A736F6E', + nftSerial: 99216371, + issuedAt: 1759439601, + ownerChangedAt: 1759439640, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%231134.json', + metadata: { + name: 'raebyzzuF #1134', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#1134.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'wolleY LPRX' + }, + { + trait_type: 'ruF', + value: 'adnaP' + }, + { + trait_type: 'ksaM', + value: 'ksaM dloG' + }, + { + trait_type: 'seyE', + value: 'seyE-ediS' + }, + { + trait_type: 'sehtolC', + value: 'dlanoDcM' + }, + { + trait_type: 'htuoM', + value: 'eugnoT' + }, + { + trait_type: 'raewdaeH', + value: 'nogarD' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#1134.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + } + ] + const { t } = useTranslation() const width = useWidth() const [mounted, setMounted] = useState(false) @@ -96,7 +1396,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi setActivityLoading(true) try { - const [salesRes, listingsRes] = await Promise.all([ + let [salesRes, listingsRes] = await Promise.all([ axios( `/v2/nft-sales?collection=${encodeURIComponent( id @@ -109,6 +1409,692 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi )}&list=onSale&order=offerCreatedNew&limit=3¤cy=${selectedCurrency}` ).catch(() => null) ]) + + salesRes = { + data: { + list: 'lastSold', + order: 'soldNew', + type: 'xls20', + saleType: 'all', + period: 'all', + convertCurrencies: ['usd'], + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + total: { + primary: 0, + secondary: 493 + }, + marker: '16F6C71A00000001', + sales: [ + { + type: 'xls20', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC90E8BAE9705E9E8FC', + acceptedAt: '1761200230', + acceptedLedgerIndex: '99710021', + acceptedTxHash: '848E1CC9386DD0B73AF17C2D3497AA63D8AE15A9F0F97561B2D753C1B9795650', + acceptedAccount: 'rpx9JThQ2y37FaGeeJP7PXDUVEXY3PHZSC', + seller: 'rPQBftvkb3oD7TqG9sDAAd6DU5bgPNKD6Q', + buyer: 'rEp5TJg3qCdnC8oKRM29gTYhGh9CtgegJ7', + amount: '160000000', + broker: true, + marketplace: 'xrp.cafe', + saleType: 'secondary', + amountInConvertCurrencies: { + usd: '385.7424' + }, + nftoken: { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC90E8BAE9705E9E8FC', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99215612, + owner: 'rEp5TJg3qCdnC8oKRM29gTYhGh9CtgegJ7', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233334382E6A736F6E', + nftSerial: 99215612, + issuedAt: 1759327490, + ownerChangedAt: 1761200230, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23348.json', + metadata: { + name: 'raebyzzuF #348', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#348.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'atnegaM LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'seyE-X resaL' + }, + { + trait_type: 'sehtolC', + value: 'ieL' + }, + { + trait_type: 'htuoM', + value: 'yfooG' + }, + { + trait_type: 'raewdaeH', + value: 'paC lortaP' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#348.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + sellerDetails: { + username: null, + service: null + }, + buyerDetails: { + username: null, + service: null + }, + acceptedAccountDetails: { + username: 'xrpcafe', + service: 'xrp.cafe' + } + }, + { + type: 'xls20', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC96CD4164E05E9E9B3', + acceptedAt: '1761192741', + acceptedLedgerIndex: '99708090', + acceptedTxHash: 'DD0EAA5C0607A704AB15061015798941055A80C6E37E5865094D27C07C86CC96', + acceptedAccount: 'rpx9JThQ2y37FaGeeJP7PXDUVEXY3PHZSC', + seller: 'rrhDuWYTsHzRGemQJJCjnSwr4EE9RyghDE', + buyer: 'rafg7VDdbjEtpJPp1XAqYcgvFerRgK5pwf', + amount: '200000000', + broker: true, + marketplace: 'xrp.cafe', + saleType: 'secondary', + amountInConvertCurrencies: { + usd: '475.704' + }, + nftoken: { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC96CD4164E05E9E9B3', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99215795, + owner: 'rDeJ4nvQ5oC5dEstxTCeYqhr9GvnDRtmjK', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233439372E6A736F6E', + nftSerial: 99215795, + issuedAt: 1759327672, + ownerChangedAt: 1761204381, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23497.json', + metadata: { + name: 'raebyzzuF #497', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#497.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'atnegaM LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'seyE ratS' + }, + { + trait_type: 'sehtolC', + value: 'yrediorbmE' + }, + { + trait_type: 'htuoM', + value: 'yfooG' + }, + { + trait_type: 'raewdaeH', + value: 'relpdiR' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#497.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + sellerDetails: { + username: null, + service: null + }, + buyerDetails: { + username: null, + service: null + }, + acceptedAccountDetails: { + username: 'xrpcafe', + service: 'xrp.cafe' + } + }, + { + type: 'xls20', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC972365DB405E9EB19', + acceptedAt: '1761188720', + acceptedLedgerIndex: '99707051', + acceptedTxHash: 'F7AFAF4C3EE4972A6417ED23A8437653E0A01A8C56C35C5B135BDD056718242A', + acceptedAccount: 'rpx9JThQ2y37FaGeeJP7PXDUVEXY3PHZSC', + seller: 'rEgKovBZ4Q9Uo8RC2e6vriF6wXmbWea44e', + buyer: 'rJuVwXaTL3KUpJN4rjtgZecrtn5kxfM31n', + amount: '225753108', + broker: true, + marketplace: 'xrp.cafe', + saleType: 'secondary', + amountInConvertCurrencies: { + usd: '537.1366' + }, + nftoken: { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC972365DB405E9EB19', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99216153, + owner: 'rJuVwXaTL3KUpJN4rjtgZecrtn5kxfM31n', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233533362E6A736F6E', + nftSerial: 99216153, + issuedAt: 1759329421, + ownerChangedAt: 1761188720, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23536.json', + metadata: { + name: 'raebyzzuF #536', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#536.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'eulB LPRX' + }, + { + trait_type: 'ruF', + value: 'kcalB' + }, + { + trait_type: 'seyE', + value: 'seyE yppaH' + }, + { + trait_type: 'sehtolC', + value: 'laitnediserP' + }, + { + trait_type: 'htuoM', + value: 'eugnoT' + }, + { + trait_type: 'raewdaeH', + value: 'reitalocohC' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#536.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + } + }, + sellerDetails: { + username: null, + service: null + }, + buyerDetails: { + username: null, + service: null + }, + acceptedAccountDetails: { + username: 'xrpcafe', + service: 'xrp.cafe' + } + } + ] + } + } + listingsRes = { + data: { + type: 'xls20', + list: 'onSale', + order: 'offerCreatedNew', + currency: 'usd', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + collectionDetails: { + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + name: 'sraebyzzuF', + family: null, + description: null, + image: 'bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#383.png', + createdAt: 1759327260, + updatedAt: 1761155150, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + issuerDetails: { + address: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + username: null, + service: 'Fuzzybear' + }, + taxon: 0 + }, + sellOffers: true, + summary: { + total: 360 + }, + nfts: [ + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC93A7D03DC05E9E941', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99215681, + owner: 'rsRBA6pgV3dTT7TA4GBzqnewQ5wxn9h17J', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233638312E6A736F6E', + nftSerial: 99215681, + issuedAt: 1759327532, + ownerChangedAt: 1761067411, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23681.json', + metadata: { + name: 'raebyzzuF #681', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#681.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'elpruP-deR LPRX' + }, + { + trait_type: 'ruF', + value: 'yenoH' + }, + { + trait_type: 'seyE', + value: 'seyE-X resaL' + }, + { + trait_type: 'sehtolC', + value: 'gaT emaN' + }, + { + trait_type: 'htuoM', + value: 'prahS' + }, + { + trait_type: 'raewdaeH', + value: 'temleH nI kcoL' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#681.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + }, + sellOffers: [ + { + type: 'xls20', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC93A7D03DC05E9E941', + offerIndex: '434D96FDB3D557B0F8BEE0A0C5B1676BFDFB991B41A796660A3C4BA9DDD60C13', + createdAt: 1761211512, + createdLedgerIndex: 99712933, + createdTxHash: '9AC8AEB6DC8DA9AEB48A28BBCF8066A27B3DA735BC369C07E59BBBDA8D3FDADF', + account: 'rsRBA6pgV3dTT7TA4GBzqnewQ5wxn9h17J', + owner: 'rsRBA6pgV3dTT7TA4GBzqnewQ5wxn9h17J', + destination: 'rpx9JThQ2y37FaGeeJP7PXDUVEXY3PHZSC', + expiration: null, + amount: '232000000', + flags: { + sellToken: true + }, + accountDetails: { + username: null, + service: null + }, + ownerDetails: { + username: null, + service: null + }, + destinationDetails: { + username: 'xrpcafe', + service: 'xrp.cafe' + } + } + ] + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC90E8BAE9705E9E8FC', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99215612, + owner: 'rEp5TJg3qCdnC8oKRM29gTYhGh9CtgegJ7', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233334382E6A736F6E', + nftSerial: 99215612, + issuedAt: 1759327490, + ownerChangedAt: 1761200230, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23348.json', + metadata: { + name: 'raebyzzuF #348', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#348.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'atnegaM LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'seyE-X resaL' + }, + { + trait_type: 'sehtolC', + value: 'ieL' + }, + { + trait_type: 'htuoM', + value: 'yfooG' + }, + { + trait_type: 'raewdaeH', + value: 'paC lortaP' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#348.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + }, + sellOffers: [ + { + type: 'xls20', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC90E8BAE9705E9E8FC', + offerIndex: 'CEB7FB87A90BE8A8AB512AF3453FFB0845F3FAE251111C67AE4CF046A4922F34', + createdAt: 1761210452, + createdLedgerIndex: 99712660, + createdTxHash: 'D1C4ED6D6AD90F8B8DFF6BA66178762FB26BF9F5D1E53EBB775F3747390B0169', + account: 'rEp5TJg3qCdnC8oKRM29gTYhGh9CtgegJ7', + owner: 'rEp5TJg3qCdnC8oKRM29gTYhGh9CtgegJ7', + destination: 'rpx9JThQ2y37FaGeeJP7PXDUVEXY3PHZSC', + expiration: null, + amount: '232500000', + flags: { + sellToken: true + }, + accountDetails: { + username: null, + service: null + }, + ownerDetails: { + username: null, + service: null + }, + destinationDetails: { + username: 'xrpcafe', + service: 'xrp.cafe' + } + } + ] + }, + { + type: 'xls20', + flags: { + burnable: false, + onlyXRP: false, + trustLine: false, + transferable: true, + mutable: false + }, + issuer: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC96CD4164E05E9E9B3', + nftokenTaxon: 0, + transferFee: 3000, + sequence: 99215795, + owner: 'rDeJ4nvQ5oC5dEstxTCeYqhr9GvnDRtmjK', + uri: '697066733A2F2F62616679626569677567637466686E696C706A74327032766678626F666370686E717479366A7963726F376A7562366B6D33787278676E366A67342F72616562797A7A754620233439372E6A736F6E', + nftSerial: 99215795, + issuedAt: 1759327672, + ownerChangedAt: 1761204381, + deletedAt: null, + mintedByMarketplace: 'xrp.cafe', + collection: 'r3NftTqH2hv3skuWAEDWKvqnxjtuqcFWYR:0', + url: 'https://ipfs.io/ipfs/bafybeigugctfhnilpjt2p2vfxbofcphnqty6jycro7jub6km3xrxgn6jg4/raebyzzuF%20%23497.json', + metadata: { + name: 'raebyzzuF #497', + description: '.regdeL PRX eht no sraebyzzuF lanigirO', + external_url: '', + image: 'ipfs://bafybeid7c2wzlm6z6fhcruulavmqonlqqdkzdvhaw54lygwxyr24zbtfki/raebyzzuf-#497.png', + attributes: [ + { + trait_type: 'dnuorgkcaB', + value: 'atnegaM LPRX' + }, + { + trait_type: 'ruF', + value: 'nworB' + }, + { + trait_type: 'seyE', + value: 'seyE ratS' + }, + { + trait_type: 'sehtolC', + value: 'yrediorbmE' + }, + { + trait_type: 'htuoM', + value: 'yfooG' + }, + { + trait_type: 'raewdaeH', + value: 'relpdiR' + } + ], + properties: { + files: [ + { + uri: 'raebyzzuf-#497.png', + type: 'image/png' + } + ], + category: 'image', + creators: [] + }, + compiler: 'NFTexport.io' + }, + jsonMeta: true, + issuerDetails: { + username: null, + service: 'Fuzzybear' + }, + ownerDetails: { + username: null, + service: null + }, + sellOffers: [ + { + type: 'xls20', + nftokenID: '00080BB84F44098667FBB6C8E7F589183B68708A94C05FC96CD4164E05E9E9B3', + offerIndex: 'E91B1FC2BEC5243C4513F9371E363CA3DB6EB01C09CD95EEEC628F23CAB0E431', + createdAt: 1761204482, + createdLedgerIndex: 99711118, + createdTxHash: '0C85F4E308978F3BB08BEA3B9E8D3F258C1F9A41D1AEA5D1520F1681BA39EC36', + account: 'rDeJ4nvQ5oC5dEstxTCeYqhr9GvnDRtmjK', + owner: 'rDeJ4nvQ5oC5dEstxTCeYqhr9GvnDRtmjK', + destination: 'rpx9JThQ2y37FaGeeJP7PXDUVEXY3PHZSC', + expiration: null, + amount: '825000000', + flags: { + sellToken: true + }, + accountDetails: { + username: null, + service: null + }, + ownerDetails: { + username: null, + service: null + }, + destinationDetails: { + username: 'xrpcafe', + service: 'xrp.cafe' + } + } + ] + } + ], + limit: 3, + marker: '16E5DA2A00000001' + } + } + setActivityData({ sales: salesRes?.data?.sales || [], listings: listingsRes?.data?.nfts || [], @@ -253,9 +2239,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi }) ) : ( - + )} @@ -276,7 +2260,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {items.length > 0 && headers.map((h, i) => ( - ))} @@ -341,9 +2325,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi )) ) : ( - + )} @@ -395,7 +2377,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi
- {mounted && collection?.issuer && ( + {collection?.issuer && (
Issuer InformationCollection information
Address - - Collection{collectionName(data)}
Username{issuerDetails.username}
Service{issuerDetails.service}Description{collection?.description}
Taxon {collection?.taxon}
Issuer + +
Created At - {fullDateAndTime(collection.createdAt)} - {fullDateAndTime(collection.createdAt)}
Updated At - {fullDateAndTime(collection.updatedAt)} - {fullDateAndTime(collection.updatedAt)}
- {'No data'} - No information found
+ {h}
- {'No data'} - No information found
@@ -413,78 +2395,84 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi )} - {collection?.taxon !== undefined && ( - - - - - )} + {collection?.taxon !== undefined && ( + + + + + )} {collection?.createdAt && ( - - + + )} {collection?.updatedAt && ( - - + + )}
{collection?.description}
Taxon{collection?.taxon}
Issuer
Taxon{collection?.taxon}
Created At{fullDateAndTime(collection.createdAt)}Created + {timeFromNow(collection.createdAt, i18n)} ({fullDateAndTime(collection.createdAt)} + ) +
Updated At{fullDateAndTime(collection.updatedAt)}Updated + {timeFromNow(collection.updatedAt, i18n)} ({fullDateAndTime(collection.updatedAt)} + ) +
)} - {mounted && statistics && ( + {statistics && ( - + {statistics?.nfts && ( - + )} {statistics?.owners && ( - + )} - {statistics?.all?.tradedNfts && ( + {statistics?.all?.buyers && ( - - + + )} - {statistics?.all?.buyers && ( + {statistics?.all?.tradedNfts && ( - - + + )} {statistics?.month?.tradedNfts && ( - + )} - {statistics?.week?.tradedNfts ? ( + {statistics?.week?.tradedNfts && ( - + - ) : null} + )}
Collection StatisticsStatistics
Total SupplyTotal NFTs {statistics.nfts}
Unique OwnersUnique owners {statistics.owners}
Total Traded NFTs{statistics.all.tradedNfts}Total buyers{statistics.all.buyers}
Total Buyers{statistics.all.buyers}Total traded NFTs{statistics.all.tradedNfts}
Monthly Traded NFTsMonthly traded NFTs {statistics.month.tradedNfts}
Weekly Traded NFTsWeekly traded NFTs {statistics.week.tradedNfts}
)} @@ -528,28 +2516,23 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi -
+
{nftList.length === 0 && No NFTs found} {nftList?.map((nft, i) => ( {nftName(nft)} 800 + ? { + width: '67.3px', + height: '67.3px', + borderRadius: '4px', + margin: '2px' + } + : { width: '51px', height: '51px', borderRadius: '4px', margin: '2px' } + } /> ))} From 41f15a7229afc4c6c2a7a8f4d31b6ce25c153701 Mon Sep 17 00:00:00 2001 From: Viacheslav Bakshaev Date: Thu, 23 Oct 2025 16:46:29 +0300 Subject: [PATCH 16/18] UI updates --- components/Account/NFTokenData.js | 23 +- pages/nft-collection/[id].js | 427 ++++++++++++++---------------- utils/format.js | 28 +- utils/nft.js | 24 ++ 4 files changed, 253 insertions(+), 249 deletions(-) diff --git a/components/Account/NFTokenData.js b/components/Account/NFTokenData.js index 41a45703c..49befceb5 100644 --- a/components/Account/NFTokenData.js +++ b/components/Account/NFTokenData.js @@ -3,7 +3,7 @@ import { useState, useEffect } from 'react' import axios from 'axios' import { useTranslation } from 'next-i18next' import { xahauNetwork, useWidth } from '../../utils' -import { nftName, nftNameLink, nftThumbnail, nftUrl } from '../../utils/nft' +import { NftImage, nftName, nftNameLink, nftThumbnail } from '../../utils/nft' import LinkIcon from '../../public/images/link.svg' import { LinkTx } from '../../utils/links' import { @@ -16,17 +16,6 @@ import { dateFormat } from '../../utils/format' -const size = 60 -const placeholder = `data:image/svg+xml;utf8,${encodeURIComponent( - ` - - - No image - - ` -)}` - export default function NFTokenData({ data, address, objects, ledgerTimestamp, selectedCurrency }) { const windowWidth = useWidth() const { t } = useTranslation() @@ -249,19 +238,13 @@ export default function NFTokenData({ data, address, objects, ledgerTimestamp, s {nfts?.map((nft, i) => ( - {'NFT 800 ? { width: '61px', height: '61px', borderRadius: '4px', margin: '2px' } : { width: '51px', height: '51px', borderRadius: '4px', margin: '2px' } } - onError={(e) => { - e.target.onerror = null - console.log('Error loading NFT image:', e.target.src) - e.target.src = placeholder - }} /> ))} diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 85be749d6..6f2ce1f9f 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -1,5 +1,5 @@ import { i18n, useTranslation } from 'next-i18next' -import { useState, useEffect } from 'react' +import React, { useState, useEffect } from 'react' import axios from 'axios' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import Link from 'next/link' @@ -7,16 +7,16 @@ import Link from 'next/link' import { usernameOrAddress, AddressWithIconFilled, - shortHash, addressUsernameOrServiceLink, amountFormat, convertedAmount, nativeCurrencyToFiat, fullDateAndTime, - timeFromNow + timeFromNow, + AddressWithIconInline } from '../../utils/format' import { getIsSsrMobile } from '../../utils/mobile' -import { nftUrl, nftName, ipfsUrl } from '../../utils/nft' +import { nftName, ipfsUrl, NftImage } from '../../utils/nft' import SEO from '../../components/SEO' import { nftClass } from '../../styles/pages/nft.module.scss' @@ -48,8 +48,7 @@ export async function getServerSideProps(context) { errorMessage = 'error.' + error.message } - //TEST!!! - //if (!dataRes?.data) errorMessage = 'No data found' + if (!dataRes?.data) errorMessage = 'No data found' return { props: { @@ -1362,10 +1361,10 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi } } ] + errorMessage = null const { t } = useTranslation() const width = useWidth() - const [mounted, setMounted] = useState(false) const collection = data?.collection const statistics = collection?.statistics const [activityData, setActivityData] = useState({ @@ -1377,7 +1376,6 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi const [isMobile, setIsMobile] = useState(isSsrMobile) useEffect(() => { - setMounted(true) // Client-side viewport fallback for mobile detection const updateIsMobile = () => { try { @@ -2126,128 +2124,122 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi let items = [] if (kind === 'sales') { title = 'Recent Sales' - headers = ['NFT', 'Seller / Buyer', 'Price', 'Date'] + headers = ['NFT', 'Seller / Buyer', 'Price', 'Sold'] items = activityData.sales || [] } else if (kind === 'listings') { title = 'Recent Listings' - headers = ['NFT', 'Owner', 'Price', 'Date'] + headers = ['NFT', 'Owner', 'Price', 'Listed'] items = activityData.listings || [] } else if (kind === 'mints') { title = 'Recent Mints' - headers = ['NFT', 'Owner', 'Date'] + headers = ['NFT', 'Owner', 'Minted'] items = activityData.mints || [] } // Mobile: render blocks instead of table if (isMobile) { return ( -
- - - - - - - - {items.length > 0 ? ( - items.map((item, i) => { - return ( - +
{title}
+ + + + + + + {items.length > 0 ? ( + items.map((item, i) => { + return ( + + + - ) - }) - ) : ( - - - - )} - -
{title}
NFT -
- NFT: - {nftUrl(item?.nftoken || item, 'thumbnail') ? ( - {nftName(item?.nftoken - ) : ( - '' - )} -
- {nftName(item?.nftoken || item)} - {shortHash(item.nftokenID, 6)} -
-
-
- {kind === 'sales' && ( - <> -
- Seller: - {item.seller ? ( - - ) : ( - '' - )} -
-
- Buyer: - {item.buyer ? ( - - ) : ( - '' - )} -
-
- Price: - {amountFormat(item.amount)}≈ {convertedAmount(item, selectedCurrency, { short: true })} -
-
- Date: - {item.acceptedAt ? fullDateAndTime(item.acceptedAt) : ''} -
- - )} - {kind === 'listings' && ( - <> -
- Owner: - {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} -
-
- Price: - {amountFormat(item?.sellOffers?.[0]?.amount)} - {nativeCurrencyToFiat({ - amount: item?.sellOffers?.[0]?.amount, - selectedCurrency, - fiatRate - })} -
-
- Date: - {fullDateAndTime(item.ownerChangedAt)} -
- - )} - {kind === 'mints' && ( - <> -
- Owner: - {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 12 })} -
-
- Date: - {fullDateAndTime(item.issuedAt)} -
- - )} -
+ {' '} + {nftName(item?.nftoken || item)}
No information found
-
+ {kind === 'sales' && ( + <> + + Seller + + + + + + Buyer + + + + + + Price + + {amountFormat(item.amount)}≈ {convertedAmount(item, selectedCurrency, { short: true })} + + + + Sold + {timeFromNow(item.acceptedAt, i18n)} + + + )} + {kind === 'listings' && ( + <> + + Owner + {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 6 })} + + + Price + + {amountFormat(item?.sellOffers?.[0]?.amount)} + {nativeCurrencyToFiat({ + amount: item?.sellOffers?.[0]?.amount, + selectedCurrency, + fiatRate + })} + + + + Date + {fullDateAndTime(item.ownerChangedAt)} + + + )} + {kind === 'mints' && ( + <> + + Owner + {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 6 })} + + + Date + {fullDateAndTime(item.issuedAt)} + + + )} + {i !== items.length - 1 && ( + + +
+ + + )} + + ) + }) + ) : ( + + No information found + + )} + + ) } + const nftImageSize = kind === 'sales' ? 40 : 20 + // Desktop: render table return ( @@ -2260,7 +2252,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {items.length > 0 && headers.map((h, i) => ( - ))} @@ -2270,55 +2262,45 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {kind === 'sales' && ( <> - - + )} {kind === 'listings' && ( <> - - + - + )} {kind === 'mints' && ( <> - + )} @@ -2333,6 +2315,8 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi ) } + const statsTdClass = isMobile ? 'right' : '' + return (
-
+
{imageUrl ? ( ) : ( -
No Image Available
+ 'No image available' )}
@@ -2398,7 +2382,11 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi
{collection?.taxon !== undefined && ( @@ -2439,127 +2427,122 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {statistics?.nfts && ( - - + + )} {statistics?.owners && ( - + )} {statistics?.all?.buyers && ( - + )} {statistics?.all?.tradedNfts && ( - + )} {statistics?.month?.tradedNfts && ( - + )} {statistics?.week?.tradedNfts && ( - + )}
+ {h}
- {nftUrl(item?.nftoken || item, 'thumbnail') ? ( - {nftName(item?.nftoken - ) : ( - '' - )} + - {nftName(item?.nftoken || item)} - {shortHash(item.nftokenID, 6)} + {nftName(item?.nftoken || item)}
- {item.seller ? ( - - ) : ( - '—' - )} - {item.buyer ? : '—'} + +
+
- {amountFormat(item.amount)}≈ {convertedAmount(item, selectedCurrency, { short: true })} + + {amountFormat(item.amount)}{' '} + ≈{convertedAmount(item, selectedCurrency, { short: true })} {item.acceptedAt ? fullDateAndTime(item.acceptedAt) : 'N/A'}{timeFromNow(item.acceptedAt, i18n)} - {item.owner && } - + {item.owner && } {amountFormat(item?.sellOffers?.[0]?.amount)} {nativeCurrencyToFiat({ amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate })} {fullDateAndTime(item.ownerChangedAt)}{timeFromNow(item.ownerChangedAt, i18n)} - {item.owner && } + {item.owner && } {fullDateAndTime(item.issuedAt)}{timeFromNow(item.issuedAt, i18n)}
Issuer - +
Total NFTs{statistics.nfts}Total NFTs{statistics.nfts}
Unique owners{statistics.owners}{statistics.owners}
Total buyers{statistics.all.buyers}{statistics.all.buyers}
Total traded NFTs{statistics.all.tradedNfts}{statistics.all.tradedNfts}
Monthly traded NFTs{statistics.month.tradedNfts}{statistics.month.tradedNfts}
Weekly traded NFTs{statistics.week.tradedNfts}{statistics.week.tradedNfts}
)} - {mounted && ( - - - - + + + + + + + +
- NFTs in this Collection - {collection?.issuer && (collection?.taxon || collection?.taxon === 0) ? ( + + + + - - - - - - - -
+ NFTs in this Collection + {collection?.issuer && (collection?.taxon || collection?.taxon === 0) ? ( + <> + {' '} + [ + + View all + + ] + + ) : ( + collection?.collection && ( <> {' '} [ View all ] - ) : ( - collection?.collection && ( - <> - {' '} - [ - - View all - - ] - - ) - )} -
-
- {nftList.length === 0 && No NFTs found} - {nftList?.map((nft, i) => ( - - {nft.sequence} 800 - ? { - width: '67.3px', - height: '67.3px', - borderRadius: '4px', - margin: '2px' - } - : { width: '51px', height: '51px', borderRadius: '4px', margin: '2px' } - } - /> - - ))} -
-
- )} + ) + )} +
+
+ {nftList.length === 0 && No NFTs found} + {nftList?.map((nft, i) => ( + + 800 + ? { + width: 67.3, + height: 67.3, + borderRadius: 4, + margin: 2 + } + : { width: 80.5, height: 80.5, borderRadius: 4, margin: 2 } + } + /> + + ))} +
+
- {mounted && ( -
- {activityLoading && ( -
- -
- )} +
+ {activityLoading && ( +
+ +
+ )} - {!activityLoading && ( -
- {renderActivityTable('sales')} - {renderActivityTable('listings')} - {renderActivityTable('mints')} -
- )} -
- )} + {!activityLoading && ( +
+ {renderActivityTable('sales')} + {renderActivityTable('listings')} + {renderActivityTable('mints')} +
+ )} +
)} diff --git a/utils/format.js b/utils/format.js index 4d08c0fe9..d99328d49 100644 --- a/utils/format.js +++ b/utils/format.js @@ -54,19 +54,33 @@ export const CurrencyWithIcon = ({ token }) => { export const AddressWithIconInline = ({ data, name = 'address', options }) => { const address = data[name] + const size = 20 + const placeholder = `data:image/svg+xml;utf8,${encodeURIComponent( + ` + + + ;( + + ` + )}` + return ( - <> + - {data?.[name?.toLowerCase() { + e.target.onerror = null + e.target.src = placeholder + }} /> {addressUsernameOrServiceLink(data, name, options)} - + ) } @@ -633,7 +647,7 @@ export const addressUsernameOrServiceLink = (data, type, options = {}) => { if (options.url === '/explorer/') { return oldExplorerLink(data?.[type], { short: options.short }) } else { - return {shortAddress(data?.[type])} + return {shortAddress(data?.[type], options.short)} } } if (options.url === '/explorer/') { diff --git a/utils/nft.js b/utils/nft.js index 2e2d43243..d912881ab 100644 --- a/utils/nft.js +++ b/utils/nft.js @@ -517,3 +517,27 @@ export const nftPriceData = (t, sellOffers, loggedInAddress) => { } return t('table.text.private-offer') //shouldn't be the case } + +export const NftImage = ({ nft, style }) => { + const size = style?.width && typeof style.width !== 'string' && style.width > 0 ? style.width : 70 + let text = size < 50 ? ';(' : 'No image' + const placeholder = `data:image/svg+xml;utf8,${encodeURIComponent( + ` + + + ${text} + + ` + )}` + return ( + {nftName(nft?.nftoken { + e.target.onerror = null + e.target.src = placeholder + }} + /> + ) +} From b3b6111fe4382c01bfa27a1b579e94fd6c843bf9 Mon Sep 17 00:00:00 2001 From: Viacheslav Bakshaev Date: Thu, 23 Oct 2025 20:18:43 +0300 Subject: [PATCH 17/18] UI fixes --- pages/nft-collection/[id].js | 51 ++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index 6f2ce1f9f..b3df31ea2 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -22,6 +22,7 @@ import SEO from '../../components/SEO' import { nftClass } from '../../styles/pages/nft.module.scss' import { useWidth } from '../../utils' import { axiosServer, passHeaders } from '../../utils/axios' +import { LinkTx } from '../../utils/links' export async function getServerSideProps(context) { const { locale, query, req } = context @@ -2151,7 +2152,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi return ( - NFT + NFT {' '} {nftName(item?.nftoken || item)} @@ -2179,7 +2180,9 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi Sold - {timeFromNow(item.acceptedAt, i18n)} + + {timeFromNow(item.acceptedAt, i18n)} + )} @@ -2187,7 +2190,9 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi <> Owner - {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 6 })} + + + Price @@ -2201,8 +2206,11 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi - Date - {fullDateAndTime(item.ownerChangedAt)} + Listed + + {timeFromNow(item.sellOffers?.[0]?.createdAt, i18n)}{' '} + + )} @@ -2210,11 +2218,16 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi <> Owner - {item.owner && addressUsernameOrServiceLink(item, 'owner', { short: 6 })} + + + - Date - {fullDateAndTime(item.issuedAt)} + Minted + + {timeFromNow(item.issuedAt, i18n)} + {/* not ready on the backend */} + )} @@ -2238,9 +2251,9 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi ) } - const nftImageSize = kind === 'sales' ? 40 : 20 + const nftImageSize = ['sales', 'listings'].includes(kind) ? 40 : 20 - // Desktop: render table + // Desktop return ( @@ -2279,10 +2292,13 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi - + )} {kind === 'listings' && ( @@ -2290,9 +2306,13 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi - + )} {kind === 'mints' && ( @@ -2300,7 +2320,10 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi - + )} From 32dbc109f491a622e5bfd5a32b70220fa459647f Mon Sep 17 00:00:00 2001 From: Viacheslav Bakshaev Date: Thu, 23 Oct 2025 20:50:11 +0300 Subject: [PATCH 18/18] ui updates --- pages/nft-collection/[id].js | 17 ++++++----------- utils/nft.js | 7 +++++-- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pages/nft-collection/[id].js b/pages/nft-collection/[id].js index b3df31ea2..b97b1ecb5 100644 --- a/pages/nft-collection/[id].js +++ b/pages/nft-collection/[id].js @@ -2154,7 +2154,7 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi @@ -2273,16 +2273,11 @@ export default function NftCollection({ id, nftList, selectedCurrency, isSsrMobi {items.length > 0 ? ( items.map((item, i) => ( - {kind === 'sales' && ( <> diff --git a/utils/nft.js b/utils/nft.js index d912881ab..31d1c4fec 100644 --- a/utils/nft.js +++ b/utils/nft.js @@ -529,11 +529,14 @@ export const NftImage = ({ nft, style }) => { ` )}` + if (style?.width === 20) { + style.marginBottom = '-5px' + } return ( {nftName(nft?.nftoken { e.target.onerror = null e.target.src = placeholder
- {amountFormat(item.amount)}{' '} + {amountFormat(item.amount)} +
≈{convertedAmount(item, selectedCurrency, { short: true })}
{timeFromNow(item.acceptedAt, i18n)} + {timeFromNow(item.acceptedAt, i18n)} + {item.owner && } {amountFormat(item?.sellOffers?.[0]?.amount)} +
{nativeCurrencyToFiat({ amount: item?.sellOffers?.[0]?.amount, selectedCurrency, fiatRate })}
{timeFromNow(item.ownerChangedAt, i18n)} + {timeFromNow(item.ownerChangedAt, i18n)}{' '} + + {item.owner && } {timeFromNow(item.issuedAt, i18n)} + {timeFromNow(item.issuedAt, i18n)} + {/* not ready on the backend */} +
NFT - {' '} + {nftName(item?.nftoken || item)}
-
- - - {nftName(item?.nftoken || item)} - -
+
+ + + {nftName(item?.nftoken || item)} +