-
Notifications
You must be signed in to change notification settings - Fork 619
[TOOL-4802] NFT Asset Page #7332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
🦋 Changeset detectedLatest commit: 913ea98 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
## Walkthrough
This update introduces a comprehensive NFT Asset Page supporting both NFT Drop Claim (ERC-721) and Edition Drop Claim (ERC-1155). It adds public NFT pages, paginated grid views, token viewers, claim/buy flows, and related UI components. The implementation includes new hooks, utilities, and refactors for displaying pricing, supply progress, and responsive layouts, as well as storybook stories for new components.
## Changes
| Files/Paths (grouped) | Change Summary |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page.tsx, .../overview/nfts-grid.tsx, .../overview/tabs.tsx, .../overview/buy-nft-drop/buy-nft-drop-card.client.tsx, .../buy-nft-drop-card.server.tsx, .../buy-nft-drop-ui.client.tsx, .../buy-nft-drop.client.tsx, .../buy-edition-drop/buy-edition-drop.client.tsx, .../token-viewer/token-viewer.tsx, .../nft-page-layout.tsx, .../utils.ts, .../client-utils.ts, .../format.ts | Added and integrated NFT public page components: main page, paginated grid, tabbed navigation, buy/claim flows for ERC-721/1155, token viewer dialog, layout, hooks, utilities, and formatting. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/supply-claimed-progress.tsx, .../supply-claimed-progress.stories.tsx | Added supply claimed progress component and Storybook stories. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop-ui.stories.tsx | Added Storybook stories for BuyNFTDropUI with multiple claim and pricing scenarios. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop.client.tsx | Added BuyNFTDrop client component, claim logic, and helper functions/types. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop-card.server.tsx | Added server-side logic for buy NFT drop card and claim parameter fetching. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-edition-drop/buy-edition-drop.client.tsx | Added BuyEditionDrop client component for ERC-1155 claims. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/token-viewer/token-viewer.tsx | Added TokenViewerSheet and PageLoadTokenViewerSheet components for token details. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page-layout.tsx | Added NFTPublicPageLayout for consistent layout of NFT public pages. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts | Added utility to get total NFT count for ERC-721/1155. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/client-utils.ts | Added hook for ERC-1155 claim condition and pricing. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/format.ts | Added supplyFormatter for compact number formatting. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx | Added TokenPrice component for displaying formatted price. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx | Refactored: renamed ClaimTokenCardUI to TokenDropClaim, removed local price/supply components, used new TokenPrice and SupplyClaimedProgress. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.stories.tsx, .../erc20.tsx | Updated to use TokenDropClaim instead of ClaimTokenCardUI. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx | Added imageClassName prop for image styling customization. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/supply-claimed-progress.stories.tsx | Added Storybook story for supply claimed progress component. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx | Added containerClassName prop for header container styling. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts | Refactored public page type detection to support erc721/erc1155, updated type. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx, .../nfts/[tokenId]/shared-nfts-token-page.tsx, .../shared-overview-page.tsx | Integrated new NFT public page logic and routing. |
| apps/dashboard/src/@/components/Responsive.tsx | Added ResponsiveLayout component for device-specific rendering. |
| apps/dashboard/src/@/components/blocks/media-renderer.tsx | Added CustomMediaRenderer component with loading skeleton. |
| apps/dashboard/src/@/components/pagination-buttons.tsx | Enhanced pagination: added className prop, special case for 2 pages. |
| apps/dashboard/src/@/components/blocks/wallet-address.tsx | Added preventOpenOnFocus prop to WalletAddress component. |
| apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.tsx, .../add-to-project-card.stories.tsx | Updated MinimalProject type and story data to include slug property. |
| apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx | Updated contract view link logic to use team/project slugs when available. |
| apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx, .../published-contract/components/uri-based-deploy.tsx | Added slug property to project objects in teamsAndProjects data. |
| packages/thirdweb/src/utils/nft/parseNft.ts | Broadened NFTMetadata properties/attributes fields to allow arrays or objects. |
| apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx | Refactored CardLink tracking and keyboard event logic for consistency. |
| apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/_common/tracking.ts | Changed contractType tracking to "NFTCollection", added ercType field. |
## Sequence Diagram(s)
```mermaid
sequenceDiagram
participant User
participant NFTPublicPage
participant NFTsGrid
participant BuyNFTDropCard
participant BuyNFTDrop
participant TokenViewerSheet
participant ThirdwebContract
User->>NFTPublicPage: Visit NFT asset page
NFTPublicPage->>ThirdwebContract: Fetch metadata, selectors, NFT count
NFTPublicPage->>NFTsGrid: Render NFT grid with contract/type
NFTPublicPage->>BuyNFTDropCard: Render buy/claim UI if available
User->>NFTsGrid: Browse NFTs, select token
NFTsGrid->>TokenViewerSheet: Open token viewer modal
TokenViewerSheet->>ThirdwebContract: Fetch token metadata/details
User->>BuyNFTDropCard: Initiate NFT claim/purchase
BuyNFTDropCard->>BuyNFTDrop: Render claim UI
BuyNFTDrop->>ThirdwebContract: Prepare claim transaction, check approval
BuyNFTDrop->>ThirdwebContract: Execute claim transaction
BuyNFTDrop->>NFTPublicPage: On success, refresh dataAssessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested reviewers
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
size-limit report 📦
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #7332 +/- ##
=======================================
Coverage 55.58% 55.58%
=======================================
Files 909 909
Lines 58683 58683
Branches 4158 4163 +5
=======================================
Hits 32617 32617
Misses 25959 25959
Partials 107 107
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
🧹 Nitpick comments (19)
packages/thirdweb/src/utils/nft/parseNft.ts (2)
20-22: Update accompanying JSDoc / TODO
propertiescan now be either a record or an array, but the comment at line 19 (“// TODO check if we truly need both of these?”) still refers to the old single-record assumption.
Consider updating the TODO (or removing it) and expanding the inline docs so future readers know why both shapes are accepted.
32-33: Add note aboutattributesshape in documentationThe new union type for
attributesmirrorsproperties, but the file-level doc-block doesn’t mention it. A short description (and maybe an example) would prevent confusion for integrators parsing the metadata.apps/dashboard/src/@/components/pagination-buttons.tsx (2)
22-23: Prop should be documented on the component signature
classNameis a welcome addition, but there’s no TSDoc comment explaining what gets applied. A one-liner keeps the public API self-documenting.
74-75: Avoid duplicatingprops.classNamelogic
className={props.className}is repeated in three branches. Consider extracting arootClass = props.classNamevariable (or just spreading{ ...props }) to keep all branches consistent.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx (1)
70-83: Missingaltattribute on the<Img>elementScreen-readers will announce this image as an unnamed graphic. Passing an
altprop (even an empty string when the image is purely decorative) is considered an accessibility baseline.<Img className={cn( "size-20 shrink-0 rounded-full border bg-muted", props.imageClassName, )} + alt={props.name} src={ ... } ... />apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.client.tsx (1)
5-16: Stabilise theonSuccesshandlerEvery render recreates the arrow function, causing a prop change on
NFTDropClaimUIand a potential unnecessary re-render. Wrap it inuseCallback.-import { useDashboardRouter } from "../../../../../../../../../@/lib/DashboardRouter"; +import { useCallback } from "react"; +import { useDashboardRouter } from "../../../../../../../../../@/lib/DashboardRouter"; ... const router = useDashboardRouter(); + const handleSuccess = useCallback(() => router.refresh(), [router]); ... - <NFTDropClaimUI {...props} onSuccess={() => router.refresh()} /> + <NFTDropClaimUI {...props} onSuccess={handleSuccess} />apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/tabs.tsx (1)
14-30: Guard againstbuyPageremoval after mountIf
buyPagebecomesnullafter the tab is already set to"buy", the component will render nothing.
Consider auto-resetting the tab whenbuyPagetoggles to falsy.-const [tab, setTab] = useState<"nfts" | "buy">("nfts"); +const [tab, setTab] = useState<"nfts" | "buy">( + props.buyPage ? "nfts" : "nfts", +); ... useEffect(() => { if (!props.buyPage && tab === "buy") { setTab("nfts"); } }, [props.buyPage, tab]);apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx (2)
17-21:loadedDatacould leak very large numbers to the UI
compactNumberFormatteris configured withmaximumFractionDigits: 10, but no upper bound is set onpriceInTokens. If the contract returns a value with a very large magnitude (e.g.1e24wei formatted to tokens), the compact formatter will happily display something like “1e21 ETH”, which is not a usable price for end-users and may break layouts.- : `${compactNumberFormatter.format(props.data.priceInTokens)} ${props.data.symbol}` + : `${compactNumberFormatter.format( + Math.min(props.data.priceInTokens, 1_000_000_000), + )} ${props.data.symbol}`Clamp or round the value (or fall back to scientific notation) before calling
.formatso the UI remains predictable.
36-39: Reuse a shared formatter instead of recreating it per bundle
Intl.NumberFormatcarries non-trivial instantiation overhead. Consider exporting a singleton from autils/formatmodule so every price/text component can reuse it instead of creating its own copy.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx (1)
415-432: Total price calculation is vulnerable to FP roundingMultiplying two JS
Numbers that originated from bigints may introduce floating-point error (e.g.0.1 * 3=0.30000000000000004).
Use bigint arithmetic up to the final UI formatting step.- priceInTokens: - Number(toTokens(claimParamsData.pricePerTokenWei, claimParamsData.decimals)) * - Number(quantity), + priceInTokens: Number( + ( + BigInt(claimParamsData.pricePerTokenWei) * + BigInt(quantity) + ).toString() / + 10n ** BigInt(claimParamsData.decimals), + ),Alternatively leverage
ethers.jsformatUnits&parseUnits.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
23-41: Extension feature gates can be merged for readabilityThree nested
ifs duplicate the same pattern (ERC check +isGetNFTsSupported).
Consider factoring into a helper to make future additions easier.- if (_supportedERCs.isERC1155 && ERC1155Ext.isGetNFTsSupported(functionSelectors)) { - return { type: "erc1155" }; - } - if (_supportedERCs.isERC721 && ERC721Ext.isGetNFTsSupported(functionSelectors)) { - return { type: "erc721" }; - } + const ercChecks: Array<[boolean, () => boolean, NewPublicPageType]> = [ + [_supportedERCs.isERC1155, () => ERC1155Ext.isGetNFTsSupported(functionSelectors), "erc1155"], + [_supportedERCs.isERC721, () => ERC721Ext.isGetNFTsSupported(functionSelectors), "erc721"], + ]; + for (const [supported, guard, type] of ercChecks) { + if (supported && guard()) return { type }; + }No functional change, but the intent becomes clearer.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/edition-drop-claim.tsx (1)
351-355:decimalsprop is unused
SupplyRemainingreceivesdecimalsbut never references it, creating dead-code noise and misleading callers.Either remove the parameter or implement formatting that actually needs it.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nft-drop-claim.tsx (1)
512-516: Unuseddecimalsparameter inSupplyRemainingThe component never touches
decimals; drop the prop to keep the API minimal.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts (1)
92-99: Minor:publicPricecan reuse the fetched meta data
claimConditionQuery.dataalready containsdecimalsandsymbol; cloning those fields intopublicPriceis fine but costs an unnecessary object allocation every render.
Consider memoising or just re-exportingclaimConditionQuery.datato keep the hook light.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.tsx (1)
11-24:asynckeyword is redundant here
NFTDropClaimEmbednever awaits, so the function always returns a resolvedPromise<JSX.Element>.
Unless you intentionally rely on React’s Server Components to stream the result, you can drop theasynckeyword to avoid an unnecessary micro-task and type widening.-export async function NFTDropClaimEmbed(props: { /* … */ }) { +export function NFTDropClaimEmbed(props: { /* … */ }) {apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/token-viewer/token-viewer.tsx (2)
150-167: ExtractattributeswithuseMemoto avoid repeated parsing
getAttributesis called on every render – even while the dialog is open but nothing changes.
Parsing large metadata arrays repeatedly can be surprisingly expensive on mobile devices.- const attributes = props.data ? getAttributes(props.data) : []; + const attributes = useMemo( + () => (props.data ? getAttributes(props.data) : []), + [props.data], + );
109-122: Error message conflates “not found” with all other errors
nftQuery.isErrorfires for network errors, RPC issues, and user-rejected requests, yet the dialog always says “No NFT found”.
Consider inspectingnftQuery.errorand showing a generic fallback or the actual error message.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nfts-grid.tsx (2)
170-176: Loading skeleton count drifts frompageSize
NFTGridSkeletonrenders 50 placeholders while the actual page size is 48.
Keeping them in sync prevents layout shifts.- {Array.from({ length: 50 }).map((_, idx) => ( + {Array.from({ length: pageSize }).map((_, idx) => (
318-327:supplyClaimedmay beundefinedduring skeleton renderWhen data hasn’t arrived yet the JSX prints “undefined of … tokens bought”.
Guard the value or fall back to a skeleton placeholder.- {claimConditionQuery.data?.supplyClaimed} of{" "} + {(claimConditionQuery.data?.supplyClaimed ?? "—")} of{" "}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
apps/dashboard/src/@/components/Responsive.tsx(1 hunks)apps/dashboard/src/@/components/blocks/wallet-address.tsx(2 hunks)apps/dashboard/src/@/components/pagination-buttons.tsx(3 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx(4 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page-layout.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.client.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/edition-drop-claim.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nft-drop-claim.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nfts-grid.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/tabs.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/token-viewer/token-viewer.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx(1 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.stories.tsx(1 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.tsx(1 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx(1 hunks)packages/thirdweb/src/utils/nft/parseNft.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (10)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
shouldRenderNewPublicPage(9-53)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts (1)
redirectToContractLandingPage(6-18)
apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.tsx (1)
apps/dashboard/src/@/api/projects.ts (1)
Project(6-6)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page.tsx (1)
NFTPublicPage(19-138)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
shouldRenderNewPublicPage(9-53)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page.tsx (1)
NFTPublicPage(19-138)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/tabs.tsx (1)
apps/dashboard/src/@/components/ui/tabs.tsx (1)
TabButtons(85-159)
apps/dashboard/src/@/components/Responsive.tsx (1)
apps/dashboard/src/components/ClientOnly/ClientOnly.tsx (1)
ClientOnly(18-43)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_utils/getCurrencyMeta.ts (1)
getCurrencyMeta(8-44)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx (1)
TokenPrice(3-34)packages/thirdweb/src/exports/thirdweb.ts (1)
toTokens(190-190)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/edition-drop-claim.tsx (6)
packages/thirdweb/src/exports/thirdweb.ts (2)
ThirdwebContract(71-71)toTokens(190-190)apps/dashboard/src/hooks/analytics/useTrack.ts (1)
useTrack(13-45)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts (2)
useERC1155ClaimCondition(46-153)ASSET_PAGE_ERC1155_QUERIES_ROOT_KEY(44-44)apps/dashboard/src/utils/errorParser.tsx (1)
parseError(29-69)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx (1)
TokenPrice(3-34)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PublicPageConnectButton.tsx (1)
PublicPageConnectButton(11-40)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.tsx (3)
packages/thirdweb/src/exports/thirdweb.ts (1)
ThirdwebContract(71-71)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.client.tsx (1)
NFTDropClaimEmbedUI(5-16)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_utils/getCurrencyMeta.ts (1)
getCurrencyMeta(8-44)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Size
- GitHub Check: Lint Packages
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (16)
apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.stories.tsx (1)
46-51:slugaddition looks correct – thanks for keeping the stub in sync
No functional issues spotted.apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx (1)
42-47: Verify thatgetProjects()always returnsslug
slug: x.slugassumes the REST/GraphQL response already contains this field. If any existing environment still omitsslug, this will explode at runtime withundefinedpaths.- slug: x.slug, + slug: x.slug ?? "", // defensive defaultor add a runtime guard / type-level guarantee.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (1)
170-175: Same runtime guarantee concern forslug
Ifx.slugcan benull/undefined, links further downstream will render/team/foo//contract/..., breaking navigation.Consider asserting presence early or filtering out projects lacking a slug.
apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.tsx (1)
22-24: Type extension approved
MinimalProjectnow mirrors the backend contract. Good catch keeping the pick list in one place.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (1)
6-6: Import path checkThe helper lives in
../_utils/newPublicPage, but we already import other helpers from the same folder using the same pattern. Good catch keeping paths consistent.apps/dashboard/src/@/components/blocks/wallet-address.tsx (2)
27-28: Nice quality-of-life prop
preventOpenOnFocussolves the common UX annoyance when tabbing through the page—good addition.
68-71: Consider forwarding the prop downstreamEven with
tabIndex={-1}, the nested<Button>is still focusable and may reopen the card on key events depending on Radix behaviour.
If that proves noisy, you might need to forward the prop toHoverCard’sopenDelayor addonFocus={(e)=>e.preventDefault()}at the trigger layer.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (2)
7-17: LGTM – flexible container classesAllowing
containerClassNamegives downstream layouts breathing room without cloning this component. Implementation looks correct.
20-21: Minor visual tweak acknowledgedLogo height change from
h-6toh-5is non-breaking and keeps vertical rhythm tighter.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx (1)
44-45: Prop addition looks goodIntroducing
imageClassNameas an optional prop keeps the component backwards-compatible while allowing style overrides.
No issues spotted.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1)
104-115: Support for ERC-721 / ERC-1155 public pages added correctlyThe new switch branch cleanly re-uses
NFTPublicPage; type-safety is preserved andtokenIdis sensibly set toundefined.
No further action required.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1)
45-59: Public token page routing logic is solidThe additional branch neatly defers to
NFTPublicPagefor ERC-721/1155 contracts when no project metadata is present. Good defensive check onshouldRenderNewPublicPage.apps/dashboard/src/@/components/Responsive.tsx (1)
18-23: Potential double evaluation ofuseIsMobile
useIsMobile()runs before we know whether we are on the client (because it is outsideClientOnly).
If the hook internally toucheswindowduring SSR, hydration warnings or runtime exceptions may surface.Verify that
useIsMobileis SSR-safe (i.e. guards everywindow/matchMediaaccess with atypeof window !== "undefined"check).apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page.tsx (1)
126-133: GuardBigIntparsing oftokenId
BigInt(props.tokenId)will throw iftokenIdis not a valid integer (e.g. query param tampering).Add a safe parse with try/catch or pre-validate via
/^\d+$/.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.tsx (1)
52-66: Verify the meaning oferc721NextTokenIdToClaim
erc721NextTokenIdToClaimis populated withERC721Ext.getTotalClaimedSupply.
If the intention is to surface the next token id (often ≙ claimed supply, but not always, e.g. when tokens are burned), consider switching toERC721Ext.nextTokenIdToClaimfor clarity:- ERC721Ext.getTotalClaimedSupply({ + ERC721Ext.nextTokenIdToClaim({Please double-check the SDK semantics to ensure the UI shows an accurate next-id.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nfts-grid.tsx (1)
51-52: Potential overflow convertingBigInttoNumber
Math.ceil(Number(props.totalNFTCount) / pageSize)silently loses precision for collections larger than ≈9 quadrillion tokens.
While unlikely, usingBigIntthroughout avoids foot-guns:- const totalPages = Math.ceil(Number(props.totalNFTCount) / pageSize); + const totalPages = Number( + (props.totalNFTCount + BigInt(pageSize) - 1n) / BigInt(pageSize), + );
apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx
Show resolved
Hide resolved
...ard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx
Show resolved
Hide resolved
...pp)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx
Outdated
Show resolved
Hide resolved
...dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nft-drop-claim.tsx
Outdated
Show resolved
Hide resolved
...ard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts
Outdated
Show resolved
Hide resolved
...ard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts
Outdated
Show resolved
Hide resolved
...shboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/token-viewer/token-viewer.tsx
Show resolved
Hide resolved
...pp)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nfts-grid.tsx
Show resolved
Hide resolved
1c2a044 to
324a08e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (7)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts (2)
54-61: 🛠️ Refactor suggestionUnstable React-Query cache keys — still embedding full contract objects
Prior review already covered this.
params.contractis still stored inside both query keys, making the key identity change whenever a new signer recreates the SDK instance and blowing away the cache.
Use a stable primitive (address and optionally chain id) instead.- { - contract: params.contract, + { + contractAddress: params.contract.address,Apply the same change to the
claimParamsQuerykey (lines 102-110).Also applies to: 102-110
101-139: 🛠️ Refactor suggestion
claimParamsQuerystill fires unconditionallyThe query is mounted even when
params.enabledis false or whileclaimConditionQueryis still loading, causing an avoidable extra RPC round-trip.
Prior review already highlighted this – add anenabledguard that mirrors the first query:const claimParamsQuery = useQuery({ queryKey: [/* … */], queryFn: async () => { /* … */ }, - }); + enabled: params.enabled && (!!publicPrice || !!account), + });apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/token-viewer/token-viewer.tsx (1)
284-286:⚠️ Potential issueDuplicate React keys risk runtime warnings & incorrect diffing
Using only
attribute.trait_typeas a React key will collide when multiple traits share the same name (e.g. two “color” traits).
Generate a stable per-element key.- {attributes.map((attribute) => ( - <TraitCard key={attribute.trait_type} {...attribute} /> - ))} + {attributes.map((attribute, idx) => ( + <TraitCard key={`${attribute.trait_type}-${idx}`} {...attribute} /> + ))}apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/edition-drop-claim.tsx (2)
94-98:⚠️ Potential issueIncorrect
contractTypesent to analytics – still hard-coded
contractTypeis hard-coded as"DropERC20"but this component handles an ERC-1155 Edition Drop. Analytics will be mis-categorised.- contractType: "DropERC20", + contractType: "EditionDrop",
149-160:⚠️ Potential issueAbort flow on failed approval
If
approveTxPromiserejects, execution still proceeds to the claim transaction, almost guaranteeing a revert and double toast noise.
Return early (or wrap claim inside the sametry) after tracking the error.} catch (err) { const errorMessage = parseError(err); trackAssetBuy({ type: "error", errorMessage: typeof errorMessage === "string" ? errorMessage : "Unknown error", }); + return; // stop – approval failed }apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nft-drop-claim.tsx (2)
173-178:⚠️ Potential issueAnalytics mis-categorisation
contractTypeagain reports"DropERC20"inside an ERC-721 drop component. Use the proper type ("NFTDrop"or similar) so downstream dashboards remain accurate.- contractType: "DropERC20", + contractType: "NFTDrop",
234-244:⚠️ Potential issueContinue-on-error after failed approval
Same logical flaw as in the ERC-1155 component: if approval fails, the claim still fires. Insert an early
return.} catch (err) { const errorMessage = parseError(err); trackAssetBuy({ type: "error", errorMessage: typeof errorMessage === "string" ? errorMessage : "Unknown error", }); + return; // abort – approval failed }
🧹 Nitpick comments (4)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (4)
3-6: Avoid star-imports from large extension packages to reduce bundle size
import * as ERC721ExtandERC1155Extwill pull every export from the extension packages into the bundle, even though you only needisGetNFTsSupported. Tree-shaking of* asnamespaces is unreliable with some bundlers.-import * as ERC721Ext from "thirdweb/extensions/erc721"; -import * as ERC1155Ext from "thirdweb/extensions/erc1155"; +import { isGetNFTsSupported as isERC721GetNFTsSupported } from "thirdweb/extensions/erc721"; +import { isGetNFTsSupported as isERC1155GetNFTsSupported } from "thirdweb/extensions/erc1155";Update the usages accordingly:
- _supportedERCs.isERC1155 && ERC1155Ext.isGetNFTsSupported(functionSelectors) + _supportedERCs.isERC1155 && isERC1155GetNFTsSupported(functionSelectors)and
- _supportedERCs.isERC721 && ERC721Ext.isGetNFTsSupported(functionSelectors) + _supportedERCs.isERC721 && isERC721GetNFTsSupported(functionSelectors)
7-8: Add a default/neverbranch to future-proof the union type
NewPublicPageTypeis now a closed union. Consider adding an exhaustive check (e.g. in aswitch) or aneverfallback wherever you consume this type so TypeScript will alert you when a new token standard is added.
21-22: Drop the leading underscore for consistencyLocal variables are camel-cased elsewhere in the codebase (
functionSelectors). Renaming_supportedERCstosupported(or similar) keeps naming conventions consistent and removes the unused private-like prefix.
43-47: Minor: guard clause can exit earlierFor slight readability, consider converting the final ERC-20 check into a guard clause at the top (after computing
supportedERCs) so the positive paths are short-circuited and the defaultreturn falsesits at the bottom without nestedifs.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
apps/dashboard/src/@/components/Responsive.tsx(1 hunks)apps/dashboard/src/@/components/blocks/wallet-address.tsx(2 hunks)apps/dashboard/src/@/components/pagination-buttons.tsx(3 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx(4 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page-layout.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.client.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/edition-drop-claim.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nft-drop-claim.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nfts-grid.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/tabs.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/token-viewer/token-viewer.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx(1 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.stories.tsx(1 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.tsx(1 hunks)apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx(1 hunks)packages/thirdweb/src/utils/nft/parseNft.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (22)
- apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.stories.tsx
- apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.client.tsx
- apps/dashboard/src/@/components/blocks/wallet-address.tsx
- apps/dashboard/src/components/contract-components/contract-deploy-form/add-to-project-card.tsx
- apps/dashboard/src/@/components/pagination-buttons.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/tabs.tsx
- apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx
- apps/dashboard/src/@/components/Responsive.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page-layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nfts-grid.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-embed.tsx
- packages/thirdweb/src/utils/nft/parseNft.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/nft-page.tsx
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/edition-drop-claim.tsx (6)
packages/thirdweb/src/exports/thirdweb.ts (2)
ThirdwebContract(71-71)toTokens(190-190)apps/dashboard/src/hooks/analytics/useTrack.ts (1)
useTrack(13-45)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts (2)
useERC1155ClaimCondition(46-153)ASSET_PAGE_ERC1155_QUERIES_ROOT_KEY(44-44)apps/dashboard/src/utils/errorParser.tsx (1)
parseError(29-69)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/token-price.tsx (1)
TokenPrice(3-34)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PublicPageConnectButton.tsx (1)
PublicPageConnectButton(11-40)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/utils.ts (2)
packages/thirdweb/src/exports/thirdweb.ts (1)
ThirdwebContract(71-71)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_utils/getCurrencyMeta.ts (1)
getCurrencyMeta(8-44)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
23-41: Verify behaviour when a contract advertises multiple standardsA single contract can technically expose both ERC-721 and ERC-1155 interfaces (e.g. multi-token wrappers). With the current ordering, such a contract will always be treated as
erc1155because that check appears first.Please confirm that this precedence is intentional; otherwise, add explicit disambiguation logic or allow the caller to decide.
if (_supportedERCs.isERC1155 && _supportedERCs.isERC721) { // decide which page to show or surface a selector to the user }
324a08e to
b8c6679
Compare

PR-Codex overview
This PR focuses on enhancing the NFT and ERC20 functionalities within the dashboard, improving type definitions, and refining components for better usability and integration.
Detailed summary
NFTMetadatatype to includeslug.slugproperty in several components.supplyFormatterfor consistent supply formatting.BuyNFTDropandTokenDropClaimcomponents for better NFT purchase handling.ClaimTokenCardUIto useSupplyClaimedProgressandTokenPrice.NFTPublicPageand layout components for better organization.Summary by CodeRabbit
New Features
Enhancements
Bug Fixes
Documentation
Refactor
Chores